diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index bbe1ece..66bc79c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1932,8 +1932,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, ph.raw = frame; - skb->protocol = proto; - skb->dev = dev; skb->priority = po->sk.sk_priority; skb->mark = po->sk.sk_mark; sock_tx_timestamp(&po->sk, &skb_shinfo(skb)->tx_flags); @@ -2002,13 +2000,18 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, if (unlikely(err)) return err; - if (dev->type == ARPHRD_ETHER) - skb->protocol = eth_type_trans(skb, dev); - data += dev->hard_header_len; to_write -= dev->hard_header_len; } + if (dev->type == ARPHRD_ETHER && + proto = htons(ETH_P_ALL)) { + skb->protocol = eth_type_trans(skb, dev); + } else { + skb->protocol = proto; + skb->dev = dev; + } + max_frame_len = dev->mtu + dev->hard_header_len; if (skb->protocol == htons(ETH_P_8021Q)) max_frame_len += VLAN_HLEN; @@ -2331,15 +2334,17 @@ static int packet_snd(struct socket *sock, sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); - if (dev->type == ARPHRD_ETHER) { + if (dev->type == ARPHRD_ETHER && + proto == htons(ETH_P_ALL)) { skb->protocol = eth_type_trans(skb, dev); - if (skb->protocol == htons(ETH_P_8021Q)) - reserve += VLAN_HLEN; } else { skb->protocol = proto; skb->dev = dev; } + if (skb->protocol == htons(ETH_P_8021Q)) + reserve += VLAN_HLEN; + if (!gso_type && (len > dev->mtu + reserve + extra_len)) { err = -EMSGSIZE; goto out_free;