]> err.no Git - linux-2.6/commitdiff
[NET]: Avoid copying writable clones in tunnel drivers
authorPatrick McHardy <kaber@trash.net>
Mon, 9 Jul 2007 22:33:40 +0000 (15:33 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 11 Jul 2007 05:19:05 +0000 (22:19 -0700)
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/ip_gre.c
net/ipv4/ipip.c
net/ipv6/ip6_tunnel.c
net/ipv6/sit.c

index 63282934725e0971672bc146491c5aa178816b3e..5c14ed63e56c97c8b53f188fd0bfd6997a3e8f8c 100644 (file)
@@ -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);
index ebd2f2d532f66bd1e57d173cde001026da1527dd..396437242a1b36186db17ff5aaa1bf5d60a1734b 100644 (file)
@@ -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);
index a0902fbdb4e1ebfa71ee3f4f4d349b0735e923e2..281aee42d3f0d9c35e26c1dac4863f59628c8b62 100644 (file)
@@ -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)))
index 1efa95a99f4533198e353f713f7287cb522ec55d..eb20bb690abd736e6699f1af7987cb8a1287d3c3 100644 (file)
@@ -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);