diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/skbuff.c | 2 | ||||
-rw-r--r-- | net/netfilter/core.c | 4 |
2 files changed, 5 insertions, 1 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3943c3ad9145..c989c3a0f907 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -415,6 +415,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) | |||
415 | C(csum); | 415 | C(csum); |
416 | C(local_df); | 416 | C(local_df); |
417 | n->cloned = 1; | 417 | n->cloned = 1; |
418 | n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; | ||
418 | n->nohdr = 0; | 419 | n->nohdr = 0; |
419 | C(pkt_type); | 420 | C(pkt_type); |
420 | C(ip_summed); | 421 | C(ip_summed); |
@@ -676,6 +677,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
676 | skb->network_header += off; | 677 | skb->network_header += off; |
677 | skb->mac_header += off; | 678 | skb->mac_header += off; |
678 | skb->cloned = 0; | 679 | skb->cloned = 0; |
680 | skb->hdr_len = 0; | ||
679 | skb->nohdr = 0; | 681 | skb->nohdr = 0; |
680 | atomic_set(&skb_shinfo(skb)->dataref, 1); | 682 | atomic_set(&skb_shinfo(skb)->dataref, 1); |
681 | return 0; | 683 | return 0; |
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index a84478ee2ded..3aaabec70d19 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
@@ -203,7 +203,9 @@ int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len) | |||
203 | return 0; | 203 | return 0; |
204 | 204 | ||
205 | /* Not exclusive use of packet? Must copy. */ | 205 | /* Not exclusive use of packet? Must copy. */ |
206 | if (skb_shared(*pskb) || skb_cloned(*pskb)) | 206 | if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len)) |
207 | goto copy_skb; | ||
208 | if (skb_shared(*pskb)) | ||
207 | goto copy_skb; | 209 | goto copy_skb; |
208 | 210 | ||
209 | return pskb_may_pull(*pskb, writable_len); | 211 | return pskb_may_pull(*pskb, writable_len); |