From: Patrick McHardy Date: Mon, 9 Jul 2007 22:33:40 +0000 (-0700) Subject: [NET]: Avoid copying writable clones in tunnel drivers X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=cfbba49d80be6cf8d3872b66fc5421f119843b36;p=linux-beck.git [NET]: Avoid copying writable clones in tunnel drivers Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 63282934725e..5c14ed63e56c 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -809,7 +809,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen; - if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { + if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| + (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index ebd2f2d532f6..396437242a1b 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -595,7 +595,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) */ max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr)); - if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { + if (skb_headroom(skb) < max_headroom || skb_shared(skb) || + (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index a0902fbdb4e1..281aee42d3f0 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -883,8 +883,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, */ max_headroom += LL_RESERVED_SPACE(tdev); - if (skb_headroom(skb) < max_headroom || - skb_cloned(skb) || skb_shared(skb)) { + if (skb_headroom(skb) < max_headroom || skb_shared(skb) || + (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { struct sk_buff *new_skb; if (!(new_skb = skb_realloc_headroom(skb, max_headroom))) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1efa95a99f45..eb20bb690abd 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -532,7 +532,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) */ max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr); - if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { + if (skb_headroom(skb) < max_headroom || skb_shared(skb) || + (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt);