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;