Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Jul 2001 15:52:07 -0700
From:      Brooks Davis <brooks@one-eyed-alien.net>
To:        net@freebsd.org, hackers@freebsd.org
Subject:   review request: vlan cloning and modularization patch
Message-ID:  <20010730155207.A19629@Odin.AC.HMC.Edu>

next in thread | raw e-mail | index | archive | help

--GvXjxJ+pjyke8COw
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Please review and test the following patch.  It adds cloning support to
vlan devices and allows loading and unloading of VLAN support.  The
downside of the this loadability is that it currently appears to require
enabling VLAN support on NICs that support it all the time which I am
concerned may have performance issues.  Can anyone confirm or deny this?
If there are performance issues, I believe changes will need to be made
to provide a machanism by which arbitrary ethernet interfaces may be
notified of VLAN attachments so they can enable support only if there is
someone there to use it.

The patch should be applied as follows:
cd /usr/src
mkdir sys/modules/if_vlan
patch < vlan.diff

The patch may also be obtained from:

http://people.freebsd.org/~brooks/patches/vlan.diff

-- Brooks

--=20
Any statement of the form "X is the one, true Y" is FALSE.
PGP fingerprint 655D 519C 26A7 82E7 2529  9BF0 5D8E 8BE9 F238 1AD4

Index: share/man/man4/vlan.4
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/share/man/man4/vlan.4,v
retrieving revision 1.1
diff -u -r1.1 vlan.4
--- share/man/man4/vlan.4	2001/07/28 12:27:06	1.1
+++ share/man/man4/vlan.4	2001/07/30 22:38:49
@@ -33,7 +33,7 @@
 .Nd IEEE 802.1Q VLAN network interface
 .Sh SYNOPSIS
 .\" In -stable: .Cd pseudo-device vlan Op Ar count
-.Cd device vlan Op Ar count
+.Cd device vlan
 .\"
 .Sh DESCRIPTION
 The
Index: sys/conf/files
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/conf/files,v
retrieving revision 1.555
diff -u -r1.555 files
--- sys/conf/files	2001/07/26 23:04:46	1.555
+++ sys/conf/files	2001/07/30 22:33:18
@@ -907,7 +907,7 @@
 net/if_stf.c		optional stf
 net/if_tun.c		optional tun
 net/if_tap.c		optional tap
-net/if_vlan.c		count vlan
+net/if_vlan.c		optional vlan
 net/intrq.c		standard
 net/net_osdep.c		standard
 net/ppp_deflate.c	optional ppp_deflate
Index: sys/dev/nge/if_nge.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/dev/nge/if_nge.c,v
retrieving revision 1.19
diff -u -r1.19 if_nge.c
--- sys/dev/nge/if_nge.c	2001/07/25 00:19:55	1.19
+++ sys/dev/nge/if_nge.c	2001/07/27 20:42:20
@@ -87,8 +87,6 @@
  * if the user selects an MTU larger than 8152 (8170 - 18).
  */
=20
-#include "vlan.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
@@ -102,11 +100,8 @@
 #include <net/ethernet.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
-
-#if NVLAN > 0
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
-#endif
=20
 #include <net/bpf.h>
=20
@@ -1335,16 +1330,19 @@
 			m->m_pkthdr.csum_data =3D 0xffff;
 		}
=20
-#if NVLAN > 0
 		/*
 		 * If we received a packet with a vlan tag, pass it
 		 * to vlan_input() instead of ether_input().
 		 */
 		if (extsts & NGE_RXEXTSTS_VLANPKT) {
-			vlan_input_tag(eh, m, extsts & NGE_RXEXTSTS_VTCI);
+			if (vlan_input_tag_p !=3D NULL) {
+				(*vlan_input_tag_p)(eh, m,
+				    extsts & NGE_RXEXTSTS_VTCI);
+			} else {
+				m_free(m);
+			}
                         continue;
                 }
-#endif
=20
 		ether_input(ifp, eh, m);
 	}
@@ -1539,14 +1537,12 @@
 	struct nge_desc		*f =3D NULL;
 	struct mbuf		*m;
 	int			frag, cur, cnt =3D 0;
-#if NVLAN > 0
 	struct ifvlan		*ifv =3D NULL;
=20
 	if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) =3D=3D (M_PROTO1|M_PKTHDR) &&
 	    m_head->m_pkthdr.rcvif !=3D NULL &&
 	    m_head->m_pkthdr.rcvif->if_type =3D=3D IFT_L2VLAN)
 		ifv =3D m_head->m_pkthdr.rcvif->if_softc;
-#endif
=20
 	/*
  	 * Start packing the mbufs in this chain into
@@ -1588,12 +1584,10 @@
 			    NGE_TXEXTSTS_UDPCSUM;
 	}
=20
-#if NVLAN > 0
 	if (ifv !=3D NULL) {
 		sc->nge_ldata->nge_tx_list[cur].nge_extsts |=3D
 			(NGE_TXEXTSTS_VLANPKT|ifv->ifv_tag);
 	}
-#endif
=20
 	sc->nge_ldata->nge_tx_list[cur].nge_mbuf =3D m_head;
 	sc->nge_ldata->nge_tx_list[cur].nge_ctl &=3D ~NGE_CMDSTS_MORE;
@@ -1754,7 +1748,6 @@
 	 */
 	CSR_WRITE_4(sc, NGE_VLAN_IP_RXCTL, NGE_VIPRXCTL_IPCSUM_ENB);
=20
-#if NVLAN > 0
 	/*
 	 * If VLAN support is enabled, tell the chip to detect
 	 * and strip VLAN tag info from received frames. The tag
@@ -1762,7 +1755,6 @@
 	 */
 	NGE_SETBIT(sc, NGE_VLAN_IP_RXCTL,
 	    NGE_VIPRXCTL_TAG_DETECT_ENB|NGE_VIPRXCTL_TAG_STRIP_ENB);
-#endif
=20
 	/* Set TX configuration */
 	CSR_WRITE_4(sc, NGE_TX_CFG, NGE_TXCFG);
@@ -1772,14 +1764,12 @@
 	 */
 	CSR_WRITE_4(sc, NGE_VLAN_IP_TXCTL, NGE_VIPTXCTL_CSUM_PER_PKT);
=20
-#if NVLAN > 0
 	/*
 	 * If VLAN support is enabled, tell the chip to insert
 	 * VLAN tags on a per-packet basis as dictated by the
 	 * code in the frame encapsulation routine.
 	 */
 	NGE_SETBIT(sc, NGE_VLAN_IP_TXCTL, NGE_VIPTXCTL_TAG_PER_PKT);
-#endif
=20
 	/* Set full/half duplex mode. */
 	if ((mii->mii_media_active & IFM_GMASK) =3D=3D IFM_FDX) {
Index: sys/dev/txp/if_txp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/dev/txp/if_txp.c,v
retrieving revision 1.4
diff -u -r1.4 if_txp.c
--- sys/dev/txp/if_txp.c	2001/07/27 19:38:56	1.4
+++ sys/dev/txp/if_txp.c	2001/07/27 21:49:57
@@ -39,8 +39,6 @@
  * Driver for 3c990 (Typhoon) Ethernet ASIC
  */
=20
-#include "vlan.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
@@ -54,6 +52,7 @@
 #include <net/ethernet.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
+#include <net/if_vlan_var.h>
=20
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -66,10 +65,6 @@
=20
 #include <net/bpf.h>
=20
-#if NVLAN > 0
-#include <net/if_vlan_var.h>
-#endif
-
 #include <vm/vm.h>              /* for vtophys */
 #include <vm/pmap.h>            /* for vtophys */
 #include <machine/clock.h>	/* for DELAY */
@@ -805,14 +800,17 @@
 			m->m_pkthdr.csum_data =3D 0xffff;
 		}
=20
-#if NVLAN > 0
 		if (rxd->rx_stat & RX_STAT_VLAN) {
-			if (vlan_input_tag(eh, m,
-			    htons(rxd->rx_vlan >> 16)) < 0)
+			if (vlan_input_tag_p !=3D NULL) {
+				if ((*vlan_input_tag_p)(eh, m,
+				    htons(rxd->rx_vlan >> 16)) < 0)
+					ifp->if_noproto++;
+			} else {
+				m_free(m);
 				ifp->if_noproto++;
+			}
 			goto next;
 		}
-#endif
=20
 		eh =3D mtod(m, struct ether_header *);
 		/* Remove header from mbuf and pass it on. */
@@ -1318,9 +1316,7 @@
 	struct mbuf *m, *m0;
 	struct txp_swdesc *sd;
 	u_int32_t firstprod, firstcnt, prod, cnt;
-#if NVLAN > 0
 	struct ifvlan		*ifv;
-#endif
=20
 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) !=3D IFF_RUNNING)
 		return;
@@ -1357,14 +1353,13 @@
 		if (++cnt >=3D (TX_ENTRIES - 4))
 			goto oactive;
=20
-#if NVLAN > 0
 		if ((m->m_flags & (M_PROTO1|M_PKTHDR)) =3D=3D (M_PROTO1|M_PKTHDR) &&
 		    m->m_pkthdr.rcvif !=3D NULL) {
 			ifv =3D m->m_pkthdr.rcvif->if_softc;
 			txd->tx_pflags =3D TX_PFLAGS_VLAN |
 			    (htons(ifv->ifv_tag) << TX_PFLAGS_VLANTAG_S);
 		}
-#endif
+
 		if (m->m_pkthdr.csum_flags & CSUM_IP)
 			txd->tx_pflags |=3D TX_PFLAGS_IPCKSUM;
=20
@@ -1880,12 +1875,10 @@
 	sc->sc_tx_capability =3D ext->ext_1 & OFFLOAD_MASK;
 	sc->sc_rx_capability =3D ext->ext_2 & OFFLOAD_MASK;
=20
-#if NVLAN > 0
 	if (rsp->rsp_par2 & rsp->rsp_par3 & OFFLOAD_VLAN) {
 		sc->sc_tx_capability |=3D OFFLOAD_VLAN;
 		sc->sc_rx_capability |=3D OFFLOAD_VLAN;
 	}
-#endif
=20
 #if 0
 	/* not ready yet */
Index: sys/i386/conf/NOTES
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/i386/conf/NOTES,v
retrieving revision 1.942
diff -u -r1.942 NOTES
--- sys/i386/conf/NOTES	2001/07/25 00:15:02	1.942
+++ sys/i386/conf/NOTES	2001/07/30 22:36:29
@@ -517,7 +517,7 @@
 # See pppd(8) for more details.
 #
 device		ether			#Generic Ethernet
-device		vlan	1		#VLAN support
+device		vlan			#VLAN support
 device		token			#Generic TokenRing
 device		fddi			#Generic FDDI
 device		sppp			#Generic Synchronous PPP
Index: sys/net/ethernet.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/net/ethernet.h,v
retrieving revision 1.16
diff -u -r1.16 ethernet.h
--- sys/net/ethernet.h	2000/07/18 22:44:52	1.16
+++ sys/net/ethernet.h	2001/07/27 00:15:29
@@ -99,6 +99,10 @@
 extern	void (*ng_ether_attach_p)(struct ifnet *ifp);
 extern	void (*ng_ether_detach_p)(struct ifnet *ifp);
=20
+extern	int (*vlan_input_p)(struct ether_header *eh, struct mbuf *m);
+extern	int (*vlan_input_tag_p)(struct ether_header *eh, struct mbuf *m,
+		u_int16_t t);
+
 #else /* _KERNEL */
=20
 #include <sys/cdefs.h>
Index: sys/net/if_ethersubr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.94
diff -u -r1.94 if_ethersubr.c
--- sys/net/if_ethersubr.c	2001/06/15 21:00:32	1.94
+++ sys/net/if_ethersubr.c	2001/07/27 00:16:04
@@ -39,7 +39,6 @@
 #include "opt_inet6.h"
 #include "opt_ipx.h"
 #include "opt_bdg.h"
-#include "opt_netgraph.h"
=20
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -101,11 +100,6 @@
 #include <net/bridge.h>
 #endif
=20
-#include "vlan.h"
-#if NVLAN > 0
-#include <net/if_vlan_var.h>
-#endif /* NVLAN > 0 */
-
 /* netgraph node hooks for ng_ether(4) */
 void	(*ng_ether_input_p)(struct ifnet *ifp,
 		struct mbuf **mp, struct ether_header *eh);
@@ -115,6 +109,10 @@
 void	(*ng_ether_attach_p)(struct ifnet *ifp);
 void	(*ng_ether_detach_p)(struct ifnet *ifp);
=20
+int	(*vlan_input_p)(struct ether_header *eh, struct mbuf *m);
+int	(*vlan_input_tag_p)(struct ether_header *eh, struct mbuf *m,
+		u_int16_t t);
+
 static	int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
 				    struct sockaddr *));
 u_char	etherbroadcastaddr[6] =3D { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -524,13 +522,11 @@
=20
 	ether_type =3D ntohs(eh->ether_type);
=20
-#if NVLAN > 0
-	if (ether_type =3D=3D vlan_proto) {
-		if (vlan_input(eh, m) < 0)
+	if (ether_type =3D=3D ETHERTYPE_VLAN) {
+		if (vlan_input_p !=3D NULL && (*vlan_input_p)(eh, m) < 0)
 			ifp->if_data.ifi_noproto++;
 		return;
 	}
-#endif /* NVLAN > 0 */
=20
 	switch (ether_type) {
 #ifdef INET
Index: sys/net/if_vlan.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/net/if_vlan.c,v
retrieving revision 1.30
diff -u -r1.30 if_vlan.c
--- sys/net/if_vlan.c	2001/07/24 17:14:37	1.30
+++ sys/net/if_vlan.c	2001/07/27 00:19:01
@@ -54,7 +54,6 @@
  * tag value that goes with it.
  */
=20
-#include "vlan.h"
 #include "opt_inet.h"
=20
 #include <sys/param.h>
@@ -67,6 +66,8 @@
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
+#include <machine/bus.h>	/* XXX: Shouldn't really be required! */
+#include <sys/rman.h>
=20
 #include <net/bpf.h>
 #include <net/ethernet.h>
@@ -81,23 +82,32 @@
 #include <netinet/if_ether.h>
 #endif
=20
+#define VLANNAME	"vlan"
+#define VLAN_MAXUNIT	0x7fff	/* ifp->if_unit is only 15 bits */
+
 SYSCTL_DECL(_net_link);
 SYSCTL_NODE(_net_link, IFT_L2VLAN, vlan, CTLFLAG_RW, 0, "IEEE 802.1Q VLAN"=
);
 SYSCTL_NODE(_net_link_vlan, PF_LINK, link, CTLFLAG_RW, 0, "for consistency=
");
-
-u_int	vlan_proto =3D ETHERTYPE_VLAN;
-SYSCTL_INT(_net_link_vlan_link, VLANCTL_PROTO, proto, CTLFLAG_RW, &vlan_pr=
oto,
-	   0, "Ethernet protocol used for VLAN encapsulation");
=20
-static	struct ifvlan ifv_softc[NVLAN];
+static MALLOC_DEFINE(M_VLAN, "vlan", "802.1Q Virtual LAN Interface");
+static struct rman vlanunits[1];
+static LIST_HEAD(, ifvlan) ifv_list;
=20
+static	int vlan_clone_create(struct if_clone *, int *);
+static	void vlan_clone_destroy(struct ifnet *);
 static	void vlan_start(struct ifnet *ifp);
 static	void vlan_ifinit(void *foo);
+static	int vlan_input(struct ether_header *eh, struct mbuf *m);
+static	int vlan_input_tag(struct ether_header *eh, struct mbuf *m,
+		u_int16_t t);
 static	int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
 static	int vlan_setmulti(struct ifnet *ifp);
 static	int vlan_unconfig(struct ifnet *ifp);
 static	int vlan_config(struct ifvlan *ifv, struct ifnet *p);
=20
+struct if_clone vlan_cloner =3D
+    IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy);
+
 /*
  * Program our multicast filter. What we're actually doing is
  * programming the multicast filter of the parent. This has the
@@ -142,14 +152,14 @@
 		if (error)
 			return(error);
 		SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries);
-		free(mc, M_DEVBUF);
+		free(mc, M_VLAN);
 	}
=20
 	/* Now program new ones. */
 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 		if (ifma->ifma_addr->sa_family !=3D AF_LINK)
 			continue;
-		mc =3D malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_WAITOK);
+		mc =3D malloc(sizeof(struct vlan_mc_entry), M_VLAN, M_WAITOK);
 		bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
 		    (char *)&mc->mc_addr, ETHER_ADDR_LEN);
 		SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries);
@@ -163,44 +173,40 @@
 	return(0);
 }
=20
-static void
-vlaninit(void)
-{
-	int i;
-
-	for (i =3D 0; i < NVLAN; i++) {
-		struct ifnet *ifp =3D &ifv_softc[i].ifv_if;
-
-		ifp->if_softc =3D &ifv_softc[i];
-		ifp->if_name =3D "vlan";
-		ifp->if_unit =3D i;
-		/* NB: flags are not set here */
-		ifp->if_linkmib =3D &ifv_softc[i].ifv_mib;
-		ifp->if_linkmiblen =3D sizeof ifv_softc[i].ifv_mib;
-		/* NB: mtu is not set here */
-
-		ifp->if_init =3D vlan_ifinit;
-		ifp->if_start =3D vlan_start;
-		ifp->if_ioctl =3D vlan_ioctl;
-		ifp->if_output =3D ether_output;
-		ifp->if_snd.ifq_maxlen =3D ifqmaxlen;
-		ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
-		/* Now undo some of the damage... */
-		ifp->if_data.ifi_type =3D IFT_L2VLAN;
-		ifp->if_data.ifi_hdrlen =3D EVL_ENCAPLEN;
-	}
-}
-
 static int
 vlan_modevent(module_t mod, int type, void *data)=20
 {=20
+	int err;
+
 	switch (type) {=20
 	case MOD_LOAD:=20
-		vlaninit();
+		vlanunits->rm_type =3D RMAN_ARRAY;
+		vlanunits->rm_descr =3D "configurable if_vlan units";
+		err =3D rman_init(vlanunits);
+		if (err !=3D 0)
+			return (err);
+		err =3D rman_manage_region(vlanunits, 0, VLAN_MAXUNIT);
+		if (err !=3D 0) {
+			printf("%s: vlanunits: rman_manage_region: Failed %d\n",
+			    VLANNAME, err);
+			rman_fini(vlanunits);
+			return (err);
+		}
+		LIST_INIT(&ifv_list);
+		vlan_input_p =3D vlan_input;
+		vlan_input_tag_p =3D vlan_input_tag;
+		if_clone_attach(&vlan_cloner);
 		break;=20
 	case MOD_UNLOAD:=20
-		printf("if_vlan module unload - not possible for this module type\n");=
=20
-		return EINVAL;=20
+		if_clone_detach(&vlan_cloner);
+		vlan_input_p =3D NULL;
+		vlan_input_tag_p =3D NULL;
+		while (!LIST_EMPTY(&ifv_list))
+			vlan_clone_destroy(&LIST_FIRST(&ifv_list)->ifv_if);
+		err =3D rman_fini(vlanunits);
+		if (err !=3D 0)
+			 return (err);
+		break;
 	}=20
 	return 0;=20
 }=20
@@ -213,7 +219,81 @@
=20
 DECLARE_MODULE(if_vlan, vlan_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
=20
+static int
+vlan_clone_create(struct if_clone *ifc, int *unit)
+{
+	struct resource *r;
+	struct ifvlan *ifv;
+	struct ifnet *ifp;
+	int s;
+
+	if (*unit > VLAN_MAXUNIT)
+		return (ENXIO);
+
+	if (*unit < 0) {
+		r  =3D rman_reserve_resource(vlanunits, 0, VLAN_MAXUNIT, 1,
+		    RF_ALLOCATED | RF_ACTIVE, NULL);
+		if (r =3D=3D NULL)
+			return (ENOSPC);
+		*unit =3D rman_get_start(r);
+	} else {
+		r  =3D rman_reserve_resource(vlanunits, *unit, *unit, 1,
+		    RF_ALLOCATED | RF_ACTIVE, NULL);
+		if (r =3D=3D NULL)
+			return (EEXIST);
+	}
+
+	ifv =3D malloc(sizeof(struct ifvlan), M_VLAN, M_WAITOK);
+	memset(ifv, 0, sizeof(struct ifvlan));
+	ifp =3D &ifv->ifv_if;
+	SLIST_INIT(&ifv->vlan_mc_listhead);
+
+	s =3D splnet();
+	LIST_INSERT_HEAD(&ifv_list, ifv, ifv_list);
+	splx(s);
+
+	ifp->if_softc =3D ifv;
+	ifp->if_name =3D "vlan";
+	ifp->if_unit =3D *unit;
+	ifv->r_unit =3D r;
+	/* NB: flags are not set here */
+	ifp->if_linkmib =3D &ifv->ifv_mib;
+	ifp->if_linkmiblen =3D sizeof ifv->ifv_mib;
+	/* NB: mtu is not set here */
+
+	ifp->if_init =3D vlan_ifinit;
+	ifp->if_start =3D vlan_start;
+	ifp->if_ioctl =3D vlan_ioctl;
+	ifp->if_output =3D ether_output;
+	ifp->if_snd.ifq_maxlen =3D ifqmaxlen;
+	ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
+	/* Now undo some of the damage... */
+	ifp->if_data.ifi_type =3D IFT_L2VLAN;
+	ifp->if_data.ifi_hdrlen =3D EVL_ENCAPLEN;
+
+	return (0);
+}
+
 static void
+vlan_clone_destroy(struct ifnet *ifp)
+{
+	struct ifvlan *ifv =3D ifp->if_softc;
+	int s;
+	int err;
+
+	s =3D splnet();
+	LIST_REMOVE(ifv, ifv_list);
+	vlan_unconfig(ifp);
+	splx(s);
+
+	ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
+
+	err =3D rman_release_resource(ifv->r_unit);
+	KASSERT(err =3D=3D 0, ("Unexpected error freeing resource"));
+	free(ifv, M_VLAN);
+}
+
+static void
 vlan_ifinit(void *foo)
 {
 	return;
@@ -294,7 +374,7 @@
 			      sizeof(struct ether_header));
 			evl =3D mtod(m, struct ether_vlan_header *);
 			evl->evl_proto =3D evl->evl_encap_proto;
-			evl->evl_encap_proto =3D htons(vlan_proto);
+			evl->evl_encap_proto =3D htons(ETHERTYPE_VLAN);
 			evl->evl_tag =3D htons(ifv->ifv_tag);
 #ifdef DEBUG
 			printf("vlan_start: %*D\n", sizeof *evl,
@@ -316,19 +396,18 @@
 	return;
 }
=20
-int
+static int
 vlan_input_tag(struct ether_header *eh, struct mbuf *m, u_int16_t t)
 {
-	int i;
 	struct ifvlan *ifv;
=20
-	for (i =3D 0; i < NVLAN; i++) {
-		ifv =3D &ifv_softc[i];
+	for (ifv =3D LIST_FIRST(&ifv_list); ifv !=3D NULL;
+	    ifv =3D LIST_NEXT(ifv, ifv_list)) {
 		if (ifv->ifv_tag =3D=3D t)
 			break;
 	}
=20
-	if (i >=3D NVLAN || (ifv->ifv_if.if_flags & IFF_UP) =3D=3D 0) {
+	if (ifv !=3DNULL || (ifv->ifv_if.if_flags & IFF_UP) =3D=3D 0) {
 		m_free(m);
 		return -1;	/* So the parent can take note */
 	}
@@ -345,21 +424,20 @@
 	return 0;
 }
=20
-int
+static int
 vlan_input(struct ether_header *eh, struct mbuf *m)
 {
-	int i;
 	struct ifvlan *ifv;
=20
-	for (i =3D 0; i < NVLAN; i++) {
-		ifv =3D &ifv_softc[i];
+	for (ifv =3D LIST_FIRST(&ifv_list); ifv !=3D NULL;
+	    ifv =3D LIST_NEXT(ifv, ifv_list)) {
 		if (m->m_pkthdr.rcvif =3D=3D ifv->ifv_p
 		    && (EVL_VLANOFTAG(ntohs(*mtod(m, u_int16_t *)))
 			=3D=3D ifv->ifv_tag))
 			break;
 	}
=20
-	if (i >=3D NVLAN || (ifv->ifv_if.if_flags & IFF_UP) =3D=3D 0) {
+	if (ifv !=3D NULL || (ifv->ifv_if.if_flags & IFF_UP) =3D=3D 0) {
 		m_freem(m);
 		return -1;	/* so ether_input can take note */
 	}
@@ -462,7 +540,7 @@
 			if (error)
 				return(error);
 			SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries);
-			free(mc, M_DEVBUF);
+			free(mc, M_VLAN);
 		}
 	}
=20
Index: sys/net/if_vlan_var.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/net/if_vlan_var.h,v
retrieving revision 1.9
diff -u -r1.9 if_vlan_var.h
--- sys/net/if_vlan_var.h	2001/07/24 00:03:51	1.9
+++ sys/net/if_vlan_var.h	2001/07/27 21:01:48
@@ -47,6 +47,8 @@
 		u_int16_t ifvm_tag; /* tag to apply on packets leaving if */
 	}	ifv_mib;
 	SLIST_HEAD(__vlan_mchead, vlan_mc_entry)	vlan_mc_listhead;
+	LIST_ENTRY(ifvlan) ifv_list;
+	struct resource *r_unit;	/* resource allocated for this unit */
 };
 #define	ifv_if	ifv_ac.ac_if
 #define	ifv_tag	ifv_mib.ifvm_tag
@@ -77,13 +79,5 @@
 };
 #define	SIOCSETVLAN	SIOCSIFGENERIC
 #define	SIOCGETVLAN	SIOCGIFGENERIC
-
-#ifdef _KERNEL
-/* shared with if_ethersubr.c: */
-extern	u_int vlan_proto;
-extern	int vlan_input(struct ether_header *eh, struct mbuf *m);
-extern	int vlan_input_tag(struct ether_header *eh,
-			struct mbuf *m, u_int16_t t);
-#endif
=20
 #endif /* _NET_IF_VLAN_VAR_H_ */
Index: sys/pci/if_ti.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/pci/if_ti.c,v
retrieving revision 1.51
diff -u -r1.51 if_ti.c
--- sys/pci/if_ti.c	2001/07/25 00:19:59	1.51
+++ sys/pci/if_ti.c	2001/07/27 20:42:41
@@ -78,8 +78,6 @@
  * - Andrew Gallatin for providing FreeBSD/Alpha support.
  */
=20
-#include "vlan.h"
-
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
@@ -94,14 +92,11 @@
 #include <net/ethernet.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
-
-#include <net/bpf.h>
-
-#if NVLAN > 0
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
-#endif
=20
+#include <net/bpf.h>
+
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
@@ -1334,9 +1329,7 @@
 	if (sc->arpcom.ac_if.if_hwassist)
 		rcb->ti_flags |=3D TI_RCB_FLAG_TCP_UDP_CKSUM |
 		     TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
-#if NVLAN > 0
 	rcb->ti_flags |=3D TI_RCB_FLAG_VLAN_ASSIST;
-#endif
=20
 	/* Set up the jumbo receive ring. */
 	rcb =3D &sc->ti_rdata->ti_info.ti_jumbo_rx_rcb;
@@ -1347,9 +1340,7 @@
 	if (sc->arpcom.ac_if.if_hwassist)
 		rcb->ti_flags |=3D TI_RCB_FLAG_TCP_UDP_CKSUM |
 		     TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
-#if NVLAN > 0
 	rcb->ti_flags |=3D TI_RCB_FLAG_VLAN_ASSIST;
-#endif
=20
 	/*
 	 * Set up the mini ring. Only activated on the
@@ -1367,9 +1358,7 @@
 	if (sc->arpcom.ac_if.if_hwassist)
 		rcb->ti_flags |=3D TI_RCB_FLAG_TCP_UDP_CKSUM |
 		     TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
-#if NVLAN > 0
 	rcb->ti_flags |=3D TI_RCB_FLAG_VLAN_ASSIST;
-#endif
=20
 	/*
 	 * Set up the receive return ring.
@@ -1403,9 +1392,7 @@
 		rcb->ti_flags =3D 0;
 	else
 		rcb->ti_flags =3D TI_RCB_FLAG_HOST_RING;
-#if NVLAN > 0
 	rcb->ti_flags |=3D TI_RCB_FLAG_VLAN_ASSIST;
-#endif
 	if (sc->arpcom.ac_if.if_hwassist)
 		rcb->ti_flags |=3D TI_RCB_FLAG_TCP_UDP_CKSUM |
 		     TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM;
@@ -1738,22 +1725,18 @@
 		u_int32_t		rxidx;
 		struct ether_header	*eh;
 		struct mbuf		*m =3D NULL;
-#if NVLAN > 0
 		u_int16_t		vlan_tag =3D 0;
 		int			have_tag =3D 0;
-#endif
=20
 		cur_rx =3D
 		    &sc->ti_rdata->ti_rx_return_ring[sc->ti_rx_saved_considx];
 		rxidx =3D cur_rx->ti_idx;
 		TI_INC(sc->ti_rx_saved_considx, TI_RETURN_RING_CNT);
=20
-#if NVLAN > 0
 		if (cur_rx->ti_flags & TI_BDFLAG_VLAN_TAG) {
 			have_tag =3D 1;
 			vlan_tag =3D cur_rx->ti_vlan_tag & 0xfff;
 		}
-#endif
=20
 		if (cur_rx->ti_flags & TI_BDFLAG_JUMBO_RING) {
 			TI_INC(sc->ti_jumbo, TI_JUMBO_RX_RING_CNT);
@@ -1815,17 +1798,19 @@
 			m->m_pkthdr.csum_data =3D cur_rx->ti_tcp_udp_cksum;
 		}
=20
-#if NVLAN > 0
 		/*
 		 * If we received a packet with a vlan tag, pass it
 		 * to vlan_input() instead of ether_input().
 		 */
 		if (have_tag) {
-			vlan_input_tag(eh, m, vlan_tag);
+			if (vlan_input_tag_p !=3D NULL) {
+				(*vlan_input_tag_p)(eh, m, vlan_tag);
+			} else {
+				m_free(m);
+			}
 			have_tag =3D vlan_tag =3D 0;
 			continue;
 		}
-#endif
 		ether_input(ifp, eh, m);
 	}
=20
@@ -1963,14 +1948,12 @@
 	struct mbuf		*m;
 	u_int32_t		frag, cur, cnt =3D 0;
 	u_int16_t		csum_flags =3D 0;
-#if NVLAN > 0
 	struct ifvlan		*ifv =3D NULL;
=20
 	if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) =3D=3D (M_PROTO1|M_PKTHDR) &&
 	    m_head->m_pkthdr.rcvif !=3D NULL &&
 	    m_head->m_pkthdr.rcvif->if_type =3D=3D IFT_L2VLAN)
 		ifv =3D m_head->m_pkthdr.rcvif->if_softc;
-#endif
=20
 	m =3D m_head;
 	cur =3D frag =3D *txidx;
@@ -2013,14 +1996,14 @@
 			TI_HOSTADDR(f->ti_addr) =3D vtophys(mtod(m, vm_offset_t));
 			f->ti_len =3D m->m_len;
 			f->ti_flags =3D csum_flags;
-#if NVLAN > 0
+
 			if (ifv !=3D NULL) {
 				f->ti_flags |=3D TI_BDFLAG_VLAN_TAG;
 				f->ti_vlan_tag =3D ifv->ifv_tag & 0xfff;
 			} else {
 				f->ti_vlan_tag =3D 0;
 			}
-#endif
+
 			/*
 			 * Sanity check: avoid coming within 16 descriptors
 			 * of the end of the ring.
--- sys/modules/if_vlan/Makefile.orig	Fri Jul 13 17:14:21 2001
+++ sys/modules/if_vlan/Makefile	Fri Jul 27 14:00:14 2001
@@ -0,0 +1,12 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../net
+
+KMOD=3D	if_vlan
+SRCS=3D	if_vlan.c opt_inet.h
+NOMAN=3D
+
+opt_inet.h:
+	echo "#define INET 1" > ${.TARGET}
+
+.include <bsd.kmod.mk>

--GvXjxJ+pjyke8COw
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE7ZeUWXY6L6fI4GtQRAgL+AKCM49r/UFCHvriO3uagKvFtO3Zk3wCfSOLE
Hmr8m5Yajymonr4MmKgmEO0=
=92jk
-----END PGP SIGNATURE-----

--GvXjxJ+pjyke8COw--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




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