On Sat, May 13, 2023 at 04:44:18PM +0200, Christian Weisgerber wrote:
> Jan Klemkow:
>
> > This diff introduces separate flags for TCP offloading. We split this
> > into LRO (large receive offloading) and TSO (TCP segmentation
> > offloading). Thus, we are able to turn it on/off separately.
>
> Wait, why do we even have a knob for TSO?
>
> We specifically decided not to have a knob for checksum offloading,
> because it should just work out of the box, and if it doesn't, then
> it should be disabled by the driver. It should not be the admin's
> task to figure out if the implementation is broken and to fiddle
> with the knobs (hi, FreeBSD!).
>
> I would assume that line of thinking extends to TSO.
You are right. This is reflected in the current state of the diff
below.
We just need a knob for TCP Large Receive Offload (LRO) because it
changes the TCP segments. You may want to avoid this on a forwarding
router.
ok?
Thanks,
Jan
Index: sbin/ifconfig/ifconfig.8
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.394
diff -u -p -r1.394 ifconfig.8
--- sbin/ifconfig/ifconfig.8 26 Apr 2023 02:38:08 -0000 1.394
+++ sbin/ifconfig/ifconfig.8 12 May 2023 06:22:35 -0000
@@ -282,8 +282,18 @@ tag.
As CSUM_TCPv4, but supports IPv6 datagrams.
.It Sy CSUM_UDPv6
As above, for UDP.
-.It Sy TSO
-The device supports TCP segment offloading (TSO).
+.It Sy LRO
+The device supports TCP large receive offload (LRO).
+.It Sy TSOv4
+The device supports IPv4 TCP segmentation offload (TSO).
+TSO is used by default.
+Use the
+.Xr sysctl 8
+variable
+.Va net.inet.tcp.tso
+to disable this feature.
+.It Sy TSOv6
+As above, for IPv6.
.It Sy WOL
The device supports Wake on LAN (WoL).
.It Sy hardmtu
@@ -491,25 +501,25 @@ Query and display information and diagno
modules installed in an interface.
It is only supported by drivers implementing the necessary functionality
on hardware which supports it.
-.It Cm tso
-Enable TCP segmentation offloading (TSO) if it's supported by the hardware; see
+.It Cm tcprecvoffload
+Enable TCP large receive offload (LRO) if it's supported by the hardware; see
.Cm hwfeatures .
-TSO enabled NICs modify received TCP/IP packets.
+LRO enabled network interfaces modify received TCP/IP packets.
This will also affect traffic of upper layer interfaces,
such as
.Xr vlan 4 ,
.Xr aggr 4 ,
and
.Xr carp 4 .
-It is not possible to use TSO with interfaces attached to a
+It is not possible to use LRO with interfaces attached to a
.Xr bridge 4 ,
.Xr veb 4 ,
or
.Xr tpmr 4 .
Changing this option will re-initialize the network interface.
-.It Cm -tso
-Disable TSO.
-TSO is disabled by default.
+.It Cm -tcprecvoffload
+Disable LRO.
+LRO is disabled by default.
.It Cm up
Mark an interface
.Dq up .
Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.462
diff -u -p -r1.462 ifconfig.c
--- sbin/ifconfig/ifconfig.c 8 Mar 2023 04:43:06 -0000 1.462
+++ sbin/ifconfig/ifconfig.c 11 May 2023 17:33:55 -0000
@@ -126,7 +126,7 @@
#define HWFEATURESBITS \
"\024\1CSUM_IPv4\2CSUM_TCPv4\3CSUM_UDPv4" \
"\5VLAN_MTU\6VLAN_HWTAGGING\10CSUM_TCPv6" \
- "\11CSUM_UDPv6\17TSO\20WOL"
+ "\11CSUM_UDPv6\15LRO\16TSOv4\17TSOv6\20WOL"
struct ifencap {
unsigned int ife_flags;
@@ -469,8 +469,8 @@ const struct cmd {
{ "-soii", IFXF_INET6_NOSOII, 0, setifxflags },
{ "monitor", IFXF_MONITOR, 0, setifxflags },
{ "-monitor", -IFXF_MONITOR, 0, setifxflags },
- { "tso", IFXF_TSO, 0, setifxflags },
- { "-tso", -IFXF_TSO, 0, setifxflags },
+ { "tcprecvoffload", IFXF_LRO, 0, setifxflags },
+ { "-tcprecvoffload", -IFXF_LRO, 0, setifxflags },
#ifndef SMALL
{ "hwfeatures", NEXTARG0, 0, printifhwfeatures },
{ "metric", NEXTARG, 0, setifmetric },
@@ -674,7 +674,7 @@ const struct cmd {
"\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX" \
"\15LINK0\16LINK1\17LINK2\20MULTICAST" \
"\23AUTOCONF6TEMP\24MPLS\25WOL\26AUTOCONF6\27INET6_NOSOII" \
- "\30AUTOCONF4" "\31MONITOR" "\32TSO"
+ "\30AUTOCONF4" "\31MONITOR" "\32LRO"
int getinfo(struct ifreq *, int);
void getsock(int);
Index: sys/dev/pci/if_ix.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ix.c,v
retrieving revision 1.193
diff -u -p -r1.193 if_ix.c
--- sys/dev/pci/if_ix.c 28 Apr 2023 10:18:57 -0000 1.193
+++ sys/dev/pci/if_ix.c 12 May 2023 06:37:44 -0000
@@ -1925,7 +1925,7 @@ ixgbe_setup_interface(struct ix_softc *s
ifp->if_capabilities |= IFCAP_CSUM_IPv4;
if (sc->hw.mac.type != ixgbe_mac_82598EB)
- ifp->if_capabilities |= IFCAP_TSO;
+ ifp->if_capabilities |= IFCAP_LRO;
/*
* Specify the media types supported by this sc and register
@@ -2873,13 +2873,13 @@ ixgbe_initialize_receive_units(struct ix
hlreg |= IXGBE_HLREG0_JUMBOEN;
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg);
- if (ISSET(ifp->if_xflags, IFXF_TSO)) {
+ if (ISSET(ifp->if_xflags, IFXF_LRO)) {
rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
/* This field has to be set to zero. */
rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
- /* Enable TSO Receive Offloading */
+ /* RSC Coalescing on ACK Change */
rdrxctl |= IXGBE_RDRXCTL_RSCACKC;
rdrxctl |= IXGBE_RDRXCTL_FCOE_WRFIX;
@@ -2902,10 +2902,10 @@ ixgbe_initialize_receive_units(struct ix
srrctl = bufsz | IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl);
- if (ISSET(ifp->if_xflags, IFXF_TSO)) {
+ if (ISSET(ifp->if_xflags, IFXF_LRO)) {
rdrxctl = IXGBE_READ_REG(&sc->hw, IXGBE_RSCCTL(i));
- /* Enable TSO Receive Side Coalescing */
+ /* Enable Receive Side Coalescing */
rdrxctl |= IXGBE_RSCCTL_RSCEN;
rdrxctl |= IXGBE_RSCCTL_MAXDESC_16;
@@ -3263,7 +3263,7 @@ ixgbe_setup_vlan_hw_support(struct ix_so
* We have to disable VLAN striping when using TCP offloading, due to a
* firmware bug.
*/
- if (ISSET(ifp->if_xflags, IFXF_TSO)) {
+ if (ISSET(ifp->if_xflags, IFXF_LRO)) {
sc->vlan_stripping = 0;
return;
}
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.695
diff -u -p -r1.695 if.c
--- sys/net/if.c 7 May 2023 16:23:23 -0000 1.695
+++ sys/net/if.c 11 May 2023 17:15:39 -0000
@@ -2101,10 +2101,9 @@ ifioctl(struct socket *so, u_long cmd, c
error = ENOTSUP;
}
#endif
-
- if (ISSET(ifr->ifr_flags, IFXF_TSO) !=
- ISSET(ifp->if_xflags, IFXF_TSO))
- error = ifsettso(ifp, ISSET(ifr->ifr_flags, IFXF_TSO));
+ if (ISSET(ifr->ifr_flags, IFXF_LRO) !=
+ ISSET(ifp->if_xflags, IFXF_LRO))
+ error = ifsetlro(ifp, ISSET(ifr->ifr_flags, IFXF_LRO));
if (error == 0)
ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
@@ -3145,36 +3144,32 @@ ifpromisc(struct ifnet *ifp, int pswitch
return (error);
}
-/* Set/clear TSO flag and restart interface if needed. */
+/* Set/clear LRO flag and restart interface if needed. */
int
-ifsettso(struct ifnet *ifp, int on)
+ifsetlro(struct ifnet *ifp, int on)
{
struct ifreq ifrq;
int error = 0;
int s = splnet();
+ if (!ISSET(ifp->if_capabilities, IFCAP_LRO)) {
+ error = ENOTSUP;
+ goto out;
+ }
+
NET_ASSERT_LOCKED(); /* for ioctl */
KERNEL_ASSERT_LOCKED(); /* for if_flags */
- if (on && !ISSET(ifp->if_xflags, IFXF_TSO)) {
- if (!ISSET(ifp->if_capabilities, IFCAP_TSO)) {
- error = ENOTSUP;
- goto out;
- }
+ if (on && !ISSET(ifp->if_xflags, IFXF_LRO)) {
if (ether_brport_isset(ifp)) {
error = EBUSY;
goto out;
}
- SET(ifp->if_xflags, IFXF_TSO);
- } else if (!on && ISSET(ifp->if_xflags, IFXF_TSO))
- CLR(ifp->if_xflags, IFXF_TSO);
+ SET(ifp->if_xflags, IFXF_LRO);
+ } else if (!on && ISSET(ifp->if_xflags, IFXF_LRO))
+ CLR(ifp->if_xflags, IFXF_LRO);
else
goto out;
-
-#if NVLAN > 0
- /* Change TSO flag also on attached vlan(4) interfaces. */
- vlan_flags_from_parent(ifp, IFXF_TSO);
-#endif
/* restart interface */
if (ISSET(ifp->if_flags, IFF_UP)) {
Index: sys/net/if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.211
diff -u -p -r1.211 if.h
--- sys/net/if.h 7 Mar 2023 20:09:48 -0000 1.211
+++ sys/net/if.h 12 May 2023 06:52:29 -0000
@@ -231,7 +231,7 @@ struct if_status_description {
#define IFXF_INET6_NOSOII 0x40 /* [N] don't do RFC 7217 */
#define IFXF_AUTOCONF4 0x80 /* [N] v4 autoconf (aka dhcp)
enabled */
#define IFXF_MONITOR 0x100 /* [N] only used for bpf */
-#define IFXF_TSO 0x200 /* [N] TCP segment offloading */
+#define IFXF_LRO 0x200 /* [N] TCP large recv offload */
#define IFXF_CANTCHANGE \
(IFXF_MPSAFE|IFXF_CLONED)
@@ -251,12 +251,16 @@ struct if_status_description {
#define IFCAP_VLAN_HWTAGGING 0x00000020 /* hardware VLAN tag
support */
#define IFCAP_CSUM_TCPv6 0x00000080 /* can do IPv6/TCP
checksums */
#define IFCAP_CSUM_UDPv6 0x00000100 /* can do IPv6/UDP
checksums */
-#define IFCAP_TSO 0x00004000 /* TCP segment
offloading */
+#define IFCAP_LRO 0x00001000 /* TCP large recv
offload */
+#define IFCAP_TSOv4 0x00002000 /* TCP segmentation
offload */
+#define IFCAP_TSOv6 0x00004000 /* TCP segmentation
offload */
#define IFCAP_WOL 0x00008000 /* can do wake on lan */
#define IFCAP_CSUM_MASK (IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | \
IFCAP_CSUM_UDPv4 | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6)
+#define IFCAP_TSO (IFCAP_TSOv4 | IFCAP_TSOv6)
+
/* symbolic names for terminal (per-protocol) CTL_IFQ_ nodes */
#define IFQCTL_LEN 1
#define IFQCTL_MAXLEN 2
@@ -544,7 +548,7 @@ void if_getdata(struct ifnet *, struct i
void ifinit(void);
int ifioctl(struct socket *, u_long, caddr_t, struct proc *);
int ifpromisc(struct ifnet *, int);
-int ifsettso(struct ifnet *, int);
+int ifsetlro(struct ifnet *, int);
struct ifg_group *if_creategroup(const char *);
int if_addgroup(struct ifnet *, const char *);
int if_delgroup(struct ifnet *, const char *);
Index: sys/net/if_aggr.c
===================================================================
RCS file: /cvs/src/sys/net/if_aggr.c,v
retrieving revision 1.39
diff -u -p -r1.39 if_aggr.c
--- sys/net/if_aggr.c 5 Feb 2022 03:56:16 -0000 1.39
+++ sys/net/if_aggr.c 11 May 2023 15:48:32 -0000
@@ -2618,6 +2618,9 @@ aggr_update_capabilities(struct aggr_sof
uint32_t capabilities = ~0;
int set = 0;
+ /* Do not inherit LRO capabilities. */
+ CLR(capabilities, IFCAP_LRO);
+
rw_enter_read(&sc->sc_lock);
TAILQ_FOREACH(p, &sc->sc_ports, p_entry) {
struct ifnet *ifp0 = p->p_ifp0;
Index: sys/net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.366
diff -u -p -r1.366 if_bridge.c
--- sys/net/if_bridge.c 7 May 2023 16:23:23 -0000 1.366
+++ sys/net/if_bridge.c 11 May 2023 17:21:05 -0000
@@ -338,7 +338,7 @@ bridge_ioctl(struct ifnet *ifp, u_long c
*/
NET_LOCK();
- ifsettso(ifs, 0);
+ ifsetlro(ifs, 0);
NET_UNLOCK();
bif->bridge_sc = sc;
@@ -401,7 +401,7 @@ bridge_ioctl(struct ifnet *ifp, u_long c
}
NET_LOCK();
- ifsettso(ifs, 0);
+ ifsetlro(ifs, 0);
NET_UNLOCK();
bif->bridge_sc = sc;
Index: sys/net/if_tpmr.c
===================================================================
RCS file: /cvs/src/sys/net/if_tpmr.c,v
retrieving revision 1.32
diff -u -p -r1.32 if_tpmr.c
--- sys/net/if_tpmr.c 27 Feb 2023 09:35:32 -0000 1.32
+++ sys/net/if_tpmr.c 11 May 2023 17:21:39 -0000
@@ -521,7 +521,7 @@ tpmr_add_port(struct tpmr_softc *sc, con
goto put;
}
- ifsettso(ifp0, 0);
+ ifsetlro(ifp0, 0);
p->p_ifp0 = ifp0;
p->p_tpmr = sc;
Index: sys/net/if_veb.c
===================================================================
RCS file: /cvs/src/sys/net/if_veb.c,v
retrieving revision 1.30
diff -u -p -r1.30 if_veb.c
--- sys/net/if_veb.c 27 Feb 2023 09:35:32 -0000 1.30
+++ sys/net/if_veb.c 11 May 2023 17:21:21 -0000
@@ -1465,7 +1465,7 @@ veb_add_port(struct veb_softc *sc, const
goto put;
}
- ifsettso(ifp0, 0);
+ ifsetlro(ifp0, 0);
p->p_ifp0 = ifp0;
p->p_veb = sc;
Index: sys/net/if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.214
diff -u -p -r1.214 if_vlan.c
--- sys/net/if_vlan.c 26 Apr 2023 00:14:21 -0000 1.214
+++ sys/net/if_vlan.c 11 May 2023 18:48:59 -0000
@@ -536,7 +536,7 @@ vlan_up(struct vlan_softc *sc)
* Chips that can do hardware-assisted VLAN encapsulation, can
* calculate the correct checksum for VLAN tagged packets.
*/
- ifp->if_capabilities = ifp0->if_capabilities & IFCAP_CSUM_MASK;
+ SET(ifp->if_capabilities, ifp0->if_capabilities &
IFCAP_CSUM_MASK);
}
/* commit the sc */
@@ -560,9 +560,6 @@ vlan_up(struct vlan_softc *sc)
/* configure the parent to handle packets for this vlan */
vlan_multi_apply(sc, ifp0, SIOCADDMULTI);
- /* Inherit flags from parent interface. */
- vlan_flags_from_parent(ifp0, IFXF_TSO);
-
/* we're running now */
SET(ifp->if_flags, IFF_RUNNING);
vlan_link_state(sc, ifp0->if_link_state, ifp0->if_baudrate);
@@ -944,6 +941,7 @@ vlan_set_parent(struct vlan_softc *sc, c
if (!ISSET(sc->sc_flags, IFVF_LLADDR))
if_setlladdr(ifp, LLADDR(ifp0->if_sadl));
+ SET(ifp->if_capabilities, ifp0->if_capabilities & IFCAP_TSO);
put:
if_put(ifp0);
return (error);
@@ -962,29 +960,9 @@ vlan_del_parent(struct vlan_softc *sc)
if (!ISSET(sc->sc_flags, IFVF_LLADDR))
if_setlladdr(ifp, etheranyaddr);
- return (0);
-}
+ CLR(ifp->if_capabilities, IFCAP_TSO);
-void
-vlan_flags_from_parent(struct ifnet *ifp0, int flags)
-{
- struct vlan_softc *sc;
- int i;
-
- for (i = 0; i < TAG_HASH_SIZE; i++) {
- SMR_SLIST_FOREACH_LOCKED(sc, &vlan_tagh[i], sc_list) {
- /* vlan and tso only works with hw tagging */
- if (!ISSET(ifp0->if_capabilities, IFCAP_VLAN_HWTAGGING))
- CLR(flags, IFXF_TSO);
-
- if (sc->sc_ifidx0 == ifp0->if_index) {
- if (ISSET(ifp0->if_xflags, flags))
- SET(sc->sc_if.if_xflags, flags);
- else
- CLR(sc->sc_if.if_xflags, flags);
- }
- }
- }
+ return (0);
}
int
Index: sys/netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.356
diff -u -p -r1.356 ip_carp.c
--- sys/netinet/ip_carp.c 8 Mar 2023 04:43:09 -0000 1.356
+++ sys/netinet/ip_carp.c 11 May 2023 19:09:34 -0000
@@ -1693,7 +1693,7 @@ carp_set_ifp(struct carp_softc *sc, stru
sc->sc_carpdevidx = ifp0->if_index;
sc->sc_if.if_capabilities = ifp0->if_capabilities &
- IFCAP_CSUM_MASK;
+ (IFCAP_CSUM_MASK | IFCAP_TSO);
SRPL_FOREACH_LOCKED(vr, cif, sc_list) {
struct carp_vhost_entry *vrhead, *schead;