diff mbox

linux-next: Tree for Aug 7

Message ID 20130807.163621.84433966934449459.davem@davemloft.net (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

David Miller Aug. 7, 2013, 11:36 p.m. UTC
From: David Miller <davem@davemloft.net>
Date: Wed, 07 Aug 2013 16:27:48 -0700 (PDT)

> Look, I'm going to fix this myself, because I'm pretty tired of
> waiting for the obvious fix.

Someone please test this:

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Sedat Dilek Aug. 8, 2013, 12:02 a.m. UTC | #1
On Thu, Aug 8, 2013 at 1:36 AM, David Miller <davem@davemloft.net> wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 07 Aug 2013 16:27:48 -0700 (PDT)
>
>> Look, I'm going to fix this myself, because I'm pretty tired of
>> waiting for the obvious fix.
>
> Someone please test this:
>

Your patch on top of next-20130807 does not fix the issue in my wifi/network.
No working Internet connection (ping etc.).

- Sedat -

> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
> index c623861..afc02a6 100644
> --- a/include/linux/etherdevice.h
> +++ b/include/linux/etherdevice.h
> @@ -29,6 +29,7 @@
>
>  #ifdef __KERNEL__
>  extern __be16          eth_type_trans(struct sk_buff *skb, struct net_device *dev);
> +extern __be16          __eth_type_trans(struct sk_buff *skb, struct net_device *dev);
>  extern const struct header_ops eth_header_ops;
>
>  extern int eth_header(struct sk_buff *skb, struct net_device *dev,
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index be1f64d..35dc1be 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -146,6 +146,45 @@ int eth_rebuild_header(struct sk_buff *skb)
>  EXPORT_SYMBOL(eth_rebuild_header);
>
>  /**
> + * __eth_type_trans - only determine the packet's protocol ID.
> + * @skb: packet
> + * @dev: device
> + */
> +__be16 __eth_type_trans(struct sk_buff *skb, struct net_device *dev)
> +{
> +       struct ethhdr *eth = (struct ethhdr *) skb->data;
> +
> +       /*
> +        * Some variants of DSA tagging don't have an ethertype field
> +        * at all, so we check here whether one of those tagging
> +        * variants has been configured on the receiving interface,
> +        * and if so, set skb->protocol without looking at the packet.
> +        */
> +       if (netdev_uses_dsa_tags(dev))
> +               return htons(ETH_P_DSA);
> +       if (netdev_uses_trailer_tags(dev))
> +               return htons(ETH_P_TRAILER);
> +
> +       if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
> +               return eth->h_proto;
> +
> +       /*
> +        *      This is a magic hack to spot IPX packets. Older Novell breaks
> +        *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
> +        *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
> +        *      won't work for fault tolerant netware but does for the rest.
> +        */
> +       if (skb->len >= 2 && *(unsigned short *)(skb->data) == 0xFFFF)
> +               return htons(ETH_P_802_3);
> +
> +       /*
> +        *      Real 802.2 LLC
> +        */
> +       return htons(ETH_P_802_2);
> +}
> +EXPORT_SYMBOL(__eth_type_trans);
> +
> +/**
>   * eth_type_trans - determine the packet's protocol ID.
>   * @skb: received socket data
>   * @dev: receiving network device
> @@ -184,33 +223,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
>                         skb->pkt_type = PACKET_OTHERHOST;
>         }
>
> -       /*
> -        * Some variants of DSA tagging don't have an ethertype field
> -        * at all, so we check here whether one of those tagging
> -        * variants has been configured on the receiving interface,
> -        * and if so, set skb->protocol without looking at the packet.
> -        */
> -       if (netdev_uses_dsa_tags(dev))
> -               return htons(ETH_P_DSA);
> -       if (netdev_uses_trailer_tags(dev))
> -               return htons(ETH_P_TRAILER);
> -
> -       if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
> -               return eth->h_proto;
> -
> -       /*
> -        *      This is a magic hack to spot IPX packets. Older Novell breaks
> -        *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
> -        *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
> -        *      won't work for fault tolerant netware but does for the rest.
> -        */
> -       if (skb->len >= 2 && *(unsigned short *)(skb->data) == 0xFFFF)
> -               return htons(ETH_P_802_3);
> -
> -       /*
> -        *      Real 802.2 LLC
> -        */
> -       return htons(ETH_P_802_2);
> +       return __eth_type_trans(skb, dev);
>  }
>  EXPORT_SYMBOL(eth_type_trans);
>
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index 0c0f6c9..ec8e1c3 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -2003,7 +2003,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
>                         return err;
>
>                 if (dev->type == ARPHRD_ETHER)
> -                       skb->protocol = eth_type_trans(skb, dev);
> +                       skb->protocol = __eth_type_trans(skb, dev);
>
>                 data += dev->hard_header_len;
>                 to_write -= dev->hard_header_len;
> @@ -2332,13 +2332,13 @@ static int packet_snd(struct socket *sock,
>         sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
>
>         if (dev->type == ARPHRD_ETHER) {
> -               skb->protocol = eth_type_trans(skb, dev);
> +               skb->protocol = __eth_type_trans(skb, dev);
>                 if (skb->protocol == htons(ETH_P_8021Q))
>                         reserve += VLAN_HLEN;
>         } else {
>                 skb->protocol = proto;
> -               skb->dev = dev;
>         }
> +       skb->dev = dev;
>
>         if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
>                 err = -EMSGSIZE;
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Eric Dumazet Aug. 8, 2013, 12:06 a.m. UTC | #2
On Wed, 2013-08-07 at 16:36 -0700, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 07 Aug 2013 16:27:48 -0700 (PDT)
> 
> > Look, I'm going to fix this myself, because I'm pretty tired of
> > waiting for the obvious fix.
> 
> Someone please test this:
> 
> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
> index c623861..afc02a6 100644
> --- a/include/linux/etherdevice.h
> +++ b/include/linux/etherdevice.h
> @@ -29,6 +29,7 @@
>  
>  #ifdef __KERNEL__
>  extern __be16		eth_type_trans(struct sk_buff *skb, struct net_device *dev);
> +extern __be16		__eth_type_trans(struct sk_buff *skb, struct net_device *dev);
>  extern const struct header_ops eth_header_ops;
>  
>  extern int eth_header(struct sk_buff *skb, struct net_device *dev,
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index be1f64d..35dc1be 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -146,6 +146,45 @@ int eth_rebuild_header(struct sk_buff *skb)
>  EXPORT_SYMBOL(eth_rebuild_header);
>  
>  /**
> + * __eth_type_trans - only determine the packet's protocol ID.
> + * @skb: packet
> + * @dev: device
> + */
> +__be16 __eth_type_trans(struct sk_buff *skb, struct net_device *dev)
> +{

We probably want an inline here

Or else, we are adding an extra function call in rx fast path.

(At least my compiler did this)


0000000000000470 <eth_type_trans>:
 470:	e8 00 00 00 00       	callq  475 <eth_type_trans+0x5>
			471: R_X86_64_PC32	__fentry__-0x4
 475:	48 8b 8f d0 00 00 00 	mov    0xd0(%rdi),%rcx
 47c:	48 8b 87 c8 00 00 00 	mov    0xc8(%rdi),%rax
 483:	44 8b 47 60          	mov    0x60(%rdi),%r8d
 487:	55                   	push   %rbp
 488:	48 89 77 20          	mov    %rsi,0x20(%rdi)
 48c:	48 89 ca             	mov    %rcx,%rdx
 48f:	48 89 e5             	mov    %rsp,%rbp
 492:	48 29 c2             	sub    %rax,%rdx
 495:	41 83 f8 0d          	cmp    $0xd,%r8d
 499:	66 89 97 b8 00 00 00 	mov    %dx,0xb8(%rdi)
 4a0:	76 19                	jbe    4bb <eth_type_trans+0x4b>
 4a2:	41 83 e8 0e          	sub    $0xe,%r8d
 4a6:	44 3b 47 64          	cmp    0x64(%rdi),%r8d
 4aa:	44 89 47 60          	mov    %r8d,0x60(%rdi)
 4ae:	72 36                	jb     4e6 <eth_type_trans+0x76>
 4b0:	48 83 c1 0e          	add    $0xe,%rcx
 4b4:	48 89 8f d0 00 00 00 	mov    %rcx,0xd0(%rdi)
 4bb:	81 e2 ff ff 00 00    	and    $0xffff,%edx
 4c1:	48 01 d0             	add    %rdx,%rax
 4c4:	f6 00 01             	testb  $0x1,(%rax)
 4c7:	75 2e                	jne    4f7 <eth_type_trans+0x87>
 4c9:	48 8b 96 88 02 00 00 	mov    0x288(%rsi),%rdx
 4d0:	48 8b 00             	mov    (%rax),%rax
 4d3:	48 33 02             	xor    (%rdx),%rax
 4d6:	48 c1 e0 10          	shl    $0x10,%rax
 4da:	48 85 c0             	test   %rax,%rax
 4dd:	75 09                	jne    4e8 <eth_type_trans+0x78>
 4df:	e8 00 00 00 00       	callq  4e4 <eth_type_trans+0x74>
			4e0: R_X86_64_PC32	__eth_type_trans-0x4
 4e4:	5d                   	pop    %rbp
 4e5:	c3                   	retq   
 4e6:	0f 0b                	ud2    
 4e8:	0f b6 47 75          	movzbl 0x75(%rdi),%eax
 4ec:	83 e0 f8             	and    $0xfffffff8,%eax
 4ef:	83 c8 03             	or     $0x3,%eax
 4f2:	88 47 75             	mov    %al,0x75(%rdi)
 4f5:	eb e8                	jmp    4df <eth_type_trans+0x6f>
 4f7:	48 8b 00             	mov    (%rax),%rax
 4fa:	48 33 86 b8 02 00 00 	xor    0x2b8(%rsi),%rax
 501:	48 c1 e0 10          	shl    $0x10,%rax
 505:	48 85 c0             	test   %rax,%rax
 508:	0f b6 47 75          	movzbl 0x75(%rdi),%eax
 50c:	75 0b                	jne    519 <eth_type_trans+0xa9>
 50e:	83 e0 f8             	and    $0xfffffff8,%eax
 511:	83 c8 01             	or     $0x1,%eax
 514:	88 47 75             	mov    %al,0x75(%rdi)
 517:	eb c6                	jmp    4df <eth_type_trans+0x6f>
 519:	83 e0 f8             	and    $0xfffffff8,%eax
 51c:	83 c8 02             	or     $0x2,%eax
 51f:	88 47 75             	mov    %al,0x75(%rdi)
 522:	eb bb                	jmp    4df <eth_type_trans+0x6f>


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Aug. 8, 2013, 12:09 a.m. UTC | #3
From: Sedat Dilek <sedat.dilek@gmail.com>
Date: Thu, 8 Aug 2013 02:02:48 +0200

> On Thu, Aug 8, 2013 at 1:36 AM, David Miller <davem@davemloft.net> wrote:
>> From: David Miller <davem@davemloft.net>
>> Date: Wed, 07 Aug 2013 16:27:48 -0700 (PDT)
>>
>>> Look, I'm going to fix this myself, because I'm pretty tired of
>>> waiting for the obvious fix.
>>
>> Someone please test this:
> 
> Your patch on top of next-20130807 does not fix the issue in my wifi/network.
> No working Internet connection (ping etc.).

Ok, I'm going to simply revert all of these changes, thanks for testing.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Phil Sutter Aug. 9, 2013, 1:58 p.m. UTC | #4
On Wed, Aug 07, 2013 at 04:36:21PM -0700, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 07 Aug 2013 16:27:48 -0700 (PDT)
> 
> > Look, I'm going to fix this myself, because I'm pretty tired of
> > waiting for the obvious fix.
> 
> Someone please test this:
> 
> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
> index c623861..afc02a6 100644
> --- a/include/linux/etherdevice.h
> +++ b/include/linux/etherdevice.h
> @@ -29,6 +29,7 @@
>  
>  #ifdef __KERNEL__
>  extern __be16		eth_type_trans(struct sk_buff *skb, struct net_device *dev);
> +extern __be16		__eth_type_trans(struct sk_buff *skb, struct net_device *dev);
>  extern const struct header_ops eth_header_ops;
>  
>  extern int eth_header(struct sk_buff *skb, struct net_device *dev,
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index be1f64d..35dc1be 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -146,6 +146,45 @@ int eth_rebuild_header(struct sk_buff *skb)
>  EXPORT_SYMBOL(eth_rebuild_header);
>  
>  /**
> + * __eth_type_trans - only determine the packet's protocol ID.
> + * @skb: packet
> + * @dev: device
> + */
> +__be16 __eth_type_trans(struct sk_buff *skb, struct net_device *dev)
> +{
> +	struct ethhdr *eth = (struct ethhdr *) skb->data;
> +
> +	/*
> +	 * Some variants of DSA tagging don't have an ethertype field
> +	 * at all, so we check here whether one of those tagging
> +	 * variants has been configured on the receiving interface,
> +	 * and if so, set skb->protocol without looking at the packet.
> +	 */
> +	if (netdev_uses_dsa_tags(dev))
> +		return htons(ETH_P_DSA);
> +	if (netdev_uses_trailer_tags(dev))
> +		return htons(ETH_P_TRAILER);
> +
> +	if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
> +		return eth->h_proto;
> +
> +	/*
> +	 *      This is a magic hack to spot IPX packets. Older Novell breaks
> +	 *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
> +	 *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
> +	 *      won't work for fault tolerant netware but does for the rest.
> +	 */
> +	if (skb->len >= 2 && *(unsigned short *)(skb->data) == 0xFFFF)
> +		return htons(ETH_P_802_3);
> +
> +	/*
> +	 *      Real 802.2 LLC
> +	 */
> +	return htons(ETH_P_802_2);
> +}
> +EXPORT_SYMBOL(__eth_type_trans);
> +
> +/**
>   * eth_type_trans - determine the packet's protocol ID.
>   * @skb: received socket data
>   * @dev: receiving network device
> @@ -184,33 +223,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
>  			skb->pkt_type = PACKET_OTHERHOST;
>  	}
>  
> -	/*
> -	 * Some variants of DSA tagging don't have an ethertype field
> -	 * at all, so we check here whether one of those tagging
> -	 * variants has been configured on the receiving interface,
> -	 * and if so, set skb->protocol without looking at the packet.
> -	 */
> -	if (netdev_uses_dsa_tags(dev))
> -		return htons(ETH_P_DSA);
> -	if (netdev_uses_trailer_tags(dev))
> -		return htons(ETH_P_TRAILER);
> -
> -	if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
> -		return eth->h_proto;
> -
> -	/*
> -	 *      This is a magic hack to spot IPX packets. Older Novell breaks
> -	 *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
> -	 *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
> -	 *      won't work for fault tolerant netware but does for the rest.
> -	 */
> -	if (skb->len >= 2 && *(unsigned short *)(skb->data) == 0xFFFF)
> -		return htons(ETH_P_802_3);
> -
> -	/*
> -	 *      Real 802.2 LLC
> -	 */
> -	return htons(ETH_P_802_2);
> +	return __eth_type_trans(skb, dev);
>  }
>  EXPORT_SYMBOL(eth_type_trans);
>  
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index 0c0f6c9..ec8e1c3 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -2003,7 +2003,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
>  			return err;
>  
>  		if (dev->type == ARPHRD_ETHER)
> -			skb->protocol = eth_type_trans(skb, dev);
> +			skb->protocol = __eth_type_trans(skb, dev);
>  
>  		data += dev->hard_header_len;
>  		to_write -= dev->hard_header_len;
> @@ -2332,13 +2332,13 @@ static int packet_snd(struct socket *sock,
>  	sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
>  
>  	if (dev->type == ARPHRD_ETHER) {
> -		skb->protocol = eth_type_trans(skb, dev);
> +		skb->protocol = __eth_type_trans(skb, dev);
>  		if (skb->protocol == htons(ETH_P_8021Q))
>  			reserve += VLAN_HLEN;
>  	} else {
>  		skb->protocol = proto;
> -		skb->dev = dev;
>  	}
> +	skb->dev = dev;
>  
>  	if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
>  		err = -EMSGSIZE;

The problem with this patch is __eth_type_trans() assuming the MAC
header at skb->data which might be correct in the most cases, but not
when called from eth_type_trans() as the later sets skb->data to after
the ethernet header (which was the problem from the beginning).

Best wishes, Phil
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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/include/linux/etherdevice.h b/include/linux/etherdevice.h
index c623861..afc02a6 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -29,6 +29,7 @@ 
 
 #ifdef __KERNEL__
 extern __be16		eth_type_trans(struct sk_buff *skb, struct net_device *dev);
+extern __be16		__eth_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern const struct header_ops eth_header_ops;
 
 extern int eth_header(struct sk_buff *skb, struct net_device *dev,
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index be1f64d..35dc1be 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -146,6 +146,45 @@  int eth_rebuild_header(struct sk_buff *skb)
 EXPORT_SYMBOL(eth_rebuild_header);
 
 /**
+ * __eth_type_trans - only determine the packet's protocol ID.
+ * @skb: packet
+ * @dev: device
+ */
+__be16 __eth_type_trans(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ethhdr *eth = (struct ethhdr *) skb->data;
+
+	/*
+	 * Some variants of DSA tagging don't have an ethertype field
+	 * at all, so we check here whether one of those tagging
+	 * variants has been configured on the receiving interface,
+	 * and if so, set skb->protocol without looking at the packet.
+	 */
+	if (netdev_uses_dsa_tags(dev))
+		return htons(ETH_P_DSA);
+	if (netdev_uses_trailer_tags(dev))
+		return htons(ETH_P_TRAILER);
+
+	if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
+		return eth->h_proto;
+
+	/*
+	 *      This is a magic hack to spot IPX packets. Older Novell breaks
+	 *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
+	 *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
+	 *      won't work for fault tolerant netware but does for the rest.
+	 */
+	if (skb->len >= 2 && *(unsigned short *)(skb->data) == 0xFFFF)
+		return htons(ETH_P_802_3);
+
+	/*
+	 *      Real 802.2 LLC
+	 */
+	return htons(ETH_P_802_2);
+}
+EXPORT_SYMBOL(__eth_type_trans);
+
+/**
  * eth_type_trans - determine the packet's protocol ID.
  * @skb: received socket data
  * @dev: receiving network device
@@ -184,33 +223,7 @@  __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
 			skb->pkt_type = PACKET_OTHERHOST;
 	}
 
-	/*
-	 * Some variants of DSA tagging don't have an ethertype field
-	 * at all, so we check here whether one of those tagging
-	 * variants has been configured on the receiving interface,
-	 * and if so, set skb->protocol without looking at the packet.
-	 */
-	if (netdev_uses_dsa_tags(dev))
-		return htons(ETH_P_DSA);
-	if (netdev_uses_trailer_tags(dev))
-		return htons(ETH_P_TRAILER);
-
-	if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
-		return eth->h_proto;
-
-	/*
-	 *      This is a magic hack to spot IPX packets. Older Novell breaks
-	 *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
-	 *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
-	 *      won't work for fault tolerant netware but does for the rest.
-	 */
-	if (skb->len >= 2 && *(unsigned short *)(skb->data) == 0xFFFF)
-		return htons(ETH_P_802_3);
-
-	/*
-	 *      Real 802.2 LLC
-	 */
-	return htons(ETH_P_802_2);
+	return __eth_type_trans(skb, dev);
 }
 EXPORT_SYMBOL(eth_type_trans);
 
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 0c0f6c9..ec8e1c3 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2003,7 +2003,7 @@  static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 			return err;
 
 		if (dev->type == ARPHRD_ETHER)
-			skb->protocol = eth_type_trans(skb, dev);
+			skb->protocol = __eth_type_trans(skb, dev);
 
 		data += dev->hard_header_len;
 		to_write -= dev->hard_header_len;
@@ -2332,13 +2332,13 @@  static int packet_snd(struct socket *sock,
 	sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 
 	if (dev->type == ARPHRD_ETHER) {
-		skb->protocol = eth_type_trans(skb, dev);
+		skb->protocol = __eth_type_trans(skb, dev);
 		if (skb->protocol == htons(ETH_P_8021Q))
 			reserve += VLAN_HLEN;
 	} else {
 		skb->protocol = proto;
-		skb->dev = dev;
 	}
+	skb->dev = dev;
 
 	if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
 		err = -EMSGSIZE;