git: fd3582e683d6 - stable/14 - loopback: improve checksum offloading

Michael Tuexen <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a744457.3bcc1.7a099521__42551.4314252482$1786004583$gmane$org@gitrepo.freebsd.org>
The branch stable/14 has been updated by tuexen:

URL: https://cgit.FreeBSD.org/src/commit/?id=fd3582e683d6cf97c59dcd898ece47a5497d5995

commit fd3582e683d6cf97c59dcd898ece47a5497d5995
Author:     Timo Völker <[email protected]>
AuthorDate: 2026-06-28 10:50:15 +0000
Commit:     Michael Tuexen <[email protected]>
CommitDate: 2026-08-06 05:45:51 +0000

    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)
---
 share/man/man4/lo.4 | 23 ++++++++++-------------
 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:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.