Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 May 2017 00:33:46 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r318330 - stable/11/sys/net
Message-ID:  <201705160033.v4G0Xk9D016755@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Tue May 16 00:33:46 2017
New Revision: 318330
URL: https://svnweb.freebsd.org/changeset/base/318330

Log:
  MFC r317547: Allow some control over enabled capabilities for if_vlan.
  
  It improves interoperability with if_bridge, which may need to disable
  some capabilities not supported by other members.  IMHO there is still
  open question about LRO capability, which may need to be disabled on
  physical interface.

Modified:
  stable/11/sys/net/if_vlan.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/net/if_vlan.c
==============================================================================
--- stable/11/sys/net/if_vlan.c	Tue May 16 00:30:40 2017	(r318329)
+++ stable/11/sys/net/if_vlan.c	Tue May 16 00:33:46 2017	(r318330)
@@ -112,6 +112,7 @@ struct	ifvlan {
 #define	PARENT(ifv)	((ifv)->ifv_trunk->parent)
 	void	*ifv_cookie;
 	int	ifv_pflags;	/* special flags we have set on parent */
+	int	ifv_capenable;
 	struct	ifv_linkmib {
 		int	ifvm_encaplen;	/* encapsulation length */
 		int	ifvm_mtufudge;	/* MTU fudged by this much */
@@ -1286,6 +1287,7 @@ exists:
 	ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN;
 	ifv->ifv_mintu = ETHERMIN;
 	ifv->ifv_pflags = 0;
+	ifv->ifv_capenable = -1;
 
 	/*
 	 * If the parent supports the VLAN_MTU capability,
@@ -1537,9 +1539,14 @@ vlan_capabilities(struct ifvlan *ifv)
 	struct ifnet *p = PARENT(ifv);
 	struct ifnet *ifp = ifv->ifv_ifp;
 	struct ifnet_hw_tsomax hw_tsomax;
+	int cap = 0, ena = 0, mena;
+	u_long hwa = 0;
 
 	TRUNK_LOCK_ASSERT(TRUNK(ifv));
 
+	/* Mask parent interface enabled capabilities disabled by user. */
+	mena = p->if_capenable & ifv->ifv_capenable;
+
 	/*
 	 * If the parent interface can do checksum offloading
 	 * on VLANs, then propagate its hardware-assisted
@@ -1547,20 +1554,18 @@ vlan_capabilities(struct ifvlan *ifv)
 	 * offloading requires hardware VLAN tagging.
 	 */
 	if (p->if_capabilities & IFCAP_VLAN_HWCSUM)
-		ifp->if_capabilities =
-		    p->if_capabilities & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6);
-
+		cap |= p->if_capabilities & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6);
 	if (p->if_capenable & IFCAP_VLAN_HWCSUM &&
 	    p->if_capenable & IFCAP_VLAN_HWTAGGING) {
-		ifp->if_capenable =
-		    p->if_capenable & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6);
-		ifp->if_hwassist = p->if_hwassist & (CSUM_IP | CSUM_TCP |
-		    CSUM_UDP | CSUM_SCTP | CSUM_TCP_IPV6 | CSUM_UDP_IPV6 |
-		    CSUM_SCTP_IPV6);
-	} else {
-		ifp->if_capenable = 0;
-		ifp->if_hwassist = 0;
+		ena |= mena & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6);
+		if (ena & IFCAP_TXCSUM)
+			hwa |= p->if_hwassist & (CSUM_IP | CSUM_TCP |
+			    CSUM_UDP | CSUM_SCTP);
+		if (ena & IFCAP_TXCSUM_IPV6)
+			hwa |= p->if_hwassist & (CSUM_TCP_IPV6 |
+			    CSUM_UDP_IPV6 | CSUM_SCTP_IPV6);
 	}
+
 	/*
 	 * If the parent interface can do TSO on VLANs then
 	 * propagate the hardware-assisted flag. TSO on VLANs
@@ -1570,13 +1575,11 @@ vlan_capabilities(struct ifvlan *ifv)
 	if_hw_tsomax_common(p, &hw_tsomax);
 	if_hw_tsomax_update(ifp, &hw_tsomax);
 	if (p->if_capabilities & IFCAP_VLAN_HWTSO)
-		ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO;
+		cap |= p->if_capabilities & IFCAP_TSO;
 	if (p->if_capenable & IFCAP_VLAN_HWTSO) {
-		ifp->if_capenable |= p->if_capenable & IFCAP_TSO;
-		ifp->if_hwassist |= p->if_hwassist & CSUM_TSO;
-	} else {
-		ifp->if_capenable &= ~(p->if_capenable & IFCAP_TSO);
-		ifp->if_hwassist &= ~(p->if_hwassist & CSUM_TSO);
+		ena |= mena & IFCAP_TSO;
+		if (ena & IFCAP_TSO)
+			hwa |= p->if_hwassist & CSUM_TSO;
 	}
 
 	/*
@@ -1589,11 +1592,22 @@ vlan_capabilities(struct ifvlan *ifv)
 	 */
 #define	IFCAP_VLAN_TOE IFCAP_TOE
 	if (p->if_capabilities & IFCAP_VLAN_TOE)
-		ifp->if_capabilities |= p->if_capabilities & IFCAP_TOE;
+		cap |= p->if_capabilities & IFCAP_TOE;
 	if (p->if_capenable & IFCAP_VLAN_TOE) {
 		TOEDEV(ifp) = TOEDEV(p);
-		ifp->if_capenable |= p->if_capenable & IFCAP_TOE;
+		ena |= mena & IFCAP_TOE;
 	}
+
+	/*
+	 * If the parent interface supports dynamic link state, so does the
+	 * VLAN interface.
+	 */
+	cap |= (p->if_capabilities & IFCAP_LINKSTATE);
+	ena |= (mena & IFCAP_LINKSTATE);
+
+	ifp->if_capabilities = cap;
+	ifp->if_capenable = ena;
+	ifp->if_hwassist = hwa;
 }
 
 static void
@@ -1797,6 +1811,18 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd
 		vlan_tag_recalculate(ifv);
 		break;
 
+	case SIOCSIFCAP:
+		VLAN_LOCK();
+		ifv->ifv_capenable = ifr->ifr_reqcap;
+		trunk = TRUNK(ifv);
+		if (trunk != NULL) {
+			TRUNK_LOCK(trunk);
+			vlan_capabilities(ifv);
+			TRUNK_UNLOCK(trunk);
+		}
+		VLAN_UNLOCK();
+		break;
+
 	default:
 		error = EINVAL;
 		break;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705160033.v4G0Xk9D016755>