[PATCH] (6/6) ipvs -- get rid of skb_linearize

STALE8359d

3 messages, 3 authors, 2003-09-17 · open the first message on its own page

[PATCH] (6/6) ipvs -- get rid of skb_linearize

From: Stephen Hemminger <hidden>
Date: 2003-09-16 21:23:50

Get rid of skb_linearize warnings, by using may_pull to get the
header where needed.

diff -Nru a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
--- a/net/ipv4/ipvs/ip_vs_app.c	Tue Sep 16 14:11:17 2003
+++ b/net/ipv4/ipvs/ip_vs_app.c	Tue Sep 16 14:11:17 2003
@@ -382,6 +382,10 @@
 		return 0;
 
 	iph = skb->nh.iph;
+	if (!pskb_may_pull(skb, (iph->ihl*4)+sizeof(*th)))
+		return 0;
+
+	iph = skb->nh.iph;
 	th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
 
 	/*
@@ -436,6 +440,10 @@
 	 *	this ip_vs_conn.
 	 */
 	if ((app = cp->app) == NULL)
+		return 0;
+
+	iph = skb->nh.iph;
+	if (!pskb_may_pull(skb, (iph->ihl*4)+sizeof(*th)))
 		return 0;
 
 	iph = skb->nh.iph;
diff -Nru a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
--- a/net/ipv4/ipvs/ip_vs_core.c	Tue Sep 16 14:11:17 2003
+++ b/net/ipv4/ipvs/ip_vs_core.c	Tue Sep 16 14:11:17 2003
@@ -526,11 +526,11 @@
 		*skb_p = skb;
 	}
 
-	if (skb_is_nonlinear(skb)) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0)
-			return NF_DROP;
-		ip_send_check(skb->nh.iph);
-	}
+	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+		return NF_STOLEN;
+
+	if (!pskb_may_pull(skb, sizeof(*iph) + sizeof(*icmph)))
+		return NF_DROP;
 
 	iph = skb->nh.iph;
 	ihl = iph->ihl << 2;
@@ -726,11 +726,12 @@
 	 * do final checksum checking.
 	 */
 
-	if (unlikely(cp->app && !pp->slave && skb_is_nonlinear(skb))) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+	if (unlikely(cp->app && !pp->slave)) {
+		if (!(skb = skb_share_check(skb, GFP_ATOMIC))) {
 			ip_vs_conn_put(cp);
-			return NF_DROP;
+			return NF_STOLEN;
 		}
+
 		iph = skb->nh.iph;
 		h.raw = (char*) iph + ihl;
 	}
@@ -816,12 +817,13 @@
 	int	rc;
 
 	*related = 1;
-	if (skb_is_nonlinear(skb)) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0)
-			return NF_DROP;
-		ip_send_check(skb->nh.iph);
-	}
-
+	if (!pskb_may_pull(skb, sizeof(*iph)))
+		return NF_DROP;
+	    
+	iph = skb->nh.iph;
+	if (!pskb_may_pull(skb, iph->ihl*4 + sizeof(*icmph)))
+		return NF_DROP;
+	    
 	iph = skb->nh.iph;
 	icmph = (struct icmphdr *)((char *)iph+(iph->ihl<<2));
 	len = ntohs(iph->tot_len) - (iph->ihl<<2);
diff -Nru a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
--- a/net/ipv4/ipvs/ip_vs_xmit.c	Tue Sep 16 14:11:17 2003
+++ b/net/ipv4/ipvs/ip_vs_xmit.c	Tue Sep 16 14:11:17 2003
@@ -265,13 +265,20 @@
 	 */
 
 	if (unlikely(cp->app && !pp->slave)) {
-		if (skb_is_nonlinear(skb) &&
-		    skb_linearize(skb, GFP_ATOMIC) != 0)
-			return NF_DROP;
+		if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+			return NF_STOLEN;
+
 	}
 
+	if (!pskb_may_pull(skb, sizeof(*iph)))
+		goto tx_error;
+
 	iph = skb->nh.iph;
 	ihl = iph->ihl << 2;
+	if (!pskb_may_pull(skb, sizeof(*iph) + ihl))
+		goto tx_error;
+
+	iph = skb->nh.iph;
 	h.raw = (char*) iph + ihl;
 	size = ntohs(iph->tot_len) - ihl;
 

Re: [PATCH] (6/6) ipvs -- get rid of skb_linearize

From: Wensong Zhang <hidden>
Date: 2003-09-17 16:53:46


Hi,

On Tue, 16 Sep 2003, Stephen Hemminger wrote:
Get rid of skb_linearize warnings, by using may_pull to get the
header where needed.
I am not sure if the calls of skb_share_check() are necessary, because
the ip_rcv has already done the skb share check for receiving packets. I 
don't know if other netfilter hooks can inject a shared skb.

Yes, we need to change IPVS to handle nonlinear skb as soon as possible, 
and remove these skb_linearize warnings.

Thanks,

Wensong
quoted hunk
diff -Nru a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
--- a/net/ipv4/ipvs/ip_vs_app.c	Tue Sep 16 14:11:17 2003
+++ b/net/ipv4/ipvs/ip_vs_app.c	Tue Sep 16 14:11:17 2003
@@ -382,6 +382,10 @@
 		return 0;
 
 	iph = skb->nh.iph;
+	if (!pskb_may_pull(skb, (iph->ihl*4)+sizeof(*th)))
+		return 0;
+
+	iph = skb->nh.iph;
 	th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
 
 	/*
@@ -436,6 +440,10 @@
 	 *	this ip_vs_conn.
 	 */
 	if ((app = cp->app) == NULL)
+		return 0;
+
+	iph = skb->nh.iph;
+	if (!pskb_may_pull(skb, (iph->ihl*4)+sizeof(*th)))
 		return 0;
 
 	iph = skb->nh.iph;
diff -Nru a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
--- a/net/ipv4/ipvs/ip_vs_core.c	Tue Sep 16 14:11:17 2003
+++ b/net/ipv4/ipvs/ip_vs_core.c	Tue Sep 16 14:11:17 2003
@@ -526,11 +526,11 @@
 		*skb_p = skb;
 	}
 
-	if (skb_is_nonlinear(skb)) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0)
-			return NF_DROP;
-		ip_send_check(skb->nh.iph);
-	}
+	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+		return NF_STOLEN;
+
+	if (!pskb_may_pull(skb, sizeof(*iph) + sizeof(*icmph)))
+		return NF_DROP;
 
 	iph = skb->nh.iph;
 	ihl = iph->ihl << 2;
@@ -726,11 +726,12 @@
 	 * do final checksum checking.
 	 */
 
-	if (unlikely(cp->app && !pp->slave && skb_is_nonlinear(skb))) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+	if (unlikely(cp->app && !pp->slave)) {
+		if (!(skb = skb_share_check(skb, GFP_ATOMIC))) {
 			ip_vs_conn_put(cp);
-			return NF_DROP;
+			return NF_STOLEN;
 		}
+
 		iph = skb->nh.iph;
 		h.raw = (char*) iph + ihl;
 	}
@@ -816,12 +817,13 @@
 	int	rc;
 
 	*related = 1;
-	if (skb_is_nonlinear(skb)) {
-		if (skb_linearize(skb, GFP_ATOMIC) != 0)
-			return NF_DROP;
-		ip_send_check(skb->nh.iph);
-	}
-
+	if (!pskb_may_pull(skb, sizeof(*iph)))
+		return NF_DROP;
+	    
+	iph = skb->nh.iph;
+	if (!pskb_may_pull(skb, iph->ihl*4 + sizeof(*icmph)))
+		return NF_DROP;
+	    
 	iph = skb->nh.iph;
 	icmph = (struct icmphdr *)((char *)iph+(iph->ihl<<2));
 	len = ntohs(iph->tot_len) - (iph->ihl<<2);
diff -Nru a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
--- a/net/ipv4/ipvs/ip_vs_xmit.c	Tue Sep 16 14:11:17 2003
+++ b/net/ipv4/ipvs/ip_vs_xmit.c	Tue Sep 16 14:11:17 2003
@@ -265,13 +265,20 @@
 	 */
 
 	if (unlikely(cp->app && !pp->slave)) {
-		if (skb_is_nonlinear(skb) &&
-		    skb_linearize(skb, GFP_ATOMIC) != 0)
-			return NF_DROP;
+		if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+			return NF_STOLEN;
+
 	}
 
+	if (!pskb_may_pull(skb, sizeof(*iph)))
+		goto tx_error;
+
 	iph = skb->nh.iph;
 	ihl = iph->ihl << 2;
+	if (!pskb_may_pull(skb, sizeof(*iph) + ihl))
+		goto tx_error;
+
+	iph = skb->nh.iph;
 	h.raw = (char*) iph + ihl;
 	size = ntohs(iph->tot_len) - ihl;
 

Re: [PATCH] (6/6) ipvs -- get rid of skb_linearize

From: Julian Anastasov <ja@ssi.bg>
Date: 2003-09-17 21:57:59

	Hello,

On Tue, 16 Sep 2003, Stephen Hemminger wrote:
Get rid of skb_linearize warnings, by using may_pull to get the
header where needed.
	We have another solution for this problem, may be it is
better the following stuff to be included now. Rusty, Dave? Is
someone willing to review this before inclusion?

http://www.ssi.bg/~ja/ipvs-2.6.0-test2/nonlinear-1.diff
http://www.ssi.bg/~ja/ipvs-2.6.0-test2/forward-1.diff
http://www.ssi.bg/~ja/ipvs-2.6.0-test2/no_route_proto-1.diff
http://www.ssi.bg/~ja/ipvs-2.6.0-test2/tcpudp_csum-1.diff

notes:
http://www.ssi.bg/~ja/ipvs-2.6.0-test2/readme.txt

Regards

--
Julian Anastasov [off-list ref]
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help