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

Cache object: 441524e0bdf8f08b133acc5e2336e05b


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