summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJan Klemkow <jan@cvs.openbsd.org>2023-12-09 10:36:06 +0000
committerJan Klemkow <jan@cvs.openbsd.org>2023-12-09 10:36:06 +0000
commit580f115c0a8f4d8a7ee38f10582c9908704e90f4 (patch)
tree62821282c9287bdc3ce84887e94b46def1f649ab /sys
parentd92b2742ae0050dfa352b7cbfc7c64a3ca5af4f9 (diff)
vio(4) add recv TCP/UDP checksum offloading
tested on Linux/KVM tested on proxmox and vultr by florian ok florian
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pv/if_vio.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/dev/pv/if_vio.c b/sys/dev/pv/if_vio.c
index 7b895238427..5c9a05faf4b 100644
--- a/sys/dev/pv/if_vio.c
+++ b/sys/dev/pv/if_vio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vio.c,v 1.26 2023/11/10 15:51:24 bluhm Exp $ */
+/* $OpenBSD: if_vio.c,v 1.27 2023/12/09 10:36:05 jan Exp $ */
/*
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
@@ -145,6 +145,7 @@ struct virtio_net_hdr {
} __packed;
#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* flags */
+#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* flags */
#define VIRTIO_NET_HDR_GSO_NONE 0 /* gso_type */
#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* gso_type */
#define VIRTIO_NET_HDR_GSO_UDP 3 /* gso_type */
@@ -533,7 +534,7 @@ vio_attach(struct device *parent, struct device *self, void *aux)
vsc->sc_driver_features = VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS |
VIRTIO_NET_F_CTRL_VQ | VIRTIO_NET_F_CTRL_RX |
VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_CSUM |
- VIRTIO_F_RING_EVENT_IDX;
+ VIRTIO_F_RING_EVENT_IDX | VIRTIO_NET_F_GUEST_CSUM;
virtio_negotiate_features(vsc, virtio_net_feature_names);
if (virtio_has_feature(vsc, VIRTIO_NET_F_MAC)) {
@@ -986,6 +987,31 @@ vio_populate_rx_mbufs(struct vio_softc *sc)
timeout_add_sec(&sc->sc_rxtick, 1);
}
+void
+vio_rx_offload(struct mbuf *m, struct virtio_net_hdr *hdr)
+{
+ struct ether_extracted ext;
+
+ if (!ISSET(hdr->flags, VIRTIO_NET_HDR_F_DATA_VALID) &&
+ !ISSET(hdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM))
+ return;
+
+ ether_extract_headers(m, &ext);
+
+ if (ext.ip4)
+ SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_OK);
+
+ if (ext.tcp) {
+ SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_OK);
+ if (ISSET(hdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM))
+ SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_OUT);
+ } else if (ext.udp) {
+ SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_IN_OK);
+ if (ISSET(hdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM))
+ SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_OUT);
+ }
+}
+
/* dequeue received packets */
int
vio_rxeof(struct vio_softc *sc)
@@ -1019,6 +1045,8 @@ vio_rxeof(struct vio_softc *sc)
bufs_left = hdr->num_buffers - 1;
else
bufs_left = 0;
+ if (virtio_has_feature(vsc, VIRTIO_NET_F_GUEST_CSUM))
+ vio_rx_offload(m, hdr);
} else {
m->m_flags &= ~M_PKTHDR;
m0->m_pkthdr.len += m->m_len;