Date: Thu, 20 Sep 2018 19:35:35 +0000 (UTC) From: Stephen Hurd <shurd@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r338838 - head/sys/net Message-ID: <201809201935.w8KJZZtb001882@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: shurd Date: Thu Sep 20 19:35:35 2018 New Revision: 338838 URL: https://svnweb.freebsd.org/changeset/base/338838 Log: Fix capabilities handling for iflib drivers Various capabilities were not being handled correctly in the SIOCSIFCAP handler. Specifically: IFCAP_RXCSUM and IFCAP_RXCSUM_IPV6 could be set even if not supported It was impossible to disable IFCAP_RXCSUM and/or IFCAP_RXCSUM_IPV6 via ifconfig since it does ioctl() per command-line flag rather than combine them into a single call. IFCAP_VLAN_HWCSUM could not be modified via the ioctl() Setting any combination of the three IFCAP_WOL flags would set only IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC. For example, setting only IFCAP_WOL_UCAST would result in both IFCAP_WOL_MCAST and IFCAP_WOL_MAGIC being enabled, but IFCAP_WOL_UCAST would not be enabled. Because if_vlancap() was called before if_togglecapenable(), vlan flags were sometimes not applied correctly. Interfaces were being unnecessarily stopped and restarted for WoL PR: 231151 Submitted by: Kaho Toshikazu <kaho@elam.kais.kyoto-u.ac.jp> Reported by: Shirkdog <mshirk@daemon-security.com> Reviewed by: galladin Approved by: re (gjb) Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D17158 Modified: head/sys/net/iflib.c Modified: head/sys/net/iflib.c ============================================================================== --- head/sys/net/iflib.c Thu Sep 20 18:30:17 2018 (r338837) +++ head/sys/net/iflib.c Thu Sep 20 19:35:35 2018 (r338838) @@ -4100,9 +4100,10 @@ iflib_if_qflush(if_t ifp) } -#define IFCAP_FLAGS (IFCAP_TXCSUM_IPV6 | IFCAP_RXCSUM_IPV6 | IFCAP_HWCSUM | IFCAP_LRO | \ - IFCAP_TSO4 | IFCAP_TSO6 | IFCAP_VLAN_HWTAGGING | IFCAP_HWSTATS | \ - IFCAP_VLAN_MTU | IFCAP_VLAN_HWFILTER | IFCAP_VLAN_HWTSO) +#define IFCAP_FLAGS (IFCAP_HWCSUM_IPV6 | IFCAP_HWCSUM | IFCAP_LRO | \ + IFCAP_TSO | IFCAP_VLAN_HWTAGGING | IFCAP_HWSTATS | \ + IFCAP_VLAN_MTU | IFCAP_VLAN_HWFILTER | \ + IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM) static int iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) @@ -4223,39 +4224,51 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) } case SIOCSIFCAP: { - int mask, setmask; + int mask, setmask, oldmask; - mask = ifr->ifr_reqcap ^ if_getcapenable(ifp); + oldmask = if_getcapenable(ifp); + mask = ifr->ifr_reqcap ^ oldmask; + mask &= ctx->ifc_softc_ctx.isc_capabilities; setmask = 0; #ifdef TCP_OFFLOAD setmask |= mask & (IFCAP_TOE4|IFCAP_TOE6); #endif setmask |= (mask & IFCAP_FLAGS); + setmask |= (mask & IFCAP_WOL); - if (setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) - setmask |= (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); - if ((mask & IFCAP_WOL) && - (if_getcapabilities(ifp) & IFCAP_WOL) != 0) - setmask |= (mask & (IFCAP_WOL_MCAST|IFCAP_WOL_MAGIC)); - if_vlancap(ifp); /* + * If we're disabling any RX csum, disable all the ones + * the driver supports. This assumes all supported are + * enabled. + * + * Otherwise, if they've changed, enable all of them. + */ + if ((setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) < + (oldmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))) + setmask &= ~(IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); + else if ((setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) != + (oldmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))) + setmask |= (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)); + + /* * want to ensure that traffic has stopped before we change any of the flags */ if (setmask) { CTX_LOCK(ctx); bits = if_getdrvflags(ifp); - if (bits & IFF_DRV_RUNNING) + if (bits & IFF_DRV_RUNNING && setmask & ~IFCAP_WOL) iflib_stop(ctx); STATE_LOCK(ctx); if_togglecapenable(ifp, setmask); STATE_UNLOCK(ctx); - if (bits & IFF_DRV_RUNNING) + if (bits & IFF_DRV_RUNNING && setmask & ~IFCAP_WOL) iflib_init_locked(ctx); STATE_LOCK(ctx); if_setdrvflags(ifp, bits); STATE_UNLOCK(ctx); CTX_UNLOCK(ctx); } + if_vlancap(ifp); break; } case SIOCGPRIVATE_0:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201809201935.w8KJZZtb001882>