struct rt6_info {
        struct dst_entry                dst;
        struct rt6_info __rcu           *rt6_next;
+       struct rt6_info                 *from;
 
        /*
         * Tail elements of dst_entry (__refcnt etc.)
 {
        struct rt6_info *rt;
 
-       for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES);
-            rt = (struct rt6_info *)rt->dst.from);
+       for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES); rt = rt->from);
        if (rt && rt != rt0)
                rt0->dst.expires = rt->dst.expires;
-
        dst_set_expires(&rt0->dst, timeout);
        rt0->rt6i_flags |= RTF_EXPIRES;
 }
        u32 cookie = 0;
 
        if (rt->rt6i_flags & RTF_PCPU ||
-           (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from))
-               rt = (struct rt6_info *)(rt->dst.from);
+           (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->from))
+               rt = rt->from;
 
        rt6_get_cookie_safe(rt, &cookie);
 
 
 
 static u32 *rt6_pcpu_cow_metrics(struct rt6_info *rt)
 {
-       return dst_metrics_write_ptr(rt->dst.from);
+       return dst_metrics_write_ptr(&rt->from->dst);
 }
 
 static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
 {
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct rt6_exception_bucket *bucket;
-       struct dst_entry *from = dst->from;
+       struct rt6_info *from = rt->from;
        struct inet6_dev *idev;
 
        dst_destroy_metrics_generic(dst);
                kfree(bucket);
        }
 
-       dst->from = NULL;
-       dst_release(from);
+       rt->from = NULL;
+       dst_release(&from->dst);
 }
 
 static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
        if (rt->rt6i_flags & RTF_EXPIRES) {
                if (time_after(jiffies, rt->dst.expires))
                        return true;
-       } else if (rt->dst.from) {
+       } else if (rt->from) {
                return rt->dst.obsolete != DST_OBSOLETE_FORCE_CHK ||
-                      rt6_check_expired((struct rt6_info *)rt->dst.from);
+                       rt6_check_expired(rt->from);
        }
        return false;
 }
         */
 
        if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
-               ort = (struct rt6_info *)ort->dst.from;
+               ort = ort->from;
 
        rcu_read_lock();
        dev = ip6_rt_get_dev_rcu(ort);
 
        /* ort can't be a cache or pcpu route */
        if (ort->rt6i_flags & (RTF_CACHE | RTF_PCPU))
-               ort = (struct rt6_info *)ort->dst.from;
+               ort = ort->from;
        WARN_ON_ONCE(ort->rt6i_flags & (RTF_CACHE | RTF_PCPU));
 
        spin_lock_bh(&rt6_exception_lock);
 /* Remove the passed in cached rt from the hash table that contains it */
 int rt6_remove_exception_rt(struct rt6_info *rt)
 {
-       struct rt6_info *from = (struct rt6_info *)rt->dst.from;
        struct rt6_exception_bucket *bucket;
+       struct rt6_info *from = rt->from;
        struct in6_addr *src_key = NULL;
        struct rt6_exception *rt6_ex;
        int err;
  */
 static void rt6_update_exception_stamp_rt(struct rt6_info *rt)
 {
-       struct rt6_info *from = (struct rt6_info *)rt->dst.from;
        struct rt6_exception_bucket *bucket;
+       struct rt6_info *from = rt->from;
        struct in6_addr *src_key = NULL;
        struct rt6_exception *rt6_ex;
 
 
 static void rt6_dst_from_metrics_check(struct rt6_info *rt)
 {
-       if (rt->dst.from &&
-           dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(rt->dst.from))
-               dst_init_metrics(&rt->dst, dst_metrics_ptr(rt->dst.from), true);
+       if (rt->from &&
+           dst_metrics_ptr(&rt->dst) != dst_metrics_ptr(&rt->from->dst))
+               dst_init_metrics(&rt->dst, dst_metrics_ptr(&rt->from->dst), true);
 }
 
 static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie)
 {
        if (!__rt6_check_expired(rt) &&
            rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
-           rt6_check((struct rt6_info *)(rt->dst.from), cookie))
+           rt6_check(rt->from, cookie))
                return &rt->dst;
        else
                return NULL;
        rt6_dst_from_metrics_check(rt);
 
        if (rt->rt6i_flags & RTF_PCPU ||
-           (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->dst.from))
+           (unlikely(!list_empty(&rt->rt6i_uncached)) && rt->from))
                return rt6_dst_from_check(rt, cookie);
        else
                return rt6_check(rt, cookie);
 
 static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
 {
-       BUG_ON(from->dst.from);
+       BUG_ON(from->from);
 
        rt->rt6i_flags &= ~RTF_EXPIRES;
        dst_hold(&from->dst);
-       rt->dst.from = &from->dst;
+       rt->from = from;
        dst_init_metrics(&rt->dst, dst_metrics_ptr(&from->dst), true);
 }