Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net Add handling of VLAN packets in if_bridge where the ...



details:   https://anonhg.NetBSD.org/src/rev/4594d346884f
branches:  trunk
changeset: 341712:4594d346884f
user:      christos <christos%NetBSD.org@localhost>
date:      Thu Nov 19 16:23:54 2015 +0000

description:
Add handling of VLAN packets in if_bridge where the parent interface supports
them (Jean-Jacques.Puig%espci.fr@localhost). Factor out the vlan_mtu enabling and
disabling code.

diffstat:

 sys/net/if_bridge.c    |   7 +++-
 sys/net/if_ether.h     |   4 ++-
 sys/net/if_ethersubr.c |  73 ++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/net/if_vlan.c      |  61 +++++++++++++----------------------------
 4 files changed, 99 insertions(+), 46 deletions(-)

diffs (237 lines):

diff -r b46a412cc859 -r 4594d346884f sys/net/if_bridge.c
--- a/sys/net/if_bridge.c       Thu Nov 19 10:45:09 2015 +0000
+++ b/sys/net/if_bridge.c       Thu Nov 19 16:23:54 2015 +0000
@@ -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 @@
 
        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 @@
                 * Don't call it with holding a spin lock.
                 */
                (void) ifpromisc(ifs, 0);
+               (void) ether_disable_vlan_mtu(ifs);
                break;
        default:
 #ifdef DIAGNOSTIC
diff -r b46a412cc859 -r 4594d346884f sys/net/if_ether.h
--- a/sys/net/if_ether.h        Thu Nov 19 10:45:09 2015 +0000
+++ b/sys/net/if_ether.h        Thu Nov 19 16:23:54 2015 +0000
@@ -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_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.
diff -r b46a412cc859 -r 4594d346884f sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c    Thu Nov 19 10:45:09 2015 +0000
+++ b/sys/net/if_ethersubr.c    Thu Nov 19 16:23:54 2015 +0000
@@ -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 @@
        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)
 {
diff -r b46a412cc859 -r 4594d346884f sys/net/if_vlan.c
--- a/sys/net/if_vlan.c Thu Nov 19 10:45:09 2015 +0000
+++ b/sys/net/if_vlan.c Thu Nov 19 16:23:54 2015 +0000
@@ -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 @@
                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 @@
        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 */



Home | Main Index | Thread Index | Old Index