Skip to content

Commit 58d19b1

Browse files
wdebruijdavem330
authored andcommitted
packet: vnet_hdr support for tpacket_rcv
Support socket option PACKET_VNET_HDR together with PACKET_RX_RING. When enabled, a struct virtio_net_hdr will precede the data in the packet ring slots. Verified with test program at github.com/wdebruij/kerneltools/blob/master/tests/psock_rxring_vnet.c pkt: 1454269209.798420 len=5066 vnet: gso_type=tcpv4 gso_size=1448 hlen=66 ecn=off csum: start=34 off=16 eth: proto=0x800 ip: src=<masked> dst=<masked> proto=6 len=5052 Signed-off-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 16cc140 commit 58d19b1

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

net/packet/af_packet.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -2206,7 +2206,9 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
22062206
unsigned int maclen = skb_network_offset(skb);
22072207
netoff = TPACKET_ALIGN(po->tp_hdrlen +
22082208
(maclen < 16 ? 16 : maclen)) +
2209-
po->tp_reserve;
2209+
po->tp_reserve;
2210+
if (po->has_vnet_hdr)
2211+
netoff += sizeof(struct virtio_net_hdr);
22102212
macoff = netoff - maclen;
22112213
}
22122214
if (po->tp_version <= TPACKET_V2) {
@@ -2243,7 +2245,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
22432245
h.raw = packet_current_rx_frame(po, skb,
22442246
TP_STATUS_KERNEL, (macoff+snaplen));
22452247
if (!h.raw)
2246-
goto ring_is_full;
2248+
goto drop_n_account;
22472249
if (po->tp_version <= TPACKET_V2) {
22482250
packet_increment_rx_head(po, &po->rx_ring);
22492251
/*
@@ -2262,6 +2264,14 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
22622264
}
22632265
spin_unlock(&sk->sk_receive_queue.lock);
22642266

2267+
if (po->has_vnet_hdr) {
2268+
if (__packet_rcv_vnet(skb, h.raw + macoff -
2269+
sizeof(struct virtio_net_hdr))) {
2270+
spin_lock(&sk->sk_receive_queue.lock);
2271+
goto drop_n_account;
2272+
}
2273+
}
2274+
22652275
skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
22662276

22672277
if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
@@ -2357,7 +2367,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
23572367
kfree_skb(skb);
23582368
return 0;
23592369

2360-
ring_is_full:
2370+
drop_n_account:
23612371
po->stats.stats1.tp_drops++;
23622372
spin_unlock(&sk->sk_receive_queue.lock);
23632373

@@ -3587,7 +3597,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
35873597
}
35883598
if (optlen < len)
35893599
return -EINVAL;
3590-
if (pkt_sk(sk)->has_vnet_hdr)
3600+
if (pkt_sk(sk)->has_vnet_hdr &&
3601+
optname == PACKET_TX_RING)
35913602
return -EINVAL;
35923603
if (copy_from_user(&req_u.req, optval, len))
35933604
return -EFAULT;

0 commit comments

Comments
 (0)