diff options
| author | Timo Völker <timo.voelker@fh-muenster.de> | 2026-06-28 10:50:15 +0000 |
|---|---|---|
| committer | Michael Tuexen <tuexen@FreeBSD.org> | 2026-08-06 05:45:51 +0000 |
| commit | fd3582e683d6cf97c59dcd898ece47a5497d5995 (patch) | |
| tree | 85a07301b8e2be7e03d402e94f9294bf223916e1 | |
| parent | 976f400a7e5284e36a62c253647d519728b1241f (diff) | |
loopback: improve checksum offloading
* Allow disabling IFCAP_RXCSUM_IPV6 or IFCAP_TXCSUM_IPV6.
* Do not pretend the checksum is correct by setting the LO_CSUM_SET
flags if IFCAP_RXCSUM_IPV6 or IFCAP_RXCSUM is enabled. Instead,
remove the LO_CSUM_SET flags (in case they have been set somehow)
if IFCAP_RXCSUM_IPV6 or IFCAP_RXCSUM is disabled.
* Do not unset the transmit checksum offload flags LO_CSUM_FEATURES or
LO_CSUM_FEATURES6 since they now have a meaning for the receive path.
Reviewed by: glebius, pouria, tuexen
Okayed by: bz
Differential Revision: https://reviews.freebsd.org/D57518
(cherry picked from commit d6c4cea7740d5c5c673a06ba37e4f1bdcddb2ece)
| -rw-r--r-- | share/man/man4/lo.4 | 23 | ||||
| -rw-r--r-- | sys/net/if_loop.c | 42 |
2 files changed, 16 insertions, 49 deletions
diff --git a/share/man/man4/lo.4 b/share/man/man4/lo.4 index f1ac67c7d7db..5b808153559a 100644 --- a/share/man/man4/lo.4 +++ b/share/man/man4/lo.4 @@ -29,7 +29,7 @@ .\" .\" @(#)lo.4 8.1 (Berkeley) 6/5/93 .\" -.Dd June 23, 2024 +.Dd June 28, 2026 .Dt LO 4 .Os .Sh NAME @@ -56,19 +56,16 @@ The loopback should be configured first unless no hardware interfaces exist. .Pp -If the transmit checksum offload capability flag is enabled on a loopback -interface, checksums will not be generated by IP, UDP, TCP, or SCTP for packets -sent on the interface. +If the transmit checksum offload capability is enabled on a loopback interface, +checksums will not be generated by IP, UDP, TCP, or SCTP for packets sent on the +interface. +By default, this capability is enabled to avoid the overhead of checksumming for +local communication where data corruption is unlikely. .Pp -If the receive checksum offload capability flag is enabled on a loopback -interface, checksums will not be validated by IP, UDP, TCP, or SCTP for packets -received on the interface. -.Pp -By default, both receive and transmit checksum flags will be enabled, in -order to avoid the overhead of checksumming for local communication where -data corruption is unlikely. -If transmit checksum generation is disabled, then validation should also be -disabled in order to avoid packets being dropped due to invalid checksums. +If the receive checksum offload capability is disabled on a loopback interface, +the flags that indicate a valid checksum will be unset if set previously. +By default, this capability is enabled to avoid another checksum validation if +it has already been validated. .Sh DIAGNOSTICS .Bl -diag .It lo%d: can't handle af%d. diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 27c9281957e2..90252ae06b05 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -231,38 +231,22 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, else af = RO_GET_FAMILY(ro, dst); -#if 1 /* XXX */ switch (af) { case AF_INET: - if (ifp->if_capenable & IFCAP_RXCSUM) { - m->m_pkthdr.csum_data = 0xffff; - m->m_pkthdr.csum_flags = LO_CSUM_SET; + if ((ifp->if_capenable & IFCAP_RXCSUM) == 0) { + m->m_pkthdr.csum_flags &= ~LO_CSUM_SET; } - m->m_pkthdr.csum_flags &= ~LO_CSUM_FEATURES; break; case AF_INET6: -#if 0 - /* - * XXX-BZ for now always claim the checksum is good despite - * any interface flags. This is a workaround for 9.1-R and - * a proper solution ought to be sought later. - */ - if (ifp->if_capenable & IFCAP_RXCSUM_IPV6) { - m->m_pkthdr.csum_data = 0xffff; - m->m_pkthdr.csum_flags = LO_CSUM_SET; + if ((ifp->if_capenable & IFCAP_RXCSUM_IPV6) == 0) { + m->m_pkthdr.csum_flags &= ~LO_CSUM_SET; } -#else - m->m_pkthdr.csum_data = 0xffff; - m->m_pkthdr.csum_flags = LO_CSUM_SET; -#endif - m->m_pkthdr.csum_flags &= ~LO_CSUM_FEATURES6; break; default: printf("looutput: af=%d unexpected\n", af); m_freem(m); return (EAFNOSUPPORT); } -#endif return (if_simloop(ifp, m, af, 0)); } @@ -416,29 +400,15 @@ loioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifp->if_capenable ^= IFCAP_RXCSUM; if ((mask & IFCAP_TXCSUM) != 0) ifp->if_capenable ^= IFCAP_TXCSUM; - if ((mask & IFCAP_RXCSUM_IPV6) != 0) { -#if 0 + if ((mask & IFCAP_RXCSUM_IPV6) != 0) ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; -#else - error = EOPNOTSUPP; - break; -#endif - } - if ((mask & IFCAP_TXCSUM_IPV6) != 0) { -#if 0 + if ((mask & IFCAP_TXCSUM_IPV6) != 0) ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; -#else - error = EOPNOTSUPP; - break; -#endif - } ifp->if_hwassist = 0; if (ifp->if_capenable & IFCAP_TXCSUM) ifp->if_hwassist = LO_CSUM_FEATURES; -#if 0 if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) ifp->if_hwassist |= LO_CSUM_FEATURES6; -#endif break; default: |
