Loading net/ipv6/route.c +38 −2 Original line number Original line Diff line number Diff line Loading @@ -1763,6 +1763,37 @@ static int ip6_convert_metrics(struct mx6_config *mxc, return -EINVAL; return -EINVAL; } } static struct rt6_info *ip6_nh_lookup_table(struct net *net, struct fib6_config *cfg, const struct in6_addr *gw_addr) { struct flowi6 fl6 = { .flowi6_oif = cfg->fc_ifindex, .daddr = *gw_addr, .saddr = cfg->fc_prefsrc, }; struct fib6_table *table; struct rt6_info *rt; int flags = 0; table = fib6_get_table(net, cfg->fc_table); if (!table) return NULL; if (!ipv6_addr_any(&cfg->fc_prefsrc)) flags |= RT6_LOOKUP_F_HAS_SADDR; rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, flags); /* if table lookup failed, fall back to full lookup */ if (rt == net->ipv6.ip6_null_entry) { ip6_rt_put(rt); rt = NULL; } return rt; } static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) { { struct net *net = cfg->fc_nlinfo.nl_net; struct net *net = cfg->fc_nlinfo.nl_net; Loading Loading @@ -1938,7 +1969,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) rt->rt6i_gateway = *gw_addr; rt->rt6i_gateway = *gw_addr; if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { struct rt6_info *grt; struct rt6_info *grt = NULL; /* IPv6 strictly inhibits using not link-local /* IPv6 strictly inhibits using not link-local addresses as nexthop address. addresses as nexthop address. Loading @@ -1950,7 +1981,12 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) if (!(gwa_type & IPV6_ADDR_UNICAST)) if (!(gwa_type & IPV6_ADDR_UNICAST)) goto out; goto out; grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); if (cfg->fc_table) grt = ip6_nh_lookup_table(net, cfg, gw_addr); if (!grt) grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); err = -EHOSTUNREACH; err = -EHOSTUNREACH; if (!grt) if (!grt) Loading Loading
net/ipv6/route.c +38 −2 Original line number Original line Diff line number Diff line Loading @@ -1763,6 +1763,37 @@ static int ip6_convert_metrics(struct mx6_config *mxc, return -EINVAL; return -EINVAL; } } static struct rt6_info *ip6_nh_lookup_table(struct net *net, struct fib6_config *cfg, const struct in6_addr *gw_addr) { struct flowi6 fl6 = { .flowi6_oif = cfg->fc_ifindex, .daddr = *gw_addr, .saddr = cfg->fc_prefsrc, }; struct fib6_table *table; struct rt6_info *rt; int flags = 0; table = fib6_get_table(net, cfg->fc_table); if (!table) return NULL; if (!ipv6_addr_any(&cfg->fc_prefsrc)) flags |= RT6_LOOKUP_F_HAS_SADDR; rt = ip6_pol_route(net, table, cfg->fc_ifindex, &fl6, flags); /* if table lookup failed, fall back to full lookup */ if (rt == net->ipv6.ip6_null_entry) { ip6_rt_put(rt); rt = NULL; } return rt; } static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) { { struct net *net = cfg->fc_nlinfo.nl_net; struct net *net = cfg->fc_nlinfo.nl_net; Loading Loading @@ -1938,7 +1969,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) rt->rt6i_gateway = *gw_addr; rt->rt6i_gateway = *gw_addr; if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { struct rt6_info *grt; struct rt6_info *grt = NULL; /* IPv6 strictly inhibits using not link-local /* IPv6 strictly inhibits using not link-local addresses as nexthop address. addresses as nexthop address. Loading @@ -1950,7 +1981,12 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) if (!(gwa_type & IPV6_ADDR_UNICAST)) if (!(gwa_type & IPV6_ADDR_UNICAST)) goto out; goto out; grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); if (cfg->fc_table) grt = ip6_nh_lookup_table(net, cfg, gw_addr); if (!grt) grt = rt6_lookup(net, gw_addr, NULL, cfg->fc_ifindex, 1); err = -EHOSTUNREACH; err = -EHOSTUNREACH; if (!grt) if (!grt) Loading