Patchwork [net-2.6] net: bug fix for vlan + gro issue

login
register
mail settings
Submitter Ajit Khaparde
Date Feb. 12, 2010, 5:34 a.m.
Message ID <20100212053451.GA23351@serverengines.com>
Download mbox | patch
Permalink /patch/45177/
State Changes Requested
Delegated to: David Miller
Headers show

Comments

Ajit Khaparde - Feb. 12, 2010, 5:34 a.m.
Traffic doesn't start on a vlan interface when gro is enabled.
Even the tcp handshake was not taking place.
This is because, the eth_type_trans() call before the netif_receive_skb()
in napi_frags_finish() resets the skb->dev to napi->dev from the previously
set vlan netdev interface. This causes the ip_route_input() to drop the
incoming packet considering it as a packet coming from a martian source.

I could repro this on 2.6.32.7 (stable) and 2.6.33-rc7.
With this fix, the traffic starts and the test runs fine. Please review.

Alternatively:
Previously the skb->dev was updated by the driver and I don't know
why it has to be set in eth_type_trans. May be removing that from
eth_type_trans() and expecting the caller to set the skb->dev could be
an alternative fix.

Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
 net/core/dev.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
Herbert Xu - Feb. 16, 2010, 11:40 a.m.
On Fri, Feb 12, 2010 at 11:04:53AM +0530, Ajit Khaparde wrote:
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index be9924f..16aac06 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2761,7 +2761,10 @@ gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb,
>  	switch (ret) {
>  	case GRO_NORMAL:
>  	case GRO_HELD:
> -		skb->protocol = eth_type_trans(skb, napi->dev);
> +		if (skb->vlan_tci)
> +			skb->protocol = eth_type_trans(skb, skb->dev);
> +		else
> +			skb->protocol = eth_type_trans(skb, napi->dev);

We should be able to just use skb->dev here.

Thanks!

Patch

diff --git a/net/core/dev.c b/net/core/dev.c
index be9924f..16aac06 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2761,7 +2761,10 @@  gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb,
 	switch (ret) {
 	case GRO_NORMAL:
 	case GRO_HELD:
-		skb->protocol = eth_type_trans(skb, napi->dev);
+		if (skb->vlan_tci)
+			skb->protocol = eth_type_trans(skb, skb->dev);
+		else
+			skb->protocol = eth_type_trans(skb, napi->dev);
 
 		if (ret == GRO_HELD)
 			skb_gro_pull(skb, -ETH_HLEN);