From ca1c76a50658eef9a8b08a6f49ab3d896a7762e9 Mon Sep 17 00:00:00 2001 From: Andreas Hofmeister Date: Wed, 26 Oct 2011 03:24:29 +0000 Subject: [PATCH] --- yaml --- r: 271631 b: refs/heads/master c: 14ef37b6d00eb5d06704e45989ba4c21e7be7673 h: refs/heads/master i: 271629: bc6c759cb7a8709b62c780e610c099fb397a5215 271627: 21b08566d9c8b4bab1d8deb9c25041b966479fa9 271623: 19eb2c3b12bfb6dd813aa6b3816e2fcfa011d743 271615: e36eb74819f0294a59e678c506f840b3199616c2 v: v3 --- [refs] | 2 +- trunk/net/ipv6/addrconf.c | 43 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 95c7d3181d81..c2e62e14e8dc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e6d265e8504ab4a3368b8645d318b344ee88b280 +refs/heads/master: 14ef37b6d00eb5d06704e45989ba4c21e7be7673 diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index e39239e6426e..d0611a5de45f 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -1713,6 +1713,40 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, ip6_route_add(&cfg); } + +static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, + int plen, + const struct net_device *dev, + u32 flags, u32 noflags) +{ + struct fib6_node *fn; + struct rt6_info *rt = NULL; + struct fib6_table *table; + + table = fib6_get_table(dev_net(dev), RT6_TABLE_PREFIX); + if (table == NULL) + return NULL; + + write_lock_bh(&table->tb6_lock); + fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0); + if (!fn) + goto out; + for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) { + if (rt->rt6i_dev->ifindex != dev->ifindex) + continue; + if ((rt->rt6i_flags & flags) != flags) + continue; + if ((noflags != 0) && ((rt->rt6i_flags & flags) != 0)) + continue; + dst_hold(&rt->dst); + break; + } +out: + write_unlock_bh(&table->tb6_lock); + return rt; +} + + /* Create "default" multicast route to the interface */ static void addrconf_add_mroute(struct net_device *dev) @@ -1842,10 +1876,13 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) if (addrconf_finite_timeout(rt_expires)) rt_expires *= HZ; - rt = rt6_lookup(net, &pinfo->prefix, NULL, - dev->ifindex, 1); + rt = addrconf_get_prefix_route(&pinfo->prefix, + pinfo->prefix_len, + dev, + RTF_ADDRCONF | RTF_PREFIX_RT, + RTF_GATEWAY | RTF_DEFAULT); - if (rt && addrconf_is_prefix_route(rt)) { + if (rt) { /* Autoconf prefix route */ if (valid_lft == 0) { ip6_del_rt(rt);