Source-Changes-HG archive

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

[src/netbsd-1-5]: src/sys/net Pull up revisions 1.1-1.14, 1.16-1.21, 1.23-1.2...



details:   https://anonhg.NetBSD.org/src/rev/8e4809604043
branches:  netbsd-1-5
changeset: 490459:8e4809604043
user:      jhawk <jhawk%NetBSD.org@localhost>
date:      Sun Dec 31 20:14:32 2000 +0000

description:
Pull up revisions 1.1-1.14, 1.16-1.21, 1.23-1.26 (new) (requested by bouyer):
        Add support for 802.1Q virtual LANs.

diffstat:

 sys/net/if_vlan.c |  857 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 857 insertions(+), 0 deletions(-)

diffs (truncated from 861 to 300 lines):

diff -r 6386725c3b1d -r 8e4809604043 sys/net/if_vlan.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/net/if_vlan.c Sun Dec 31 20:14:32 2000 +0000
@@ -0,0 +1,857 @@
+/*     $NetBSD: if_vlan.c,v 1.26.2.2 2000/12/31 20:14:32 jhawk Exp $   */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran, and by Jason R. Thorpe of Zembu Labs, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the NetBSD
+ *     Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from FreeBSD: if_vlan.c,v 1.16 2000/03/26 15:21:40 charnier Exp
+ * via OpenBSD: if_vlan.c,v 1.4 2000/05/15 19:15:00 chris Exp
+ */
+
+/*
+ * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs.  Might be
+ * extended some day to also handle IEEE 802.1P priority tagging.  This is
+ * sort of sneaky in the implementation, since we need to pretend to be
+ * enough of an Ethernet implementation to make ARP work.  The way we do
+ * this is by telling everyone that we are an Ethernet interface, and then
+ * catch the packets that ether_output() left on our output queue when it
+ * calls if_start(), rewrite them for use by the real outgoing interface,
+ * and ask it to send them.
+ *
+ * TODO:
+ *
+ *     - Need some way to notify vlan interfaces when the parent
+ *       interface changes MTU.
+ */
+
+#include "opt_inet.h"
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/if_ether.h>
+#include <net/if_vlanvar.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_inarp.h>
+#endif
+
+extern struct  ifaddr **ifnet_addrs;   /* XXX if.c */
+
+struct vlan_mc_entry {
+       LIST_ENTRY(vlan_mc_entry)       mc_entries;
+       /*
+        * A key to identify this entry.  The mc_addr below can't be
+        * used since multiple sockaddr may mapped into the same
+        * ether_multi (e.g., AF_UNSPEC).
+        */
+       union {
+               struct ether_multi      *mcu_enm;
+       } mc_u;
+       struct sockaddr_storage         mc_addr;
+};
+
+#define        mc_enm          mc_u.mcu_enm
+
+struct ifvlan {
+       union {
+               struct ethercom ifvu_ec;
+       } ifv_u;
+       struct ifnet *ifv_p;    /* parent interface of this vlan */
+       struct ifv_linkmib {
+               const struct vlan_multisw *ifvm_msw;
+               int     ifvm_encaplen;  /* encapsulation length */
+               int     ifvm_mtufudge;  /* MTU fudged by this much */
+               int     ifvm_mintu;     /* min transmission unit */
+               u_int16_t ifvm_proto;   /* encapsulation ethertype */
+               u_int16_t ifvm_tag;     /* tag to apply on packets */
+       } ifv_mib;
+       LIST_HEAD(__vlan_mchead, vlan_mc_entry) ifv_mc_listhead;
+       LIST_ENTRY(ifvlan) ifv_list;
+       int ifv_flags;
+};
+
+#define        IFVF_PROMISC    0x01            /* promiscuous mode enabled */
+
+#define        ifv_ec          ifv_u.ifvu_ec
+
+#define        ifv_if          ifv_ec.ec_if
+
+#define        ifv_msw         ifv_mib.ifvm_msw
+#define        ifv_encaplen    ifv_mib.ifvm_encaplen
+#define        ifv_mtufudge    ifv_mib.ifvm_mtufudge
+#define        ifv_mintu       ifv_mib.ifvm_mintu
+#define        ifv_tag         ifv_mib.ifvm_tag
+
+struct vlan_multisw {
+       int     (*vmsw_addmulti)(struct ifvlan *, struct ifreq *);
+       int     (*vmsw_delmulti)(struct ifvlan *, struct ifreq *);
+       void    (*vmsw_purgemulti)(struct ifvlan *);
+};
+
+static int     vlan_ether_addmulti(struct ifvlan *, struct ifreq *);
+static int     vlan_ether_delmulti(struct ifvlan *, struct ifreq *);
+static void    vlan_ether_purgemulti(struct ifvlan *);
+
+const struct vlan_multisw vlan_ether_multisw = {
+       vlan_ether_addmulti,
+       vlan_ether_delmulti,
+       vlan_ether_purgemulti,
+};
+
+static int     vlan_clone_create(struct if_clone *, int);
+static void    vlan_clone_destroy(struct ifnet *);
+static int     vlan_config(struct ifvlan *, struct ifnet *);
+static int     vlan_ioctl(struct ifnet *, u_long, caddr_t);
+static void    vlan_start(struct ifnet *);
+static void    vlan_unconfig(struct ifnet *);
+
+void           vlanattach(int);
+
+/* XXX This should be a hash table with the tag as the basis of the key. */
+static LIST_HEAD(, ifvlan) ifv_list;
+
+struct if_clone vlan_cloner =
+    IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy);
+
+void
+vlanattach(int n)
+{
+
+       LIST_INIT(&ifv_list);
+       if_clone_attach(&vlan_cloner);
+}
+
+static int
+vlan_clone_create(struct if_clone *ifc, int unit)
+{
+       struct ifvlan *ifv;
+       struct ifnet *ifp;
+       int s;
+
+       ifv = malloc(sizeof(struct ifvlan), M_DEVBUF, M_WAITOK);
+       memset(ifv, 0, sizeof(struct ifvlan));
+       ifp = &ifv->ifv_if;
+       LIST_INIT(&ifv->ifv_mc_listhead);
+
+       s = splnet();
+       LIST_INSERT_HEAD(&ifv_list, ifv, ifv_list);
+       splx(s);
+
+       sprintf(ifp->if_xname, "%s%d", ifc->ifc_name, unit);
+       ifp->if_softc = ifv;
+       ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+       ifp->if_start = vlan_start;
+       ifp->if_ioctl = vlan_ioctl;
+
+       if_attach(ifp);
+
+       return (0);
+}
+
+static void
+vlan_clone_destroy(struct ifnet *ifp)
+{
+       struct ifvlan *ifv = ifp->if_softc;
+       int s;
+
+       s = splnet();
+       LIST_REMOVE(ifv, ifv_list);
+       vlan_unconfig(ifp);
+       splx(s);
+
+#if NBPFILTER > 0
+       bpfdetach(ifp);
+#endif
+       ether_ifdetach(ifp);
+       if_detach(ifp);
+       free(ifv, M_DEVBUF);
+}
+
+/*
+ * Configure a VLAN interface.  Must be called at splnet().
+ */
+static int
+vlan_config(struct ifvlan *ifv, struct ifnet *p)
+{
+       struct ifnet *ifp = &ifv->ifv_if;
+       int error;
+
+       if (ifv->ifv_p != NULL)
+               return (EBUSY);
+
+       switch (p->if_type) {
+       case IFT_ETHER:
+           {
+               struct ethercom *ec = (void *) p;
+
+               ifv->ifv_msw = &vlan_ether_multisw;
+               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) {
+                               struct ifreq ifr;
+
+                               ifr.ifr_flags = p->if_flags;
+                               error = (*p->if_ioctl)(p, SIOCSIFFLAGS,
+                                   (caddr_t) &ifr);
+                               if (error) {
+                                       if (ec->ec_nvlans-- == 1)
+                                               ec->ec_capenable &=
+                                                   ~ETHERCAP_VLAN_MTU;
+                                       return (error);
+                               }
+                       }
+                       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,



Home | Main Index | Thread Index | Old Index