Hi, 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.
For ifconfig(8) we use "tcprecvoffload" and "tcpsendoffload". So, the user has a better insight of what this features are doing. ok? bye, 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 10 May 2023 16:22:30 -0000 @@ -282,8 +282,10 @@ tag. As CSUM_TCPv4, but supports IPv6 datagrams. .It Sy CSUM_UDPv6 As above, for UDP. +.It Sy LRO +The device supports TCP large receive offloading (LRO). .It Sy TSO -The device supports TCP segment offloading (TSO). +The device supports TCP segmentation offloading (TSO). .It Sy WOL The device supports Wake on LAN (WoL). .It Sy hardmtu @@ -491,10 +493,30 @@ 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 +.It Cm tcprecvoffload +Enable TCP large receive offloading (LRO) if it's supported by the hardware; see +.Cm hwfeatures . +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 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 -tcprecvoffload +Disable LRO. +LRO is disabled by default. +.It Cm tcpsendoffload Enable TCP segmentation offloading (TSO) if it's supported by the hardware; see .Cm hwfeatures . -TSO enabled NICs modify received TCP/IP packets. +TSO enabled network interfaces are able to split large TCP segments into smaller +peaces that fits into MTU and MSS. This will also affect traffic of upper layer interfaces, such as .Xr vlan 4 , @@ -506,8 +528,7 @@ It is not possible to use TSO with inter .Xr veb 4 , or .Xr tpmr 4 . -Changing this option will re-initialize the network interface. -.It Cm -tso +.It Cm -tcpsendoffload Disable TSO. TSO is disabled by default. .It Cm 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 10 May 2023 15:40:17 -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\16LRO\17TSO\20WOL" struct ifencap { unsigned int ife_flags; @@ -469,8 +469,10 @@ 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 }, + { "tcpsendoffload", IFXF_TSO, 0, setifxflags }, + { "-tcpsendoffload", -IFXF_TSO, 0, setifxflags }, #ifndef SMALL { "hwfeatures", NEXTARG0, 0, printifhwfeatures }, { "metric", NEXTARG, 0, setifmetric }, @@ -674,7 +676,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" "\33TSO" 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 10 May 2023 16:32: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 */ + /* Enable TCP Receive Offloading */ 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 10 May 2023 15:15:18 -0000 @@ -2101,6 +2101,9 @@ ifioctl(struct socket *so, u_long cmd, c error = ENOTSUP; } #endif + if (ISSET(ifr->ifr_flags, IFXF_LRO) != + ISSET(ifp->if_xflags, IFXF_LRO)) + error = ifsetlro(ifp, ISSET(ifr->ifr_flags, IFXF_LRO)); if (ISSET(ifr->ifr_flags, IFXF_TSO) != ISSET(ifp->if_xflags, IFXF_TSO)) @@ -3145,37 +3148,33 @@ 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)) { /* go down for a moment... */ @@ -3188,6 +3187,43 @@ ifsettso(struct ifnet *ifp, int on) ifrq.ifr_flags = ifp->if_flags; (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); } + out: + splx(s); + + return error; +} + +/* Set/clear TSO flag. */ +int +ifsettso(struct ifnet *ifp, int on) +{ + int error = 0; + int s = splnet(); + + if (!ISSET(ifp->if_capabilities, IFCAP_TSO)) { + error = ENOTSUP; + goto out; + } + + NET_ASSERT_LOCKED(); /* for ioctl */ + KERNEL_ASSERT_LOCKED(); /* for if_flags */ + + if (on && !ISSET(ifp->if_xflags, IFXF_TSO)) { + 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); + else + goto out; + +#if NVLAN > 0 + /* Change TSO flag also on attached vlan(4) interfaces. */ + vlan_flags_from_parent(ifp, IFXF_TSO); +#endif + out: splx(s); 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 10 May 2023 16:04:38 -0000 @@ -231,7 +231,8 @@ 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 offloading */ +#define IFXF_TSO 0x400 /* [N] TCP segment offloading */ #define IFXF_CANTCHANGE \ (IFXF_MPSAFE|IFXF_CLONED) @@ -251,6 +252,7 @@ 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_LRO 0x00002000 /* TCP large recv offloading */ #define IFCAP_TSO 0x00004000 /* TCP segment offloading */ #define IFCAP_WOL 0x00008000 /* can do wake on lan */ @@ -544,6 +546,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 ifsetlro(struct ifnet *, int); int ifsettso(struct ifnet *, int); struct ifg_group *if_creategroup(const char *); int if_addgroup(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 10 May 2023 16:39:59 -0000 @@ -2618,6 +2618,9 @@ aggr_update_capabilities(struct aggr_sof uint32_t capabilities = ~0; int set = 0; + /* Do not inherit LRO/TSO capabilities. */ + CLR(capabilities, IFCAP_LRO|IFCAP_TSO); + 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 10 May 2023 14:55:59 -0000 @@ -338,6 +338,7 @@ bridge_ioctl(struct ifnet *ifp, u_long c */ NET_LOCK(); + ifsetlro(ifs, 0); ifsettso(ifs, 0); NET_UNLOCK(); 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 10 May 2023 14:56:12 -0000 @@ -521,6 +521,7 @@ tpmr_add_port(struct tpmr_softc *sc, con goto put; } + ifsetlro(ifp0, 0); ifsettso(ifp0, 0); p->p_ifp0 = ifp0; 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 10 May 2023 14:56:24 -0000 @@ -1465,6 +1465,7 @@ veb_add_port(struct veb_softc *sc, const goto put; } + ifsetlro(ifp0, 0); ifsettso(ifp0, 0); p->p_ifp0 = ifp0;