struct rt6_info {
        struct dst_entry                dst;
-       struct rt6_info __rcu           *rt6_next;
        struct fib6_info                *from;
 
-       /*
-        * Tail elements of dst_entry (__refcnt etc.)
-        * and these elements (rarely used in hot path) are in
-        * the same cache line.
-        */
-       struct fib6_table               *rt6i_table;
-       struct fib6_node __rcu          *rt6i_node;
-
+       struct rt6key                   rt6i_dst;
+       struct rt6key                   rt6i_src;
        struct in6_addr                 rt6i_gateway;
-
-       /* Multipath routes:
-        * siblings is a list of rt6_info that have the the same metric/weight,
-        * destination, but not the same gateway. nsiblings is just a cache
-        * to speed up lookup.
-        */
-       struct list_head                rt6i_siblings;
-       unsigned int                    rt6i_nsiblings;
-
-       atomic_t                        rt6i_ref;
-
-       /* These are in a separate cache line. */
-       struct rt6key                   rt6i_dst ____cacheline_aligned_in_smp;
+       struct inet6_dev                *rt6i_idev;
        u32                             rt6i_flags;
-       struct rt6key                   rt6i_src;
        struct rt6key                   rt6i_prefsrc;
 
        struct list_head                rt6i_uncached;
        struct uncached_list            *rt6i_uncached_list;
 
-       struct inet6_dev                *rt6i_idev;
-       struct rt6_info * __percpu      *rt6i_pcpu;
-       struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
-
-       u32                             rt6i_metric;
        /* more non-fragment space at head required */
        unsigned short                  rt6i_nfheader_len;
-       u8                              rt6i_protocol;
-       u8                              fib6_type;
-       u8                              exception_bucket_flushed:1,
-                                       should_flush:1,
-                                       dst_nocount:1,
-                                       dst_nopolicy:1,
-                                       dst_host:1,
-                                       unused:3;
-
-       unsigned long                   expires;
-       struct dst_metrics              *fib6_metrics;
-#define fib6_pmtu              fib6_metrics->metrics[RTAX_MTU-1]
-       struct fib6_nh                  fib6_nh;
 };
 
 #define for_each_fib6_node_rt_rcu(fn)                                  \
        dst_release(&rt->dst);
 }
 
-void rt6_free_pcpu(struct rt6_info *non_pcpu_rt);
-
 struct fib6_info *fib6_info_alloc(gfp_t gfp_flags);
 void fib6_info_destroy(struct fib6_info *f6i);
 
                fib6_info_destroy(f6i);
 }
 
-static inline void rt6_hold(struct rt6_info *rt)
-{
-       atomic_inc(&rt->rt6i_ref);
-}
-
-static inline void rt6_release(struct rt6_info *rt)
-{
-       if (atomic_dec_and_test(&rt->rt6i_ref)) {
-               rt6_free_pcpu(rt);
-               dst_dev_put(&rt->dst);
-               dst_release(&rt->dst);
-       }
-}
-
 enum fib6_walk_state {
 #ifdef CONFIG_IPV6_SUBTREES
        FWS_S,
 
                .output         = ip6_pkt_discard_out,
        },
        .rt6i_flags     = (RTF_REJECT | RTF_NONEXTHOP),
-       .rt6i_protocol  = RTPROT_KERNEL,
-       .rt6i_metric    = ~(u32) 0,
-       .rt6i_ref       = ATOMIC_INIT(1),
-       .fib6_type      = RTN_UNREACHABLE,
 };
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
                .output         = ip6_pkt_prohibit_out,
        },
        .rt6i_flags     = (RTF_REJECT | RTF_NONEXTHOP),
-       .rt6i_protocol  = RTPROT_KERNEL,
-       .rt6i_metric    = ~(u32) 0,
-       .rt6i_ref       = ATOMIC_INIT(1),
-       .fib6_type      = RTN_PROHIBIT,
 };
 
 static const struct rt6_info ip6_blk_hole_entry_template = {
                .output         = dst_discard_out,
        },
        .rt6i_flags     = (RTF_REJECT | RTF_NONEXTHOP),
-       .rt6i_protocol  = RTPROT_KERNEL,
-       .rt6i_metric    = ~(u32) 0,
-       .rt6i_ref       = ATOMIC_INIT(1),
-       .fib6_type      = RTN_BLACKHOLE,
 };
 
 #endif
        struct dst_entry *dst = &rt->dst;
 
        memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
-       INIT_LIST_HEAD(&rt->rt6i_siblings);
        INIT_LIST_HEAD(&rt->rt6i_uncached);
 }
 
        rt->rt6i_gateway = ort->fib6_nh.nh_gw;
        rt->rt6i_flags = ort->rt6i_flags;
        rt6_set_from(rt, ort);
-       rt->rt6i_metric = ort->rt6i_metric;
 #ifdef CONFIG_IPV6_SUBTREES
        rt->rt6i_src = ort->rt6i_src;
 #endif
        rt->rt6i_prefsrc = ort->rt6i_prefsrc;
-       rt->rt6i_table = ort->rt6i_table;
        rt->dst.lwtstate = lwtstate_get(ort->fib6_nh.nh_lwtstate);
 }
 
 
        ip6_rt_copy_init(rt, ort);
        rt->rt6i_flags |= RTF_CACHE;
-       rt->rt6i_metric = 0;
        rt->dst.flags |= DST_HOST;
        rt->rt6i_dst.addr = *daddr;
        rt->rt6i_dst.plen = 128;
        if (!pcpu_rt)
                return NULL;
        ip6_rt_copy_init(pcpu_rt, rt);
-       pcpu_rt->rt6i_protocol = rt->rt6i_protocol;
        pcpu_rt->rt6i_flags |= RTF_PCPU;
        return pcpu_rt;
 }
                return;
 
        net = dev_net(rt6_ex->rt6i->dst.dev);
-       rt6_ex->rt6i->rt6i_node = NULL;
        hlist_del_rcu(&rt6_ex->hlist);
-       ip6_rt_put(rt6_ex->rt6i);
+       dst_release(&rt6_ex->rt6i->dst);
        kfree_rcu(rt6_ex, rcu);
        WARN_ON_ONCE(!bucket->depth);
        bucket->depth--;
        }
        rt6_ex->rt6i = nrt;
        rt6_ex->stamp = jiffies;
-       atomic_inc(&nrt->rt6i_ref);
-       nrt->rt6i_node = ort->rt6i_node;
        hlist_add_head_rcu(&rt6_ex->hlist, &bucket->chain);
        bucket->depth++;
        net->ipv6.rt6_stats->fib_rt_cache++;
                rt->rt6i_idev = in6_dev_get(loopback_dev);
                rt->rt6i_gateway = ort->rt6i_gateway;
                rt->rt6i_flags = ort->rt6i_flags & ~RTF_PCPU;
-               rt->rt6i_metric = 0;
 
                memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
 #ifdef CONFIG_IPV6_SUBTREES
 static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt)
 {
        return !(rt->rt6i_flags & RTF_CACHE) &&
-               (rt->rt6i_flags & RTF_PCPU ||
-                rcu_access_pointer(rt->rt6i_node));
+               (rt->rt6i_flags & RTF_PCPU || rt->from);
 }
 
 static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
        if (on_link)
                nrt->rt6i_flags &= ~RTF_GATEWAY;
 
-       nrt->rt6i_protocol = RTPROT_REDIRECT;
        nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
 
        /* No need to remove rt from the exception table if rt is