diff options
author | Jan Klemkow <jan@cvs.openbsd.org> | 2023-12-09 10:36:06 +0000 |
---|---|---|
committer | Jan Klemkow <jan@cvs.openbsd.org> | 2023-12-09 10:36:06 +0000 |
commit | 580f115c0a8f4d8a7ee38f10582c9908704e90f4 (patch) | |
tree | 62821282c9287bdc3ce84887e94b46def1f649ab /sys | |
parent | d92b2742ae0050dfa352b7cbfc7c64a3ca5af4f9 (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.c | 32 |
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; |