Page MenuHomeFreeBSD

D51639.id159518.diff
No OneTemporary

D51639.id159518.diff

diff --git a/share/man/man4/epair.4 b/share/man/man4/epair.4
--- 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 March 18, 2015
+.Dd July 30, 2025
.Dt EPAIR 4
.Os
.Sh NAME
@@ -96,6 +96,21 @@
can have a
.Xr vlan 4
configured on top of it.
+.Pp
+The
+.Nm
+supports TXCSUM and TXCSUM6 for TCP and UDP,
+but only by forwarding the order to compute the checksum.
+Thus, when using an
+.Nm
+interface, a TCP or UDP sender can offload checksum computation
+to a physical interface.
+Note that, in case the packet does not leave the host, the checksum is
+unnecessary and will be ignored if offloaded.
+TXCSUM and TXCSUM6 are synchronized between the
+.Nm
+interface pair (i.e., enabling/disabling the capability on one end
+enables/disables it on the other end).
.Sh SEE ALSO
.Xr ioctl 2 ,
.Xr altq 4 ,
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -66,9 +66,9 @@
#include <net/if_var.h>
#include <net/if_clone.h>
#include <net/if_media.h>
-#include <net/if_var.h>
#include <net/if_private.h>
#include <net/if_types.h>
+#include <net/if_vlan_var.h>
#include <net/netisr.h>
#ifdef RSS
#include <net/rss_config.h>
@@ -96,6 +96,7 @@
#define EPAIR_LOCK_DESTROY() mtx_destroy(&epair_n_index_mtx)
#define EPAIR_LOCK() mtx_lock(&epair_n_index_mtx)
#define EPAIR_UNLOCK() mtx_unlock(&epair_n_index_mtx)
+#define EPAIR_LOCK_ASSERT() mtx_assert(&epair_n_index_mtx, MA_OWNED);
struct epair_softc;
struct epair_queue {
@@ -425,6 +426,23 @@
imr->ifm_active = IFM_ETHER | IFM_10G_T | IFM_FDX;
}
+/*
+ * To be called under EPAIR_LOCK. Update ifp->if_hwassist according to the
+ * current value of ifp->if_capenable.
+ */
+static void
+epair_caps_changed(struct ifnet *ifp)
+{
+ uint64_t hwassist = 0;
+
+ EPAIR_LOCK_ASSERT();
+ if (ifp->if_capenable & IFCAP_TXCSUM)
+ hwassist |= CSUM_IP_TCP | CSUM_IP_UDP;
+ if (ifp->if_capenable & IFCAP_TXCSUM_IPV6)
+ hwassist |= CSUM_IP6_TCP | CSUM_IP6_UDP;
+ ifp->if_hwassist = hwassist;
+}
+
static int
epair_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
@@ -452,6 +470,33 @@
error = 0;
break;
+ case SIOCGIFCAP:
+ ifr->ifr_reqcap = ifp->if_capabilities;
+ ifr->ifr_curcap = ifp->if_capenable;
+ error = 0;
+ break;
+ case SIOCSIFCAP:
+ sc = ifp->if_softc;
+ EPAIR_LOCK();
+ ifp->if_capenable = ifr->ifr_reqcap;
+ epair_caps_changed(ifp);
+ /*
+ * If IFCAP_TXCSUM(_IPV6) has been changed, change it on the
+ * other epair interface as well.
+ */
+ if ((ifp->if_capenable ^ sc->oifp->if_capenable) &
+ (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) {
+ sc->oifp->if_capenable &=
+ ~(IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
+ sc->oifp->if_capenable |= ifp->if_capenable &
+ (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
+ epair_caps_changed(sc->oifp);
+ }
+ EPAIR_UNLOCK();
+ VLAN_CAPABILITIES(ifp);
+ error = 0;
+ break;
+
default:
/* Let the common ethernet handler process this. */
error = ether_ioctl(ifp, cmd, data);
@@ -549,8 +594,12 @@
ifp->if_dname = epairname;
ifp->if_dunit = unit;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_capabilities = IFCAP_VLAN_MTU;
+ EPAIR_LOCK();
+ ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_TXCSUM |
+ IFCAP_TXCSUM_IPV6 | IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6;
ifp->if_capenable = IFCAP_VLAN_MTU;
+ epair_caps_changed(ifp);
+ EPAIR_UNLOCK();
ifp->if_transmit = epair_transmit;
ifp->if_qflush = epair_qflush;
ifp->if_start = epair_start;

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 28, 3:33 PM (6 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37464377
Default Alt Text
D51639.id159518.diff (3 KB)

Event Timeline