On 9/16/16 1:15 PM, Vincent Bernat wrote: >> diff --git a/net/ipv6/route.c b/net/ipv6/route.c >> index ad4a7ff301fc..48bae2ee2e18 100644 >> --- a/net/ipv6/route.c >> +++ b/net/ipv6/route.c >> @@ -1991,9 +1991,19 @@ static struct rt6_info *ip6_route_info_create(struct >> fib6_config *cfg) >> if (!(gwa_type & IPV6_ADDR_UNICAST)) >> goto out; >> >> - if (cfg->fc_table) >> + if (cfg->fc_table) { >> grt = ip6_nh_lookup_table(net, cfg, gw_addr); >> >> + /* a nexthop lookup can not go through a gw. >> + * if this happens on a table based lookup >> + * then fallback to a full lookup >> + */ >> + if (grt && grt->rt6i_flags & RTF_GATEWAY) { >> + ip6_rt_put(grt); >> + grt = NULL; >> + } >> + } >> + >> if (!grt) >> grt = rt6_lookup(net, gw_addr, NULL, >> cfg->fc_ifindex, 1); > > OK. Should the dev check be dismissed or do we add "dev && dev != > grt->dst.dev" just as a safety net (this would be a convulated setup, > but the correct direct route could be in an ip rule with higher priority > while the one in this table is incorrect)? >
yes. So the validity check becomes: grt = ip6_nh_lookup_table(net, cfg, gw_addr); if (grt) { if (grt->rt6i_flags & RTF_GATEWAY || dev && dev != grt->dst.dev) { ip6_rt_put(grt); grt = NULL; <---- causes the full rt6_lookup } }