Module Name:    src
Committed By:   christos
Date:           Thu Nov 19 16:23:54 UTC 2015

Modified Files:
        src/sys/net: if_bridge.c if_ether.h if_ethersubr.c if_vlan.c

Log Message:
Add handling of VLAN packets in if_bridge where the parent interface supports
them (jean-jacques.p...@espci.fr). Factor out the vlan_mtu enabling and
disabling code.


To generate a diff of this commit:
cvs rdiff -u -r1.104 -r1.105 src/sys/net/if_bridge.c
cvs rdiff -u -r1.64 -r1.65 src/sys/net/if_ether.h
cvs rdiff -u -r1.214 -r1.215 src/sys/net/if_ethersubr.c
cvs rdiff -u -r1.82 -r1.83 src/sys/net/if_vlan.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if_bridge.c
diff -u src/sys/net/if_bridge.c:1.104 src/sys/net/if_bridge.c:1.105
--- src/sys/net/if_bridge.c:1.104	Tue Oct 20 10:46:45 2015
+++ src/sys/net/if_bridge.c	Thu Nov 19 11:23:54 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_bridge.c,v 1.104 2015/10/20 14:46:45 maxv Exp $	*/
+/*	$NetBSD: if_bridge.c,v 1.105 2015/11/19 16:23:54 christos Exp $	*/
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.104 2015/10/20 14:46:45 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.105 2015/11/19 16:23:54 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_bridge_ipf.h"
@@ -893,6 +893,8 @@ bridge_ioctl_add(struct bridge_softc *sc
 
 	switch (ifs->if_type) {
 	case IFT_ETHER:
+		if ((error = ether_enable_vlan_mtu(ifs)) > 0)
+			goto out;
 		/*
 		 * Place the interface into promiscuous mode.
 		 */
@@ -970,6 +972,7 @@ bridge_ioctl_del(struct bridge_softc *sc
 		 * Don't call it with holding a spin lock.
 		 */
 		(void) ifpromisc(ifs, 0);
+		(void) ether_disable_vlan_mtu(ifs);
 		break;
 	default:
 #ifdef DIAGNOSTIC

Index: src/sys/net/if_ether.h
diff -u src/sys/net/if_ether.h:1.64 src/sys/net/if_ether.h:1.65
--- src/sys/net/if_ether.h:1.64	Mon Jul 28 10:24:48 2014
+++ src/sys/net/if_ether.h	Thu Nov 19 11:23:54 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ether.h,v 1.64 2014/07/28 14:24:48 ozaki-r Exp $	*/
+/*	$NetBSD: if_ether.h,v 1.65 2015/11/19 16:23:54 christos Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -337,6 +337,8 @@ uint32_t ether_crc32_le(const uint8_t *,
 uint32_t ether_crc32_be(const uint8_t *, size_t);
 
 int	ether_aton_r(u_char *, size_t, const char *);
+int	ether_enable_vlan_mtu(struct ifnet *);
+int	ether_disable_vlan_mtu(struct ifnet *);
 #else
 /*
  * Prototype ethers(3) functions.

Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.214 src/sys/net/if_ethersubr.c:1.215
--- src/sys/net/if_ethersubr.c:1.214	Tue Oct 13 08:33:07 2015
+++ src/sys/net/if_ethersubr.c	Thu Nov 19 11:23:54 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ethersubr.c,v 1.214 2015/10/13 12:33:07 roy Exp $	*/
+/*	$NetBSD: if_ethersubr.c,v 1.215 2015/11/19 16:23:54 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.214 2015/10/13 12:33:07 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.215 2015/11/19 16:23:54 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -1416,6 +1416,75 @@ ether_ioctl(struct ifnet *ifp, u_long cm
 	return 0;
 }
 
+/*
+ * Enable/disable passing VLAN packets if the parent interface supports it.
+ * Return:
+ * 	 0: Ok
+ *	-1: Parent interface does not support vlans
+ *	>0: Error
+ */
+int
+ether_enable_vlan_mtu(struct ifnet *ifp)
+{
+	int error;
+	struct ethercom *ec = (void *)ifp;
+
+	/* Already have VLAN's do nothing. */
+	if (ec->ec_nvlans != 0)
+		return 0;
+
+	/* Parent does not support VLAN's */
+	if ((ec->ec_capabilities & ETHERCAP_VLAN_MTU) == 0)
+		return -1;
+
+	/*
+	 * Parent supports the VLAN_MTU capability,
+	 * i.e. can Tx/Rx larger than ETHER_MAX_LEN frames;
+	 * enable it.
+	 */
+	ec->ec_capenable |= ETHERCAP_VLAN_MTU;
+
+	/* Interface is down, defer for later */
+	if ((ifp->if_flags & IFF_UP) == 0)
+		return 0;
+
+	if ((error = if_flags_set(ifp, ifp->if_flags)) == 0)
+		return 0;
+
+	ec->ec_capenable &= ~ETHERCAP_VLAN_MTU;
+	return error;
+}
+
+int
+ether_disable_vlan_mtu(struct ifnet *ifp)
+{
+	int error;
+	struct ethercom *ec = (void *)ifp;
+
+	/* We still have VLAN's, defer for later */
+	if (ec->ec_nvlans != 0)
+		return 0;
+
+	/* Parent does not support VLAB's, nothing to do. */
+	if ((ec->ec_capenable & ETHERCAP_VLAN_MTU) == 0)
+		return -1;
+
+	/*
+	 * Disable Tx/Rx of VLAN-sized frames.
+	 */
+	ec->ec_capenable &= ~ETHERCAP_VLAN_MTU;
+	
+	/* Interface is down, defer for later */
+	if ((ifp->if_flags & IFF_UP) == 0)
+		return 0;
+
+	if ((error = if_flags_set(ifp, ifp->if_flags)) == 0)
+		return 0;
+
+	ec->ec_capenable |= ETHERCAP_VLAN_MTU;
+	return error;
+}
+
 static int
 ether_multicast_sysctl(SYSCTLFN_ARGS)
 {

Index: src/sys/net/if_vlan.c
diff -u src/sys/net/if_vlan.c:1.82 src/sys/net/if_vlan.c:1.83
--- src/sys/net/if_vlan.c:1.82	Thu Aug 20 10:40:19 2015
+++ src/sys/net/if_vlan.c	Thu Nov 19 11:23:54 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vlan.c,v 1.82 2015/08/20 14:40:19 christos Exp $	*/
+/*	$NetBSD: if_vlan.c,v 1.83 2015/11/19 16:23:54 christos Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.82 2015/08/20 14:40:19 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.83 2015/11/19 16:23:54 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -284,36 +284,22 @@ vlan_config(struct ifvlan *ifv, struct i
 		ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN;
 		ifv->ifv_mintu = ETHERMIN;
 
-		/*
-		 * If the parent supports the VLAN_MTU capability,
-		 * i.e. can Tx/Rx larger than ETHER_MAX_LEN frames,
-		 * enable it.
-		 */
-		if (ec->ec_nvlans++ == 0 &&
-		    (ec->ec_capabilities & ETHERCAP_VLAN_MTU) != 0) {
-			/*
-			 * Enable Tx/Rx of VLAN-sized frames.
-			 */
-			ec->ec_capenable |= ETHERCAP_VLAN_MTU;
-			if (p->if_flags & IFF_UP) {
-				error = if_flags_set(p, p->if_flags);
-				if (error) {
-					if (ec->ec_nvlans-- == 1)
-						ec->ec_capenable &=
-						    ~ETHERCAP_VLAN_MTU;
-					return (error);
-				}
+		if (ec->ec_nvlans == 0) {
+			if ((error = ether_enable_vlan_mtu(p)) >= 0) {
+				if (error)
+					return error;
+				ifv->ifv_mtufudge = 0;
+			} else {
+				/*
+				 * Fudge the MTU by the encapsulation size. This
+				 * makes us incompatible with strictly compliant
+				 * 802.1Q implementations, but allows us to use
+				 * the feature with other NetBSD
+				 * implementations, which might still be useful.
+				 */
+				ifv->ifv_mtufudge = ifv->ifv_encaplen;
 			}
-			ifv->ifv_mtufudge = 0;
-		} else if ((ec->ec_capabilities & ETHERCAP_VLAN_MTU) == 0) {
-			/*
-			 * Fudge the MTU by the encapsulation size.  This
-			 * makes us incompatible with strictly compliant
-			 * 802.1Q implementations, but allows us to use
-			 * the feature with other NetBSD implementations,
-			 * which might still be useful.
-			 */
-			ifv->ifv_mtufudge = ifv->ifv_encaplen;
+			ec->ec_nvlans++;
 		}
 
 		/*
@@ -386,16 +372,9 @@ vlan_unconfig(struct ifnet *ifp)
 	switch (p->if_type) {
 	case IFT_ETHER:
 	    {
-		struct ethercom *ec = (void *) p;
-
-		if (ec->ec_nvlans-- == 1) {
-			/*
-			 * Disable Tx/Rx of VLAN-sized frames.
-			 */
-			ec->ec_capenable &= ~ETHERCAP_VLAN_MTU;
-			if (p->if_flags & IFF_UP)
-				(void)if_flags_set(p, p->if_flags);
-		}
+		struct ethercom *ec = (void *)p;
+		if (--ec->ec_nvlans == 0)
+			(void)ether_disable_vlan_mtu(p);
 
 		ether_ifdetach(ifp);
 		/* Restore vlan_ioctl overwritten by ether_ifdetach */

Reply via email to