diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 68 |
1 files changed, 20 insertions, 48 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 50eba77f5a0d..27b3733568b5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -101,13 +101,11 @@ static int rt6_score_route(struct rt6_info *rt, int oif, int strict); #ifdef CONFIG_IPV6_ROUTE_INFO static struct rt6_info *rt6_add_route_info(struct net *net, const struct in6_addr *prefix, int prefixlen, - const struct in6_addr *gwaddr, - struct net_device *dev, + const struct in6_addr *gwaddr, int ifindex, unsigned int pref); static struct rt6_info *rt6_get_route_info(struct net *net, const struct in6_addr *prefix, int prefixlen, - const struct in6_addr *gwaddr, - struct net_device *dev); + const struct in6_addr *gwaddr, int ifindex); #endif struct uncached_list { @@ -804,7 +802,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, rt = rt6_get_dflt_router(gwaddr, dev); else rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, - gwaddr, dev); + gwaddr, dev->ifindex); if (rt && !lifetime) { ip6_del_rt(rt); @@ -812,8 +810,8 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, } if (!rt && lifetime) - rt = rt6_add_route_info(net, prefix, rinfo->prefix_len, gwaddr, - dev, pref); + rt = rt6_add_route_info(net, prefix, rinfo->prefix_len, gwaddr, dev->ifindex, + pref); else if (rt) rt->rt6i_flags = RTF_ROUTEINFO | (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); @@ -2276,16 +2274,13 @@ static void ip6_rt_copy_init(struct rt6_info *rt, struct rt6_info *ort) #ifdef CONFIG_IPV6_ROUTE_INFO static struct rt6_info *rt6_get_route_info(struct net *net, const struct in6_addr *prefix, int prefixlen, - const struct in6_addr *gwaddr, - struct net_device *dev) + const struct in6_addr *gwaddr, int ifindex) { - u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO; - int ifindex = dev->ifindex; struct fib6_node *fn; struct rt6_info *rt = NULL; struct fib6_table *table; - table = fib6_get_table(net, tb_id); + table = fib6_get_table(net, RT6_TABLE_INFO); if (!table) return NULL; @@ -2311,13 +2306,12 @@ out: static struct rt6_info *rt6_add_route_info(struct net *net, const struct in6_addr *prefix, int prefixlen, - const struct in6_addr *gwaddr, - struct net_device *dev, + const struct in6_addr *gwaddr, int ifindex, unsigned int pref) { struct fib6_config cfg = { .fc_metric = IP6_RT_PRIO_USER, - .fc_ifindex = dev->ifindex, + .fc_ifindex = ifindex, .fc_dst_len = prefixlen, .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | RTF_UP | RTF_PREF(pref), @@ -2326,7 +2320,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net, .fc_nlinfo.nl_net = net, }; - cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO, + cfg.fc_table = l3mdev_fib_table_by_index(net, ifindex) ? : RT6_TABLE_INFO; cfg.fc_dst = *prefix; cfg.fc_gateway = *gwaddr; @@ -2336,17 +2330,16 @@ static struct rt6_info *rt6_add_route_info(struct net *net, ip6_route_add(&cfg); - return rt6_get_route_info(net, prefix, prefixlen, gwaddr, dev); + return rt6_get_route_info(net, prefix, prefixlen, gwaddr, ifindex); } #endif struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_device *dev) { - u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT; struct rt6_info *rt; struct fib6_table *table; - table = fib6_get_table(dev_net(dev), tb_id); + table = fib6_get_table(dev_net(dev), RT6_TABLE_DFLT); if (!table) return NULL; @@ -2380,20 +2373,20 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, cfg.fc_gateway = *gwaddr; - if (!ip6_route_add(&cfg)) { - struct fib6_table *table; - - table = fib6_get_table(dev_net(dev), cfg.fc_table); - if (table) - table->flags |= RT6_TABLE_HAS_DFLT_ROUTER; - } + ip6_route_add(&cfg); return rt6_get_dflt_router(gwaddr, dev); } -static void __rt6_purge_dflt_routers(struct fib6_table *table) +void rt6_purge_dflt_routers(struct net *net) { struct rt6_info *rt; + struct fib6_table *table; + + /* NOTE: Keep consistent with rt6_get_dflt_router */ + table = fib6_get_table(net, RT6_TABLE_DFLT); + if (!table) + return; restart: read_lock_bh(&table->tb6_lock); @@ -2407,27 +2400,6 @@ restart: } } read_unlock_bh(&table->tb6_lock); - - table->flags &= ~RT6_TABLE_HAS_DFLT_ROUTER; -} - -void rt6_purge_dflt_routers(struct net *net) -{ - struct fib6_table *table; - struct hlist_head *head; - unsigned int h; - - rcu_read_lock(); - - for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { - head = &net->ipv6.fib_table_hash[h]; - hlist_for_each_entry_rcu(table, head, tb6_hlist) { - if (table->flags & RT6_TABLE_HAS_DFLT_ROUTER) - __rt6_purge_dflt_routers(table); - } - } - - rcu_read_unlock(); } static void rtmsg_to_fib6_config(struct net *net, |