Skip to content

Commit 012d69f

Browse files
ebirgerdavem330
authored andcommitted
vrf: fix packet sniffing for traffic originating from ip tunnels
in commit 0489390 ("vrf: add mac header for tunneled packets when sniffer is attached") an Ethernet header was cooked for traffic originating from tunnel devices. However, the header is added based on whether the mac_header is unset and ignores cases where the device doesn't expose a mac header to upper layers, such as in ip tunnels like ipip and gre. Traffic originating from such devices still appears garbled when capturing on the vrf device. Fix by observing whether the original device exposes a header to upper layers, similar to the logic done in af_packet. In addition, skb->mac_len needs to be adjusted after adding the Ethernet header for the skb_push/pull() surrounding dev_queue_xmit_nit() to work on these packets. Fixes: 0489390 ("vrf: add mac header for tunneled packets when sniffer is attached") Signed-off-by: Eyal Birger <[email protected]> Reviewed-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9381fe8 commit 012d69f

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

drivers/net/vrf.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,7 @@ static int vrf_prepare_mac_header(struct sk_buff *skb,
12651265
eth = (struct ethhdr *)skb->data;
12661266

12671267
skb_reset_mac_header(skb);
1268+
skb_reset_mac_len(skb);
12681269

12691270
/* we set the ethernet destination and the source addresses to the
12701271
* address of the VRF device.
@@ -1294,9 +1295,9 @@ static int vrf_prepare_mac_header(struct sk_buff *skb,
12941295
*/
12951296
static int vrf_add_mac_header_if_unset(struct sk_buff *skb,
12961297
struct net_device *vrf_dev,
1297-
u16 proto)
1298+
u16 proto, struct net_device *orig_dev)
12981299
{
1299-
if (skb_mac_header_was_set(skb))
1300+
if (skb_mac_header_was_set(skb) && dev_has_header(orig_dev))
13001301
return 0;
13011302

13021303
return vrf_prepare_mac_header(skb, vrf_dev, proto);
@@ -1402,6 +1403,8 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
14021403

14031404
/* if packet is NDISC then keep the ingress interface */
14041405
if (!is_ndisc) {
1406+
struct net_device *orig_dev = skb->dev;
1407+
14051408
vrf_rx_stats(vrf_dev, skb->len);
14061409
skb->dev = vrf_dev;
14071410
skb->skb_iif = vrf_dev->ifindex;
@@ -1410,7 +1413,8 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
14101413
int err;
14111414

14121415
err = vrf_add_mac_header_if_unset(skb, vrf_dev,
1413-
ETH_P_IPV6);
1416+
ETH_P_IPV6,
1417+
orig_dev);
14141418
if (likely(!err)) {
14151419
skb_push(skb, skb->mac_len);
14161420
dev_queue_xmit_nit(skb, vrf_dev);
@@ -1440,6 +1444,8 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
14401444
static struct sk_buff *vrf_ip_rcv(struct net_device *vrf_dev,
14411445
struct sk_buff *skb)
14421446
{
1447+
struct net_device *orig_dev = skb->dev;
1448+
14431449
skb->dev = vrf_dev;
14441450
skb->skb_iif = vrf_dev->ifindex;
14451451
IPCB(skb)->flags |= IPSKB_L3SLAVE;
@@ -1460,7 +1466,8 @@ static struct sk_buff *vrf_ip_rcv(struct net_device *vrf_dev,
14601466
if (!list_empty(&vrf_dev->ptype_all)) {
14611467
int err;
14621468

1463-
err = vrf_add_mac_header_if_unset(skb, vrf_dev, ETH_P_IP);
1469+
err = vrf_add_mac_header_if_unset(skb, vrf_dev, ETH_P_IP,
1470+
orig_dev);
14641471
if (likely(!err)) {
14651472
skb_push(skb, skb->mac_len);
14661473
dev_queue_xmit_nit(skb, vrf_dev);

0 commit comments

Comments
 (0)