aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/addrconf.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e39239e6426e..d0611a5de45f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1713,6 +1713,40 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
1713 ip6_route_add(&cfg); 1713 ip6_route_add(&cfg);
1714} 1714}
1715 1715
1716
1717static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1718 int plen,
1719 const struct net_device *dev,
1720 u32 flags, u32 noflags)
1721{
1722 struct fib6_node *fn;
1723 struct rt6_info *rt = NULL;
1724 struct fib6_table *table;
1725
1726 table = fib6_get_table(dev_net(dev), RT6_TABLE_PREFIX);
1727 if (table == NULL)
1728 return NULL;
1729
1730 write_lock_bh(&table->tb6_lock);
1731 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0);
1732 if (!fn)
1733 goto out;
1734 for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
1735 if (rt->rt6i_dev->ifindex != dev->ifindex)
1736 continue;
1737 if ((rt->rt6i_flags & flags) != flags)
1738 continue;
1739 if ((noflags != 0) && ((rt->rt6i_flags & flags) != 0))
1740 continue;
1741 dst_hold(&rt->dst);
1742 break;
1743 }
1744out:
1745 write_unlock_bh(&table->tb6_lock);
1746 return rt;
1747}
1748
1749
1716/* Create "default" multicast route to the interface */ 1750/* Create "default" multicast route to the interface */
1717 1751
1718static void addrconf_add_mroute(struct net_device *dev) 1752static void addrconf_add_mroute(struct net_device *dev)
@@ -1842,10 +1876,13 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1842 if (addrconf_finite_timeout(rt_expires)) 1876 if (addrconf_finite_timeout(rt_expires))
1843 rt_expires *= HZ; 1877 rt_expires *= HZ;
1844 1878
1845 rt = rt6_lookup(net, &pinfo->prefix, NULL, 1879 rt = addrconf_get_prefix_route(&pinfo->prefix,
1846 dev->ifindex, 1); 1880 pinfo->prefix_len,
1881 dev,
1882 RTF_ADDRCONF | RTF_PREFIX_RT,
1883 RTF_GATEWAY | RTF_DEFAULT);
1847 1884
1848 if (rt && addrconf_is_prefix_route(rt)) { 1885 if (rt) {
1849 /* Autoconf prefix route */ 1886 /* Autoconf prefix route */
1850 if (valid_lft == 0) { 1887 if (valid_lft == 0) {
1851 ip6_del_rt(rt); 1888 ip6_del_rt(rt);