|
@@ -2338,6 +2338,15 @@ static bool ll_header_truncated(const struct net_device *dev, int len)
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void tpacket_set_protocol(const struct net_device *dev,
|
|
|
|
+ struct sk_buff *skb)
|
|
|
|
+{
|
|
|
|
+ if (dev->type == ARPHRD_ETHER) {
|
|
|
|
+ skb_reset_mac_header(skb);
|
|
|
|
+ skb->protocol = eth_hdr(skb)->h_proto;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
|
|
static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
|
|
void *frame, struct net_device *dev, int size_max,
|
|
void *frame, struct net_device *dev, int size_max,
|
|
__be16 proto, unsigned char *addr, int hlen)
|
|
__be16 proto, unsigned char *addr, int hlen)
|
|
@@ -2419,6 +2428,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
|
|
dev->hard_header_len);
|
|
dev->hard_header_len);
|
|
if (unlikely(err))
|
|
if (unlikely(err))
|
|
return err;
|
|
return err;
|
|
|
|
+ if (!skb->protocol)
|
|
|
|
+ tpacket_set_protocol(dev, skb);
|
|
|
|
|
|
data += dev->hard_header_len;
|
|
data += dev->hard_header_len;
|
|
to_write -= dev->hard_header_len;
|
|
to_write -= dev->hard_header_len;
|