Skip to contentSkip to conversation

: Avoid copying writable clones in tunnel drivers

NET Applied Patrick McHardy 2 participants 2 messages Jul 6, 2007 – Jul 10, 2007

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

[NET]: Avoid copying writable clones in tunnel drivers

---
commit f9dcf4c066b67c80d81ed2de40f62169f3bb5cf0
tree c7cf908b9b97a9d9476fa7a96372305ec1478078
parent 720d6ee708b60d1f1f61484af02c900134de0651
author Patrick McHardy <[email protected]> Fri, 06 Jul 2007 14:25:50 +0200 committer Patrick McHardy <[email protected]> Fri, 06 Jul 2007 14:26:34 +0200

 net/ipv4/ip_gre.c     |    3 ++-
 net/ipv4/ipip.c       |    3 ++-
 net/ipv6/ip6_tunnel.c |    4 ++--
 net/ipv6/sit.c        |    3 ++-
 4 files changed, 8 insertions(+), 5 deletions(-)
net/ipv4/ip_gre.c +2 -1
index 6328293..5c14ed6 100644
@@ -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);
net/ipv4/ipip.c +2 -1
index ebd2f2d..3964372 100644
@@ -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);
net/ipv6/ip6_tunnel.c +2 -2
index a0902fb..281aee4 100644
@@ -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)))
net/ipv6/sit.c +2 -1
index 1efa95a..eb20bb6 100644
@@ -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);