diff mbox

ipv6: Add GSO support on forwarding path

Message ID 20100526221601.GA3369@gondor.apana.org.au
State Superseded, archived
Delegated to: David Miller
Headers show

Commit Message

Herbert Xu May 26, 2010, 10:16 p.m. UTC
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,

Comments

Ralf Baechle May 27, 2010, 9:22 a.m. UTC | #1
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. UTC | #2
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. UTC | #3
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,
diff mbox

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);