diff mbox

Re: skb_segment() questions

Message ID 20090401091801.GA5970@ff.dom.local
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Jarek Poplawski April 1, 2009, 9:18 a.m. UTC
On 29-03-2009 03:07, Herbert Xu wrote:
> On Wed, Mar 04, 2009 at 07:12:40PM -0800, James Huang wrote:
>> (2) What is the purpose of the this check?
>>
>> `    if (pos >= offset + len)
>>         continue;
>>
>>      If the payload in the head buffer of skb has at least mss bytes, this
>> check will succeed and no payload in skbâ??s head buffer will be copy into
>> nskb
>> through a call to skb_copy_from_linear_data_offset(). Something seems to be
>> wrong here.
> 
> Indeed.  This breaks linear packets, which unfortunately older
> versions of tun likes to construct.
> 
> gso: Fix support for linear packets
> 
> When GRO/frag_list support was added to GSO, I made an error
> which broke the support for segmenting linear GSO packets (GSO
> packets are normally non-linear in the payload).
> 
> These days most of these packets are constructed by the tun
> driver, which prefers to allocate linear memory if possible.
> This is fixed in the latest kernel, but for 2.6.29 and earlier
> it is still the norm.
> 
> Therefore this bug causes failures with GSO when used with tun
> in 2.6.29.
> 
> Reported-by: James Huang <jamesclhuang@gmail.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> 
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 6acbf9e..ce6356c 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -2579,7 +2579,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
>  					  skb_network_header_len(skb));
>  		skb_copy_from_linear_data(skb, nskb->data, doffset);
>  
> -		if (pos >= offset + len)
> +		if (fskb != skb_shinfo(skb)->frag_list)
>  			continue;
>  
>  		if (!sg) {
> 

----------------------->
gso: Fix support for linear packets 2

The previous fix removed a check, which should be useful, only a bit
later, by skipping at least two similar checks and three useless
assignments in case a header is (still) copied.

Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---

 net/core/skbuff.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

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

Comments

Herbert Xu April 1, 2009, 9:24 a.m. UTC | #1
On Wed, Apr 01, 2009 at 09:18:01AM +0000, Jarek Poplawski wrote:
>
> gso: Fix support for linear packets 2
> 
> The previous fix removed a check, which should be useful, only a bit
> later, by skipping at least two similar checks and three useless
> assignments in case a header is (still) copied.
> 
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
> ---
> 
>  net/core/skbuff.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index ce6356c..2123a92 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -2594,6 +2594,8 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
>  
>  		skb_copy_from_linear_data_offset(skb, offset,
>  						 skb_put(nskb, hsize), hsize);
> +		if (pos >= offset + len)
> +			continue;
>  
>  		while (pos < offset + len && i < nfrags) {
>  			*frag = skb_shinfo(skb)->frags[i];

The common case (non-linear skb) is going to fail that check so 
I'm no sure if it's warranted.

Thanks,
Jarek Poplawski April 1, 2009, 9:50 a.m. UTC | #2
On Wed, Apr 01, 2009 at 05:24:57PM +0800, Herbert Xu wrote:
> On Wed, Apr 01, 2009 at 09:18:01AM +0000, Jarek Poplawski wrote:
> >
> > gso: Fix support for linear packets 2
> > 
> > The previous fix removed a check, which should be useful, only a bit
> > later, by skipping at least two similar checks and three useless
> > assignments in case a header is (still) copied.
> > 
> > Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
> > ---
> > 
> >  net/core/skbuff.c |    2 ++
> >  1 files changed, 2 insertions(+), 0 deletions(-)
> > 
> > diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> > index ce6356c..2123a92 100644
> > --- a/net/core/skbuff.c
> > +++ b/net/core/skbuff.c
> > @@ -2594,6 +2594,8 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
> >  
> >  		skb_copy_from_linear_data_offset(skb, offset,
> >  						 skb_put(nskb, hsize), hsize);
> > +		if (pos >= offset + len)
> > +			continue;
> >  
> >  		while (pos < offset + len && i < nfrags) {
> >  			*frag = skb_shinfo(skb)->frags[i];
> 
> The common case (non-linear skb) is going to fail that check so 
> I'm no sure if it's warranted.

I guess you mean non-linear skb with a header smaller than mtu? Well,
if it's the most common case now, I agree.

Thanks,
Jarek P.
--
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 April 1, 2009, 9:53 a.m. UTC | #3
On Wed, Apr 01, 2009 at 09:50:50AM +0000, Jarek Poplawski wrote:
>
> I guess you mean non-linear skb with a header smaller than mtu? Well,
> if it's the most common case now, I agree.

The common case is the path stemming from the TCP stack, where
we always construct skb's with the entire payload in page frags,
and only the header is placed in skb->data.

Cheers,
Jarek Poplawski April 1, 2009, 10:02 a.m. UTC | #4
On Wed, Apr 01, 2009 at 05:53:52PM +0800, Herbert Xu wrote:
> On Wed, Apr 01, 2009 at 09:50:50AM +0000, Jarek Poplawski wrote:
> >
> > I guess you mean non-linear skb with a header smaller than mtu? Well,
> > if it's the most common case now, I agree.
> 
> The common case is the path stemming from the TCP stack, where
> we always construct skb's with the entire payload in page frags,
> and only the header is placed in skb->data.

OK, then let's forget about this patch.

Thanks for the explanation,
Jarek P.
--
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
diff mbox

Patch

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index ce6356c..2123a92 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2594,6 +2594,8 @@  struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 
 		skb_copy_from_linear_data_offset(skb, offset,
 						 skb_put(nskb, hsize), hsize);
+		if (pos >= offset + len)
+			continue;
 
 		while (pos < offset + len && i < nfrags) {
 			*frag = skb_shinfo(skb)->frags[i];