EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
+static inline
+void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
+ struct in6_addr *daddr, struct in6_addr *saddr)
+{
+ __ip6_dst_store(sk, dst, daddr, saddr);
+
+#ifdef CONFIG_XFRM
+ if (dst) {
+ struct rt6_info *rt = (struct rt6_info *)dst;
+ rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
+ }
+#endif
+}
+
+static inline
+struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
+{
+ struct dst_entry *dst;
+
+ dst = __sk_dst_check(sk, cookie);
+
+#ifdef CONFIG_XFRM
+ if (dst) {
+ struct rt6_info *rt = (struct rt6_info *)dst;
+ if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
+ sk->sk_dst_cache = NULL;
+ dst_release(dst);
+ dst = NULL;
+ }
+ }
+#endif
+
+ return dst;
+}
+
int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
{
struct sock *sk = skb->sk;
final_p = &final;
}
- dst = __sk_dst_check(sk, np->dst_cookie);
+ dst = __inet6_csk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
int err = ip6_dst_lookup(sk, &dst, &fl);
return err;
}
- __ip6_dst_store(sk, dst, NULL, NULL);
+ __inet6_csk_dst_store(sk, dst, NULL, NULL);
}
skb->dst = dst_clone(dst);