ipv6: Only create RTF_CACHE routes after encountering pmtu exception
[firefly-linux-kernel-4.4.55.git] / include / net / ip6_route.h
index 5e192068e6cb61a78d9b19b2b58bffd7c68b44bb..784ee3d01dbf5adad590c1baf82faf96d7632bac 100644 (file)
@@ -163,11 +163,14 @@ static inline bool ipv6_unicast_destination(const struct sk_buff *skb)
        return rt->rt6i_flags & RTF_LOCAL;
 }
 
-static inline bool ipv6_anycast_destination(const struct sk_buff *skb)
+static inline bool ipv6_anycast_destination(const struct dst_entry *dst,
+                                           const struct in6_addr *daddr)
 {
-       struct rt6_info *rt = (struct rt6_info *) skb_dst(skb);
+       struct rt6_info *rt = (struct rt6_info *)dst;
 
-       return rt->rt6i_flags & RTF_ANYCAST;
+       return rt->rt6i_flags & RTF_ANYCAST ||
+               (rt->rt6i_dst.plen != 128 &&
+                ipv6_addr_equal(&rt->rt6i_dst.addr, daddr));
 }
 
 int ip6_fragment(struct sock *sk, struct sk_buff *skb,
@@ -194,9 +197,15 @@ static inline bool ip6_sk_ignore_df(const struct sock *sk)
               inet6_sk(sk)->pmtudisc == IPV6_PMTUDISC_OMIT;
 }
 
-static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt)
+static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,
+                                          struct in6_addr *daddr)
 {
-       return &rt->rt6i_gateway;
+       if (rt->rt6i_flags & RTF_GATEWAY)
+               return &rt->rt6i_gateway;
+       else if (unlikely(rt->rt6i_flags & RTF_CACHE))
+               return &rt->rt6i_dst.addr;
+       else
+               return daddr;
 }
 
 #endif