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

Cache object: 545b4b30948418d65a8ab45c0de1c2ca


[ 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.