diff options
author | Michael Tuexen <tuexen@FreeBSD.org> | 2023-11-09 10:37:27 +0000 |
---|---|---|
committer | Michael Tuexen <tuexen@FreeBSD.org> | 2023-11-09 10:37:27 +0000 |
commit | ff69d13a50d1d07601de0885fd94f6a09a7ba383 (patch) | |
tree | 125da2f42a521205d8b303dda20780771c92b4d2 /sys/net/if_tuntap.c | |
parent | 0d2ab4a4ced0f153a6b6a58ca3cfa6efbeeec7a2 (diff) | |
download | src-ff69d13a50d1d07601de0885fd94f6a09a7ba383.tar.gz src-ff69d13a50d1d07601de0885fd94f6a09a7ba383.zip |
if_tuntap: support receive checksum offloading for tap interfaces
When enabled, pretend that the IPv4 and transport layer checksum
is correct for packets injected via the character device.
This is a prerequisite for adding support for LRO, which will
be added next. Then packetdrill can be used to test the LRO
code in local mode.
Reviewed by: rscheff, zlei
MFC after: 1 week
Sponsored by: Netflix, Inc.
Differential Revision: https://reviews.freebsd.org/D42477
Diffstat (limited to 'sys/net/if_tuntap.c')
-rw-r--r-- | sys/net/if_tuntap.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c index a865c23cb372..30d1d84b2f59 100644 --- a/sys/net/if_tuntap.c +++ b/sys/net/if_tuntap.c @@ -977,6 +977,8 @@ tuncreate(struct cdev *dev) ifp->if_flags = iflags; IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); ifp->if_capabilities |= IFCAP_LINKSTATE; + if ((tp->tun_flags & TUN_L2) != 0) + ifp->if_capabilities |= IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6; ifp->if_capenable |= IFCAP_LINKSTATE; if ((tp->tun_flags & TUN_L2) != 0) { @@ -1784,9 +1786,35 @@ tunwrite_l2(struct tuntap_softc *tp, struct mbuf *m, return (0); } - if (vhdr != NULL && virtio_net_rx_csum(m, &vhdr->hdr)) { - m_freem(m); - return (0); + if (vhdr != NULL) { + if (virtio_net_rx_csum(m, &vhdr->hdr)) { + m_freem(m); + return (0); + } + } else { + switch (ntohs(eh->ether_type)) { +#ifdef INET + case ETHERTYPE_IP: + if (ifp->if_capenable & IFCAP_RXCSUM) { + m->m_pkthdr.csum_flags |= + CSUM_IP_CHECKED | CSUM_IP_VALID | + CSUM_DATA_VALID | CSUM_SCTP_VALID | + CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + break; +#endif +#ifdef INET6 + case ETHERTYPE_IPV6: + if (ifp->if_capenable & IFCAP_RXCSUM_IPV6) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID_IPV6 | CSUM_SCTP_VALID | + CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + break; +#endif + } } /* Pass packet up to parent. */ |