aboutsummaryrefslogtreecommitdiff
path: root/sys/net/if_tuntap.c
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2023-11-09 10:37:27 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2023-11-09 10:37:27 +0000
commitff69d13a50d1d07601de0885fd94f6a09a7ba383 (patch)
tree125da2f42a521205d8b303dda20780771c92b4d2 /sys/net/if_tuntap.c
parent0d2ab4a4ced0f153a6b6a58ca3cfa6efbeeec7a2 (diff)
downloadsrc-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.c34
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. */