The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System, Second Edition

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/if_bridge.c

Version: -  FREEBSD  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc Exp $       */
    2 
    3 /*
    4  * Copyright 2001 Wasabi Systems, Inc.
    5  * All rights reserved.
    6  *
    7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed for the NetBSD Project by
   20  *      Wasabi Systems, Inc.
   21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
   22  *    or promote products derived from this software without specific prior
   23  *    written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
   29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35  * POSSIBILITY OF SUCH DAMAGE.
   36  */
   37 
   38 /*
   39  * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
   40  * All rights reserved.
   41  *
   42  * Redistribution and use in source and binary forms, with or without
   43  * modification, are permitted provided that the following conditions
   44  * are met:
   45  * 1. Redistributions of source code must retain the above copyright
   46  *    notice, this list of conditions and the following disclaimer.
   47  * 2. Redistributions in binary form must reproduce the above copyright
   48  *    notice, this list of conditions and the following disclaimer in the
   49  *    documentation and/or other materials provided with the distribution.
   50  * 3. All advertising materials mentioning features or use of this software
   51  *    must display the following acknowledgement:
   52  *      This product includes software developed by Jason L. Wright
   53  * 4. The name of the author may not be used to endorse or promote products
   54  *    derived from this software without specific prior written permission.
   55  *
   56  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   57  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   58  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   59  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   60  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   61  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   62  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   63  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   64  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   65  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   66  * POSSIBILITY OF SUCH DAMAGE.
   67  *
   68  * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp
   69  */
   70 
   71 /*
   72  * Network interface bridge support.
   73  *
   74  * TODO:
   75  *
   76  *      - Currently only supports Ethernet-like interfaces (Ethernet,
   77  *        802.11, VLANs on Ethernet, etc.)  Figure out a nice way
   78  *        to bridge other types of interfaces (FDDI-FDDI, and maybe
   79  *        consider heterogenous bridges).
   80  */
   81 
   82 #include <sys/cdefs.h>
   83 __FBSDID("$FreeBSD$");
   84 
   85 #include "opt_inet.h"
   86 #include "opt_inet6.h"
   87 
   88 #include <sys/param.h>
   89 #include <sys/mbuf.h>
   90 #include <sys/malloc.h>
   91 #include <sys/protosw.h>
   92 #include <sys/systm.h>
   93 #include <sys/time.h>
   94 #include <sys/socket.h> /* for net/if.h */
   95 #include <sys/sockio.h>
   96 #include <sys/ctype.h>  /* string functions */
   97 #include <sys/kernel.h>
   98 #include <sys/random.h>
   99 #include <sys/sysctl.h>
  100 #include <vm/uma.h>
  101 #include <sys/module.h>
  102 #include <sys/proc.h>
  103 #include <sys/lock.h>
  104 #include <sys/mutex.h>
  105 
  106 #include <net/bpf.h>
  107 #include <net/if.h>
  108 #include <net/if_clone.h>
  109 #include <net/if_dl.h>
  110 #include <net/if_types.h>
  111 #include <net/if_var.h>
  112 #include <net/pfil.h>
  113 
  114 #include <netinet/in.h> /* for struct arpcom */
  115 #include <netinet/in_systm.h>
  116 #include <netinet/in_var.h>
  117 #include <netinet/ip.h>
  118 #include <netinet/ip_var.h>
  119 #ifdef INET6
  120 #include <netinet/ip6.h>
  121 #include <netinet6/ip6_var.h>
  122 #endif
  123 #include <machine/in_cksum.h>
  124 #include <netinet/if_ether.h> /* for struct arpcom */
  125 #include <net/if_bridgevar.h>
  126 #include <net/if_llc.h>
  127 
  128 #include <net/route.h>
  129 #include <netinet/ip_fw.h>
  130 #include <netinet/ip_dummynet.h>
  131 
  132 #define sc_if ifb_ac.ac_if
  133 /*
  134  * Size of the route hash table.  Must be a power of two.
  135  */
  136 #ifndef BRIDGE_RTHASH_SIZE
  137 #define BRIDGE_RTHASH_SIZE              1024
  138 #endif
  139 
  140 #define BRIDGE_RTHASH_MASK              (BRIDGE_RTHASH_SIZE - 1)
  141 
  142 /*
  143  * Maximum number of addresses to cache.
  144  */
  145 #ifndef BRIDGE_RTABLE_MAX
  146 #define BRIDGE_RTABLE_MAX               100
  147 #endif
  148 
  149 /*
  150  * Spanning tree defaults.
  151  */
  152 #define BSTP_DEFAULT_MAX_AGE            (20 * 256)
  153 #define BSTP_DEFAULT_HELLO_TIME         (2 * 256)
  154 #define BSTP_DEFAULT_FORWARD_DELAY      (15 * 256)
  155 #define BSTP_DEFAULT_HOLD_TIME          (1 * 256)
  156 #define BSTP_DEFAULT_BRIDGE_PRIORITY    0x8000
  157 #define BSTP_DEFAULT_PORT_PRIORITY      0x80
  158 #define BSTP_DEFAULT_PATH_COST          55
  159 
  160 /*
  161  * Timeout (in seconds) for entries learned dynamically.
  162  */
  163 #ifndef BRIDGE_RTABLE_TIMEOUT
  164 #define BRIDGE_RTABLE_TIMEOUT           (20 * 60)       /* same as ARP */
  165 #endif
  166 
  167 /*
  168  * Number of seconds between walks of the route list.
  169  */
  170 #ifndef BRIDGE_RTABLE_PRUNE_PERIOD
  171 #define BRIDGE_RTABLE_PRUNE_PERIOD      (5 * 60)
  172 #endif
  173 
  174 /*
  175  * List of capabilities to mask on the member interface.
  176  */
  177 #define BRIDGE_IFCAPS_MASK              IFCAP_TXCSUM
  178 
  179 static struct mtx       bridge_list_mtx;
  180 eventhandler_tag        bridge_detach_cookie = NULL;
  181 
  182 int     bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
  183 
  184 uma_zone_t bridge_rtnode_zone;
  185 
  186 static int      bridge_clone_create(struct if_clone *, int);
  187 static void     bridge_clone_destroy(struct ifnet *);
  188 
  189 static int      bridge_ioctl(struct ifnet *, u_long, caddr_t);
  190 static void     bridge_mutecaps(struct bridge_iflist *, int);
  191 static void     bridge_ifdetach(void *arg __unused, struct ifnet *);
  192 static void     bridge_init(void *);
  193 static void     bridge_dummynet(struct mbuf *, struct ifnet *);
  194 static void     bridge_stop(struct ifnet *, int);
  195 static void     bridge_start(struct ifnet *);
  196 static struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
  197 static int      bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
  198                     struct rtentry *);
  199 
  200 static void     bridge_forward(struct bridge_softc *, struct mbuf *m);
  201 
  202 static void     bridge_timer(void *);
  203 
  204 static void     bridge_broadcast(struct bridge_softc *, struct ifnet *,
  205                     struct mbuf *, int);
  206 static void     bridge_span(struct bridge_softc *, struct mbuf *);
  207 
  208 static int      bridge_rtupdate(struct bridge_softc *, const uint8_t *,
  209                     struct ifnet *, int, uint8_t);
  210 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
  211 static void     bridge_rttrim(struct bridge_softc *);
  212 static void     bridge_rtage(struct bridge_softc *);
  213 static void     bridge_rtflush(struct bridge_softc *, int);
  214 static int      bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
  215 
  216 static int      bridge_rtable_init(struct bridge_softc *);
  217 static void     bridge_rtable_fini(struct bridge_softc *);
  218 
  219 static int      bridge_rtnode_addr_cmp(const uint8_t *, const uint8_t *);
  220 static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
  221                     const uint8_t *);
  222 static int      bridge_rtnode_insert(struct bridge_softc *,
  223                     struct bridge_rtnode *);
  224 static void     bridge_rtnode_destroy(struct bridge_softc *,
  225                     struct bridge_rtnode *);
  226 
  227 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
  228                     const char *name);
  229 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
  230                     struct ifnet *ifp);
  231 static void     bridge_delete_member(struct bridge_softc *,
  232                     struct bridge_iflist *, int);
  233 static void     bridge_delete_span(struct bridge_softc *,
  234                     struct bridge_iflist *);
  235 
  236 static int      bridge_ioctl_add(struct bridge_softc *, void *);
  237 static int      bridge_ioctl_del(struct bridge_softc *, void *);
  238 static int      bridge_ioctl_gifflags(struct bridge_softc *, void *);
  239 static int      bridge_ioctl_sifflags(struct bridge_softc *, void *);
  240 static int      bridge_ioctl_scache(struct bridge_softc *, void *);
  241 static int      bridge_ioctl_gcache(struct bridge_softc *, void *);
  242 static int      bridge_ioctl_gifs(struct bridge_softc *, void *);
  243 static int      bridge_ioctl_rts(struct bridge_softc *, void *);
  244 static int      bridge_ioctl_saddr(struct bridge_softc *, void *);
  245 static int      bridge_ioctl_sto(struct bridge_softc *, void *);
  246 static int      bridge_ioctl_gto(struct bridge_softc *, void *);
  247 static int      bridge_ioctl_daddr(struct bridge_softc *, void *);
  248 static int      bridge_ioctl_flush(struct bridge_softc *, void *);
  249 static int      bridge_ioctl_gpri(struct bridge_softc *, void *);
  250 static int      bridge_ioctl_spri(struct bridge_softc *, void *);
  251 static int      bridge_ioctl_ght(struct bridge_softc *, void *);
  252 static int      bridge_ioctl_sht(struct bridge_softc *, void *);
  253 static int      bridge_ioctl_gfd(struct bridge_softc *, void *);
  254 static int      bridge_ioctl_sfd(struct bridge_softc *, void *);
  255 static int      bridge_ioctl_gma(struct bridge_softc *, void *);
  256 static int      bridge_ioctl_sma(struct bridge_softc *, void *);
  257 static int      bridge_ioctl_sifprio(struct bridge_softc *, void *);
  258 static int      bridge_ioctl_sifcost(struct bridge_softc *, void *);
  259 static int      bridge_ioctl_addspan(struct bridge_softc *, void *);
  260 static int      bridge_ioctl_delspan(struct bridge_softc *, void *);
  261 static int      bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
  262                     int);
  263 static int      bridge_ip_checkbasic(struct mbuf **mp);
  264 # ifdef INET6
  265 static int      bridge_ip6_checkbasic(struct mbuf **mp);
  266 # endif /* INET6 */
  267 
  268 SYSCTL_DECL(_net_link);
  269 SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW, 0, "Bridge");
  270 
  271 static int pfil_onlyip = 1; /* only pass IP[46] packets when pfil is enabled */
  272 static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
  273 static int pfil_member = 1; /* run pfil hooks on the member interface */
  274 static int pfil_ipfw = 0;   /* layer2 filter with ipfw */
  275 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW,
  276     &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
  277 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
  278     &pfil_bridge, 0, "Packet filter on the bridge interface");
  279 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
  280     &pfil_member, 0, "Packet filter on the member interface");
  281 
  282 struct bridge_control {
  283         int     (*bc_func)(struct bridge_softc *, void *);
  284         int     bc_argsize;
  285         int     bc_flags;
  286 };
  287 
  288 #define BC_F_COPYIN             0x01    /* copy arguments in */
  289 #define BC_F_COPYOUT            0x02    /* copy arguments out */
  290 #define BC_F_SUSER              0x04    /* do super-user check */
  291 
  292 const struct bridge_control bridge_control_table[] = {
  293         { bridge_ioctl_add,             sizeof(struct ifbreq),
  294           BC_F_COPYIN|BC_F_SUSER },
  295         { bridge_ioctl_del,             sizeof(struct ifbreq),
  296           BC_F_COPYIN|BC_F_SUSER },
  297 
  298         { bridge_ioctl_gifflags,        sizeof(struct ifbreq),
  299           BC_F_COPYIN|BC_F_COPYOUT },
  300         { bridge_ioctl_sifflags,        sizeof(struct ifbreq),
  301           BC_F_COPYIN|BC_F_SUSER },
  302 
  303         { bridge_ioctl_scache,          sizeof(struct ifbrparam),
  304           BC_F_COPYIN|BC_F_SUSER },
  305         { bridge_ioctl_gcache,          sizeof(struct ifbrparam),
  306           BC_F_COPYOUT },
  307 
  308         { bridge_ioctl_gifs,            sizeof(struct ifbifconf),
  309           BC_F_COPYIN|BC_F_COPYOUT },
  310         { bridge_ioctl_rts,             sizeof(struct ifbaconf),
  311           BC_F_COPYIN|BC_F_COPYOUT },
  312 
  313         { bridge_ioctl_saddr,           sizeof(struct ifbareq),
  314           BC_F_COPYIN|BC_F_SUSER },
  315 
  316         { bridge_ioctl_sto,             sizeof(struct ifbrparam),
  317           BC_F_COPYIN|BC_F_SUSER },
  318         { bridge_ioctl_gto,             sizeof(struct ifbrparam),
  319           BC_F_COPYOUT },
  320 
  321         { bridge_ioctl_daddr,           sizeof(struct ifbareq),
  322           BC_F_COPYIN|BC_F_SUSER },
  323 
  324         { bridge_ioctl_flush,           sizeof(struct ifbreq),
  325           BC_F_COPYIN|BC_F_SUSER },
  326 
  327         { bridge_ioctl_gpri,            sizeof(struct ifbrparam),
  328           BC_F_COPYOUT },
  329         { bridge_ioctl_spri,            sizeof(struct ifbrparam),
  330           BC_F_COPYIN|BC_F_SUSER },
  331 
  332         { bridge_ioctl_ght,             sizeof(struct ifbrparam),
  333           BC_F_COPYOUT },
  334         { bridge_ioctl_sht,             sizeof(struct ifbrparam),
  335           BC_F_COPYIN|BC_F_SUSER },
  336 
  337         { bridge_ioctl_gfd,             sizeof(struct ifbrparam),
  338           BC_F_COPYOUT },
  339         { bridge_ioctl_sfd,             sizeof(struct ifbrparam),
  340           BC_F_COPYIN|BC_F_SUSER },
  341 
  342         { bridge_ioctl_gma,             sizeof(struct ifbrparam),
  343           BC_F_COPYOUT },
  344         { bridge_ioctl_sma,             sizeof(struct ifbrparam),
  345           BC_F_COPYIN|BC_F_SUSER },
  346 
  347         { bridge_ioctl_sifprio,         sizeof(struct ifbreq),
  348           BC_F_COPYIN|BC_F_SUSER },
  349 
  350         { bridge_ioctl_sifcost,         sizeof(struct ifbreq),
  351           BC_F_COPYIN|BC_F_SUSER },
  352 
  353         { bridge_ioctl_addspan,         sizeof(struct ifbreq),
  354           BC_F_COPYIN|BC_F_SUSER },
  355         { bridge_ioctl_delspan,         sizeof(struct ifbreq),
  356           BC_F_COPYIN|BC_F_SUSER },
  357 };
  358 const int bridge_control_table_size =
  359     sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
  360 
  361 static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
  362                         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  363 
  364 LIST_HEAD(, bridge_softc) bridge_list;
  365 
  366 IFC_SIMPLE_DECLARE(bridge, 0);
  367 
  368 static int
  369 bridge_modevent(module_t mod, int type, void *data)
  370 {
  371 
  372         switch (type) {
  373         case MOD_LOAD:
  374                 mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF);
  375                 if_clone_attach(&bridge_cloner);
  376                 bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
  377                     sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
  378                     UMA_ALIGN_PTR, 0);
  379                 LIST_INIT(&bridge_list);
  380                 bridge_input_p = bridge_input;
  381                 bridge_output_p = bridge_output;
  382                 bridge_dn_p = bridge_dummynet;
  383                 bridge_detach_cookie = EVENTHANDLER_REGISTER(
  384                     ifnet_departure_event, bridge_ifdetach, NULL,
  385                     EVENTHANDLER_PRI_ANY);
  386                 break;
  387         case MOD_UNLOAD:
  388                 EVENTHANDLER_DEREGISTER(ifnet_departure_event,
  389                     bridge_detach_cookie);
  390                 if_clone_detach(&bridge_cloner);
  391                 while (!LIST_EMPTY(&bridge_list))
  392                         bridge_clone_destroy(&LIST_FIRST(&bridge_list)->sc_if);
  393                 uma_zdestroy(bridge_rtnode_zone);
  394                 bridge_input_p = NULL;
  395                 bridge_output_p = NULL;
  396                 bridge_dn_p = NULL;
  397                 mtx_destroy(&bridge_list_mtx);
  398                 break;
  399         default:
  400                 return EOPNOTSUPP;
  401         }
  402         return 0;
  403 }
  404 
  405 static moduledata_t bridge_mod = {
  406         "if_bridge",
  407         bridge_modevent,
  408         0
  409 };
  410 
  411 DECLARE_MODULE(if_bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  412 
  413 /*
  414  * handler for net.link.bridge.pfil_ipfw
  415  */
  416 static int
  417 sysctl_pfil_ipfw(SYSCTL_HANDLER_ARGS)
  418 {
  419         int enable = pfil_ipfw;
  420         int error;
  421 
  422         error = sysctl_handle_int(oidp, &enable, 0, req);
  423         enable = (enable) ? 1 : 0;
  424 
  425         if (enable != pfil_ipfw) {
  426                 pfil_ipfw = enable;
  427 
  428                 /*
  429                  * Disable pfil so that ipfw doesnt run twice, if the user
  430                  * really wants both then they can re-enable pfil_bridge and/or
  431                  * pfil_member. Also allow non-ip packets as ipfw can filter by
  432                  * layer2 type.
  433                  */
  434                 if (pfil_ipfw) {
  435                         pfil_onlyip = 0;
  436                         pfil_bridge = 0;
  437                         pfil_member = 0;
  438                 }
  439         }
  440 
  441         return error;
  442 }
  443 SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW,
  444             &pfil_ipfw, 0, &sysctl_pfil_ipfw, "I", "Layer2 filter with IPFW");
  445 
  446 /*
  447  * bridge_clone_create:
  448  *
  449  *      Create a new bridge instance.
  450  */
  451 static int
  452 bridge_clone_create(struct if_clone *ifc, int unit)
  453 {
  454         struct bridge_softc *sc;
  455         struct ifnet *ifp;
  456 
  457         sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
  458         BRIDGE_LOCK_INIT(sc);
  459         ifp = &sc->sc_if;
  460 
  461         sc->sc_brtmax = BRIDGE_RTABLE_MAX;
  462         sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
  463         sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
  464         sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
  465         sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
  466         sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
  467         sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
  468 
  469         /* Initialize our routing table. */
  470         bridge_rtable_init(sc);
  471 
  472         callout_init(&sc->sc_brcallout, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
  473         callout_init(&sc->sc_bstpcallout, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
  474 
  475         LIST_INIT(&sc->sc_iflist);
  476         LIST_INIT(&sc->sc_spanlist);
  477 
  478         ifp->if_softc = sc;
  479         if_initname(ifp, ifc->ifc_name, unit);
  480         ifp->if_mtu = ETHERMTU;
  481         ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
  482         ifp->if_ioctl = bridge_ioctl;
  483         ifp->if_output = bridge_output;
  484         ifp->if_start = bridge_start;
  485         ifp->if_init = bridge_init;
  486         ifp->if_type = IFT_BRIDGE;
  487         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
  488         ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
  489         IFQ_SET_READY(&ifp->if_snd);
  490         ifp->if_hdrlen = ETHER_HDR_LEN;
  491 
  492         /*
  493          * Generate a random ethernet address and use the private AC:DE:48
  494          * OUI code.
  495          */
  496         arc4rand( &sc->ifb_ac.ac_enaddr, ETHER_ADDR_LEN, 1);
  497         sc->ifb_ac.ac_enaddr[0] = 0xAC;
  498         sc->ifb_ac.ac_enaddr[1] = 0xDE;
  499         sc->ifb_ac.ac_enaddr[2] = 0x48;
  500 
  501         ether_ifattach(ifp, sc->ifb_ac.ac_enaddr);
  502         /* Now undo some of the damage... */
  503         ifp->if_baudrate = 0;
  504         ifp->if_type = IFT_BRIDGE;
  505 
  506         mtx_lock(&bridge_list_mtx);
  507         LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
  508         mtx_unlock(&bridge_list_mtx);
  509 
  510         return (0);
  511 }
  512 
  513 /*
  514  * bridge_clone_destroy:
  515  *
  516  *      Destroy a bridge instance.
  517  */
  518 static void
  519 bridge_clone_destroy(struct ifnet *ifp)
  520 {
  521         struct bridge_softc *sc = ifp->if_softc;
  522         struct bridge_iflist *bif;
  523 
  524         BRIDGE_LOCK(sc);
  525 
  526         bridge_stop(ifp, 1);
  527         ifp->if_flags &= ~IFF_UP;
  528 
  529         while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
  530                 bridge_delete_member(sc, bif, 0);
  531 
  532         while ((bif = LIST_FIRST(&sc->sc_spanlist)) != NULL) {
  533                 bridge_delete_span(sc, bif);
  534         }
  535 
  536         BRIDGE_UNLOCK(sc);
  537 
  538         mtx_lock(&bridge_list_mtx);
  539         LIST_REMOVE(sc, sc_list);
  540         mtx_unlock(&bridge_list_mtx);
  541 
  542         ether_ifdetach(ifp);
  543 
  544         /* Tear down the routing table. */
  545         bridge_rtable_fini(sc);
  546 
  547         BRIDGE_LOCK_DESTROY(sc);
  548         free(sc, M_DEVBUF);
  549 }
  550 
  551 /*
  552  * bridge_ioctl:
  553  *
  554  *      Handle a control request from the operator.
  555  */
  556 static int
  557 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  558 {
  559         struct bridge_softc *sc = ifp->if_softc;
  560         struct thread *td = curthread;
  561         union {
  562                 struct ifbreq ifbreq;
  563                 struct ifbifconf ifbifconf;
  564                 struct ifbareq ifbareq;
  565                 struct ifbaconf ifbaconf;
  566                 struct ifbrparam ifbrparam;
  567         } args;
  568         struct ifdrv *ifd = (struct ifdrv *) data;
  569         const struct bridge_control *bc;
  570         int error = 0;
  571 
  572         BRIDGE_LOCK(sc);
  573 
  574         switch (cmd) {
  575 
  576         case SIOCADDMULTI:
  577         case SIOCDELMULTI:
  578                 break;
  579 
  580         case SIOCGDRVSPEC:
  581         case SIOCSDRVSPEC:
  582                 if (ifd->ifd_cmd >= bridge_control_table_size) {
  583                         error = EINVAL;
  584                         break;
  585                 }
  586                 bc = &bridge_control_table[ifd->ifd_cmd];
  587 
  588                 if (cmd == SIOCGDRVSPEC &&
  589                     (bc->bc_flags & BC_F_COPYOUT) == 0) {
  590                         error = EINVAL;
  591                         break;
  592                 }
  593                 else if (cmd == SIOCSDRVSPEC &&
  594                     (bc->bc_flags & BC_F_COPYOUT) != 0) {
  595                         error = EINVAL;
  596                         break;
  597                 }
  598 
  599                 if (bc->bc_flags & BC_F_SUSER) {
  600                         error = suser(td);
  601                         if (error)
  602                                 break;
  603                 }
  604 
  605                 if (ifd->ifd_len != bc->bc_argsize ||
  606                     ifd->ifd_len > sizeof(args)) {
  607                         error = EINVAL;
  608                         break;
  609                 }
  610 
  611                 bzero(&args, sizeof args);
  612                 if (bc->bc_flags & BC_F_COPYIN) {
  613                         error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
  614                         if (error)
  615                                 break;
  616                 }
  617 
  618                 error = (*bc->bc_func)(sc, &args);
  619                 if (error)
  620                         break;
  621 
  622                 if (bc->bc_flags & BC_F_COPYOUT)
  623                         error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
  624 
  625                 break;
  626 
  627         case SIOCSIFFLAGS:
  628                 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) {
  629                         /*
  630                          * If interface is marked down and it is running,
  631                          * then stop and disable it.
  632                          */
  633                         bridge_stop(ifp, 1);
  634                 } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) {
  635                         /*
  636                          * If interface is marked up and it is stopped, then
  637                          * start it.
  638                          */
  639                         BRIDGE_UNLOCK(sc);
  640                         (*ifp->if_init)(sc);
  641                 }
  642                 break;
  643 
  644         case SIOCSIFMTU:
  645                 /* Do not allow the MTU to be changed on the bridge */
  646                 error = EINVAL;
  647                 break;
  648 
  649         default:
  650                 /*
  651                  * drop the lock as ether_ioctl() will call bridge_start() and
  652                  * cause the lock to be recursed.
  653                  */
  654                 BRIDGE_UNLOCK(sc);
  655                 error = ether_ioctl(ifp, cmd, data);
  656                 break;
  657         }
  658 
  659         if (BRIDGE_LOCKED(sc))
  660                 BRIDGE_UNLOCK(sc);
  661 
  662         return (error);
  663 }
  664 
  665 /*
  666  * bridge_mutecaps:
  667  *
  668  *      Clear or restore unwanted capabilities on the member interface
  669  */
  670 static void
  671 bridge_mutecaps(struct bridge_iflist *bif, int mute)
  672 {
  673         struct ifnet *ifp = bif->bif_ifp;
  674         struct ifreq ifr;
  675         int error;
  676 
  677         if (ifp->if_ioctl == NULL)
  678                 return;
  679 
  680         bzero(&ifr, sizeof ifr);
  681         ifr.ifr_reqcap = ifp->if_capenable;
  682 
  683         if (mute) {
  684                 /* mask off and save capabilities */
  685                 bif->bif_mutecap = ifr.ifr_reqcap & BRIDGE_IFCAPS_MASK;
  686                 if (bif->bif_mutecap != 0)
  687                         ifr.ifr_reqcap &= ~BRIDGE_IFCAPS_MASK;
  688         } else
  689                 /* restore muted capabilities */
  690                 ifr.ifr_reqcap |= bif->bif_mutecap;
  691 
  692 
  693         if (bif->bif_mutecap != 0) {
  694                 IFF_LOCKGIANT(ifp);
  695                 error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr);
  696                 IFF_UNLOCKGIANT(ifp);
  697         }
  698 }
  699         
  700 
  701 /*
  702  * bridge_lookup_member:
  703  *
  704  *      Lookup a bridge member interface.
  705  */
  706 static struct bridge_iflist *
  707 bridge_lookup_member(struct bridge_softc *sc, const char *name)
  708 {
  709         struct bridge_iflist *bif;
  710         struct ifnet *ifp;
  711 
  712         BRIDGE_LOCK_ASSERT(sc);
  713 
  714         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
  715                 ifp = bif->bif_ifp;
  716                 if (strcmp(ifp->if_xname, name) == 0)
  717                         return (bif);
  718         }
  719 
  720         return (NULL);
  721 }
  722 
  723 /*
  724  * bridge_lookup_member_if:
  725  *
  726  *      Lookup a bridge member interface by ifnet*.
  727  */
  728 static struct bridge_iflist *
  729 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
  730 {
  731         struct bridge_iflist *bif;
  732 
  733         BRIDGE_LOCK_ASSERT(sc);
  734 
  735         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
  736                 if (bif->bif_ifp == member_ifp)
  737                         return (bif);
  738         }
  739 
  740         return (NULL);
  741 }
  742 
  743 /*
  744  * bridge_delete_member:
  745  *
  746  *      Delete the specified member interface.
  747  */
  748 static void
  749 bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
  750     int gone)
  751 {
  752         struct ifnet *ifs = bif->bif_ifp;
  753 
  754         BRIDGE_LOCK_ASSERT(sc);
  755 
  756         if (!gone) {
  757                 switch (ifs->if_type) {
  758                 case IFT_ETHER:
  759                 case IFT_L2VLAN:
  760                         /*
  761                          * Take the interface out of promiscuous mode.
  762                          */
  763                         (void) ifpromisc(ifs, 0);
  764                         bridge_mutecaps(bif, 0);
  765                         break;
  766 
  767                 default:
  768 #ifdef DIAGNOSTIC
  769                         panic("bridge_delete_member: impossible");
  770 #endif
  771                         break;
  772                 }
  773         }
  774 
  775         ifs->if_bridge = NULL;
  776         BRIDGE_XLOCK(sc);
  777         LIST_REMOVE(bif, bif_next);
  778         BRIDGE_XDROP(sc);
  779 
  780         bridge_rtdelete(sc, ifs, IFBF_FLUSHALL);
  781 
  782         free(bif, M_DEVBUF);
  783 
  784         if (sc->sc_if.if_flags & IFF_RUNNING)
  785                 bstp_initialization(sc);
  786 }
  787 
  788 /*
  789  * bridge_delete_span:
  790  *
  791  *      Delete the specified span interface.
  792  */
  793 static void
  794 bridge_delete_span(struct bridge_softc *sc, struct bridge_iflist *bif)
  795 {
  796         BRIDGE_LOCK_ASSERT(sc);
  797 
  798         KASSERT(bif->bif_ifp->if_bridge == NULL,
  799             ("%s: not a span interface", __func__));
  800 
  801         LIST_REMOVE(bif, bif_next);
  802         free(bif, M_DEVBUF);
  803 }
  804 
  805 static int
  806 bridge_ioctl_add(struct bridge_softc *sc, void *arg)
  807 {
  808         struct ifbreq *req = arg;
  809         struct bridge_iflist *bif = NULL;
  810         struct ifnet *ifs;
  811         int error = 0;
  812 
  813         BRIDGE_LOCK_ASSERT(sc);
  814 
  815         ifs = ifunit(req->ifbr_ifsname);
  816         if (ifs == NULL)
  817                 return (ENOENT);
  818 
  819         /* If it's in the span list, it can't be a member. */
  820         LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
  821                 if (ifs == bif->bif_ifp)
  822                         return (EBUSY);
  823 
  824         /* Allow the first member to define the MTU */
  825         if (LIST_EMPTY(&sc->sc_iflist))
  826                 sc->sc_if.if_mtu = ifs->if_mtu;
  827         else if (sc->sc_if.if_mtu != ifs->if_mtu) {
  828                 if_printf(&sc->sc_if, "invalid MTU for %s\n", ifs->if_xname);
  829                 return (EINVAL);
  830         }
  831 
  832         if (ifs->if_bridge == sc)
  833                 return (EEXIST);
  834 
  835         if (ifs->if_bridge != NULL)
  836                 return (EBUSY);
  837 
  838         bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
  839         if (bif == NULL)
  840                 return (ENOMEM);
  841 
  842         bif->bif_ifp = ifs;
  843         bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
  844         bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
  845         bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
  846 
  847         switch (ifs->if_type) {
  848         case IFT_ETHER:
  849         case IFT_L2VLAN:
  850                 /*
  851                  * Place the interface into promiscuous mode.
  852                  */
  853                 error = ifpromisc(ifs, 1);
  854                 if (error)
  855                         goto out;
  856 
  857                 bridge_mutecaps(bif, 1);
  858                 break;
  859 
  860         default:
  861                 error = EINVAL;
  862                 goto out;
  863         }
  864 
  865         ifs->if_bridge = sc;
  866         /*
  867          * XXX: XLOCK HERE!?!
  868          *
  869          * NOTE: insert_***HEAD*** should be safe for the traversals.
  870          */
  871         LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
  872 
  873         if (sc->sc_if.if_flags & IFF_RUNNING)
  874                 bstp_initialization(sc);
  875         else
  876                 bstp_stop(sc);
  877 
  878 out:
  879         if (error) {
  880                 if (bif != NULL)
  881                         free(bif, M_DEVBUF);
  882         }
  883         return (error);
  884 }
  885 
  886 static int
  887 bridge_ioctl_del(struct bridge_softc *sc, void *arg)
  888 {
  889         struct ifbreq *req = arg;
  890         struct bridge_iflist *bif;
  891 
  892         BRIDGE_LOCK_ASSERT(sc);
  893 
  894         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
  895         if (bif == NULL)
  896                 return (ENOENT);
  897 
  898         bridge_delete_member(sc, bif, 0);
  899 
  900         return (0);
  901 }
  902 
  903 static int
  904 bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
  905 {
  906         struct ifbreq *req = arg;
  907         struct bridge_iflist *bif;
  908 
  909         BRIDGE_LOCK_ASSERT(sc);
  910 
  911         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
  912         if (bif == NULL)
  913                 return (ENOENT);
  914 
  915         req->ifbr_ifsflags = bif->bif_flags;
  916         req->ifbr_state = bif->bif_state;
  917         req->ifbr_priority = bif->bif_priority;
  918         req->ifbr_path_cost = bif->bif_path_cost;
  919         req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
  920 
  921         return (0);
  922 }
  923 
  924 static int
  925 bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
  926 {
  927         struct ifbreq *req = arg;
  928         struct bridge_iflist *bif;
  929 
  930         BRIDGE_LOCK_ASSERT(sc);
  931 
  932         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
  933         if (bif == NULL)
  934                 return (ENOENT);
  935 
  936         if (req->ifbr_ifsflags & IFBIF_SPAN)
  937                 /* SPAN is readonly */
  938                 return (EINVAL);
  939 
  940         if (req->ifbr_ifsflags & IFBIF_STP) {
  941                 switch (bif->bif_ifp->if_type) {
  942                 case IFT_ETHER:
  943                         /* These can do spanning tree. */
  944                         break;
  945 
  946                 default:
  947                         /* Nothing else can. */
  948                         return (EINVAL);
  949                 }
  950         }
  951 
  952         bif->bif_flags = req->ifbr_ifsflags;
  953 
  954         if (sc->sc_if.if_flags & IFF_RUNNING)
  955                 bstp_initialization(sc);
  956 
  957         return (0);
  958 }
  959 
  960 static int
  961 bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
  962 {
  963         struct ifbrparam *param = arg;
  964 
  965         BRIDGE_LOCK_ASSERT(sc);
  966 
  967         sc->sc_brtmax = param->ifbrp_csize;
  968         bridge_rttrim(sc);
  969 
  970         return (0);
  971 }
  972 
  973 static int
  974 bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
  975 {
  976         struct ifbrparam *param = arg;
  977 
  978         BRIDGE_LOCK_ASSERT(sc);
  979 
  980         param->ifbrp_csize = sc->sc_brtmax;
  981 
  982         return (0);
  983 }
  984 
  985 static int
  986 bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
  987 {
  988         struct ifbifconf *bifc = arg;
  989         struct bridge_iflist *bif;
  990         struct ifbreq breq;
  991         int count, len, error = 0;
  992 
  993         BRIDGE_LOCK_ASSERT(sc);
  994 
  995         count = 0;
  996         LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
  997                 count++;
  998         LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
  999                 count++;
 1000 
 1001         if (bifc->ifbic_len == 0) {
 1002                 bifc->ifbic_len = sizeof(breq) * count;
 1003                 return (0);
 1004         }
 1005 
 1006         count = 0;
 1007         len = bifc->ifbic_len;
 1008         bzero(&breq, sizeof breq);
 1009         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 1010                 if (len < sizeof(breq))
 1011                         break;
 1012 
 1013                 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
 1014                     sizeof(breq.ifbr_ifsname));
 1015                 breq.ifbr_ifsflags = bif->bif_flags;
 1016                 breq.ifbr_state = bif->bif_state;
 1017                 breq.ifbr_priority = bif->bif_priority;
 1018                 breq.ifbr_path_cost = bif->bif_path_cost;
 1019                 breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
 1020                 error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
 1021                 if (error)
 1022                         break;
 1023                 count++;
 1024                 len -= sizeof(breq);
 1025         }
 1026         LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
 1027                 if (len < sizeof(breq))
 1028                         break;
 1029 
 1030                 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
 1031                     sizeof(breq.ifbr_ifsname));
 1032                 breq.ifbr_ifsflags = bif->bif_flags;
 1033                 breq.ifbr_state = bif->bif_state;
 1034                 breq.ifbr_priority = bif->bif_priority;
 1035                 breq.ifbr_path_cost = bif->bif_path_cost;
 1036                 breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
 1037                 error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
 1038                 if (error)
 1039                         break;
 1040                 count++;
 1041                 len -= sizeof(breq);
 1042         }
 1043 
 1044         bifc->ifbic_len = sizeof(breq) * count;
 1045         return (error);
 1046 }
 1047 
 1048 static int
 1049 bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
 1050 {
 1051         struct ifbaconf *bac = arg;
 1052         struct bridge_rtnode *brt;
 1053         struct ifbareq bareq;
 1054         int count = 0, error = 0, len;
 1055 
 1056         BRIDGE_LOCK_ASSERT(sc);
 1057 
 1058         if (bac->ifbac_len == 0)
 1059                 return (0);
 1060 
 1061         len = bac->ifbac_len;
 1062         bzero(&bareq, sizeof bareq);
 1063         LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
 1064                 if (len < sizeof(bareq))
 1065                         goto out;
 1066                 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
 1067                     sizeof(bareq.ifba_ifsname));
 1068                 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
 1069                 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
 1070                                 time_uptime < brt->brt_expire)
 1071                         bareq.ifba_expire = brt->brt_expire - time_uptime;
 1072                 else
 1073                         bareq.ifba_expire = 0;
 1074                 bareq.ifba_flags = brt->brt_flags;
 1075 
 1076                 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq));
 1077                 if (error)
 1078                         goto out;
 1079                 count++;
 1080                 len -= sizeof(bareq);
 1081         }
 1082 out:
 1083         bac->ifbac_len = sizeof(bareq) * count;
 1084         return (error);
 1085 }
 1086 
 1087 static int
 1088 bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
 1089 {
 1090         struct ifbareq *req = arg;
 1091         struct bridge_iflist *bif;
 1092         int error;
 1093 
 1094         BRIDGE_LOCK_ASSERT(sc);
 1095 
 1096         bif = bridge_lookup_member(sc, req->ifba_ifsname);
 1097         if (bif == NULL)
 1098                 return (ENOENT);
 1099 
 1100         error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1,
 1101             req->ifba_flags);
 1102 
 1103         return (error);
 1104 }
 1105 
 1106 static int
 1107 bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
 1108 {
 1109         struct ifbrparam *param = arg;
 1110 
 1111         BRIDGE_LOCK_ASSERT(sc);
 1112 
 1113         sc->sc_brttimeout = param->ifbrp_ctime;
 1114 
 1115         return (0);
 1116 }
 1117 
 1118 static int
 1119 bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
 1120 {
 1121         struct ifbrparam *param = arg;
 1122 
 1123         BRIDGE_LOCK_ASSERT(sc);
 1124 
 1125         param->ifbrp_ctime = sc->sc_brttimeout;
 1126 
 1127         return (0);
 1128 }
 1129 
 1130 static int
 1131 bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
 1132 {
 1133         struct ifbareq *req = arg;
 1134 
 1135         BRIDGE_LOCK_ASSERT(sc);
 1136 
 1137         return (bridge_rtdaddr(sc, req->ifba_dst));
 1138 }
 1139 
 1140 static int
 1141 bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
 1142 {
 1143         struct ifbreq *req = arg;
 1144 
 1145         BRIDGE_LOCK_ASSERT(sc);
 1146 
 1147         bridge_rtflush(sc, req->ifbr_ifsflags);
 1148 
 1149         return (0);
 1150 }
 1151 
 1152 static int
 1153 bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
 1154 {
 1155         struct ifbrparam *param = arg;
 1156 
 1157         BRIDGE_LOCK_ASSERT(sc);
 1158 
 1159         param->ifbrp_prio = sc->sc_bridge_priority;
 1160 
 1161         return (0);
 1162 }
 1163 
 1164 static int
 1165 bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
 1166 {
 1167         struct ifbrparam *param = arg;
 1168 
 1169         BRIDGE_LOCK_ASSERT(sc);
 1170 
 1171         sc->sc_bridge_priority = param->ifbrp_prio;
 1172 
 1173         if (sc->sc_if.if_flags & IFF_RUNNING)
 1174                 bstp_initialization(sc);
 1175 
 1176         return (0);
 1177 }
 1178 
 1179 static int
 1180 bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
 1181 {
 1182         struct ifbrparam *param = arg;
 1183 
 1184         BRIDGE_LOCK_ASSERT(sc);
 1185 
 1186         param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
 1187 
 1188         return (0);
 1189 }
 1190 
 1191 static int
 1192 bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
 1193 {
 1194         struct ifbrparam *param = arg;
 1195 
 1196         BRIDGE_LOCK_ASSERT(sc);
 1197 
 1198         if (param->ifbrp_hellotime == 0)
 1199                 return (EINVAL);
 1200         sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
 1201 
 1202         if (sc->sc_if.if_flags & IFF_RUNNING)
 1203                 bstp_initialization(sc);
 1204 
 1205         return (0);
 1206 }
 1207 
 1208 static int
 1209 bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
 1210 {
 1211         struct ifbrparam *param = arg;
 1212 
 1213         BRIDGE_LOCK_ASSERT(sc);
 1214 
 1215         param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
 1216 
 1217         return (0);
 1218 }
 1219 
 1220 static int
 1221 bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
 1222 {
 1223         struct ifbrparam *param = arg;
 1224 
 1225         BRIDGE_LOCK_ASSERT(sc);
 1226 
 1227         if (param->ifbrp_fwddelay == 0)
 1228                 return (EINVAL);
 1229         sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
 1230 
 1231         if (sc->sc_if.if_flags & IFF_RUNNING)
 1232                 bstp_initialization(sc);
 1233 
 1234         return (0);
 1235 }
 1236 
 1237 static int
 1238 bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
 1239 {
 1240         struct ifbrparam *param = arg;
 1241 
 1242         BRIDGE_LOCK_ASSERT(sc);
 1243 
 1244         param->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
 1245 
 1246         return (0);
 1247 }
 1248 
 1249 static int
 1250 bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
 1251 {
 1252         struct ifbrparam *param = arg;
 1253 
 1254         BRIDGE_LOCK_ASSERT(sc);
 1255 
 1256         if (param->ifbrp_maxage == 0)
 1257                 return (EINVAL);
 1258         sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
 1259 
 1260         if (sc->sc_if.if_flags & IFF_RUNNING)
 1261                 bstp_initialization(sc);
 1262 
 1263         return (0);
 1264 }
 1265 
 1266 static int
 1267 bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
 1268 {
 1269         struct ifbreq *req = arg;
 1270         struct bridge_iflist *bif;
 1271 
 1272         BRIDGE_LOCK_ASSERT(sc);
 1273 
 1274         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 1275         if (bif == NULL)
 1276                 return (ENOENT);
 1277 
 1278         bif->bif_priority = req->ifbr_priority;
 1279 
 1280         if (sc->sc_if.if_flags & IFF_RUNNING)
 1281                 bstp_initialization(sc);
 1282 
 1283         return (0);
 1284 }
 1285 
 1286 static int
 1287 bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
 1288 {
 1289         struct ifbreq *req = arg;
 1290         struct bridge_iflist *bif;
 1291 
 1292         BRIDGE_LOCK_ASSERT(sc);
 1293 
 1294         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 1295         if (bif == NULL)
 1296                 return (ENOENT);
 1297 
 1298         bif->bif_path_cost = req->ifbr_path_cost;
 1299 
 1300         if (sc->sc_if.if_flags & IFF_RUNNING)
 1301                 bstp_initialization(sc);
 1302 
 1303         return (0);
 1304 }
 1305 
 1306 static int
 1307 bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
 1308 {
 1309         struct ifbreq *req = arg;
 1310         struct bridge_iflist *bif = NULL;
 1311         struct ifnet *ifs;
 1312 
 1313         BRIDGE_LOCK_ASSERT(sc);
 1314 
 1315         ifs = ifunit(req->ifbr_ifsname);
 1316         if (ifs == NULL)
 1317                 return (ENOENT);
 1318 
 1319         LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
 1320                 if (ifs == bif->bif_ifp)
 1321                         return (EBUSY);
 1322 
 1323         if (ifs->if_bridge != NULL)
 1324                 return (EBUSY);
 1325 
 1326         switch (ifs->if_type) {
 1327                 case IFT_ETHER:
 1328                 case IFT_L2VLAN:
 1329                         break;
 1330                 default:
 1331                         return (EINVAL);
 1332         }
 1333 
 1334         bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
 1335         if (bif == NULL)
 1336                 return (ENOMEM);
 1337 
 1338         bif->bif_ifp = ifs;
 1339         bif->bif_flags = IFBIF_SPAN;
 1340 
 1341         LIST_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next);
 1342 
 1343         return (0);
 1344 }
 1345 
 1346 static int
 1347 bridge_ioctl_delspan(struct bridge_softc *sc, void *arg)
 1348 {
 1349         struct ifbreq *req = arg;
 1350         struct bridge_iflist *bif;
 1351         struct ifnet *ifs;
 1352 
 1353         BRIDGE_LOCK_ASSERT(sc);
 1354 
 1355         ifs = ifunit(req->ifbr_ifsname);
 1356         if (ifs == NULL)
 1357                 return (ENOENT);
 1358 
 1359         LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
 1360                 if (ifs == bif->bif_ifp)
 1361                         break;
 1362 
 1363         if (bif == NULL)
 1364                 return (ENOENT);
 1365 
 1366         bridge_delete_span(sc, bif);
 1367 
 1368         return (0);
 1369 }
 1370 
 1371 /*
 1372  * bridge_ifdetach:
 1373  *
 1374  *      Detach an interface from a bridge.  Called when a member
 1375  *      interface is detaching.
 1376  */
 1377 static void
 1378 bridge_ifdetach(void *arg __unused, struct ifnet *ifp)
 1379 {
 1380         struct bridge_softc *sc = ifp->if_bridge;
 1381         struct bridge_iflist *bif;
 1382 
 1383         /* Check if the interface is a bridge member */
 1384         if (sc != NULL) {
 1385                 BRIDGE_LOCK(sc);
 1386 
 1387                 bif = bridge_lookup_member_if(sc, ifp);
 1388                 if (bif != NULL)
 1389                         bridge_delete_member(sc, bif, 1);
 1390 
 1391                 BRIDGE_UNLOCK(sc);
 1392                 return;
 1393         }
 1394 
 1395         /* Check if the interface is a span port */
 1396         mtx_lock(&bridge_list_mtx);
 1397         LIST_FOREACH(sc, &bridge_list, sc_list) {
 1398                 BRIDGE_LOCK(sc);
 1399                 LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
 1400                         if (ifp == bif->bif_ifp) {
 1401                                 bridge_delete_span(sc, bif);
 1402                                 break;
 1403                         }
 1404 
 1405                 BRIDGE_UNLOCK(sc);
 1406         }
 1407         mtx_unlock(&bridge_list_mtx);
 1408 }
 1409 
 1410 /*
 1411  * bridge_init:
 1412  *
 1413  *      Initialize a bridge interface.
 1414  */
 1415 static void
 1416 bridge_init(void *xsc)
 1417 {
 1418         struct bridge_softc *sc = (struct bridge_softc *)xsc;
 1419         struct ifnet *ifp = &sc->sc_if;
 1420 
 1421         if (ifp->if_flags & IFF_RUNNING)
 1422                 return;
 1423 
 1424         BRIDGE_LOCK(sc);
 1425         callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
 1426             bridge_timer, sc);
 1427 
 1428         ifp->if_flags |= IFF_RUNNING;
 1429         bstp_initialization(sc);
 1430         BRIDGE_UNLOCK(sc);
 1431         return;
 1432 }
 1433 
 1434 /*
 1435  * bridge_stop:
 1436  *
 1437  *      Stop the bridge interface.
 1438  */
 1439 static void
 1440 bridge_stop(struct ifnet *ifp, int disable)
 1441 {
 1442         struct bridge_softc *sc = ifp->if_softc;
 1443 
 1444         BRIDGE_LOCK_ASSERT(sc);
 1445 
 1446         if ((ifp->if_flags & IFF_RUNNING) == 0)
 1447                 return;
 1448 
 1449         callout_stop(&sc->sc_brcallout);
 1450         bstp_stop(sc);
 1451 
 1452         bridge_rtflush(sc, IFBF_FLUSHDYN);
 1453 
 1454         ifp->if_flags &= ~IFF_RUNNING;
 1455 }
 1456 
 1457 /*
 1458  * bridge_enqueue:
 1459  *
 1460  *      Enqueue a packet on a bridge member interface.
 1461  *
 1462  */
 1463 __inline void
 1464 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
 1465 {
 1466         int len, err;
 1467         short mflags;
 1468 
 1469         len = m->m_pkthdr.len;
 1470         mflags = m->m_flags;
 1471 
 1472         IFQ_ENQUEUE(&dst_ifp->if_snd, m, err);
 1473         if (err == 0) {
 1474 
 1475                 sc->sc_if.if_opackets++;
 1476                 sc->sc_if.if_obytes += len;
 1477 
 1478                 dst_ifp->if_obytes += len;
 1479 
 1480                 if (mflags & M_MCAST) {
 1481                         sc->sc_if.if_omcasts++;
 1482                         dst_ifp->if_omcasts++;
 1483                 }
 1484         }
 1485 
 1486         if ((dst_ifp->if_flags & IFF_OACTIVE) == 0)
 1487                 (*dst_ifp->if_start)(dst_ifp);
 1488 }
 1489 
 1490 /*
 1491  * bridge_dummynet:
 1492  *
 1493  *      Receive a queued packet from dummynet and pass it on to the output
 1494  *      interface.
 1495  *
 1496  *      The mbuf has the Ethernet header already attached.
 1497  */
 1498 static void
 1499 bridge_dummynet(struct mbuf *m, struct ifnet *ifp)
 1500 {
 1501         struct bridge_softc *sc;
 1502 
 1503         sc = ifp->if_bridge;
 1504 
 1505         /*
 1506          * The packet didnt originate from a member interface. This should only
 1507          * ever happen if a member interface is removed while packets are
 1508          * queued for it.
 1509          */
 1510         if (sc == NULL) {
 1511                 m_freem(m);
 1512                 return;
 1513         }
 1514 
 1515         if (inet_pfil_hook.ph_busy_count >= 0
 1516 #ifdef INET6
 1517             || inet6_pfil_hook.ph_busy_count >= 0
 1518 #endif
 1519             ) {
 1520                 if (bridge_pfil(&m, &sc->sc_if, ifp, PFIL_OUT) != 0)
 1521                         return;
 1522                 if (m == NULL)
 1523                         return;
 1524         }
 1525 
 1526         bridge_enqueue(sc, ifp, m);
 1527 }
 1528 
 1529 /*
 1530  * bridge_output:
 1531  *
 1532  *      Send output from a bridge member interface.  This
 1533  *      performs the bridging function for locally originated
 1534  *      packets.
 1535  *
 1536  *      The mbuf has the Ethernet header already attached.  We must
 1537  *      enqueue or free the mbuf before returning.
 1538  */
 1539 static int
 1540 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
 1541     struct rtentry *rt)
 1542 {
 1543         struct ether_header *eh;
 1544         struct ifnet *dst_if;
 1545         struct bridge_softc *sc;
 1546 
 1547         if (m->m_len < ETHER_HDR_LEN) {
 1548                 m = m_pullup(m, ETHER_HDR_LEN);
 1549                 if (m == NULL)
 1550                         return (0);
 1551         }
 1552 
 1553         eh = mtod(m, struct ether_header *);
 1554         sc = ifp->if_bridge;
 1555 
 1556         BRIDGE_LOCK(sc);
 1557 
 1558         /*
 1559          * If bridge is down, but the original output interface is up,
 1560          * go ahead and send out that interface.  Otherwise, the packet
 1561          * is dropped below.
 1562          */
 1563         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
 1564                 dst_if = ifp;
 1565                 goto sendunicast;
 1566         }
 1567 
 1568         /*
 1569          * If the packet is a multicast, or we don't know a better way to
 1570          * get there, send to all interfaces.
 1571          */
 1572         if (ETHER_IS_MULTICAST(eh->ether_dhost))
 1573                 dst_if = NULL;
 1574         else
 1575                 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
 1576         if (dst_if == NULL) {
 1577                 struct bridge_iflist *bif;
 1578                 struct mbuf *mc;
 1579                 int error = 0, used = 0;
 1580 
 1581                 BRIDGE_LOCK2REF(sc, error);
 1582                 if (error) {
 1583                         m_freem(m);
 1584                         return (0);
 1585                 }
 1586 
 1587                 bridge_span(sc, m);
 1588 
 1589                 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 1590                         dst_if = bif->bif_ifp;
 1591                         if ((dst_if->if_flags & IFF_RUNNING) == 0)
 1592                                 continue;
 1593 
 1594                         /*
 1595                          * If this is not the original output interface,
 1596                          * and the interface is participating in spanning
 1597                          * tree, make sure the port is in a state that
 1598                          * allows forwarding.
 1599                          */
 1600                         if (dst_if != ifp &&
 1601                             (bif->bif_flags & IFBIF_STP) != 0) {
 1602                                 switch (bif->bif_state) {
 1603                                 case BSTP_IFSTATE_BLOCKING:
 1604                                 case BSTP_IFSTATE_LISTENING:
 1605                                 case BSTP_IFSTATE_DISABLED:
 1606                                         continue;
 1607                                 }
 1608                         }
 1609 
 1610                         if (LIST_NEXT(bif, bif_next) == NULL) {
 1611                                 used = 1;
 1612                                 mc = m;
 1613                         } else {
 1614                                 mc = m_copypacket(m, M_DONTWAIT);
 1615                                 if (mc == NULL) {
 1616                                         sc->sc_if.if_oerrors++;
 1617                                         continue;
 1618                                 }
 1619                         }
 1620 
 1621                         bridge_enqueue(sc, dst_if, mc);
 1622                 }
 1623                 if (used == 0)
 1624                         m_freem(m);
 1625                 BRIDGE_UNREF(sc);
 1626                 return (0);
 1627         }
 1628 
 1629 sendunicast:
 1630         /*
 1631          * XXX Spanning tree consideration here?
 1632          */
 1633 
 1634         bridge_span(sc, m);
 1635         if ((dst_if->if_flags & IFF_RUNNING) == 0) {
 1636                 m_freem(m);
 1637                 BRIDGE_UNLOCK(sc);
 1638                 return (0);
 1639         }
 1640 
 1641         BRIDGE_UNLOCK(sc);
 1642         bridge_enqueue(sc, dst_if, m);
 1643         return (0);
 1644 }
 1645 
 1646 /*
 1647  * bridge_start:
 1648  *
 1649  *      Start output on a bridge.
 1650  *
 1651  */
 1652 static void
 1653 bridge_start(struct ifnet *ifp)
 1654 {
 1655         struct bridge_softc *sc;
 1656         struct mbuf *m;
 1657         struct ether_header *eh;
 1658         struct ifnet *dst_if;
 1659 
 1660         sc = ifp->if_softc;
 1661 
 1662         ifp->if_flags |= IFF_OACTIVE;
 1663         for (;;) {
 1664                 IFQ_DEQUEUE(&ifp->if_snd, m);
 1665                 if (m == 0)
 1666                         break;
 1667                 BPF_MTAP(ifp, m);
 1668 
 1669                 eh = mtod(m, struct ether_header *);
 1670                 dst_if = NULL;
 1671 
 1672                 BRIDGE_LOCK(sc);
 1673                 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
 1674                         dst_if = bridge_rtlookup(sc, eh->ether_dhost);
 1675                 }
 1676 
 1677                 if (dst_if == NULL)
 1678                         bridge_broadcast(sc, ifp, m, 0);
 1679                 else {
 1680                         BRIDGE_UNLOCK(sc);
 1681                         bridge_enqueue(sc, dst_if, m);
 1682                 }
 1683         }
 1684         ifp->if_flags &= ~IFF_OACTIVE;
 1685 
 1686         return;
 1687 }
 1688 
 1689 /*
 1690  * bridge_forward:
 1691  *
 1692  *      The forwarding function of the bridge.
 1693  *
 1694  *      NOTE: Releases the lock on return.
 1695  */
 1696 static void
 1697 bridge_forward(struct bridge_softc *sc, struct mbuf *m)
 1698 {
 1699         struct bridge_iflist *bif;
 1700         struct ifnet *src_if, *dst_if, *ifp;
 1701         struct ether_header *eh;
 1702 
 1703         src_if = m->m_pkthdr.rcvif;
 1704         BRIDGE_LOCK_ASSERT(sc);
 1705         ifp = &sc->sc_if;
 1706 
 1707         sc->sc_if.if_ipackets++;
 1708         sc->sc_if.if_ibytes += m->m_pkthdr.len;
 1709 
 1710         /*
 1711          * Look up the bridge_iflist.
 1712          */
 1713         bif = bridge_lookup_member_if(sc, src_if);
 1714         if (bif == NULL) {
 1715                 /* Interface is not a bridge member (anymore?) */
 1716                 BRIDGE_UNLOCK(sc);
 1717                 m_freem(m);
 1718                 return;
 1719         }
 1720 
 1721         if (bif->bif_flags & IFBIF_STP) {
 1722                 switch (bif->bif_state) {
 1723                 case BSTP_IFSTATE_BLOCKING:
 1724                 case BSTP_IFSTATE_LISTENING:
 1725                 case BSTP_IFSTATE_DISABLED:
 1726                         BRIDGE_UNLOCK(sc);
 1727                         m_freem(m);
 1728                         return;
 1729                 }
 1730         }
 1731 
 1732         eh = mtod(m, struct ether_header *);
 1733 
 1734         /*
 1735          * If the interface is learning, and the source
 1736          * address is valid and not multicast, record
 1737          * the address.
 1738          */
 1739         if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
 1740             ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
 1741             (eh->ether_shost[0] == 0 &&
 1742              eh->ether_shost[1] == 0 &&
 1743              eh->ether_shost[2] == 0 &&
 1744              eh->ether_shost[3] == 0 &&
 1745              eh->ether_shost[4] == 0 &&
 1746              eh->ether_shost[5] == 0) == 0) {
 1747                 (void) bridge_rtupdate(sc, eh->ether_shost,
 1748                     src_if, 0, IFBAF_DYNAMIC);
 1749         }
 1750 
 1751         if ((bif->bif_flags & IFBIF_STP) != 0 &&
 1752             bif->bif_state == BSTP_IFSTATE_LEARNING) {
 1753                 m_freem(m);
 1754                 BRIDGE_UNLOCK(sc);
 1755                 return;
 1756         }
 1757 
 1758         /*
 1759          * At this point, the port either doesn't participate
 1760          * in spanning tree or it is in the forwarding state.
 1761          */
 1762 
 1763         /*
 1764          * If the packet is unicast, destined for someone on
 1765          * "this" side of the bridge, drop it.
 1766          */
 1767         if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
 1768                 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
 1769                 if (src_if == dst_if) {
 1770                         BRIDGE_UNLOCK(sc);
 1771                         m_freem(m);
 1772                         return;
 1773                 }
 1774         } else {
 1775                 /* ...forward it to all interfaces. */
 1776                 sc->sc_if.if_imcasts++;
 1777                 dst_if = NULL;
 1778         }
 1779 
 1780         /* run the packet filter */
 1781         if (inet_pfil_hook.ph_busy_count >= 0
 1782 #ifdef INET6
 1783             || inet6_pfil_hook.ph_busy_count >= 0
 1784 #endif
 1785             ) {
 1786                 BRIDGE_UNLOCK(sc);
 1787                 if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0)
 1788                         return;
 1789                 if (m == NULL)
 1790                         return;
 1791                 BRIDGE_LOCK(sc);
 1792         }
 1793 
 1794         if (dst_if == NULL) {
 1795                 /*
 1796                  * Tap off packets passing the bridge. Broadcast packets will
 1797                  * already be tapped as they are reinjected into ether_input.
 1798                  */
 1799                 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0)
 1800                         BPF_MTAP(ifp, m);
 1801 
 1802                 bridge_broadcast(sc, src_if, m, 1);
 1803                 return;
 1804         }
 1805 
 1806         /*
 1807          * At this point, we're dealing with a unicast frame
 1808          * going to a different interface.
 1809          */
 1810         if ((dst_if->if_flags & IFF_RUNNING) == 0) {
 1811                 BRIDGE_UNLOCK(sc);
 1812                 m_freem(m);
 1813                 return;
 1814         }
 1815         bif = bridge_lookup_member_if(sc, dst_if);
 1816         if (bif == NULL) {
 1817                 /* Not a member of the bridge (anymore?) */
 1818                 BRIDGE_UNLOCK(sc);
 1819                 m_freem(m);
 1820                 return;
 1821         }
 1822 
 1823         if (bif->bif_flags & IFBIF_STP) {
 1824                 switch (bif->bif_state) {
 1825                 case BSTP_IFSTATE_DISABLED:
 1826                 case BSTP_IFSTATE_BLOCKING:
 1827                         BRIDGE_UNLOCK(sc);
 1828                         m_freem(m);
 1829                         return;
 1830                 }
 1831         }
 1832 
 1833         /* tap off packets passing the bridge */
 1834         BPF_MTAP(ifp, m);
 1835 
 1836         BRIDGE_UNLOCK(sc);
 1837 
 1838         if (inet_pfil_hook.ph_busy_count >= 0
 1839 #ifdef INET6
 1840             || inet6_pfil_hook.ph_busy_count >= 0
 1841 #endif
 1842             ) {
 1843                 if (bridge_pfil(&m, &sc->sc_if, dst_if, PFIL_OUT) != 0)
 1844                         return;
 1845                 if (m == NULL)
 1846                         return;
 1847         }
 1848 
 1849         bridge_enqueue(sc, dst_if, m);
 1850 }
 1851 
 1852 /*
 1853  * bridge_input:
 1854  *
 1855  *      Receive input from a member interface.  Queue the packet for
 1856  *      bridging if it is not for us.
 1857  */
 1858 static struct mbuf *
 1859 bridge_input(struct ifnet *ifp, struct mbuf *m)
 1860 {
 1861         struct bridge_softc *sc = ifp->if_bridge;
 1862         struct bridge_iflist *bif;
 1863         struct ifnet *bifp;
 1864         struct ether_header *eh;
 1865         struct mbuf *mc, *mc2;
 1866 
 1867         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 1868                 return (m);
 1869 
 1870         bifp = &sc->sc_if;
 1871 
 1872         BRIDGE_LOCK(sc);
 1873         bif = bridge_lookup_member_if(sc, ifp);
 1874         if (bif == NULL) {
 1875                 BRIDGE_UNLOCK(sc);
 1876                 return (m);
 1877         }
 1878 
 1879         eh = mtod(m, struct ether_header *);
 1880 
 1881         if (memcmp(eh->ether_dhost, sc->ifb_ac.ac_enaddr,
 1882             ETHER_ADDR_LEN) == 0) {
 1883                 /*
 1884                  * If the packet is for us, set the packets source as the
 1885                  * bridge, and return the packet back to ether_input for
 1886                  * local processing.
 1887                  */
 1888 
 1889                 /* XXX Do we tap the packet for the member interface too?
 1890                  * BPF_MTAP(&m->m_pkthdr.rcvif, m);
 1891                  */
 1892 
 1893                 /* Mark the packet as arriving on the bridge interface */
 1894                 m->m_pkthdr.rcvif = bifp;
 1895                 BPF_MTAP(bifp, m);
 1896                 sc->sc_if.if_ipackets++;
 1897 
 1898                 BRIDGE_UNLOCK(sc);
 1899                 return (m);
 1900         }
 1901 
 1902         bridge_span(sc, m);
 1903 
 1904         if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
 1905                 /* Tap off 802.1D packets; they do not get forwarded. */
 1906                 if (memcmp(eh->ether_dhost, bstp_etheraddr,
 1907                     ETHER_ADDR_LEN) == 0) {
 1908                         m = bstp_input(ifp, m);
 1909                         if (m == NULL) {
 1910                                 BRIDGE_UNLOCK(sc);
 1911                                 return (NULL);
 1912                         }
 1913                 }
 1914 
 1915                 if (bif->bif_flags & IFBIF_STP) {
 1916                         switch (bif->bif_state) {
 1917                         case BSTP_IFSTATE_BLOCKING:
 1918                         case BSTP_IFSTATE_LISTENING:
 1919                         case BSTP_IFSTATE_DISABLED:
 1920                                 BRIDGE_UNLOCK(sc);
 1921                                 return (m);
 1922                         }
 1923                 }
 1924 
 1925                 if (bcmp(etherbroadcastaddr, eh->ether_dhost,
 1926                     sizeof(etherbroadcastaddr)) == 0)
 1927                         m->m_flags |= M_BCAST;
 1928                 else
 1929                         m->m_flags |= M_MCAST;
 1930 
 1931                 /*
 1932                  * Make a deep copy of the packet and enqueue the copy
 1933                  * for bridge processing; return the original packet for
 1934                  * local processing.
 1935                  */
 1936                 mc = m_dup(m, M_DONTWAIT);
 1937                 if (mc == NULL) {
 1938                         BRIDGE_UNLOCK(sc);
 1939                         return (m);
 1940                 }
 1941 
 1942                 /* Perform the bridge forwarding function with the copy. */
 1943                 bridge_forward(sc, mc);
 1944 
 1945                 /*
 1946                  * Reinject the mbuf as arriving on the bridge so we have a
 1947                  * chance at claiming multicast packets. We can not loop back
 1948                  * here from ether_input as a bridge is never a member of a
 1949                  * bridge.
 1950                  */
 1951                 KASSERT(bifp->if_bridge == NULL,
 1952                     ("loop created in bridge_input"));
 1953                 mc2 = m_dup(m, M_DONTWAIT);
 1954                 if (mc2 != NULL) {
 1955                         /* Keep the layer3 header aligned */
 1956                         int i = min(mc2->m_pkthdr.len, max_protohdr);
 1957                         mc2 = m_copyup(mc2, i, ETHER_ALIGN);
 1958                 }
 1959                 if (mc2 != NULL) {
 1960                         mc2->m_pkthdr.rcvif = bifp;
 1961                         (*bifp->if_input)(bifp, mc2);
 1962                 }
 1963 
 1964                 /* Return the original packet for local processing. */
 1965                 return (m);
 1966         }
 1967 
 1968         if (bif->bif_flags & IFBIF_STP) {
 1969                 switch (bif->bif_state) {
 1970                 case BSTP_IFSTATE_BLOCKING:
 1971                 case BSTP_IFSTATE_LISTENING:
 1972                 case BSTP_IFSTATE_DISABLED:
 1973                         BRIDGE_UNLOCK(sc);
 1974                         return (m);
 1975                 }
 1976         }
 1977 
 1978         /*
 1979          * Unicast.  Make sure it's not for us.
 1980          */
 1981         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 1982                 /* It is destined for us. */
 1983                 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_dhost,
 1984                     ETHER_ADDR_LEN) == 0) {
 1985                         if (bif->bif_flags & IFBIF_LEARNING)
 1986                                 (void) bridge_rtupdate(sc,
 1987                                     eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
 1988                         m->m_pkthdr.rcvif = bif->bif_ifp;
 1989                         BRIDGE_UNLOCK(sc);
 1990                         return (m);
 1991                 }
 1992 
 1993                 /* We just received a packet that we sent out. */
 1994                 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_shost,
 1995                     ETHER_ADDR_LEN) == 0) {
 1996                         BRIDGE_UNLOCK(sc);
 1997                         m_freem(m);
 1998                         return (NULL);
 1999                 }
 2000         }
 2001 
 2002         /* Perform the bridge forwarding function. */
 2003         bridge_forward(sc, m);
 2004 
 2005         return (NULL);
 2006 }
 2007 
 2008 /*
 2009  * bridge_broadcast:
 2010  *
 2011  *      Send a frame to all interfaces that are members of
 2012  *      the bridge, except for the one on which the packet
 2013  *      arrived.
 2014  *
 2015  *      NOTE: Releases the lock on return.
 2016  */
 2017 static void
 2018 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
 2019     struct mbuf *m, int runfilt)
 2020 {
 2021         struct bridge_iflist *bif;
 2022         struct mbuf *mc;
 2023         struct ifnet *dst_if;
 2024         int error = 0, used = 0, i;
 2025 
 2026         BRIDGE_LOCK_ASSERT(sc);
 2027         BRIDGE_LOCK2REF(sc, error);
 2028         if (error) {
 2029                 m_freem(m);
 2030                 return;
 2031         }
 2032 
 2033         /* Filter on the bridge interface before broadcasting */
 2034         if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
 2035 #ifdef INET6
 2036             || inet6_pfil_hook.ph_busy_count >= 0
 2037 #endif
 2038             )) {
 2039                 if (bridge_pfil(&m, &sc->sc_if, NULL, PFIL_OUT) != 0)
 2040                         goto out;
 2041                 if (m == NULL)
 2042                         goto out;
 2043         }
 2044 
 2045         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 2046                 dst_if = bif->bif_ifp;
 2047                 if (dst_if == src_if)
 2048                         continue;
 2049 
 2050                 if (bif->bif_flags & IFBIF_STP) {
 2051                         switch (bif->bif_state) {
 2052                         case BSTP_IFSTATE_BLOCKING:
 2053                         case BSTP_IFSTATE_DISABLED:
 2054                                 continue;
 2055                         }
 2056                 }
 2057 
 2058                 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
 2059                     (m->m_flags & (M_BCAST|M_MCAST)) == 0)
 2060                         continue;
 2061 
 2062                 if ((dst_if->if_flags & IFF_RUNNING) == 0)
 2063                         continue;
 2064 
 2065                 if (LIST_NEXT(bif, bif_next) == NULL) {
 2066                         mc = m;
 2067                         used = 1;
 2068                 } else {
 2069                         mc = m_dup(m, M_DONTWAIT);
 2070                         if (mc == NULL) {
 2071                                 sc->sc_if.if_oerrors++;
 2072                                 continue;
 2073                         }
 2074                 }
 2075 
 2076                 /*
 2077                  * Filter on the output interface. Pass a NULL bridge interface
 2078                  * pointer so we do not redundantly filter on the bridge for
 2079                  * each interface we broadcast on.
 2080                  */
 2081                 if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
 2082 #ifdef INET6
 2083                     || inet6_pfil_hook.ph_busy_count >= 0
 2084 #endif
 2085                     )) {
 2086                         if (used == 0) {
 2087                                 /* Keep the layer3 header aligned */
 2088                                 i = min(mc->m_pkthdr.len, max_protohdr);
 2089                                 mc = m_copyup(mc, i, ETHER_ALIGN);
 2090                                 if (mc == NULL) {
 2091                                         sc->sc_if.if_oerrors++;
 2092                                         continue;
 2093                                 }
 2094                         }
 2095                         if (bridge_pfil(&mc, NULL, dst_if, PFIL_OUT) != 0)
 2096                                 continue;
 2097                         if (mc == NULL)
 2098                                 continue;
 2099                 }
 2100 
 2101                 bridge_enqueue(sc, dst_if, mc);
 2102         }
 2103         if (used == 0)
 2104                 m_freem(m);
 2105 
 2106 out:
 2107         BRIDGE_UNREF(sc);
 2108 }
 2109 
 2110 /*
 2111  * bridge_span:
 2112  *
 2113  *      Duplicate a packet out one or more interfaces that are in span mode,
 2114  *      the original mbuf is unmodified.
 2115  */
 2116 static void
 2117 bridge_span(struct bridge_softc *sc, struct mbuf *m)
 2118 {
 2119         struct bridge_iflist *bif;
 2120         struct ifnet *dst_if;
 2121         struct mbuf *mc;
 2122 
 2123         if (LIST_EMPTY(&sc->sc_spanlist))
 2124                 return;
 2125 
 2126         LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
 2127                 dst_if = bif->bif_ifp;
 2128                 
 2129                 if ((dst_if->if_flags & IFF_RUNNING) == 0)
 2130                         continue;
 2131 
 2132                 mc = m_copypacket(m, M_DONTWAIT);
 2133                 if (mc == NULL) {
 2134                         sc->sc_if.if_oerrors++;
 2135                         continue;
 2136                 }
 2137 
 2138                 bridge_enqueue(sc, dst_if, mc);
 2139         }
 2140 }
 2141 
 2142 /*
 2143  * bridge_rtupdate:
 2144  *
 2145  *      Add a bridge routing entry.
 2146  */
 2147 static int
 2148 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
 2149     struct ifnet *dst_if, int setflags, uint8_t flags)
 2150 {
 2151         struct bridge_rtnode *brt;
 2152         int error;
 2153 
 2154         BRIDGE_LOCK_ASSERT(sc);
 2155 
 2156         /*
 2157          * A route for this destination might already exist.  If so,
 2158          * update it, otherwise create a new one.
 2159          */
 2160         if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
 2161                 if (sc->sc_brtcnt >= sc->sc_brtmax)
 2162                         return (ENOSPC);
 2163 
 2164                 /*
 2165                  * Allocate a new bridge forwarding node, and
 2166                  * initialize the expiration time and Ethernet
 2167                  * address.
 2168                  */
 2169                 brt = uma_zalloc(bridge_rtnode_zone, M_NOWAIT | M_ZERO);
 2170                 if (brt == NULL)
 2171                         return (ENOMEM);
 2172 
 2173                 brt->brt_flags = IFBAF_DYNAMIC;
 2174                 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
 2175 
 2176                 if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
 2177                         uma_zfree(bridge_rtnode_zone, brt);
 2178                         return (error);
 2179                 }
 2180         }
 2181 
 2182         if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
 2183                 brt->brt_ifp = dst_if;
 2184         if ((flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
 2185                 brt->brt_expire = time_uptime + sc->sc_brttimeout;
 2186         if (setflags)
 2187                 brt->brt_flags = flags;
 2188 
 2189         return (0);
 2190 }
 2191 
 2192 /*
 2193  * bridge_rtlookup:
 2194  *
 2195  *      Lookup the destination interface for an address.
 2196  */
 2197 static struct ifnet *
 2198 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
 2199 {
 2200         struct bridge_rtnode *brt;
 2201 
 2202         BRIDGE_LOCK_ASSERT(sc);
 2203 
 2204         if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
 2205                 return (NULL);
 2206 
 2207         return (brt->brt_ifp);
 2208 }
 2209 
 2210 /*
 2211  * bridge_rttrim:
 2212  *
 2213  *      Trim the routine table so that we have a number
 2214  *      of routing entries less than or equal to the
 2215  *      maximum number.
 2216  */
 2217 static void
 2218 bridge_rttrim(struct bridge_softc *sc)
 2219 {
 2220         struct bridge_rtnode *brt, *nbrt;
 2221 
 2222         BRIDGE_LOCK_ASSERT(sc);
 2223 
 2224         /* Make sure we actually need to do this. */
 2225         if (sc->sc_brtcnt <= sc->sc_brtmax)
 2226                 return;
 2227 
 2228         /* Force an aging cycle; this might trim enough addresses. */
 2229         bridge_rtage(sc);
 2230         if (sc->sc_brtcnt <= sc->sc_brtmax)
 2231                 return;
 2232 
 2233         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 2234                 nbrt = LIST_NEXT(brt, brt_list);
 2235                 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
 2236                         bridge_rtnode_destroy(sc, brt);
 2237                         if (sc->sc_brtcnt <= sc->sc_brtmax)
 2238                                 return;
 2239                 }
 2240         }
 2241 }
 2242 
 2243 /*
 2244  * bridge_timer:
 2245  *
 2246  *      Aging timer for the bridge.
 2247  */
 2248 static void
 2249 bridge_timer(void *arg)
 2250 {
 2251         struct bridge_softc *sc = arg;
 2252 
 2253         BRIDGE_LOCK(sc);
 2254         bridge_rtage(sc);
 2255         BRIDGE_UNLOCK(sc);
 2256 
 2257         if (sc->sc_if.if_flags & IFF_RUNNING)
 2258                 callout_reset(&sc->sc_brcallout,
 2259                     bridge_rtable_prune_period * hz, bridge_timer, sc);
 2260 }
 2261 
 2262 /*
 2263  * bridge_rtage:
 2264  *
 2265  *      Perform an aging cycle.
 2266  */
 2267 static void
 2268 bridge_rtage(struct bridge_softc *sc)
 2269 {
 2270         struct bridge_rtnode *brt, *nbrt;
 2271 
 2272         BRIDGE_LOCK_ASSERT(sc);
 2273 
 2274         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 2275                 nbrt = LIST_NEXT(brt, brt_list);
 2276                 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
 2277                         if (time_uptime >= brt->brt_expire)
 2278                                 bridge_rtnode_destroy(sc, brt);
 2279                 }
 2280         }
 2281 }
 2282 
 2283 /*
 2284  * bridge_rtflush:
 2285  *
 2286  *      Remove all dynamic addresses from the bridge.
 2287  */
 2288 static void
 2289 bridge_rtflush(struct bridge_softc *sc, int full)
 2290 {
 2291         struct bridge_rtnode *brt, *nbrt;
 2292 
 2293         BRIDGE_LOCK_ASSERT(sc);
 2294 
 2295         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 2296                 nbrt = LIST_NEXT(brt, brt_list);
 2297                 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
 2298                         bridge_rtnode_destroy(sc, brt);
 2299         }
 2300 }
 2301 
 2302 /*
 2303  * bridge_rtdaddr:
 2304  *
 2305  *      Remove an address from the table.
 2306  */
 2307 static int
 2308 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
 2309 {
 2310         struct bridge_rtnode *brt;
 2311 
 2312         BRIDGE_LOCK_ASSERT(sc);
 2313 
 2314         if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
 2315                 return (ENOENT);
 2316 
 2317         bridge_rtnode_destroy(sc, brt);
 2318         return (0);
 2319 }
 2320 
 2321 /*
 2322  * bridge_rtdelete:
 2323  *
 2324  *      Delete routes to a speicifc member interface.
 2325  */
 2326 void
 2327 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full)
 2328 {
 2329         struct bridge_rtnode *brt, *nbrt;
 2330 
 2331         BRIDGE_LOCK_ASSERT(sc);
 2332 
 2333         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 2334                 nbrt = LIST_NEXT(brt, brt_list);
 2335                 if (brt->brt_ifp == ifp && (full ||
 2336                             (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC))
 2337                         bridge_rtnode_destroy(sc, brt);
 2338         }
 2339 }
 2340 
 2341 /*
 2342  * bridge_rtable_init:
 2343  *
 2344  *      Initialize the route table for this bridge.
 2345  */
 2346 static int
 2347 bridge_rtable_init(struct bridge_softc *sc)
 2348 {
 2349         int i;
 2350 
 2351         sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
 2352             M_DEVBUF, M_NOWAIT);
 2353         if (sc->sc_rthash == NULL)
 2354                 return (ENOMEM);
 2355 
 2356         for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
 2357                 LIST_INIT(&sc->sc_rthash[i]);
 2358 
 2359         sc->sc_rthash_key = arc4random();
 2360 
 2361         LIST_INIT(&sc->sc_rtlist);
 2362 
 2363         return (0);
 2364 }
 2365 
 2366 /*
 2367  * bridge_rtable_fini:
 2368  *
 2369  *      Deconstruct the route table for this bridge.
 2370  */
 2371 static void
 2372 bridge_rtable_fini(struct bridge_softc *sc)
 2373 {
 2374 
 2375         free(sc->sc_rthash, M_DEVBUF);
 2376 }
 2377 
 2378 /*
 2379  * The following hash function is adapted from "Hash Functions" by Bob Jenkins
 2380  * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
 2381  */
 2382 #define mix(a, b, c)                                                    \
 2383 do {                                                                    \
 2384         a -= b; a -= c; a ^= (c >> 13);                                 \
 2385         b -= c; b -= a; b ^= (a << 8);                                  \
 2386         c -= a; c -= b; c ^= (b >> 13);                                 \
 2387         a -= b; a -= c; a ^= (c >> 12);                                 \
 2388         b -= c; b -= a; b ^= (a << 16);                                 \
 2389         c -= a; c -= b; c ^= (b >> 5);                                  \
 2390         a -= b; a -= c; a ^= (c >> 3);                                  \
 2391         b -= c; b -= a; b ^= (a << 10);                                 \
 2392         c -= a; c -= b; c ^= (b >> 15);                                 \
 2393 } while (/*CONSTCOND*/0)
 2394 
 2395 static __inline uint32_t
 2396 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
 2397 {
 2398         uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
 2399 
 2400         b += addr[5] << 8;
 2401         b += addr[4];
 2402         a += addr[3] << 24;
 2403         a += addr[2] << 16;
 2404         a += addr[1] << 8;
 2405         a += addr[0];
 2406 
 2407         mix(a, b, c);
 2408 
 2409         return (c & BRIDGE_RTHASH_MASK);
 2410 }
 2411 
 2412 #undef mix
 2413 
 2414 static int
 2415 bridge_rtnode_addr_cmp(const uint8_t *a, const uint8_t *b)
 2416 {
 2417         int i, d;
 2418 
 2419         for (i = 0, d = 0; i < ETHER_ADDR_LEN && d == 0; i++) {
 2420                 d = ((int)a[i]) - ((int)b[i]);
 2421         }
 2422 
 2423         return (d);
 2424 }
 2425 
 2426 /*
 2427  * bridge_rtnode_lookup:
 2428  *
 2429  *      Look up a bridge route node for the specified destination.
 2430  */
 2431 static struct bridge_rtnode *
 2432 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
 2433 {
 2434         struct bridge_rtnode *brt;
 2435         uint32_t hash;
 2436         int dir;
 2437 
 2438         BRIDGE_LOCK_ASSERT(sc);
 2439 
 2440         hash = bridge_rthash(sc, addr);
 2441         LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
 2442                 dir = bridge_rtnode_addr_cmp(addr, brt->brt_addr);
 2443                 if (dir == 0)
 2444                         return (brt);
 2445                 if (dir > 0)
 2446                         return (NULL);
 2447         }
 2448 
 2449         return (NULL);
 2450 }
 2451 
 2452 /*
 2453  * bridge_rtnode_insert:
 2454  *
 2455  *      Insert the specified bridge node into the route table.  We
 2456  *      assume the entry is not already in the table.
 2457  */
 2458 static int
 2459 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
 2460 {
 2461         struct bridge_rtnode *lbrt;
 2462         uint32_t hash;
 2463         int dir;
 2464 
 2465         BRIDGE_LOCK_ASSERT(sc);
 2466 
 2467         hash = bridge_rthash(sc, brt->brt_addr);
 2468 
 2469         lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
 2470         if (lbrt == NULL) {
 2471                 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
 2472                 goto out;
 2473         }
 2474 
 2475         do {
 2476                 dir = bridge_rtnode_addr_cmp(brt->brt_addr, lbrt->brt_addr);
 2477                 if (dir == 0)
 2478                         return (EEXIST);
 2479                 if (dir > 0) {
 2480                         LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
 2481                         goto out;
 2482                 }
 2483                 if (LIST_NEXT(lbrt, brt_hash) == NULL) {
 2484                         LIST_INSERT_AFTER(lbrt, brt, brt_hash);
 2485                         goto out;
 2486                 }
 2487                 lbrt = LIST_NEXT(lbrt, brt_hash);
 2488         } while (lbrt != NULL);
 2489 
 2490 #ifdef DIAGNOSTIC
 2491         panic("bridge_rtnode_insert: impossible");
 2492 #endif
 2493 
 2494 out:
 2495         LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
 2496         sc->sc_brtcnt++;
 2497 
 2498         return (0);
 2499 }
 2500 
 2501 /*
 2502  * bridge_rtnode_destroy:
 2503  *
 2504  *      Destroy a bridge rtnode.
 2505  */
 2506 static void
 2507 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
 2508 {
 2509         BRIDGE_LOCK_ASSERT(sc);
 2510 
 2511         LIST_REMOVE(brt, brt_hash);
 2512 
 2513         LIST_REMOVE(brt, brt_list);
 2514         sc->sc_brtcnt--;
 2515         uma_zfree(bridge_rtnode_zone, brt);
 2516 }
 2517 
 2518 /*
 2519  * Send bridge packets through pfil if they are one of the types pfil can deal
 2520  * with, or if they are ARP or REVARP.  (pfil will pass ARP and REVARP without
 2521  * question.) If *bifp or *ifp are NULL then packet filtering is skipped for
 2522  * that interface.
 2523  */
 2524 static int
 2525 bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
 2526 {
 2527         int snap, error, i;
 2528         struct ether_header *eh1, eh2;
 2529         struct ip_fw_args args;
 2530         struct ip *ip;
 2531         struct llc llc1;
 2532         u_int16_t ether_type;
 2533 
 2534         snap = 0;
 2535         error = -1;     /* Default error if not error == 0 */
 2536 
 2537         /* we may return with the IP fields swapped, ensure its not shared */
 2538         KASSERT(M_WRITABLE(*mp), ("%s: modifying a shared mbuf", __func__));
 2539 
 2540         if (pfil_bridge == 0 && pfil_member == 0 && pfil_ipfw == 0)
 2541                 return 0; /* filtering is disabled */
 2542 
 2543         i = min((*mp)->m_pkthdr.len, max_protohdr);
 2544         if ((*mp)->m_len < i) {
 2545             *mp = m_pullup(*mp, i);
 2546             if (*mp == NULL) {
 2547                 printf("%s: m_pullup failed\n", __func__);
 2548                 return -1;
 2549             }
 2550         }
 2551 
 2552         eh1 = mtod(*mp, struct ether_header *);
 2553         ether_type = ntohs(eh1->ether_type);
 2554 
 2555         /*
 2556          * Check for SNAP/LLC.
 2557          */
 2558         if (ether_type < ETHERMTU) {
 2559                 struct llc *llc2 = (struct llc *)(eh1 + 1);
 2560 
 2561                 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
 2562                     llc2->llc_dsap == LLC_SNAP_LSAP &&
 2563                     llc2->llc_ssap == LLC_SNAP_LSAP &&
 2564                     llc2->llc_control == LLC_UI) {
 2565                         ether_type = htons(llc2->llc_un.type_snap.ether_type);
 2566                         snap = 1;
 2567                 }
 2568         }
 2569 
 2570         /*
 2571          * If we're trying to filter bridge traffic, don't look at anything
 2572          * other than IP and ARP traffic.  If the filter doesn't understand
 2573          * IPv6, don't allow IPv6 through the bridge either.  This is lame
 2574          * since if we really wanted, say, an AppleTalk filter, we are hosed,
 2575          * but of course we don't have an AppleTalk filter to begin with.
 2576          * (Note that since pfil doesn't understand ARP it will pass *ALL*
 2577          * ARP traffic.)
 2578          */
 2579         switch (ether_type) {
 2580                 case ETHERTYPE_ARP:
 2581                 case ETHERTYPE_REVARP:
 2582                         return 0; /* Automatically pass */
 2583                 case ETHERTYPE_IP:
 2584 # ifdef INET6
 2585                 case ETHERTYPE_IPV6:
 2586 # endif /* INET6 */
 2587                         break;
 2588                 default:
 2589                         /*
 2590                          * Check to see if the user wants to pass non-ip
 2591                          * packets, these will not be checked by pfil(9) and
 2592                          * passed unconditionally so the default is to drop.
 2593                          */
 2594                         if (pfil_onlyip)
 2595                                 goto bad;
 2596         }
 2597 
 2598         /* Strip off the Ethernet header and keep a copy. */
 2599         m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
 2600         m_adj(*mp, ETHER_HDR_LEN);
 2601 
 2602         /* Strip off snap header, if present */
 2603         if (snap) {
 2604                 m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1);
 2605                 m_adj(*mp, sizeof(struct llc));
 2606         }
 2607 
 2608         /*
 2609          * Check the IP header for alignment and errors
 2610          */
 2611         if (dir == PFIL_IN) {
 2612                 switch (ether_type) {
 2613                         case ETHERTYPE_IP:
 2614                                 error = bridge_ip_checkbasic(mp);
 2615                                 break;
 2616 # ifdef INET6
 2617                         case ETHERTYPE_IPV6:
 2618                                 error = bridge_ip6_checkbasic(mp);
 2619                                 break;
 2620 # endif /* INET6 */
 2621                         default:
 2622                                 error = 0;
 2623                 }
 2624                 if (error)
 2625                         goto bad;
 2626         }
 2627 
 2628         if (IPFW_LOADED && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) {
 2629                 error = -1;
 2630                 args.rule = ip_dn_claim_rule(*mp);
 2631                 if (args.rule != NULL && fw_one_pass)
 2632                         goto ipfwpass; /* packet already partially processed */
 2633 
 2634                 args.m = *mp;
 2635                 args.oif = ifp;
 2636                 args.next_hop = NULL;
 2637                 args.eh = &eh2;
 2638                 args.inp = NULL;        /* used by ipfw uid/gid/jail rules */
 2639                 i = ip_fw_chk_ptr(&args);
 2640                 *mp = args.m;
 2641 
 2642                 if (*mp == NULL)
 2643                         return error;
 2644 
 2645                 if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) {
 2646 
 2647                         /* put the Ethernet header back on */
 2648                         M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
 2649                         if (*mp == NULL)
 2650                                 return error;
 2651                         bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
 2652 
 2653                         /*
 2654                          * Pass the pkt to dummynet, which consumes it. The
 2655                          * packet will return to us via bridge_dummynet().
 2656                          */
 2657                         args.oif = ifp;
 2658                         ip_dn_io_ptr(*mp, (i & 0xffff), DN_TO_IFB_FWD, &args);
 2659                         return error;
 2660                 }
 2661 
 2662                 if (i & IP_FW_PORT_DENY_FLAG) /* drop */
 2663                         goto bad;
 2664         }
 2665 
 2666 ipfwpass:
 2667         error = 0;
 2668 
 2669         /*
 2670          * Run the packet through pfil
 2671          */
 2672         switch (ether_type)
 2673         {
 2674         case ETHERTYPE_IP :
 2675                 /*
 2676                  * before calling the firewall, swap fields the same as
 2677                  * IP does. here we assume the header is contiguous
 2678                  */
 2679                 ip = mtod(*mp, struct ip *);
 2680 
 2681                 ip->ip_len = ntohs(ip->ip_len);
 2682                 ip->ip_off = ntohs(ip->ip_off);
 2683 
 2684                 /*
 2685                  * Run pfil on the member interface and the bridge, both can
 2686                  * be skipped by clearing pfil_member or pfil_bridge.
 2687                  *
 2688                  * Keep the order:
 2689                  *   in_if -> bridge_if -> out_if
 2690                  */
 2691                 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
 2692                         error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
 2693                                         dir, NULL);
 2694 
 2695                 if (*mp == NULL || error != 0) /* filter may consume */
 2696                         break;
 2697 
 2698                 if (pfil_member && ifp != NULL)
 2699                         error = pfil_run_hooks(&inet_pfil_hook, mp, ifp,
 2700                                         dir, NULL);
 2701 
 2702                 if (*mp == NULL || error != 0) /* filter may consume */
 2703                         break;
 2704 
 2705                 if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
 2706                         error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
 2707                                         dir, NULL);
 2708 
 2709                 /* Restore ip and the fields ntohs()'d. */
 2710                 if (*mp != NULL && error == 0) {
 2711                         ip = mtod(*mp, struct ip *);
 2712                         ip->ip_len = htons(ip->ip_len);
 2713                         ip->ip_off = htons(ip->ip_off);
 2714                 }
 2715 
 2716                 break;
 2717 # ifdef INET6
 2718         case ETHERTYPE_IPV6 :
 2719                 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
 2720                         error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
 2721                                         dir, NULL);
 2722 
 2723                 if (*mp == NULL || error != 0) /* filter may consume */
 2724                         break;
 2725 
 2726                 if (pfil_member && ifp != NULL)
 2727                         error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp,
 2728                                         dir, NULL);
 2729 
 2730                 if (*mp == NULL || error != 0) /* filter may consume */
 2731                         break;
 2732 
 2733                 if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
 2734                         error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
 2735                                         dir, NULL);
 2736                 break;
 2737 # endif
 2738         default :
 2739                 error = 0;
 2740                 break;
 2741         }
 2742 
 2743         if (*mp == NULL)
 2744                 return error;
 2745         if (error != 0)
 2746                 goto bad;
 2747 
 2748         error = -1;
 2749 
 2750         /*
 2751          * Finally, put everything back the way it was and return
 2752          */
 2753         if (snap) {
 2754                 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
 2755                 if (*mp == NULL)
 2756                         return error;
 2757                 bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc));
 2758         }
 2759 
 2760         M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
 2761         if (*mp == NULL)
 2762                 return error;
 2763         bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
 2764 
 2765         return 0;
 2766 
 2767 bad:
 2768         m_freem(*mp);
 2769         *mp = NULL;
 2770         return error;
 2771 }
 2772 
 2773 /*
 2774  * Perform basic checks on header size since
 2775  * pfil assumes ip_input has already processed
 2776  * it for it.  Cut-and-pasted from ip_input.c.
 2777  * Given how simple the IPv6 version is,
 2778  * does the IPv4 version really need to be
 2779  * this complicated?
 2780  *
 2781  * XXX Should we update ipstat here, or not?
 2782  * XXX Right now we update ipstat but not
 2783  * XXX csum_counter.
 2784  */
 2785 static int
 2786 bridge_ip_checkbasic(struct mbuf **mp)
 2787 {
 2788         struct mbuf *m = *mp;
 2789         struct ip *ip;
 2790         int len, hlen;
 2791         u_short sum;
 2792 
 2793         if (*mp == NULL)
 2794                 return -1;
 2795 
 2796         if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
 2797                 if ((m = m_copyup(m, sizeof(struct ip),
 2798                         (max_linkhdr + 3) & ~3)) == NULL) {
 2799                         /* XXXJRT new stat, please */
 2800                         ipstat.ips_toosmall++;
 2801                         goto bad;
 2802                 }
 2803         } else if (__predict_false(m->m_len < sizeof (struct ip))) {
 2804                 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
 2805                         ipstat.ips_toosmall++;
 2806                         goto bad;
 2807                 }
 2808         }
 2809         ip = mtod(m, struct ip *);
 2810         if (ip == NULL) goto bad;
 2811 
 2812         if (ip->ip_v != IPVERSION) {
 2813                 ipstat.ips_badvers++;
 2814                 goto bad;
 2815         }
 2816         hlen = ip->ip_hl << 2;
 2817         if (hlen < sizeof(struct ip)) { /* minimum header length */
 2818                 ipstat.ips_badhlen++;
 2819                 goto bad;
 2820         }
 2821         if (hlen > m->m_len) {
 2822                 if ((m = m_pullup(m, hlen)) == 0) {
 2823                         ipstat.ips_badhlen++;
 2824                         goto bad;
 2825                 }
 2826                 ip = mtod(m, struct ip *);
 2827                 if (ip == NULL) goto bad;
 2828         }
 2829 
 2830         if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) {
 2831                 sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
 2832         } else {
 2833                 if (hlen == sizeof(struct ip)) {
 2834                         sum = in_cksum_hdr(ip);
 2835                 } else {
 2836                         sum = in_cksum(m, hlen);
 2837                 }
 2838         }
 2839         if (sum) {
 2840                 ipstat.ips_badsum++;
 2841                 goto bad;
 2842         }
 2843 
 2844         /* Retrieve the packet length. */
 2845         len = ntohs(ip->ip_len);
 2846 
 2847         /*
 2848          * Check for additional length bogosity
 2849          */
 2850         if (len < hlen) {
 2851                 ipstat.ips_badlen++;
 2852                 goto bad;
 2853         }
 2854 
 2855         /*
 2856          * Check that the amount of data in the buffers
 2857          * is as at least much as the IP header would have us expect.
 2858          * Drop packet if shorter than we expect.
 2859          */
 2860         if (m->m_pkthdr.len < len) {
 2861                 ipstat.ips_tooshort++;
 2862                 goto bad;
 2863         }
 2864 
 2865         /* Checks out, proceed */
 2866         *mp = m;
 2867         return 0;
 2868 
 2869 bad:
 2870         *mp = m;
 2871         return -1;
 2872 }
 2873 
 2874 # ifdef INET6
 2875 /*
 2876  * Same as above, but for IPv6.
 2877  * Cut-and-pasted from ip6_input.c.
 2878  * XXX Should we update ip6stat, or not?
 2879  */
 2880 static int
 2881 bridge_ip6_checkbasic(struct mbuf **mp)
 2882 {
 2883         struct mbuf *m = *mp;
 2884         struct ip6_hdr *ip6;
 2885 
 2886         /*
 2887          * If the IPv6 header is not aligned, slurp it up into a new
 2888          * mbuf with space for link headers, in the event we forward
 2889          * it.  Otherwise, if it is aligned, make sure the entire base
 2890          * IPv6 header is in the first mbuf of the chain.
 2891          */
 2892         if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
 2893                 struct ifnet *inifp = m->m_pkthdr.rcvif;
 2894                 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
 2895                             (max_linkhdr + 3) & ~3)) == NULL) {
 2896                         /* XXXJRT new stat, please */
 2897                         ip6stat.ip6s_toosmall++;
 2898                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);
 2899                         goto bad;
 2900                 }
 2901         } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
 2902                 struct ifnet *inifp = m->m_pkthdr.rcvif;
 2903                 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
 2904                         ip6stat.ip6s_toosmall++;
 2905                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);
 2906                         goto bad;
 2907                 }
 2908         }
 2909 
 2910         ip6 = mtod(m, struct ip6_hdr *);
 2911 
 2912         if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
 2913                 ip6stat.ip6s_badvers++;
 2914                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
 2915                 goto bad;
 2916         }
 2917 
 2918         /* Checks out, proceed */
 2919         *mp = m;
 2920         return 0;
 2921 
 2922 bad:
 2923         *mp = m;
 2924         return -1;
 2925 }
 2926 # endif /* INET6 */

Cache object: c065d5a15e06c391a91654fce64fcd68


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.