Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 3197

kernel-2.6.18-238.el5.src.rpm

From: Michael S. Tsirkin <mst@redhat.com>
Date: Wed, 21 Apr 2010 14:46:56 -0400
Subject: [net] tun: orphan an skb on tx
Message-id: <20100421144655.GA24296@redhat.com>
Patchwork-id: 24274
O-Subject: [RHEL5.5.z/5.6 PATCH] tun: orphan an skb on tx
Bugzilla: 584412
RH-Acked-by: David S. Miller <davem@redhat.com>
RH-Acked-by: Jiri Olsa <jolsa@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Jiri Pirko <jpirko@redhat.com>
RH-Acked-by: Herbert Xu <herbert.xu@redhat.com>

BZ#584412
https://bugzilla.redhat.com/show_bug.cgi?id=584412

Description
The following situation was observed in the field:
tap1 sends packets, tap2 does not consume them, as a result
tap1 can not be closed. This happens because
tun/tap devices can hang on to skbs undefinitely.

As noted by Herbert, possible solutions include a timeout followed by a
copy/change of ownership of the skb, or always copying/changing
ownership if we're going into a hostile device.

This patch implements the second approach.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Yan Vugenfirer <yvugenfi@redhat.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Tested-by: Jan Kiszka <jan.kiszka@siemens.com>

Upstream status
This patch has been merged for 2.6.34, commit
0110d6f22f392f976e84ab49da1b42f85b64a3c5

Test status
The patch was tested in-house on x86_64, an upstream version of this
patch was tested by jan.kiszka@siemens.com at customer's lab.

Brew build:
http://brewweb.devel.redhat.com/brew/taskinfo?taskID=2376934


diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 4df9ef0..40eb2b4 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -125,6 +125,10 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
+       /* Orphan the skb - required as we might hang on to it
+        * for indefinite time. */
+	skb_orphan(skb);
+
 	/* Queue packet */
 	skb_queue_tail(&tun->readq, skb);
 	dev->trans_start = jiffies;