]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv6/ip6_output.c
[INET]: Prevent out-of-sync truesize on ip_fragment slow path
[net-next-2.6.git] / net / ipv6 / ip6_output.c
index 15c4f6cee3e6e54daf41bec34d5015fb7a5fdf4b..cfe9e707883c84a2f08a85c72adf12d091a2f95b 100644 (file)
@@ -636,6 +636,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
        if (skb_shinfo(skb)->frag_list) {
                int first_len = skb_pagelen(skb);
+               int truesizes = 0;
 
                if (first_len - hlen > mtu ||
                    ((first_len - hlen) & 7) ||
@@ -658,7 +659,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                                sock_hold(skb->sk);
                                frag->sk = skb->sk;
                                frag->destructor = sock_wfree;
-                               skb->truesize -= frag->truesize;
+                               truesizes += frag->truesize;
                        }
                }
 
@@ -689,6 +690,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
                first_len = skb_pagelen(skb);
                skb->data_len = first_len - skb_headlen(skb);
+               skb->truesize -= truesizes;
                skb->len = first_len;
                ipv6_hdr(skb)->payload_len = htons(first_len -
                                                   sizeof(struct ipv6hdr));