]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv6/inet6_connection_sock.c
[INET]: Collect frag queues management objects together
[linux-2.6-omap-h63xx.git] / net / ipv6 / inet6_connection_sock.c
index c700302ad51a47a6e4d85029a00550fa5895a9df..78de42ada8444225799e9509ecb5424944e493f6 100644 (file)
@@ -139,8 +139,44 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
 
 EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
 
-int inet6_csk_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok)
+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
+       {
+               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;
        struct inet_sock *inet = inet_sk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct flowi fl;
@@ -165,7 +201,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok)
                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);
@@ -185,7 +221,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok)
                        return err;
                }
 
-               __ip6_dst_store(sk, dst, NULL, NULL);
+               __inet6_csk_dst_store(sk, dst, NULL, NULL);
        }
 
        skb->dst = dst_clone(dst);