From owner-freebsd-hackers Mon Jul 30 15:53: 6 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from odin.ac.hmc.edu (Odin.AC.HMC.Edu [134.173.32.75]) by hub.freebsd.org (Postfix) with ESMTP id 4933337B403; Mon, 30 Jul 2001 15:52:08 -0700 (PDT) (envelope-from brdavis@odin.ac.hmc.edu) Received: (from brdavis@localhost) by odin.ac.hmc.edu (8.11.0/8.11.0) id f6UMq7721055; Mon, 30 Jul 2001 15:52:07 -0700 Date: Mon, 30 Jul 2001 15:52:07 -0700 From: Brooks Davis To: net@freebsd.org, hackers@freebsd.org Subject: review request: vlan cloning and modularization patch Message-ID: <20010730155207.A19629@Odin.AC.HMC.Edu> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="GvXjxJ+pjyke8COw" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --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 #include #include @@ -102,11 +100,8 @@ #include #include #include - -#if NVLAN > 0 #include #include -#endif =20 #include =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 #include #include @@ -54,6 +52,7 @@ #include #include #include +#include =20 #include #include @@ -66,10 +65,6 @@ =20 #include =20 -#if NVLAN > 0 -#include -#endif - #include /* for vtophys */ #include /* for vtophys */ #include /* 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 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 #include @@ -101,11 +100,6 @@ #include #endif =20 -#include "vlan.h" -#if NVLAN > 0 -#include -#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 @@ -67,6 +66,8 @@ #include #include #include +#include /* XXX: Shouldn't really be required! */ +#include =20 #include #include @@ -81,23 +82,32 @@ #include #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 #include #include @@ -94,14 +92,11 @@ #include #include #include - -#include - -#if NVLAN > 0 #include #include -#endif =20 +#include + #include #include #include @@ -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 --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-hackers" in the body of the message