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.29.2.2 2006/02/12 16:49:50 tron 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 __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.29.2.2 2006/02/12 16:49:50 tron Exp $");
   84 
   85 #include "opt_bridge_ipf.h"
   86 #include "opt_inet.h"
   87 #include "opt_pfil_hooks.h"
   88 #include "bpfilter.h"
   89 #include "gif.h"
   90 
   91 #include <sys/param.h>
   92 #include <sys/kernel.h>
   93 #include <sys/mbuf.h>
   94 #include <sys/queue.h>
   95 #include <sys/socket.h>
   96 #include <sys/sockio.h>
   97 #include <sys/systm.h>
   98 #include <sys/proc.h>
   99 #include <sys/pool.h>
  100 
  101 #if NBPFILTER > 0
  102 #include <net/bpf.h>
  103 #endif
  104 #include <net/if.h>
  105 #include <net/if_dl.h>
  106 #include <net/if_types.h>
  107 #include <net/if_llc.h>
  108 
  109 #include <net/if_ether.h>
  110 #include <net/if_bridgevar.h>
  111 
  112 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
  113 /* Used for bridge_ip[6]_checkbasic */
  114 #include <netinet/in.h>
  115 #include <netinet/in_systm.h>
  116 #include <netinet/ip.h>
  117 #include <netinet/ip_var.h>
  118 
  119 #include <netinet/ip6.h>
  120 #include <netinet6/in6_var.h>
  121 #include <netinet6/ip6_var.h>
  122 #endif /* BRIDGE_IPF && PFIL_HOOKS */
  123 
  124 /*
  125  * Size of the route hash table.  Must be a power of two.
  126  */
  127 #ifndef BRIDGE_RTHASH_SIZE
  128 #define BRIDGE_RTHASH_SIZE              1024
  129 #endif
  130 
  131 #define BRIDGE_RTHASH_MASK              (BRIDGE_RTHASH_SIZE - 1)
  132 
  133 /*
  134  * Maximum number of addresses to cache.
  135  */
  136 #ifndef BRIDGE_RTABLE_MAX
  137 #define BRIDGE_RTABLE_MAX               100
  138 #endif
  139 
  140 /*
  141  * Spanning tree defaults.
  142  */
  143 #define BSTP_DEFAULT_MAX_AGE            (20 * 256)
  144 #define BSTP_DEFAULT_HELLO_TIME         (2 * 256)
  145 #define BSTP_DEFAULT_FORWARD_DELAY      (15 * 256)
  146 #define BSTP_DEFAULT_HOLD_TIME          (1 * 256)
  147 #define BSTP_DEFAULT_BRIDGE_PRIORITY    0x8000
  148 #define BSTP_DEFAULT_PORT_PRIORITY      0x80
  149 #define BSTP_DEFAULT_PATH_COST          55
  150 
  151 /*
  152  * Timeout (in seconds) for entries learned dynamically.
  153  */
  154 #ifndef BRIDGE_RTABLE_TIMEOUT
  155 #define BRIDGE_RTABLE_TIMEOUT           (20 * 60)       /* same as ARP */
  156 #endif
  157 
  158 /*
  159  * Number of seconds between walks of the route list.
  160  */
  161 #ifndef BRIDGE_RTABLE_PRUNE_PERIOD
  162 #define BRIDGE_RTABLE_PRUNE_PERIOD      (5 * 60)
  163 #endif
  164 
  165 int     bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
  166 
  167 struct pool bridge_rtnode_pool;
  168 
  169 void    bridgeattach(int);
  170 
  171 int     bridge_clone_create(struct if_clone *, int);
  172 int     bridge_clone_destroy(struct ifnet *);
  173 
  174 int     bridge_ioctl(struct ifnet *, u_long, caddr_t);
  175 int     bridge_init(struct ifnet *);
  176 void    bridge_stop(struct ifnet *, int);
  177 void    bridge_start(struct ifnet *);
  178 
  179 void    bridge_forward(struct bridge_softc *, struct mbuf *m);
  180 
  181 void    bridge_timer(void *);
  182 
  183 void    bridge_broadcast(struct bridge_softc *, struct ifnet *, struct mbuf *);
  184 
  185 int     bridge_rtupdate(struct bridge_softc *, const uint8_t *,
  186             struct ifnet *, int, uint8_t);
  187 struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
  188 void    bridge_rttrim(struct bridge_softc *);
  189 void    bridge_rtage(struct bridge_softc *);
  190 void    bridge_rtflush(struct bridge_softc *, int);
  191 int     bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
  192 void    bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp);
  193 
  194 int     bridge_rtable_init(struct bridge_softc *);
  195 void    bridge_rtable_fini(struct bridge_softc *);
  196 
  197 struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
  198             const uint8_t *);
  199 int     bridge_rtnode_insert(struct bridge_softc *, struct bridge_rtnode *);
  200 void    bridge_rtnode_destroy(struct bridge_softc *, struct bridge_rtnode *);
  201 
  202 struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
  203             const char *name);
  204 struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
  205             struct ifnet *ifp);
  206 void    bridge_delete_member(struct bridge_softc *, struct bridge_iflist *);
  207 
  208 int     bridge_ioctl_add(struct bridge_softc *, void *);
  209 int     bridge_ioctl_del(struct bridge_softc *, void *);
  210 int     bridge_ioctl_gifflags(struct bridge_softc *, void *);
  211 int     bridge_ioctl_sifflags(struct bridge_softc *, void *);
  212 int     bridge_ioctl_scache(struct bridge_softc *, void *);
  213 int     bridge_ioctl_gcache(struct bridge_softc *, void *);
  214 int     bridge_ioctl_gifs(struct bridge_softc *, void *);
  215 int     bridge_ioctl_rts(struct bridge_softc *, void *);
  216 int     bridge_ioctl_saddr(struct bridge_softc *, void *);
  217 int     bridge_ioctl_sto(struct bridge_softc *, void *);
  218 int     bridge_ioctl_gto(struct bridge_softc *, void *);
  219 int     bridge_ioctl_daddr(struct bridge_softc *, void *);
  220 int     bridge_ioctl_flush(struct bridge_softc *, void *);
  221 int     bridge_ioctl_gpri(struct bridge_softc *, void *);
  222 int     bridge_ioctl_spri(struct bridge_softc *, void *);
  223 int     bridge_ioctl_ght(struct bridge_softc *, void *);
  224 int     bridge_ioctl_sht(struct bridge_softc *, void *);
  225 int     bridge_ioctl_gfd(struct bridge_softc *, void *);
  226 int     bridge_ioctl_sfd(struct bridge_softc *, void *);
  227 int     bridge_ioctl_gma(struct bridge_softc *, void *);
  228 int     bridge_ioctl_sma(struct bridge_softc *, void *);
  229 int     bridge_ioctl_sifprio(struct bridge_softc *, void *);
  230 int     bridge_ioctl_sifcost(struct bridge_softc *, void *);
  231 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
  232 int     bridge_ioctl_gfilt(struct bridge_softc *, void *);
  233 int     bridge_ioctl_sfilt(struct bridge_softc *, void *);
  234 static int bridge_ipf(void *, struct mbuf **, struct ifnet *, int);
  235 static int bridge_ip_checkbasic(struct mbuf **mp);
  236 # ifdef INET6
  237 static int bridge_ip6_checkbasic(struct mbuf **mp);
  238 # endif /* INET6 */
  239 #endif /* BRIDGE_IPF && PFIL_HOOKS */
  240 
  241 struct bridge_control {
  242         int     (*bc_func)(struct bridge_softc *, void *);
  243         int     bc_argsize;
  244         int     bc_flags;
  245 };
  246 
  247 #define BC_F_COPYIN             0x01    /* copy arguments in */
  248 #define BC_F_COPYOUT            0x02    /* copy arguments out */
  249 #define BC_F_SUSER              0x04    /* do super-user check */
  250 
  251 const struct bridge_control bridge_control_table[] = {
  252         { bridge_ioctl_add,             sizeof(struct ifbreq),
  253           BC_F_COPYIN|BC_F_SUSER },
  254         { bridge_ioctl_del,             sizeof(struct ifbreq),
  255           BC_F_COPYIN|BC_F_SUSER },
  256 
  257         { bridge_ioctl_gifflags,        sizeof(struct ifbreq),
  258           BC_F_COPYIN|BC_F_COPYOUT },
  259         { bridge_ioctl_sifflags,        sizeof(struct ifbreq),
  260           BC_F_COPYIN|BC_F_SUSER },
  261 
  262         { bridge_ioctl_scache,          sizeof(struct ifbrparam),
  263           BC_F_COPYIN|BC_F_SUSER },
  264         { bridge_ioctl_gcache,          sizeof(struct ifbrparam),
  265           BC_F_COPYOUT },
  266 
  267         { bridge_ioctl_gifs,            sizeof(struct ifbifconf),
  268           BC_F_COPYIN|BC_F_COPYOUT },
  269         { bridge_ioctl_rts,             sizeof(struct ifbaconf),
  270           BC_F_COPYIN|BC_F_COPYOUT },
  271 
  272         { bridge_ioctl_saddr,           sizeof(struct ifbareq),
  273           BC_F_COPYIN|BC_F_SUSER },
  274 
  275         { bridge_ioctl_sto,             sizeof(struct ifbrparam),
  276           BC_F_COPYIN|BC_F_SUSER },
  277         { bridge_ioctl_gto,             sizeof(struct ifbrparam),
  278           BC_F_COPYOUT },
  279 
  280         { bridge_ioctl_daddr,           sizeof(struct ifbareq),
  281           BC_F_COPYIN|BC_F_SUSER },
  282 
  283         { bridge_ioctl_flush,           sizeof(struct ifbreq),
  284           BC_F_COPYIN|BC_F_SUSER },
  285 
  286         { bridge_ioctl_gpri,            sizeof(struct ifbrparam),
  287           BC_F_COPYOUT },
  288         { bridge_ioctl_spri,            sizeof(struct ifbrparam),
  289           BC_F_COPYIN|BC_F_SUSER },
  290 
  291         { bridge_ioctl_ght,             sizeof(struct ifbrparam),
  292           BC_F_COPYOUT },
  293         { bridge_ioctl_sht,             sizeof(struct ifbrparam),
  294           BC_F_COPYIN|BC_F_SUSER },
  295 
  296         { bridge_ioctl_gfd,             sizeof(struct ifbrparam),
  297           BC_F_COPYOUT },
  298         { bridge_ioctl_sfd,             sizeof(struct ifbrparam),
  299           BC_F_COPYIN|BC_F_SUSER },
  300 
  301         { bridge_ioctl_gma,             sizeof(struct ifbrparam),
  302           BC_F_COPYOUT },
  303         { bridge_ioctl_sma,             sizeof(struct ifbrparam),
  304           BC_F_COPYIN|BC_F_SUSER },
  305 
  306         { bridge_ioctl_sifprio,         sizeof(struct ifbreq),
  307           BC_F_COPYIN|BC_F_SUSER },
  308 
  309         { bridge_ioctl_sifcost,         sizeof(struct ifbreq),
  310           BC_F_COPYIN|BC_F_SUSER },
  311 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
  312         { bridge_ioctl_gfilt,           sizeof(struct ifbrparam),
  313           BC_F_COPYOUT },
  314         { bridge_ioctl_sfilt,           sizeof(struct ifbrparam),
  315           BC_F_COPYIN|BC_F_SUSER },
  316 #endif /* BRIDGE_IPF && PFIL_HOOKS */
  317 };
  318 const int bridge_control_table_size =
  319     sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
  320 
  321 LIST_HEAD(, bridge_softc) bridge_list;
  322 
  323 struct if_clone bridge_cloner =
  324     IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
  325 
  326 /*
  327  * bridgeattach:
  328  *
  329  *      Pseudo-device attach routine.
  330  */
  331 void
  332 bridgeattach(int n)
  333 {
  334 
  335         pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode),
  336             0, 0, 0, "brtpl", NULL);
  337 
  338         LIST_INIT(&bridge_list);
  339         if_clone_attach(&bridge_cloner);
  340 }
  341 
  342 /*
  343  * bridge_clone_create:
  344  *
  345  *      Create a new bridge instance.
  346  */
  347 int
  348 bridge_clone_create(struct if_clone *ifc, int unit)
  349 {
  350         struct bridge_softc *sc;
  351         struct ifnet *ifp;
  352         int s;
  353 
  354         sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK);
  355         memset(sc, 0, sizeof(*sc));
  356         ifp = &sc->sc_if;
  357 
  358         sc->sc_brtmax = BRIDGE_RTABLE_MAX;
  359         sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
  360         sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
  361         sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
  362         sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
  363         sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
  364         sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
  365         sc->sc_filter_flags = 0;
  366 
  367         /* Initialize our routing table. */
  368         bridge_rtable_init(sc);
  369 
  370         callout_init(&sc->sc_brcallout);
  371         callout_init(&sc->sc_bstpcallout);
  372 
  373         LIST_INIT(&sc->sc_iflist);
  374 
  375         snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d", ifc->ifc_name,
  376             unit);
  377         ifp->if_softc = sc;
  378         ifp->if_mtu = ETHERMTU;
  379         ifp->if_ioctl = bridge_ioctl;
  380         ifp->if_output = bridge_output;
  381         ifp->if_start = bridge_start;
  382         ifp->if_stop = bridge_stop;
  383         ifp->if_init = bridge_init;
  384         ifp->if_type = IFT_BRIDGE;
  385         ifp->if_addrlen = 0;
  386         ifp->if_dlt = DLT_EN10MB;
  387         ifp->if_hdrlen = ETHER_HDR_LEN;
  388 
  389         if_attach(ifp);
  390 
  391         if_alloc_sadl(ifp);
  392 
  393         s = splnet();
  394         LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
  395         splx(s);
  396 
  397         return (0);
  398 }
  399 
  400 /*
  401  * bridge_clone_destroy:
  402  *
  403  *      Destroy a bridge instance.
  404  */
  405 int
  406 bridge_clone_destroy(struct ifnet *ifp)
  407 {
  408         struct bridge_softc *sc = ifp->if_softc;
  409         struct bridge_iflist *bif;
  410         int s;
  411 
  412         s = splnet();
  413 
  414         bridge_stop(ifp, 1);
  415 
  416         while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
  417                 bridge_delete_member(sc, bif);
  418 
  419         LIST_REMOVE(sc, sc_list);
  420 
  421         splx(s);
  422 
  423         if_detach(ifp);
  424 
  425         /* Tear down the routing table. */
  426         bridge_rtable_fini(sc);
  427 
  428         free(sc, M_DEVBUF);
  429 
  430         return (0);
  431 }
  432 
  433 /*
  434  * bridge_ioctl:
  435  *
  436  *      Handle a control request from the operator.
  437  */
  438 int
  439 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  440 {
  441         struct bridge_softc *sc = ifp->if_softc;
  442         struct proc *p = curproc;       /* XXX */
  443         union {
  444                 struct ifbreq ifbreq;
  445                 struct ifbifconf ifbifconf;
  446                 struct ifbareq ifbareq;
  447                 struct ifbaconf ifbaconf;
  448                 struct ifbrparam ifbrparam;
  449         } args;
  450         struct ifdrv *ifd = (struct ifdrv *) data;
  451         const struct bridge_control *bc;
  452         int s, error = 0;
  453 
  454         s = splnet();
  455 
  456         switch (cmd) {
  457         case SIOCGDRVSPEC:
  458         case SIOCSDRVSPEC:
  459                 if (ifd->ifd_cmd >= bridge_control_table_size) {
  460                         error = EINVAL;
  461                         break;
  462                 }
  463                 bc = &bridge_control_table[ifd->ifd_cmd];
  464 
  465                 if (cmd == SIOCGDRVSPEC &&
  466                     (bc->bc_flags & BC_F_COPYOUT) == 0) {
  467                         error = EINVAL;
  468                         break;
  469                 }
  470                 else if (cmd == SIOCSDRVSPEC &&
  471                     (bc->bc_flags & BC_F_COPYOUT) != 0) {
  472                         error = EINVAL;
  473                         break;
  474                 }
  475 
  476                 if (bc->bc_flags & BC_F_SUSER) {
  477                         error = suser(p->p_ucred, &p->p_acflag);
  478                         if (error)
  479                                 break;
  480                 }
  481 
  482                 if (ifd->ifd_len != bc->bc_argsize ||
  483                     ifd->ifd_len > sizeof(args)) {
  484                         error = EINVAL;
  485                         break;
  486                 }
  487 
  488                 memset(&args, 0, sizeof(args));
  489                 if (bc->bc_flags & BC_F_COPYIN) {
  490                         error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
  491                         if (error)
  492                                 break;
  493                 }
  494 
  495                 error = (*bc->bc_func)(sc, &args);
  496                 if (error)
  497                         break;
  498 
  499                 if (bc->bc_flags & BC_F_COPYOUT)
  500                         error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
  501 
  502                 break;
  503 
  504         case SIOCSIFFLAGS:
  505                 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) {
  506                         /*
  507                          * If interface is marked down and it is running,
  508                          * then stop and disable it.
  509                          */
  510                         (*ifp->if_stop)(ifp, 1);
  511                 } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) {
  512                         /*
  513                          * If interface is marked up and it is stopped, then
  514                          * start it.
  515                          */
  516                         error = (*ifp->if_init)(ifp);
  517                 }
  518                 break;
  519 
  520         default:
  521                 error = ENOTTY;
  522                 break;
  523         }
  524 
  525         splx(s);
  526 
  527         return (error);
  528 }
  529 
  530 /*
  531  * bridge_lookup_member:
  532  *
  533  *      Lookup a bridge member interface.  Must be called at splnet().
  534  */
  535 struct bridge_iflist *
  536 bridge_lookup_member(struct bridge_softc *sc, const char *name)
  537 {
  538         struct bridge_iflist *bif;
  539         struct ifnet *ifp;
  540 
  541         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
  542                 ifp = bif->bif_ifp;
  543                 if (strcmp(ifp->if_xname, name) == 0)
  544                         return (bif);
  545         }
  546 
  547         return (NULL);
  548 }
  549 
  550 /*
  551  * bridge_lookup_member_if:
  552  *
  553  *      Lookup a bridge member interface by ifnet*.  Must be called at splnet().
  554  */
  555 struct bridge_iflist *
  556 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
  557 {
  558         struct bridge_iflist *bif;
  559 
  560         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
  561                 if (bif->bif_ifp == member_ifp)
  562                         return (bif);
  563         }
  564 
  565         return (NULL);
  566 }
  567 
  568 /*
  569  * bridge_delete_member:
  570  *
  571  *      Delete the specified member interface.
  572  */
  573 void
  574 bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
  575 {
  576         struct ifnet *ifs = bif->bif_ifp;
  577 
  578         switch (ifs->if_type) {
  579         case IFT_ETHER:
  580                 /*
  581                  * Take the interface out of promiscuous mode.
  582                  */
  583                 (void) ifpromisc(ifs, 0);
  584                 break;
  585 #if NGIF > 0
  586         case IFT_GIF:
  587                 break;
  588 #endif
  589         default:
  590 #ifdef DIAGNOSTIC
  591                 panic("bridge_delete_member: impossible");
  592 #endif
  593                 break;
  594         }
  595 
  596         ifs->if_bridge = NULL;
  597         LIST_REMOVE(bif, bif_next);
  598 
  599         bridge_rtdelete(sc, ifs);
  600 
  601         free(bif, M_DEVBUF);
  602 
  603         if (sc->sc_if.if_flags & IFF_RUNNING)
  604                 bstp_initialization(sc);
  605 }
  606 
  607 int
  608 bridge_ioctl_add(struct bridge_softc *sc, void *arg)
  609 {
  610         struct ifbreq *req = arg;
  611         struct bridge_iflist *bif = NULL;
  612         struct ifnet *ifs;
  613         int error = 0;
  614 
  615         ifs = ifunit(req->ifbr_ifsname);
  616         if (ifs == NULL)
  617                 return (ENOENT);
  618 
  619         if (sc->sc_if.if_mtu != ifs->if_mtu)
  620                 return (EINVAL);
  621 
  622         if (ifs->if_bridge == sc)
  623                 return (EEXIST);
  624 
  625         if (ifs->if_bridge != NULL)
  626                 return (EBUSY);
  627 
  628         bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT);
  629         if (bif == NULL)
  630                 return (ENOMEM);
  631 
  632         switch (ifs->if_type) {
  633         case IFT_ETHER:
  634                 /*
  635                  * Place the interface into promiscuous mode.
  636                  */
  637                 error = ifpromisc(ifs, 1);
  638                 if (error)
  639                         goto out;
  640                 break;
  641 #if NGIF > 0
  642         case IFT_GIF:
  643                 break;
  644 #endif
  645         default:
  646                 error = EINVAL;
  647                 goto out;
  648         }
  649 
  650         bif->bif_ifp = ifs;
  651         bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
  652         bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
  653         bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
  654 
  655         ifs->if_bridge = sc;
  656         LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
  657 
  658         if (sc->sc_if.if_flags & IFF_RUNNING)
  659                 bstp_initialization(sc);
  660         else
  661                 bstp_stop(sc);
  662 
  663  out:
  664         if (error) {
  665                 if (bif != NULL)
  666                         free(bif, M_DEVBUF);
  667         }
  668         return (error);
  669 }
  670 
  671 int
  672 bridge_ioctl_del(struct bridge_softc *sc, void *arg)
  673 {
  674         struct ifbreq *req = arg;
  675         struct bridge_iflist *bif;
  676 
  677         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
  678         if (bif == NULL)
  679                 return (ENOENT);
  680 
  681         bridge_delete_member(sc, bif);
  682 
  683         return (0);
  684 }
  685 
  686 int
  687 bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
  688 {
  689         struct ifbreq *req = arg;
  690         struct bridge_iflist *bif;
  691 
  692         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
  693         if (bif == NULL)
  694                 return (ENOENT);
  695 
  696         req->ifbr_ifsflags = bif->bif_flags;
  697         req->ifbr_state = bif->bif_state;
  698         req->ifbr_priority = bif->bif_priority;
  699         req->ifbr_path_cost = bif->bif_path_cost;
  700         req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
  701 
  702         return (0);
  703 }
  704 
  705 int
  706 bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
  707 {
  708         struct ifbreq *req = arg;
  709         struct bridge_iflist *bif;
  710 
  711         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
  712         if (bif == NULL)
  713                 return (ENOENT);
  714 
  715         if (req->ifbr_ifsflags & IFBIF_STP) {
  716                 switch (bif->bif_ifp->if_type) {
  717                 case IFT_ETHER:
  718                         /* These can do spanning tree. */
  719                         break;
  720 
  721                 default:
  722                         /* Nothing else can. */
  723                         return (EINVAL);
  724                 }
  725         }
  726 
  727         bif->bif_flags = req->ifbr_ifsflags;
  728 
  729         if (sc->sc_if.if_flags & IFF_RUNNING)
  730                 bstp_initialization(sc);
  731 
  732         return (0);
  733 }
  734 
  735 int
  736 bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
  737 {
  738         struct ifbrparam *param = arg;
  739 
  740         sc->sc_brtmax = param->ifbrp_csize;
  741         bridge_rttrim(sc);
  742 
  743         return (0);
  744 }
  745 
  746 int
  747 bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
  748 {
  749         struct ifbrparam *param = arg;
  750 
  751         param->ifbrp_csize = sc->sc_brtmax;
  752 
  753         return (0);
  754 }
  755 
  756 int
  757 bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
  758 {
  759         struct ifbifconf *bifc = arg;
  760         struct bridge_iflist *bif;
  761         struct ifbreq breq;
  762         int count, len, error = 0;
  763 
  764         count = 0;
  765         LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
  766                 count++;
  767 
  768         if (bifc->ifbic_len == 0) {
  769                 bifc->ifbic_len = sizeof(breq) * count;
  770                 return (0);
  771         }
  772 
  773         count = 0;
  774         len = bifc->ifbic_len;
  775         memset(&breq, 0, sizeof breq);
  776         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
  777                 if (len < sizeof(breq))
  778                         break;
  779 
  780                 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
  781                     sizeof(breq.ifbr_ifsname));
  782                 breq.ifbr_ifsflags = bif->bif_flags;
  783                 breq.ifbr_state = bif->bif_state;
  784                 breq.ifbr_priority = bif->bif_priority;
  785                 breq.ifbr_path_cost = bif->bif_path_cost;
  786                 breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
  787                 error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
  788                 if (error)
  789                         break;
  790                 count++;
  791                 len -= sizeof(breq);
  792         }
  793 
  794         bifc->ifbic_len = sizeof(breq) * count;
  795         return (error);
  796 }
  797 
  798 int
  799 bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
  800 {
  801         struct ifbaconf *bac = arg;
  802         struct bridge_rtnode *brt;
  803         struct ifbareq bareq;
  804         int count = 0, error = 0, len;
  805 
  806         if (bac->ifbac_len == 0)
  807                 return (0);
  808 
  809         len = bac->ifbac_len;
  810         LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
  811                 if (len < sizeof(bareq))
  812                         goto out;
  813                 memset(&bareq, 0, sizeof(bareq));
  814                 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
  815                     sizeof(bareq.ifba_ifsname));
  816                 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
  817                 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
  818                         bareq.ifba_expire = brt->brt_expire - mono_time.tv_sec;
  819                 else
  820                         bareq.ifba_expire = 0;
  821                 bareq.ifba_flags = brt->brt_flags;
  822 
  823                 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq));
  824                 if (error)
  825                         goto out;
  826                 count++;
  827                 len -= sizeof(bareq);
  828         }
  829  out:
  830         bac->ifbac_len = sizeof(bareq) * count;
  831         return (error);
  832 }
  833 
  834 int
  835 bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
  836 {
  837         struct ifbareq *req = arg;
  838         struct bridge_iflist *bif;
  839         int error;
  840 
  841         bif = bridge_lookup_member(sc, req->ifba_ifsname);
  842         if (bif == NULL)
  843                 return (ENOENT);
  844 
  845         error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1,
  846             req->ifba_flags);
  847 
  848         return (error);
  849 }
  850 
  851 int
  852 bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
  853 {
  854         struct ifbrparam *param = arg;
  855 
  856         sc->sc_brttimeout = param->ifbrp_ctime;
  857 
  858         return (0);
  859 }
  860 
  861 int
  862 bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
  863 {
  864         struct ifbrparam *param = arg;
  865 
  866         param->ifbrp_ctime = sc->sc_brttimeout;
  867 
  868         return (0);
  869 }
  870 
  871 int
  872 bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
  873 {
  874         struct ifbareq *req = arg;
  875 
  876         return (bridge_rtdaddr(sc, req->ifba_dst));
  877 }
  878 
  879 int
  880 bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
  881 {
  882         struct ifbreq *req = arg;
  883 
  884         bridge_rtflush(sc, req->ifbr_ifsflags);
  885 
  886         return (0);
  887 }
  888 
  889 int
  890 bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
  891 {
  892         struct ifbrparam *param = arg;
  893 
  894         param->ifbrp_prio = sc->sc_bridge_priority;
  895 
  896         return (0);
  897 }
  898 
  899 int
  900 bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
  901 {
  902         struct ifbrparam *param = arg;
  903 
  904         sc->sc_bridge_priority = param->ifbrp_prio;
  905 
  906         if (sc->sc_if.if_flags & IFF_RUNNING)
  907                 bstp_initialization(sc);
  908 
  909         return (0);
  910 }
  911 
  912 int
  913 bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
  914 {
  915         struct ifbrparam *param = arg;
  916 
  917         param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
  918 
  919         return (0);
  920 }
  921 
  922 int
  923 bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
  924 {
  925         struct ifbrparam *param = arg;
  926 
  927         if (param->ifbrp_hellotime == 0)
  928                 return (EINVAL);
  929         sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
  930 
  931         if (sc->sc_if.if_flags & IFF_RUNNING)
  932                 bstp_initialization(sc);
  933 
  934         return (0);
  935 }
  936 
  937 int
  938 bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
  939 {
  940         struct ifbrparam *param = arg;
  941 
  942         param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
  943 
  944         return (0);
  945 }
  946 
  947 int
  948 bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
  949 {
  950         struct ifbrparam *param = arg;
  951 
  952         if (param->ifbrp_fwddelay == 0)
  953                 return (EINVAL);
  954         sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
  955 
  956         if (sc->sc_if.if_flags & IFF_RUNNING)
  957                 bstp_initialization(sc);
  958 
  959         return (0);
  960 }
  961 
  962 int
  963 bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
  964 {
  965         struct ifbrparam *param = arg;
  966 
  967         param->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
  968 
  969         return (0);
  970 }
  971 
  972 int
  973 bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
  974 {
  975         struct ifbrparam *param = arg;
  976 
  977         if (param->ifbrp_maxage == 0)
  978                 return (EINVAL);
  979         sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
  980 
  981         if (sc->sc_if.if_flags & IFF_RUNNING)
  982                 bstp_initialization(sc);
  983 
  984         return (0);
  985 }
  986 
  987 int
  988 bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
  989 {
  990         struct ifbreq *req = arg;
  991         struct bridge_iflist *bif;
  992 
  993         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
  994         if (bif == NULL)
  995                 return (ENOENT);
  996 
  997         bif->bif_priority = req->ifbr_priority;
  998 
  999         if (sc->sc_if.if_flags & IFF_RUNNING)
 1000                 bstp_initialization(sc);
 1001 
 1002         return (0);
 1003 }
 1004 
 1005 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
 1006 int
 1007 bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg)
 1008 {
 1009         struct ifbrparam *param = arg;
 1010 
 1011         param->ifbrp_filter = sc->sc_filter_flags;
 1012 
 1013         return (0);
 1014 }
 1015 
 1016 int
 1017 bridge_ioctl_sfilt(struct bridge_softc *sc, void *arg)
 1018 {
 1019         struct ifbrparam *param = arg;
 1020         uint32_t nflags, oflags;
 1021 
 1022         if (param->ifbrp_filter & ~IFBF_FILT_MASK)
 1023                 return (EINVAL);
 1024 
 1025         nflags = param->ifbrp_filter;
 1026         oflags = sc->sc_filter_flags;
 1027 
 1028         if ((nflags & IFBF_FILT_USEIPF) && !(oflags & IFBF_FILT_USEIPF)) {
 1029                 pfil_add_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
 1030                         &sc->sc_if.if_pfil);
 1031         }
 1032         if (!(nflags & IFBF_FILT_USEIPF) && (oflags & IFBF_FILT_USEIPF)) {
 1033                 pfil_remove_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
 1034                         &sc->sc_if.if_pfil);
 1035         }
 1036 
 1037         sc->sc_filter_flags = nflags;
 1038 
 1039         return (0);
 1040 }
 1041 #endif /* BRIDGE_IPF && PFIL_HOOKS */
 1042 
 1043 int
 1044 bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
 1045 {
 1046         struct ifbreq *req = arg;
 1047         struct bridge_iflist *bif;
 1048 
 1049         bif = bridge_lookup_member(sc, req->ifbr_ifsname);
 1050         if (bif == NULL)
 1051                 return (ENOENT);
 1052 
 1053         bif->bif_path_cost = req->ifbr_path_cost;
 1054 
 1055         if (sc->sc_if.if_flags & IFF_RUNNING)
 1056                 bstp_initialization(sc);
 1057 
 1058         return (0);
 1059 }
 1060 
 1061 /*
 1062  * bridge_ifdetach:
 1063  *
 1064  *      Detach an interface from a bridge.  Called when a member
 1065  *      interface is detaching.
 1066  */
 1067 void
 1068 bridge_ifdetach(struct ifnet *ifp)
 1069 {
 1070         struct bridge_softc *sc = ifp->if_bridge;
 1071         struct ifbreq breq;
 1072 
 1073         memset(&breq, 0, sizeof(breq));
 1074         snprintf(breq.ifbr_ifsname, sizeof(breq.ifbr_ifsname), ifp->if_xname);
 1075 
 1076         (void) bridge_ioctl_del(sc, &breq);
 1077 }
 1078 
 1079 /*
 1080  * bridge_init:
 1081  *
 1082  *      Initialize a bridge interface.
 1083  */
 1084 int
 1085 bridge_init(struct ifnet *ifp)
 1086 {
 1087         struct bridge_softc *sc = ifp->if_softc;
 1088 
 1089         if (ifp->if_flags & IFF_RUNNING)
 1090                 return (0);
 1091 
 1092         callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
 1093             bridge_timer, sc);
 1094 
 1095         ifp->if_flags |= IFF_RUNNING;
 1096         bstp_initialization(sc);
 1097         return (0);
 1098 }
 1099 
 1100 /*
 1101  * bridge_stop:
 1102  *
 1103  *      Stop the bridge interface.
 1104  */
 1105 void
 1106 bridge_stop(struct ifnet *ifp, int disable)
 1107 {
 1108         struct bridge_softc *sc = ifp->if_softc;
 1109 
 1110         if ((ifp->if_flags & IFF_RUNNING) == 0)
 1111                 return;
 1112 
 1113         callout_stop(&sc->sc_brcallout);
 1114         bstp_stop(sc);
 1115 
 1116         IF_PURGE(&ifp->if_snd);
 1117 
 1118         bridge_rtflush(sc, IFBF_FLUSHDYN);
 1119 
 1120         ifp->if_flags &= ~IFF_RUNNING;
 1121 }
 1122 
 1123 /*
 1124  * bridge_enqueue:
 1125  *
 1126  *      Enqueue a packet on a bridge member interface.
 1127  *
 1128  *      NOTE: must be called at splnet().
 1129  */
 1130 __inline void
 1131 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m,
 1132     int runfilt)
 1133 {
 1134         ALTQ_DECL(struct altq_pktattr pktattr;)
 1135         int len, error;
 1136         short mflags;
 1137 
 1138         /*
 1139          * Clear any in-bound checksum flags for this packet.
 1140          */
 1141         m->m_pkthdr.csum_flags = 0;
 1142 
 1143 #ifdef PFIL_HOOKS
 1144         if (runfilt) {
 1145                 if (pfil_run_hooks(&sc->sc_if.if_pfil, &m,
 1146                     dst_ifp, PFIL_OUT) != 0) {
 1147                         if (m != NULL)
 1148                                 m_freem(m);
 1149                         return;
 1150                 }
 1151                 if (m == NULL)
 1152                         return;
 1153         }
 1154 #endif /* PFIL_HOOKS */
 1155 
 1156 #ifdef ALTQ
 1157         /*
 1158          * If ALTQ is enabled on the member interface, do
 1159          * classification; the queueing discipline might
 1160          * not require classification, but might require
 1161          * the address family/header pointer in the pktattr.
 1162          */
 1163         if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) {
 1164                 /* XXX IFT_ETHER */
 1165                 altq_etherclassify(&dst_ifp->if_snd, m, &pktattr);
 1166         }
 1167 #endif /* ALTQ */
 1168 
 1169         len = m->m_pkthdr.len;
 1170         m->m_flags |= M_PROTO1;
 1171         mflags = m->m_flags;
 1172         IFQ_ENQUEUE(&dst_ifp->if_snd, m, &pktattr, error);
 1173         if (error) {
 1174                 /* mbuf is already freed */
 1175                 sc->sc_if.if_oerrors++;
 1176                 return;
 1177         }
 1178 
 1179         sc->sc_if.if_opackets++;
 1180         sc->sc_if.if_obytes += len;
 1181 
 1182         dst_ifp->if_obytes += len;
 1183 
 1184         if (mflags & M_MCAST) {
 1185                 sc->sc_if.if_omcasts++;
 1186                 dst_ifp->if_omcasts++;
 1187         }
 1188 
 1189         if ((dst_ifp->if_flags & IFF_OACTIVE) == 0)
 1190                 (*dst_ifp->if_start)(dst_ifp);
 1191 }
 1192 
 1193 /*
 1194  * bridge_output:
 1195  *
 1196  *      Send output from a bridge member interface.  This
 1197  *      performs the bridging function for locally originated
 1198  *      packets.
 1199  *
 1200  *      The mbuf has the Ethernet header already attached.  We must
 1201  *      enqueue or free the mbuf before returning.
 1202  */
 1203 int
 1204 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
 1205     struct rtentry *rt)
 1206 {
 1207         struct ether_header *eh;
 1208         struct ifnet *dst_if;
 1209         struct bridge_softc *sc;
 1210         int s;
 1211 
 1212         if (m->m_len < ETHER_HDR_LEN) {
 1213                 m = m_pullup(m, ETHER_HDR_LEN);
 1214                 if (m == NULL)
 1215                         return (0);
 1216         }
 1217 
 1218         eh = mtod(m, struct ether_header *);
 1219         sc = ifp->if_bridge;
 1220 
 1221         s = splnet();
 1222 
 1223         /*
 1224          * If bridge is down, but the original output interface is up,
 1225          * go ahead and send out that interface.  Otherwise, the packet
 1226          * is dropped below.
 1227          */
 1228         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
 1229                 dst_if = ifp;
 1230                 goto sendunicast;
 1231         }
 1232 
 1233         /*
 1234          * If the packet is a multicast, or we don't know a better way to
 1235          * get there, send to all interfaces.
 1236          */
 1237         if (ETHER_IS_MULTICAST(eh->ether_dhost))
 1238                 dst_if = NULL;
 1239         else
 1240                 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
 1241         if (dst_if == NULL) {
 1242                 struct bridge_iflist *bif;
 1243                 struct mbuf *mc;
 1244                 int used = 0;
 1245 
 1246                 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 1247                         dst_if = bif->bif_ifp;
 1248                         if ((dst_if->if_flags & IFF_RUNNING) == 0)
 1249                                 continue;
 1250 
 1251                         /*
 1252                          * If this is not the original output interface,
 1253                          * and the interface is participating in spanning
 1254                          * tree, make sure the port is in a state that
 1255                          * allows forwarding.
 1256                          */
 1257                         if (dst_if != ifp &&
 1258                             (bif->bif_flags & IFBIF_STP) != 0) {
 1259                                 switch (bif->bif_state) {
 1260                                 case BSTP_IFSTATE_BLOCKING:
 1261                                 case BSTP_IFSTATE_LISTENING:
 1262                                 case BSTP_IFSTATE_DISABLED:
 1263                                         continue;
 1264                                 }
 1265                         }
 1266 
 1267                         if (LIST_NEXT(bif, bif_next) == NULL) {
 1268                                 used = 1;
 1269                                 mc = m;
 1270                         } else {
 1271                                 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 1272                                 if (mc == NULL) {
 1273                                         sc->sc_if.if_oerrors++;
 1274                                         continue;
 1275                                 }
 1276                         }
 1277 
 1278                         bridge_enqueue(sc, dst_if, mc, 0);
 1279                 }
 1280                 if (used == 0)
 1281                         m_freem(m);
 1282                 splx(s);
 1283                 return (0);
 1284         }
 1285 
 1286  sendunicast:
 1287         /*
 1288          * XXX Spanning tree consideration here?
 1289          */
 1290 
 1291         if ((dst_if->if_flags & IFF_RUNNING) == 0) {
 1292                 m_freem(m);
 1293                 splx(s);
 1294                 return (0);
 1295         }
 1296 
 1297         bridge_enqueue(sc, dst_if, m, 0);
 1298 
 1299         splx(s);
 1300         return (0);
 1301 }
 1302 
 1303 /*
 1304  * bridge_start:
 1305  *
 1306  *      Start output on a bridge.
 1307  *
 1308  *      NOTE: This routine should never be called in this implementation.
 1309  */
 1310 void
 1311 bridge_start(struct ifnet *ifp)
 1312 {
 1313 
 1314         printf("%s: bridge_start() called\n", ifp->if_xname);
 1315 }
 1316 
 1317 /*
 1318  * bridge_forward:
 1319  *
 1320  *      The forwarding function of the bridge.
 1321  */
 1322 void
 1323 bridge_forward(struct bridge_softc *sc, struct mbuf *m)
 1324 {
 1325         struct bridge_iflist *bif;
 1326         struct ifnet *src_if, *dst_if;
 1327         struct ether_header *eh;
 1328 
 1329         src_if = m->m_pkthdr.rcvif;
 1330 
 1331         sc->sc_if.if_ipackets++;
 1332         sc->sc_if.if_ibytes += m->m_pkthdr.len;
 1333 
 1334         /*
 1335          * Look up the bridge_iflist.
 1336          */
 1337         bif = bridge_lookup_member_if(sc, src_if);
 1338         if (bif == NULL) {
 1339                 /* Interface is not a bridge member (anymore?) */
 1340                 m_freem(m);
 1341                 return;
 1342         }
 1343 
 1344         if (bif->bif_flags & IFBIF_STP) {
 1345                 switch (bif->bif_state) {
 1346                 case BSTP_IFSTATE_BLOCKING:
 1347                 case BSTP_IFSTATE_LISTENING:
 1348                 case BSTP_IFSTATE_DISABLED:
 1349                         m_freem(m);
 1350                         return;
 1351                 }
 1352         }
 1353 
 1354         eh = mtod(m, struct ether_header *);
 1355 
 1356         /*
 1357          * If the interface is learning, and the source
 1358          * address is valid and not multicast, record
 1359          * the address.
 1360          */
 1361         if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
 1362             ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
 1363             (eh->ether_shost[0] == 0 &&
 1364              eh->ether_shost[1] == 0 &&
 1365              eh->ether_shost[2] == 0 &&
 1366              eh->ether_shost[3] == 0 &&
 1367              eh->ether_shost[4] == 0 &&
 1368              eh->ether_shost[5] == 0) == 0) {
 1369                 (void) bridge_rtupdate(sc, eh->ether_shost,
 1370                     src_if, 0, IFBAF_DYNAMIC);
 1371         }
 1372 
 1373         if ((bif->bif_flags & IFBIF_STP) != 0 &&
 1374             bif->bif_state == BSTP_IFSTATE_LEARNING) {
 1375                 m_freem(m);
 1376                 return;
 1377         }
 1378 
 1379         /*
 1380          * At this point, the port either doesn't participate
 1381          * in spanning tree or it is in the forwarding state.
 1382          */
 1383 
 1384         /*
 1385          * If the packet is unicast, destined for someone on
 1386          * "this" side of the bridge, drop it.
 1387          */
 1388         if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
 1389                 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
 1390                 if (src_if == dst_if) {
 1391                         m_freem(m);
 1392                         return;
 1393                 }
 1394         } else {
 1395                 /* ...forward it to all interfaces. */
 1396                 sc->sc_if.if_imcasts++;
 1397                 dst_if = NULL;
 1398         }
 1399 
 1400 #ifdef PFIL_HOOKS
 1401         if (pfil_run_hooks(&sc->sc_if.if_pfil, &m,
 1402             m->m_pkthdr.rcvif, PFIL_IN) != 0) {
 1403                 if (m != NULL)
 1404                         m_freem(m);
 1405                 return;
 1406         }
 1407         if (m == NULL)
 1408                 return;
 1409 #endif /* PFIL_HOOKS */
 1410 
 1411         if (dst_if == NULL) {
 1412                 bridge_broadcast(sc, src_if, m);
 1413                 return;
 1414         }
 1415 
 1416         /*
 1417          * At this point, we're dealing with a unicast frame
 1418          * going to a different interface.
 1419          */
 1420         if ((dst_if->if_flags & IFF_RUNNING) == 0) {
 1421                 m_freem(m);
 1422                 return;
 1423         }
 1424         bif = bridge_lookup_member_if(sc, dst_if);
 1425         if (bif == NULL) {
 1426                 /* Not a member of the bridge (anymore?) */
 1427                 m_freem(m);
 1428                 return;
 1429         }
 1430 
 1431         if (bif->bif_flags & IFBIF_STP) {
 1432                 switch (bif->bif_state) {
 1433                 case BSTP_IFSTATE_DISABLED:
 1434                 case BSTP_IFSTATE_BLOCKING:
 1435                         m_freem(m);
 1436                         return;
 1437                 }
 1438         }
 1439 
 1440         bridge_enqueue(sc, dst_if, m, 1);
 1441 }
 1442 
 1443 /*
 1444  * bridge_input:
 1445  *
 1446  *      Receive input from a member interface.  Queue the packet for
 1447  *      bridging if it is not for us.
 1448  */
 1449 struct mbuf *
 1450 bridge_input(struct ifnet *ifp, struct mbuf *m)
 1451 {
 1452         struct bridge_softc *sc = ifp->if_bridge;
 1453         struct bridge_iflist *bif;
 1454         struct ether_header *eh;
 1455         struct mbuf *mc;
 1456 
 1457         if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
 1458                 return (m);
 1459 
 1460         bif = bridge_lookup_member_if(sc, ifp);
 1461         if (bif == NULL)
 1462                 return (m);
 1463 
 1464         eh = mtod(m, struct ether_header *);
 1465 
 1466         if (m->m_flags & (M_BCAST|M_MCAST)) {
 1467                 /* Tap off 802.1D packets; they do not get forwarded. */
 1468                 if (memcmp(eh->ether_dhost, bstp_etheraddr,
 1469                     ETHER_ADDR_LEN) == 0) {
 1470                         m = bstp_input(ifp, m);
 1471                         if (m == NULL)
 1472                                 return (NULL);
 1473                 }
 1474 
 1475                 if (bif->bif_flags & IFBIF_STP) {
 1476                         switch (bif->bif_state) {
 1477                         case BSTP_IFSTATE_BLOCKING:
 1478                         case BSTP_IFSTATE_LISTENING:
 1479                         case BSTP_IFSTATE_DISABLED:
 1480                                 return (m);
 1481                         }
 1482                 }
 1483 
 1484                 /*
 1485                  * Make a deep copy of the packet and enqueue the copy
 1486                  * for bridge processing; return the original packet for
 1487                  * local processing.
 1488                  */
 1489                 mc = m_dup(m, 0, M_COPYALL, M_NOWAIT);
 1490                 if (mc == NULL)
 1491                         return (m);
 1492 
 1493                 /* Perform the bridge forwarding function with the copy. */
 1494 #if NGIF > 0
 1495                 if (ifp->if_type == IFT_GIF) {
 1496                         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 1497                                 if (bif->bif_ifp->if_type == IFT_ETHER)
 1498                                 break;
 1499                         }
 1500                         if (bif != NULL) {
 1501                                 m->m_flags |= M_PROTO1;
 1502                                 m->m_pkthdr.rcvif = bif->bif_ifp;
 1503                                 (*bif->bif_ifp->if_input)(bif->bif_ifp, m);
 1504                                 m = NULL;
 1505                         }
 1506                 }
 1507 #endif
 1508                 bridge_forward(sc, mc);
 1509 
 1510                 /* Return the original packet for local processing. */
 1511                 return (m);
 1512         }
 1513 
 1514         if (bif->bif_flags & IFBIF_STP) {
 1515                 switch (bif->bif_state) {
 1516                 case BSTP_IFSTATE_BLOCKING:
 1517                 case BSTP_IFSTATE_LISTENING:
 1518                 case BSTP_IFSTATE_DISABLED:
 1519                         return (m);
 1520                 }
 1521         }
 1522 
 1523         /*
 1524          * Unicast.  Make sure it's not for us.
 1525          */
 1526         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 1527                 if(bif->bif_ifp->if_type != IFT_ETHER)
 1528                         continue;
 1529                 /* It is destined for us. */
 1530                 if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_dhost,
 1531                     ETHER_ADDR_LEN) == 0) {
 1532                         if (bif->bif_flags & IFBIF_LEARNING)
 1533                                 (void) bridge_rtupdate(sc,
 1534                                     eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
 1535                         m->m_pkthdr.rcvif = bif->bif_ifp;
 1536 #if NGIF > 0
 1537                         if (ifp->if_type == IFT_GIF) {
 1538                                 m->m_flags |= M_PROTO1;
 1539                                 m->m_pkthdr.rcvif = bif->bif_ifp;
 1540                                 (*bif->bif_ifp->if_input)(bif->bif_ifp, m);
 1541                                 m = NULL;
 1542                         }
 1543 #endif
 1544                         return (m);
 1545                 }
 1546 
 1547                 /* We just received a packet that we sent out. */
 1548                 if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_shost,
 1549                     ETHER_ADDR_LEN) == 0) {
 1550                         m_freem(m);
 1551                         return (NULL);
 1552                 }
 1553         }
 1554 
 1555         /* Perform the bridge forwarding function. */
 1556         bridge_forward(sc, m);
 1557 
 1558         return (NULL);
 1559 }
 1560 
 1561 /*
 1562  * bridge_broadcast:
 1563  *
 1564  *      Send a frame to all interfaces that are members of
 1565  *      the bridge, except for the one on which the packet
 1566  *      arrived.
 1567  */
 1568 void
 1569 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
 1570     struct mbuf *m)
 1571 {
 1572         struct bridge_iflist *bif;
 1573         struct mbuf *mc;
 1574         struct ifnet *dst_if;
 1575         int used = 0;
 1576 
 1577         LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
 1578                 dst_if = bif->bif_ifp;
 1579                 if (dst_if == src_if)
 1580                         continue;
 1581 
 1582                 if (bif->bif_flags & IFBIF_STP) {
 1583                         switch (bif->bif_state) {
 1584                         case BSTP_IFSTATE_BLOCKING:
 1585                         case BSTP_IFSTATE_DISABLED:
 1586                                 continue;
 1587                         }
 1588                 }
 1589 
 1590                 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
 1591                     (m->m_flags & (M_BCAST|M_MCAST)) == 0)
 1592                         continue;
 1593 
 1594                 if ((dst_if->if_flags & IFF_RUNNING) == 0)
 1595                         continue;
 1596 
 1597                 if (LIST_NEXT(bif, bif_next) == NULL) {
 1598                         mc = m;
 1599                         used = 1;
 1600                 } else {
 1601                         mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
 1602                         if (mc == NULL) {
 1603                                 sc->sc_if.if_oerrors++;
 1604                                 continue;
 1605                         }
 1606                 }
 1607 
 1608                 bridge_enqueue(sc, dst_if, mc, 1);
 1609         }
 1610         if (used == 0)
 1611                 m_freem(m);
 1612 }
 1613 
 1614 /*
 1615  * bridge_rtupdate:
 1616  *
 1617  *      Add a bridge routing entry.
 1618  */
 1619 int
 1620 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
 1621     struct ifnet *dst_if, int setflags, uint8_t flags)
 1622 {
 1623         struct bridge_rtnode *brt;
 1624         int error;
 1625 
 1626         /*
 1627          * A route for this destination might already exist.  If so,
 1628          * update it, otherwise create a new one.
 1629          */
 1630         if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
 1631                 if (sc->sc_brtcnt >= sc->sc_brtmax)
 1632                         return (ENOSPC);
 1633 
 1634                 /*
 1635                  * Allocate a new bridge forwarding node, and
 1636                  * initialize the expiration time and Ethernet
 1637                  * address.
 1638                  */
 1639                 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT);
 1640                 if (brt == NULL)
 1641                         return (ENOMEM);
 1642 
 1643                 memset(brt, 0, sizeof(*brt));
 1644                 brt->brt_expire = mono_time.tv_sec + sc->sc_brttimeout;
 1645                 brt->brt_flags = IFBAF_DYNAMIC;
 1646                 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
 1647 
 1648                 if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
 1649                         pool_put(&bridge_rtnode_pool, brt);
 1650                         return (error);
 1651                 }
 1652         }
 1653 
 1654         brt->brt_ifp = dst_if;
 1655         if (setflags) {
 1656                 brt->brt_flags = flags;
 1657                 brt->brt_expire = (flags & IFBAF_STATIC) ? 0 :
 1658                     mono_time.tv_sec + sc->sc_brttimeout;
 1659         }
 1660 
 1661         return (0);
 1662 }
 1663 
 1664 /*
 1665  * bridge_rtlookup:
 1666  *
 1667  *      Lookup the destination interface for an address.
 1668  */
 1669 struct ifnet *
 1670 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
 1671 {
 1672         struct bridge_rtnode *brt;
 1673 
 1674         if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
 1675                 return (NULL);
 1676 
 1677         return (brt->brt_ifp);
 1678 }
 1679 
 1680 /*
 1681  * bridge_rttrim:
 1682  *
 1683  *      Trim the routine table so that we have a number
 1684  *      of routing entries less than or equal to the
 1685  *      maximum number.
 1686  */
 1687 void
 1688 bridge_rttrim(struct bridge_softc *sc)
 1689 {
 1690         struct bridge_rtnode *brt, *nbrt;
 1691 
 1692         /* Make sure we actually need to do this. */
 1693         if (sc->sc_brtcnt <= sc->sc_brtmax)
 1694                 return;
 1695 
 1696         /* Force an aging cycle; this might trim enough addresses. */
 1697         bridge_rtage(sc);
 1698         if (sc->sc_brtcnt <= sc->sc_brtmax)
 1699                 return;
 1700 
 1701         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 1702                 nbrt = LIST_NEXT(brt, brt_list);
 1703                 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
 1704                         bridge_rtnode_destroy(sc, brt);
 1705                         if (sc->sc_brtcnt <= sc->sc_brtmax)
 1706                                 return;
 1707                 }
 1708         }
 1709 }
 1710 
 1711 /*
 1712  * bridge_timer:
 1713  *
 1714  *      Aging timer for the bridge.
 1715  */
 1716 void
 1717 bridge_timer(void *arg)
 1718 {
 1719         struct bridge_softc *sc = arg;
 1720         int s;
 1721 
 1722         s = splnet();
 1723         bridge_rtage(sc);
 1724         splx(s);
 1725 
 1726         if (sc->sc_if.if_flags & IFF_RUNNING)
 1727                 callout_reset(&sc->sc_brcallout,
 1728                     bridge_rtable_prune_period * hz, bridge_timer, sc);
 1729 }
 1730 
 1731 /*
 1732  * bridge_rtage:
 1733  *
 1734  *      Perform an aging cycle.
 1735  */
 1736 void
 1737 bridge_rtage(struct bridge_softc *sc)
 1738 {
 1739         struct bridge_rtnode *brt, *nbrt;
 1740 
 1741         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 1742                 nbrt = LIST_NEXT(brt, brt_list);
 1743                 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
 1744                         if (mono_time.tv_sec >= brt->brt_expire)
 1745                                 bridge_rtnode_destroy(sc, brt);
 1746                 }
 1747         }
 1748 }
 1749 
 1750 /*
 1751  * bridge_rtflush:
 1752  *
 1753  *      Remove all dynamic addresses from the bridge.
 1754  */
 1755 void
 1756 bridge_rtflush(struct bridge_softc *sc, int full)
 1757 {
 1758         struct bridge_rtnode *brt, *nbrt;
 1759 
 1760         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 1761                 nbrt = LIST_NEXT(brt, brt_list);
 1762                 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
 1763                         bridge_rtnode_destroy(sc, brt);
 1764         }
 1765 }
 1766 
 1767 /*
 1768  * bridge_rtdaddr:
 1769  *
 1770  *      Remove an address from the table.
 1771  */
 1772 int
 1773 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
 1774 {
 1775         struct bridge_rtnode *brt;
 1776 
 1777         if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
 1778                 return (ENOENT);
 1779 
 1780         bridge_rtnode_destroy(sc, brt);
 1781         return (0);
 1782 }
 1783 
 1784 /*
 1785  * bridge_rtdelete:
 1786  *
 1787  *      Delete routes to a speicifc member interface.
 1788  */
 1789 void
 1790 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp)
 1791 {
 1792         struct bridge_rtnode *brt, *nbrt;
 1793 
 1794         for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
 1795                 nbrt = LIST_NEXT(brt, brt_list);
 1796                 if (brt->brt_ifp == ifp)
 1797                         bridge_rtnode_destroy(sc, brt);
 1798         }
 1799 }
 1800 
 1801 /*
 1802  * bridge_rtable_init:
 1803  *
 1804  *      Initialize the route table for this bridge.
 1805  */
 1806 int
 1807 bridge_rtable_init(struct bridge_softc *sc)
 1808 {
 1809         int i;
 1810 
 1811         sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
 1812             M_DEVBUF, M_NOWAIT);
 1813         if (sc->sc_rthash == NULL)
 1814                 return (ENOMEM);
 1815 
 1816         for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
 1817                 LIST_INIT(&sc->sc_rthash[i]);
 1818 
 1819         sc->sc_rthash_key = arc4random();
 1820 
 1821         LIST_INIT(&sc->sc_rtlist);
 1822 
 1823         return (0);
 1824 }
 1825 
 1826 /*
 1827  * bridge_rtable_fini:
 1828  *
 1829  *      Deconstruct the route table for this bridge.
 1830  */
 1831 void
 1832 bridge_rtable_fini(struct bridge_softc *sc)
 1833 {
 1834 
 1835         free(sc->sc_rthash, M_DEVBUF);
 1836 }
 1837 
 1838 /*
 1839  * The following hash function is adapted from "Hash Functions" by Bob Jenkins
 1840  * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
 1841  */
 1842 #define mix(a, b, c)                                                    \
 1843 do {                                                                    \
 1844         a -= b; a -= c; a ^= (c >> 13);                                 \
 1845         b -= c; b -= a; b ^= (a << 8);                                  \
 1846         c -= a; c -= b; c ^= (b >> 13);                                 \
 1847         a -= b; a -= c; a ^= (c >> 12);                                 \
 1848         b -= c; b -= a; b ^= (a << 16);                                 \
 1849         c -= a; c -= b; c ^= (b >> 5);                                  \
 1850         a -= b; a -= c; a ^= (c >> 3);                                  \
 1851         b -= c; b -= a; b ^= (a << 10);                                 \
 1852         c -= a; c -= b; c ^= (b >> 15);                                 \
 1853 } while (/*CONSTCOND*/0)
 1854 
 1855 static __inline uint32_t
 1856 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
 1857 {
 1858         uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
 1859 
 1860         b += addr[5] << 8;
 1861         b += addr[4];
 1862         a += addr[3] << 24;
 1863         a += addr[2] << 16;
 1864         a += addr[1] << 8;
 1865         a += addr[0];
 1866 
 1867         mix(a, b, c);
 1868 
 1869         return (c & BRIDGE_RTHASH_MASK);
 1870 }
 1871 
 1872 #undef mix
 1873 
 1874 /*
 1875  * bridge_rtnode_lookup:
 1876  *
 1877  *      Look up a bridge route node for the specified destination.
 1878  */
 1879 struct bridge_rtnode *
 1880 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
 1881 {
 1882         struct bridge_rtnode *brt;
 1883         uint32_t hash;
 1884         int dir;
 1885 
 1886         hash = bridge_rthash(sc, addr);
 1887         LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
 1888                 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
 1889                 if (dir == 0)
 1890                         return (brt);
 1891                 if (dir > 0)
 1892                         return (NULL);
 1893         }
 1894 
 1895         return (NULL);
 1896 }
 1897 
 1898 /*
 1899  * bridge_rtnode_insert:
 1900  *
 1901  *      Insert the specified bridge node into the route table.  We
 1902  *      assume the entry is not already in the table.
 1903  */
 1904 int
 1905 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
 1906 {
 1907         struct bridge_rtnode *lbrt;
 1908         uint32_t hash;
 1909         int dir;
 1910 
 1911         hash = bridge_rthash(sc, brt->brt_addr);
 1912 
 1913         lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
 1914         if (lbrt == NULL) {
 1915                 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
 1916                 goto out;
 1917         }
 1918 
 1919         do {
 1920                 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
 1921                 if (dir == 0)
 1922                         return (EEXIST);
 1923                 if (dir > 0) {
 1924                         LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
 1925                         goto out;
 1926                 }
 1927                 if (LIST_NEXT(lbrt, brt_hash) == NULL) {
 1928                         LIST_INSERT_AFTER(lbrt, brt, brt_hash);
 1929                         goto out;
 1930                 }
 1931                 lbrt = LIST_NEXT(lbrt, brt_hash);
 1932         } while (lbrt != NULL);
 1933 
 1934 #ifdef DIAGNOSTIC
 1935         panic("bridge_rtnode_insert: impossible");
 1936 #endif
 1937 
 1938  out:
 1939         LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
 1940         sc->sc_brtcnt++;
 1941 
 1942         return (0);
 1943 }
 1944 
 1945 /*
 1946  * bridge_rtnode_destroy:
 1947  *
 1948  *      Destroy a bridge rtnode.
 1949  */
 1950 void
 1951 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
 1952 {
 1953 
 1954         LIST_REMOVE(brt, brt_hash);
 1955 
 1956         LIST_REMOVE(brt, brt_list);
 1957         sc->sc_brtcnt--;
 1958         pool_put(&bridge_rtnode_pool, brt);
 1959 }
 1960 
 1961 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
 1962 extern struct pfil_head inet_pfil_hook;                 /* XXX */
 1963 extern struct pfil_head inet6_pfil_hook;                /* XXX */
 1964 
 1965 /*
 1966  * Send bridge packets through IPF if they are one of the types IPF can deal
 1967  * with, or if they are ARP or REVARP.  (IPF will pass ARP and REVARP without
 1968  * question.)
 1969  */
 1970 static int bridge_ipf(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
 1971 {
 1972         int snap, error;
 1973         struct ether_header *eh1, eh2;
 1974         struct llc llc;
 1975         u_int16_t ether_type;
 1976 
 1977         snap = 0;
 1978         error = -1;     /* Default error if not error == 0 */
 1979         eh1 = mtod(*mp, struct ether_header *);
 1980         ether_type = ntohs(eh1->ether_type);
 1981 
 1982         /*
 1983          * Check for SNAP/LLC.
 1984          */
 1985         if (ether_type < ETHERMTU) {
 1986                 struct llc *llc = (struct llc *)(eh1 + 1);
 1987 
 1988                 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
 1989                     llc->llc_dsap == LLC_SNAP_LSAP &&
 1990                     llc->llc_ssap == LLC_SNAP_LSAP &&
 1991                     llc->llc_control == LLC_UI) {
 1992                         ether_type = htons(llc->llc_un.type_snap.ether_type);
 1993                         snap = 1;
 1994                 }
 1995         }
 1996 
 1997         /*
 1998          * If we're trying to filter bridge traffic, don't look at anything
 1999          * other than IP and ARP traffic.  If the filter doesn't understand
 2000          * IPv6, don't allow IPv6 through the bridge either.  This is lame
 2001          * since if we really wanted, say, an AppleTalk filter, we are hosed,
 2002          * but of course we don't have an AppleTalk filter to begin with.
 2003          * (Note that since IPF doesn't understand ARP it will pass *ALL*
 2004          * ARP traffic.)
 2005          */
 2006         switch (ether_type) {
 2007                 case ETHERTYPE_ARP:
 2008                 case ETHERTYPE_REVARP:
 2009                         return 0; /* Automatically pass */
 2010                 case ETHERTYPE_IP:
 2011 # ifdef INET6
 2012                 case ETHERTYPE_IPV6:
 2013 # endif /* INET6 */
 2014                         break;
 2015                 default:
 2016                         goto bad;
 2017         }
 2018 
 2019         /* Strip off the Ethernet header and keep a copy. */
 2020         m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
 2021         m_adj(*mp, ETHER_HDR_LEN);
 2022 
 2023         /* Strip off snap header, if present */
 2024         if (snap) {
 2025                 m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc);
 2026                 m_adj(*mp, sizeof(struct llc));
 2027         }
 2028 
 2029         /*
 2030          * Check basic packet sanity and run IPF through pfil.
 2031          */
 2032         switch (ether_type)
 2033         {
 2034         case ETHERTYPE_IP :
 2035                 error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0;
 2036                 if (error == 0)
 2037                         error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, dir);
 2038                 break;
 2039 # ifdef INET6
 2040         case ETHERTYPE_IPV6 :
 2041                 error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0;
 2042                 if (error == 0)
 2043                         error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, dir);
 2044                 break;
 2045 # endif
 2046         default :
 2047                 error = 0;
 2048                 break;
 2049         }
 2050 
 2051         if (*mp == NULL)
 2052                 return error;
 2053         if (error != 0)
 2054                 goto bad;
 2055 
 2056         error = -1;
 2057 
 2058         /*
 2059          * Finally, put everything back the way it was and return
 2060          */
 2061         if (snap) {
 2062                 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
 2063                 if (*mp == NULL)
 2064                         return error;
 2065                 bcopy(&llc, mtod(*mp, caddr_t), sizeof(struct llc));
 2066         }
 2067 
 2068         M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
 2069         if (*mp == NULL)
 2070                 return error;
 2071         bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
 2072 
 2073         return 0;
 2074 
 2075     bad:
 2076         m_freem(*mp);
 2077         *mp = NULL;
 2078         return error;
 2079 }
 2080 
 2081 /*
 2082  * Perform basic checks on header size since
 2083  * IPF assumes ip_input has already processed
 2084  * it for it.  Cut-and-pasted from ip_input.c.
 2085  * Given how simple the IPv6 version is,
 2086  * does the IPv4 version really need to be
 2087  * this complicated?
 2088  *
 2089  * XXX Should we update ipstat here, or not?
 2090  * XXX Right now we update ipstat but not
 2091  * XXX csum_counter.
 2092  */
 2093 static int
 2094 bridge_ip_checkbasic(struct mbuf **mp)
 2095 {
 2096         struct mbuf *m = *mp;
 2097         struct ip *ip;
 2098         int len, hlen;
 2099 
 2100         if (*mp == NULL)
 2101                 return -1;
 2102 
 2103         if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
 2104                 if ((m = m_copyup(m, sizeof(struct ip),
 2105                         (max_linkhdr + 3) & ~3)) == NULL) {
 2106                         /* XXXJRT new stat, please */
 2107                         ipstat.ips_toosmall++;
 2108                         goto bad;
 2109                 }
 2110         } else if (__predict_false(m->m_len < sizeof (struct ip))) {
 2111                 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
 2112                         ipstat.ips_toosmall++;
 2113                         goto bad;
 2114                 }
 2115         }
 2116         ip = mtod(m, struct ip *);
 2117         if (ip == NULL) goto bad;
 2118 
 2119         if (ip->ip_v != IPVERSION) {
 2120                 ipstat.ips_badvers++;
 2121                 goto bad;
 2122         }
 2123         hlen = ip->ip_hl << 2;
 2124         if (hlen < sizeof(struct ip)) { /* minimum header length */
 2125                 ipstat.ips_badhlen++;
 2126                 goto bad;
 2127         }
 2128         if (hlen > m->m_len) {
 2129                 if ((m = m_pullup(m, hlen)) == 0) {
 2130                         ipstat.ips_badhlen++;
 2131                         goto bad;
 2132                 }
 2133                 ip = mtod(m, struct ip *);
 2134                 if (ip == NULL) goto bad;
 2135         }
 2136 
 2137         switch (m->m_pkthdr.csum_flags &
 2138                 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) |
 2139                  M_CSUM_IPv4_BAD)) {
 2140         case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
 2141                 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */
 2142                 goto bad;
 2143 
 2144         case M_CSUM_IPv4:
 2145                 /* Checksum was okay. */
 2146                 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */
 2147                 break;
 2148 
 2149         default:
 2150                 /* Must compute it ourselves. */
 2151                 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */
 2152                 if (in_cksum(m, hlen) != 0)
 2153                         goto bad;
 2154                 break;
 2155         }
 2156 
 2157         /* Retrieve the packet length. */
 2158         len = ntohs(ip->ip_len);
 2159 
 2160         /*
 2161          * Check for additional length bogosity
 2162          */
 2163         if (len < hlen) {
 2164                 ipstat.ips_badlen++;
 2165                 goto bad;
 2166         }
 2167 
 2168         /*
 2169          * Check that the amount of data in the buffers
 2170          * is as at least much as the IP header would have us expect.
 2171          * Drop packet if shorter than we expect.
 2172          */
 2173         if (m->m_pkthdr.len < len) {
 2174                 ipstat.ips_tooshort++;
 2175                 goto bad;
 2176         }
 2177 
 2178         /* Checks out, proceed */
 2179         *mp = m;
 2180         return 0;
 2181 
 2182     bad:
 2183         *mp = m;
 2184         return -1;
 2185 }
 2186 
 2187 # ifdef INET6
 2188 /*
 2189  * Same as above, but for IPv6.
 2190  * Cut-and-pasted from ip6_input.c.
 2191  * XXX Should we update ip6stat, or not?
 2192  */
 2193 static int
 2194 bridge_ip6_checkbasic(struct mbuf **mp)
 2195 {
 2196         struct mbuf *m = *mp;
 2197         struct ip6_hdr *ip6;
 2198 
 2199         /*
 2200          * If the IPv6 header is not aligned, slurp it up into a new
 2201          * mbuf with space for link headers, in the event we forward
 2202          * it.  Otherwise, if it is aligned, make sure the entire base
 2203          * IPv6 header is in the first mbuf of the chain.
 2204          */
 2205         if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
 2206                 struct ifnet *inifp = m->m_pkthdr.rcvif;
 2207                 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
 2208                                   (max_linkhdr + 3) & ~3)) == NULL) {
 2209                         /* XXXJRT new stat, please */
 2210                         ip6stat.ip6s_toosmall++;
 2211                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);
 2212                         goto bad;
 2213                 }
 2214         } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
 2215                 struct ifnet *inifp = m->m_pkthdr.rcvif;
 2216                 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
 2217                         ip6stat.ip6s_toosmall++;
 2218                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);
 2219                         goto bad;
 2220                 }
 2221         }
 2222 
 2223         ip6 = mtod(m, struct ip6_hdr *);
 2224 
 2225         if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
 2226                 ip6stat.ip6s_badvers++;
 2227                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
 2228                 goto bad;
 2229         }
 2230 
 2231         /* Checks out, proceed */
 2232         *mp = m;
 2233         return 0;
 2234 
 2235     bad:
 2236         *mp = m;
 2237         return -1;
 2238 }
 2239 # endif /* INET6 */
 2240 #endif /* BRIDGE_IPF && PFIL_HOOKS */

Cache object: 911f730d2f12ac99aca0331e3490884c


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