aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Völker <timo.voelker@fh-muenster.de>2026-08-16 18:31:33 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2026-08-16 18:38:36 +0000
commitf343f036c780cfd8e7f243b7708d96b006a257d7 (patch)
tree15ffc32cd06d7edd3eeabbf2a22f365f259f7acc
parent550db3d6f502946f6cf01eeb34f53e70395ddc6f (diff)
epair: allow disabling receive checksum offloading
Allow disabling RXCSUM and RXCSUM6 on an epair interface. If disabled, epair unsets the mbuf flags that indicate a valid checksum when transferring a packet from one epair end to the other. This gives a user in a jail the power to control whether the user wants to use the result of a previous validation (by a physical interface) or not. Reviewed by: kp, tuexen MFC after: 1 month MFC to: stable/15 Differential Revision: https://reviews.freebsd.org/D58786
-rw-r--r--share/man/man4/epair.410
-rw-r--r--sys/net/if_epair.c24
2 files changed, 23 insertions, 11 deletions
diff --git a/share/man/man4/epair.4 b/share/man/man4/epair.4
index ba42106d45f8..f28f68bdfc19 100644
--- a/share/man/man4/epair.4
+++ b/share/man/man4/epair.4
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 30, 2026
+.Dd August 16, 2026
.Dt EPAIR 4
.Os
.Sh NAME
@@ -111,8 +111,12 @@ configured on top of it.
.Pp
The
.Nm
-has RXCSUM and RXCSUM6 enabled because it may receive a packet where the
-checksum has already been validated by a physical interface.
+supports RXCSUM and RXCSUM6 but does not validate a checksum.
+In case an interface previously validated the checksum,
+.Nm
+leaves the flags set that indicate a valid checksum if RXCSUM and RXCSUM6 are
+enabled or unsets these flags if RXCSUM and RXCSUM6 are disabled.
+Note that RXCSUM and RXCSUM6 can only be enabled or disabled as a pair.
.Pp
The
.Nm
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index 5addd43b6190..c3354bc76e64 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -242,6 +242,9 @@ epair_prepare_mbuf(struct mbuf *m, struct ifnet *src_ifp)
epair_clear_mbuf(m);
if_setrcvif(m, src_ifp);
M_SETFIB(m, src_ifp->if_fib);
+ if ((if_getcapenable(src_ifp) & IFCAP_RXCSUM) == 0)
+ m->m_pkthdr.csum_flags &= ~(CSUM_L3_CALC | CSUM_L3_VALID |
+ CSUM_L4_CALC | CSUM_L4_VALID);
MPASS(m->m_nextpkt == NULL);
MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0);
@@ -455,7 +458,7 @@ epair_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct epair_softc *sc;
struct ifreq *ifr;
- int error;
+ int error, cap;
ifr = (struct ifreq *)data;
switch (cmd) {
@@ -484,14 +487,19 @@ epair_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCSIFCAP:
/*
- * Enable/disable capabilities as requested, besides
- * IFCAP_RXCSUM(_IPV6), which always remain enabled.
- * Incoming packets may have the mbuf flag CSUM_DATA_VALID set.
- * Without IFCAP_RXCSUM(_IPV6), this flag would have to be
- * removed, which does not seem helpful.
+ * Enable/disable capabilities as requested, but treat
+ * IFCAP_RXCSUM and IFCAP_RXCSUM_IPV6 special as they can only
+ * be set or unset as pair.
*/
- ifp->if_capenable = ifr->ifr_reqcap | IFCAP_RXCSUM |
- IFCAP_RXCSUM_IPV6;
+ cap = ifr->ifr_reqcap;
+ if (((cap & IFCAP_RXCSUM) == 0) !=
+ ((cap & IFCAP_RXCSUM_IPV6) == 0)) {
+ if ((ifp->if_capenable & IFCAP_RXCSUM) == 0)
+ cap |= (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
+ else
+ cap &= ~(IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
+ }
+ ifp->if_capenable = cap;
epair_caps_changed(ifp);
VLAN_CAPABILITIES(ifp);
/*