OSDN Git Service

net/ipv6: separate handling of FIB entries from dst based routes
[uclinux-h8/linux.git] / net / ipv6 / addrconf.c
index 915cd07..e533a44 100644 (file)
@@ -916,7 +916,6 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
                pr_warn("Freeing alive inet6 address %p\n", ifp);
                return;
        }
-       ip6_rt_put(ifp->rt);
 
        kfree_rcu(ifp, rcu);
 }
@@ -1102,8 +1101,8 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
        inet6addr_notifier_call_chain(NETDEV_UP, ifa);
 out:
        if (unlikely(err < 0)) {
-               if (rt)
-                       ip6_rt_put(rt);
+               fib6_info_release(rt);
+
                if (ifa) {
                        if (ifa->idev)
                                in6_dev_put(ifa->idev);
@@ -1191,7 +1190,7 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_r
                else {
                        if (!(rt->rt6i_flags & RTF_EXPIRES))
                                fib6_set_expires(rt, expires);
-                       ip6_rt_put(rt);
+                       fib6_info_release(rt);
                }
        }
 }
@@ -2375,8 +2374,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
                        continue;
                if ((rt->rt6i_flags & noflags) != 0)
                        continue;
-               if (!dst_hold_safe(&rt->dst))
-                       rt = NULL;
+               fib6_info_hold(rt);
                break;
        }
 out:
@@ -2687,7 +2685,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
                        addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
                                              dev, expires, flags, GFP_ATOMIC);
                }
-               ip6_rt_put(rt);
+               fib6_info_release(rt);
        }
 
        /* Try to figure out our local address for this prefix */
@@ -3361,7 +3359,7 @@ static int fixup_permanent_addr(struct net *net,
                ifp->rt = rt;
                spin_unlock(&ifp->lock);
 
-               ip6_rt_put(prev);
+               fib6_info_release(prev);
        }
 
        if (!(ifp->flags & IFA_F_NOPREFIXROUTE)) {
@@ -5636,8 +5634,8 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
                                ip6_del_rt(net, rt);
                }
                if (ifp->rt) {
-                       if (dst_hold_safe(&ifp->rt->dst))
-                               ip6_del_rt(net, ifp->rt);
+                       ip6_del_rt(net, ifp->rt);
+                       ifp->rt = NULL;
                }
                rt_genid_bump_ipv6(net);
                break;