Patchwork ipv6: Add GSO support on forwarding path

login
register
mail settings
Submitter Herbert Xu
Date May 26, 2010, 10:16 p.m.
Message ID <20100526221601.GA3369@gondor.apana.org.au>
Download mbox | patch
Permalink /patch/53666/
State Superseded
Delegated to: David Miller
Headers show

Comments

Herbert Xu - May 26, 2010, 10:16 p.m.
On Wed, May 26, 2010 at 04:20:19PM +0100, Ralf Baechle wrote:
> 
> I tested this on top of a 2.6.34 release kernel and asked the user
> experiencing the problem to re-test and the problem still persists.

OK, it looks like my patch doesn't work because the transport
header isn't set on the forwarding path.  Here's an updated patch:

ipv6: Add GSO support on forwarding path

Currently we disallow GSO packets on the IPv6 forward path.
This patch fixes this.

Note that I discovered that our existing GSO MTU checks (e.g.,
IPv4 forwarding) are buggy in that they skip the check altogether, 
hen they really should be checking gso_size instead.

I have also been lazy here in that I haven't bothered to segment
the GSO packet by hand before generating an ICMP message.  Someone
should add that to be 100% correct.

Reported-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>


Thanks,
Ralf Baechle - May 27, 2010, 9:22 a.m.
On Thu, May 27, 2010 at 08:16:01AM +1000, Herbert Xu wrote:

> > I tested this on top of a 2.6.34 release kernel and asked the user
> > experiencing the problem to re-test and the problem still persists.
> 
> OK, it looks like my patch doesn't work because the transport
> header isn't set on the forwarding path.  Here's an updated patch:

Still no improvment.  I've moved all the collected tcpdumps to
ftp://www.linux-ax25.org/pub/traces/ including a README file describing
contents.

  Ralf
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ralf Baechle - May 27, 2010, 10:14 a.m.
On Thu, May 27, 2010 at 10:22:46AM +0100, Ralf Baechle wrote:

> > > I tested this on top of a 2.6.34 release kernel and asked the user
> > > experiencing the problem to re-test and the problem still persists.
> > 
> > OK, it looks like my patch doesn't work because the transport
> > header isn't set on the forwarding path.  Here's an updated patch:
> 
> Still no improvment.  I've moved all the collected tcpdumps to
> ftp://www.linux-ax25.org/pub/traces/ including a README file describing
> contents.

Uh..  Of course I should have upgraded the host not the client.  And
after having done that things are working fine now.  Thanks!

  Ralf
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Herbert Xu - May 27, 2010, 10:24 a.m.
On Thu, May 27, 2010 at 08:16:01AM +1000, Herbert Xu wrote:
> 
> OK, it looks like my patch doesn't work because the transport
> header isn't set on the forwarding path.  Here's an updated patch:
> 
> ipv6: Add GSO support on forwarding path

Actually, this patch is still not quite right for the GSO case.
Right now it's only adding the IP header size, not the full header
size.

I need to think a bit more about this.

Cheers,

Patch

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7cdfb4d..6ec5238 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2117,6 +2117,13 @@  static inline int skb_is_gso(const struct sk_buff *skb)
 	return skb_shinfo(skb)->gso_size;
 }
 
+static inline int skb_gso_len(const struct sk_buff *skb)
+{
+	return skb_is_gso(skb) ?
+	       skb_shinfo(skb)->gso_size +
+	       (skb->csum_start - skb_headroom(skb)) : skb->len;
+}
+
 static inline int skb_is_gso_v6(const struct sk_buff *skb)
 {
 	return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index cd963f6..8904767 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -507,7 +507,7 @@  int ip6_forward(struct sk_buff *skb)
 	if (mtu < IPV6_MIN_MTU)
 		mtu = IPV6_MIN_MTU;
 
-	if (skb->len > mtu) {
+	if (skb_gso_len(skb) > mtu) {
 		/* Again, force OUTPUT device used as source address */
 		skb->dev = dst->dev;
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);