ipv6: fix incorrent ipv6 ipsec packet fragment
authorGao feng <gaofeng@cn.fujitsu.com>
Mon, 19 Mar 2012 22:36:10 +0000 (22:36 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 Apr 2012 16:53:08 +0000 (09:53 -0700)
[ Upstream commit 1f85851e17b64cabd089a8a8839dddebc627948c ]

Since commit 299b0767(ipv6: Fix IPsec slowpath fragmentation problem)
In func ip6_append_data,after call skb_put(skb, fraglen + dst_exthdrlen)
the skb->len contains dst_exthdrlen,and we don't reduce dst_exthdrlen at last
This will make fraggap>0 in next "while cycle",and cause the size of skb incorrent

Fix this by reserve headroom for dst_exthdrlen.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Acked-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/ipv6/ip6_output.c

index ec56271..f7f07e2 100644 (file)
@@ -1411,8 +1411,9 @@ alloc_new_skb:
                         */
                        skb->ip_summed = csummode;
                        skb->csum = 0;
-                       /* reserve for fragmentation */
-                       skb_reserve(skb, hh_len+sizeof(struct frag_hdr));
+                       /* reserve for fragmentation and ipsec header */
+                       skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
+                                   dst_exthdrlen);
 
                        if (sk->sk_type == SOCK_DGRAM)
                                skb_shinfo(skb)->tx_flags = tx_flags;
@@ -1420,9 +1421,9 @@ alloc_new_skb:
                        /*
                         *      Find where to start putting bytes
                         */
-                       data = skb_put(skb, fraglen + dst_exthdrlen);
-                       skb_set_network_header(skb, exthdrlen + dst_exthdrlen);
-                       data += fragheaderlen + dst_exthdrlen;
+                       data = skb_put(skb, fraglen);
+                       skb_set_network_header(skb, exthdrlen);
+                       data += fragheaderlen;
                        skb->transport_header = (skb->network_header +
                                                 fragheaderlen);
                        if (fraggap) {