return ip6_route_output_flags(net, sk, fl6, 0);
 }
 
+/* Only conditionally release dst if flags indicates
+ * !RT6_LOOKUP_F_DST_NOREF or dst is in uncached_list.
+ */
+static inline void ip6_rt_put_flags(struct rt6_info *rt, int flags)
+{
+       if (!(flags & RT6_LOOKUP_F_DST_NOREF) ||
+           !list_empty(&rt->rt6i_uncached))
+               ip6_rt_put(rt);
+}
+
 struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
                                   const struct sk_buff *skb, int flags);
 struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 
                rt = lookup(net, net->ipv6.fib6_local_tbl, fl6, skb, flags);
                if (rt != net->ipv6.ip6_null_entry && rt->dst.error != -EAGAIN)
                        return &rt->dst;
-               ip6_rt_put(rt);
+               ip6_rt_put_flags(rt, flags);
                rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, skb, flags);
                if (rt->dst.error != -EAGAIN)
                        return &rt->dst;
-               ip6_rt_put(rt);
+               ip6_rt_put_flags(rt, flags);
        }
 
-       dst_hold(&net->ipv6.ip6_null_entry->dst);
+       if (!(flags & RT6_LOOKUP_F_DST_NOREF))
+               dst_hold(&net->ipv6.ip6_null_entry->dst);
        return &net->ipv6.ip6_null_entry->dst;
 }
 
                        goto out;
        }
 again:
-       ip6_rt_put(rt);
+       ip6_rt_put_flags(rt, flags);
        err = -EAGAIN;
        rt = NULL;
        goto out;
 
 discard_pkt:
-       dst_hold(&rt->dst);
+       if (!(flags & RT6_LOOKUP_F_DST_NOREF))
+               dst_hold(&rt->dst);
 out:
        res->rt6 = rt;
        return err;
 
 
        rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, skb, flags);
        if (rt->dst.error == -EAGAIN) {
-               ip6_rt_put(rt);
+               ip6_rt_put_flags(rt, flags);
                rt = net->ipv6.ip6_null_entry;
-               dst_hold(&rt->dst);
+               if (!(flags | RT6_LOOKUP_F_DST_NOREF))
+                       dst_hold(&rt->dst);
        }
 
        return &rt->dst;