struct dst_entry *dst = skb_dst(skb);
        struct net_device *dev = dst->dev;
        struct neighbour *neigh;
+       struct rt6_info *rt;
 
        skb->protocol = htons(ETH_P_IPV6);
        skb->dev = dev;
        }
 
        rcu_read_lock();
-       neigh = dst_get_neighbour_noref(dst);
+       rt = (struct rt6_info *) dst;
+       neigh = rt->n;
        if (neigh) {
                int res = dst_neigh_output(dst, neigh, skb);
 
        struct net *net = sock_net(sk);
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
        struct neighbour *n;
+       struct rt6_info *rt;
 #endif
        int err;
 
         * dst entry of the nexthop router
         */
        rcu_read_lock();
-       n = dst_get_neighbour_noref(*dst);
+       rt = (struct rt6_info *) dst;
+       n = rt->n;
        if (n && !(n->nud_state & NUD_VALID)) {
                struct inet6_ifaddr *ifp;
                struct flowi6 fl_gw6;
 
                if (IS_ERR(n))
                        return PTR_ERR(n);
        }
-       dst_set_neighbour(&rt->dst, n);
+       rt->n = n;
 
        return 0;
 }
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct inet6_dev *idev = rt->rt6i_idev;
 
+       if (rt->n)
+               neigh_release(rt->n);
+
        if (!(rt->dst.flags & DST_HOST))
                dst_destroy_metrics_generic(dst);
 
        struct net_device *loopback_dev =
                dev_net(dev)->loopback_dev;
 
-       if (dev != loopback_dev && idev && idev->dev == dev) {
-               struct inet6_dev *loopback_idev =
-                       in6_dev_get(loopback_dev);
-               if (loopback_idev) {
-                       rt->rt6i_idev = loopback_idev;
-                       in6_dev_put(idev);
+       if (dev != loopback_dev) {
+               if (idev && idev->dev == dev) {
+                       struct inet6_dev *loopback_idev =
+                               in6_dev_get(loopback_dev);
+                       if (loopback_idev) {
+                               rt->rt6i_idev = loopback_idev;
+                               in6_dev_put(idev);
+                       }
+               }
+               if (rt->n && rt->n->dev == dev) {
+                       rt->n->dev = loopback_dev;
+                       dev_hold(loopback_dev);
+                       dev_put(dev);
                }
        }
 }
         * to no more than one per minute.
         */
        rcu_read_lock();
-       neigh = rt ? dst_get_neighbour_noref(&rt->dst) : NULL;
+       neigh = rt ? rt->n : NULL;
        if (!neigh || (neigh->nud_state & NUD_VALID))
                goto out;
        read_lock_bh(&neigh->lock);
        int m;
 
        rcu_read_lock();
-       neigh = dst_get_neighbour_noref(&rt->dst);
+       neigh = rt->n;
        if (rt->rt6i_flags & RTF_NONEXTHOP ||
            !(rt->rt6i_flags & RTF_GATEWAY))
                m = 1;
 
        if (rt) {
                rt->rt6i_flags |= RTF_CACHE;
-               dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_noref_raw(&ort->dst)));
+               rt->n = neigh_clone(ort->n);
        }
        return rt;
 }
        dst_hold(&rt->dst);
        read_unlock_bh(&table->tb6_lock);
 
-       if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
+       if (!rt->n && !(rt->rt6i_flags & RTF_NONEXTHOP))
                nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
        else if (!(rt->dst.flags & DST_HOST))
                nrt = rt6_alloc_clone(rt, &fl6->daddr);
 
        rt->dst.flags |= DST_HOST;
        rt->dst.output  = ip6_output;
-       dst_set_neighbour(&rt->dst, neigh);
+       rt->n = neigh;
        atomic_set(&rt->dst.__refcnt, 1);
        rt->rt6i_dst.addr = fl6->daddr;
        rt->rt6i_dst.plen = 128;
        dst_confirm(&rt->dst);
 
        /* Duplicate redirect: silently ignore. */
-       old_neigh = dst_get_neighbour_noref_raw(&rt->dst);
+       old_neigh = rt->n;
        if (neigh == old_neigh)
                goto out;
 
                nrt->rt6i_flags &= ~RTF_GATEWAY;
 
        nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
-       dst_set_neighbour(&nrt->dst, neigh_clone(neigh));
+       nrt->n = neigh_clone(neigh);
 
        if (ip6_ins_rt(nrt))
                goto out;
                goto nla_put_failure;
 
        rcu_read_lock();
-       n = dst_get_neighbour_noref(&rt->dst);
+       n = rt->n;
        if (n) {
                if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) {
                        rcu_read_unlock();
        seq_puts(m, "00000000000000000000000000000000 00 ");
 #endif
        rcu_read_lock();
-       n = dst_get_neighbour_noref(&rt->dst);
+       n = rt->n;
        if (n) {
                seq_printf(m, "%pi6", n->primary_key);
        } else {