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 /*      $OpenBSD: if_bridge.c,v 1.364 2022/08/07 00:57:43 bluhm Exp $   */
    2 
    3 /*
    4  * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   26  * POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * Effort sponsored in part by the Defense Advanced Research Projects
   29  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   30  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
   31  *
   32  */
   33 
   34 #include "bpfilter.h"
   35 #include "gif.h"
   36 #include "pf.h"
   37 #include "carp.h"
   38 #include "vlan.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/mbuf.h>
   43 #include <sys/socket.h>
   44 #include <sys/ioctl.h>
   45 #include <sys/kernel.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_types.h>
   49 #include <net/if_llc.h>
   50 #include <net/netisr.h>
   51 
   52 #include <netinet/in.h>
   53 #include <netinet/ip.h>
   54 #include <netinet/ip_var.h>
   55 #include <netinet/if_ether.h>
   56 #include <netinet/ip_icmp.h>
   57 
   58 #ifdef IPSEC
   59 #include <netinet/ip_ipsp.h>
   60 #include <net/if_enc.h>
   61 #endif
   62 
   63 #ifdef INET6
   64 #include <netinet6/in6_var.h>
   65 #include <netinet/ip6.h>
   66 #include <netinet6/ip6_var.h>
   67 #endif
   68 
   69 #if NPF > 0
   70 #include <net/pfvar.h>
   71 #define BRIDGE_IN       PF_IN
   72 #define BRIDGE_OUT      PF_OUT
   73 #else
   74 #define BRIDGE_IN       0
   75 #define BRIDGE_OUT      1
   76 #endif
   77 
   78 #if NBPFILTER > 0
   79 #include <net/bpf.h>
   80 #endif
   81 
   82 #if NCARP > 0
   83 #include <netinet/ip_carp.h>
   84 #endif
   85 
   86 #if NVLAN > 0
   87 #include <net/if_vlan_var.h>
   88 #endif
   89 
   90 #include <net/if_bridge.h>
   91 
   92 /*
   93  * Maximum number of addresses to cache
   94  */
   95 #ifndef BRIDGE_RTABLE_MAX
   96 #define BRIDGE_RTABLE_MAX       100
   97 #endif
   98 
   99 /*
  100  * Timeout (in seconds) for entries learned dynamically
  101  */
  102 #ifndef BRIDGE_RTABLE_TIMEOUT
  103 #define BRIDGE_RTABLE_TIMEOUT   240
  104 #endif
  105 
  106 void    bridgeattach(int);
  107 int     bridge_ioctl(struct ifnet *, u_long, caddr_t);
  108 void    bridge_ifdetach(void *);
  109 void    bridge_spandetach(void *);
  110 int     bridge_ifremove(struct bridge_iflist *);
  111 void    bridge_spanremove(struct bridge_iflist *);
  112 struct mbuf *
  113         bridge_input(struct ifnet *, struct mbuf *, uint64_t, void *);
  114 void    bridge_process(struct ifnet *, struct mbuf *);
  115 void    bridgeintr_frame(struct ifnet *, struct ifnet *, struct mbuf *);
  116 void    bridge_bifgetstp(struct bridge_softc *, struct bridge_iflist *,
  117             struct ifbreq *);
  118 void    bridge_broadcast(struct bridge_softc *, struct ifnet *,
  119     struct ether_header *, struct mbuf *);
  120 int     bridge_localbroadcast(struct ifnet *, struct ether_header *,
  121     struct mbuf *);
  122 void    bridge_span(struct ifnet *, struct mbuf *);
  123 void    bridge_stop(struct bridge_softc *);
  124 void    bridge_init(struct bridge_softc *);
  125 int     bridge_bifconf(struct bridge_softc *, struct ifbifconf *);
  126 int bridge_blocknonip(struct ether_header *, struct mbuf *);
  127 void    bridge_ifinput(struct ifnet *, struct mbuf *);
  128 int     bridge_dummy_output(struct ifnet *, struct mbuf *, struct sockaddr *,
  129     struct rtentry *);
  130 void    bridge_send_icmp_err(struct ifnet *, struct ether_header *,
  131     struct mbuf *, int, struct llc *, int, int, int);
  132 int     bridge_ifenqueue(struct ifnet *, struct ifnet *, struct mbuf *);
  133 struct mbuf *bridge_ip(struct ifnet *, int, struct ifnet *,
  134     struct ether_header *, struct mbuf *);
  135 #ifdef IPSEC
  136 int bridge_ipsec(struct ifnet *, struct ether_header *, int, struct llc *,
  137     int, int, int, struct mbuf *);
  138 #endif
  139 int     bridge_clone_create(struct if_clone *, int);
  140 int     bridge_clone_destroy(struct ifnet *);
  141 void    bridge_take(void *);
  142 void    bridge_rele(void *);
  143 
  144 #define ETHERADDR_IS_IP_MCAST(a) \
  145         /* struct etheraddr *a; */                              \
  146         ((a)->ether_addr_octet[0] == 0x01 &&                    \
  147          (a)->ether_addr_octet[1] == 0x00 &&                    \
  148          (a)->ether_addr_octet[2] == 0x5e)
  149 
  150 struct niqueue bridgeintrq = NIQUEUE_INITIALIZER(1024, NETISR_BRIDGE);
  151 
  152 struct if_clone bridge_cloner =
  153     IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
  154 
  155 const struct ether_brport bridge_brport = {
  156         bridge_input,
  157         bridge_take,
  158         bridge_rele,
  159         NULL,
  160 };
  161 
  162 void
  163 bridgeattach(int n)
  164 {
  165         if_clone_attach(&bridge_cloner);
  166 }
  167 
  168 int
  169 bridge_clone_create(struct if_clone *ifc, int unit)
  170 {
  171         struct bridge_softc *sc;
  172         struct ifnet *ifp;
  173         int i;
  174 
  175         sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
  176         sc->sc_stp = bstp_create();
  177         if (!sc->sc_stp) {
  178                 free(sc, M_DEVBUF, sizeof *sc);
  179                 return (ENOMEM);
  180         }
  181 
  182         sc->sc_brtmax = BRIDGE_RTABLE_MAX;
  183         sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
  184         timeout_set(&sc->sc_brtimeout, bridge_rtage, sc);
  185         SMR_SLIST_INIT(&sc->sc_iflist);
  186         SMR_SLIST_INIT(&sc->sc_spanlist);
  187         mtx_init(&sc->sc_mtx, IPL_MPFLOOR);
  188         for (i = 0; i < BRIDGE_RTABLE_SIZE; i++)
  189                 LIST_INIT(&sc->sc_rts[i]);
  190         arc4random_buf(&sc->sc_hashkey, sizeof(sc->sc_hashkey));
  191         ifp = &sc->sc_if;
  192         snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
  193             unit);
  194         ifp->if_softc = sc;
  195         ifp->if_mtu = ETHERMTU;
  196         ifp->if_ioctl = bridge_ioctl;
  197         ifp->if_output = bridge_dummy_output;
  198         ifp->if_xflags = IFXF_CLONED;
  199         ifp->if_start = NULL;
  200         ifp->if_type = IFT_BRIDGE;
  201         ifp->if_hdrlen = ETHER_HDR_LEN;
  202 
  203         if_attach(ifp);
  204         if_alloc_sadl(ifp);
  205 
  206 #if NBPFILTER > 0
  207         bpfattach(&sc->sc_if.if_bpf, ifp,
  208             DLT_EN10MB, ETHER_HDR_LEN);
  209 #endif
  210 
  211         return (0);
  212 }
  213 
  214 int
  215 bridge_dummy_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
  216     struct rtentry *rt)
  217 {
  218         m_freem(m);
  219         return (EAFNOSUPPORT);
  220 }
  221 
  222 int
  223 bridge_clone_destroy(struct ifnet *ifp)
  224 {
  225         struct bridge_softc *sc = ifp->if_softc;
  226         struct bridge_iflist *bif;
  227 
  228         /*
  229          * bridge(4) detach hook doesn't need the NET_LOCK(), worst the
  230          * use of smr_barrier() while holding the lock might lead to a
  231          * deadlock situation.
  232          */
  233         NET_ASSERT_UNLOCKED();
  234 
  235         bridge_stop(sc);
  236         bridge_rtflush(sc, IFBF_FLUSHALL);
  237         while ((bif = SMR_SLIST_FIRST_LOCKED(&sc->sc_iflist)) != NULL)
  238                 bridge_ifremove(bif);
  239         while ((bif = SMR_SLIST_FIRST_LOCKED(&sc->sc_spanlist)) != NULL)
  240                 bridge_spanremove(bif);
  241 
  242         bstp_destroy(sc->sc_stp);
  243 
  244         if_detach(ifp);
  245 
  246         free(sc, M_DEVBUF, sizeof *sc);
  247         return (0);
  248 }
  249 
  250 int
  251 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  252 {
  253         struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc;
  254         struct ifbreq *req = (struct ifbreq *)data;
  255         struct ifbropreq *brop = (struct ifbropreq *)data;
  256         struct ifnet *ifs;
  257         struct bridge_iflist *bif;
  258         struct bstp_port *bp;
  259         struct bstp_state *bs = sc->sc_stp;
  260         int error = 0;
  261 
  262         /*
  263          * bridge(4) data structure aren't protected by the NET_LOCK().
  264          * Idealy it shouldn't be taken before calling `ifp->if_ioctl'
  265          * but we aren't there yet.  Media ioctl run without netlock.
  266          */
  267         switch (cmd) {
  268         case SIOCSIFMEDIA:
  269         case SIOCGIFMEDIA:
  270                 return (ENOTTY);
  271         }
  272         NET_UNLOCK();
  273 
  274         switch (cmd) {
  275         case SIOCBRDGADD:
  276         /* bridge(4) does not distinguish between routing/forwarding ports */
  277         case SIOCBRDGADDL:
  278                 if ((error = suser(curproc)) != 0)
  279                         break;
  280 
  281                 ifs = if_unit(req->ifbr_ifsname);
  282                 if (ifs == NULL) {                      /* no such interface */
  283                         error = ENOENT;
  284                         break;
  285                 }
  286                 if (ifs->if_type != IFT_ETHER) {
  287                         if_put(ifs);
  288                         error = EINVAL;
  289                         break;
  290                 }
  291                 if (ifs->if_bridgeidx != 0) {
  292                         if (ifs->if_bridgeidx == ifp->if_index)
  293                                 error = EEXIST;
  294                         else
  295                                 error = EBUSY;
  296                         if_put(ifs);
  297                         break;
  298                 }
  299 
  300                 error = ether_brport_isset(ifs);
  301                 if (error != 0) {
  302                         if_put(ifs);
  303                         break;
  304                 }
  305 
  306                 /* If it's in the span list, it can't be a member. */
  307                 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
  308                         if (bif->ifp == ifs)
  309                                 break;
  310                 }
  311                 if (bif != NULL) {
  312                         if_put(ifs);
  313                         error = EBUSY;
  314                         break;
  315                 }
  316 
  317                 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
  318                 if (bif == NULL) {
  319                         if_put(ifs);
  320                         error = ENOMEM;
  321                         break;
  322                 }
  323 
  324                 NET_LOCK();
  325                 error = ifpromisc(ifs, 1);
  326                 NET_UNLOCK();
  327                 if (error != 0) {
  328                         if_put(ifs);
  329                         free(bif, M_DEVBUF, sizeof(*bif));
  330                         break;
  331                 }
  332 
  333                 /*
  334                  * XXX If the NET_LOCK() or ifpromisc() calls above
  335                  * had to sleep, then something else could have come
  336                  * along and taken over ifs while the kernel lock was
  337                  * released.
  338                  */
  339 
  340                 bif->bridge_sc = sc;
  341                 bif->ifp = ifs;
  342                 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
  343                 SIMPLEQ_INIT(&bif->bif_brlin);
  344                 SIMPLEQ_INIT(&bif->bif_brlout);
  345                 ifs->if_bridgeidx = ifp->if_index;
  346                 task_set(&bif->bif_dtask, bridge_ifdetach, bif);
  347                 if_detachhook_add(ifs, &bif->bif_dtask);
  348                 ether_brport_set(bif->ifp, &bridge_brport);
  349                 SMR_SLIST_INSERT_HEAD_LOCKED(&sc->sc_iflist, bif, bif_next);
  350                 break;
  351         case SIOCBRDGDEL:
  352                 if ((error = suser(curproc)) != 0)
  353                         break;
  354                 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
  355                 if (error != 0)
  356                         break;
  357                 bridge_ifremove(bif);
  358                 break;
  359         case SIOCBRDGIFS:
  360                 error = bridge_bifconf(sc, (struct ifbifconf *)data);
  361                 break;
  362         case SIOCBRDGADDS:
  363                 if ((error = suser(curproc)) != 0)
  364                         break;
  365                 ifs = if_unit(req->ifbr_ifsname);
  366                 if (ifs == NULL) {                      /* no such interface */
  367                         error = ENOENT;
  368                         break;
  369                 }
  370                 if (ifs->if_type != IFT_ETHER) {
  371                         if_put(ifs);
  372                         error = EINVAL;
  373                         break;
  374                 }
  375                 if (ifs->if_bridgeidx != 0) {
  376                         if (ifs->if_bridgeidx == ifp->if_index)
  377                                 error = EEXIST;
  378                         else
  379                                 error = EBUSY;
  380                         if_put(ifs);
  381                         break;
  382                 }
  383                 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
  384                         if (bif->ifp == ifs)
  385                                 break;
  386                 }
  387                 if (bif != NULL) {
  388                         if_put(ifs);
  389                         error = EEXIST;
  390                         break;
  391                 }
  392                 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
  393                 if (bif == NULL) {
  394                         if_put(ifs);
  395                         error = ENOMEM;
  396                         break;
  397                 }
  398                 bif->bridge_sc = sc;
  399                 bif->ifp = ifs;
  400                 bif->bif_flags = IFBIF_SPAN;
  401                 SIMPLEQ_INIT(&bif->bif_brlin);
  402                 SIMPLEQ_INIT(&bif->bif_brlout);
  403                 task_set(&bif->bif_dtask, bridge_spandetach, bif);
  404                 if_detachhook_add(ifs, &bif->bif_dtask);
  405                 SMR_SLIST_INSERT_HEAD_LOCKED(&sc->sc_spanlist, bif, bif_next);
  406                 break;
  407         case SIOCBRDGDELS:
  408                 if ((error = suser(curproc)) != 0)
  409                         break;
  410                 ifs = if_unit(req->ifbr_ifsname);
  411                 if (ifs == NULL) {
  412                         error = ENOENT;
  413                         break;
  414                 }
  415                 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
  416                         if (bif->ifp == ifs)
  417                                 break;
  418                 }
  419                 if_put(ifs);
  420                 if (bif == NULL) {
  421                         error = ESRCH;
  422                         break;
  423                 }
  424                 bridge_spanremove(bif);
  425                 break;
  426         case SIOCBRDGGIFFLGS:
  427                 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
  428                 if (error != 0)
  429                         break;
  430                 req->ifbr_ifsflags = bif->bif_flags;
  431                 req->ifbr_portno = bif->ifp->if_index & 0xfff;
  432                 req->ifbr_protected = bif->bif_protected;
  433                 if (bif->bif_flags & IFBIF_STP)
  434                         bridge_bifgetstp(sc, bif, req);
  435                 break;
  436         case SIOCBRDGSIFFLGS:
  437                 if (req->ifbr_ifsflags & IFBIF_RO_MASK) {
  438                         error = EINVAL;
  439                         break;
  440                 }
  441                 if ((error = suser(curproc)) != 0)
  442                         break;
  443                 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
  444                 if (error != 0)
  445                         break;
  446                 if (req->ifbr_ifsflags & IFBIF_STP) {
  447                         if ((bif->bif_flags & IFBIF_STP) == 0) {
  448                                 /* Enable STP */
  449                                 if ((bif->bif_stp = bstp_add(sc->sc_stp,
  450                                     bif->ifp)) == NULL) {
  451                                         error = ENOMEM;
  452                                         break;
  453                                 }
  454                         } else {
  455                                 /* Update STP flags */
  456                                 bstp_ifsflags(bif->bif_stp, req->ifbr_ifsflags);
  457                         }
  458                 } else if (bif->bif_flags & IFBIF_STP) {
  459                         bstp_delete(bif->bif_stp);
  460                         bif->bif_stp = NULL;
  461                 }
  462                 bif->bif_flags = req->ifbr_ifsflags;
  463                 break;
  464         case SIOCSIFFLAGS:
  465                 if ((ifp->if_flags & IFF_UP) == IFF_UP)
  466                         bridge_init(sc);
  467 
  468                 if ((ifp->if_flags & IFF_UP) == 0)
  469                         bridge_stop(sc);
  470 
  471                 break;
  472         case SIOCBRDGGPARAM:
  473                 if ((bp = bs->bs_root_port) == NULL)
  474                         brop->ifbop_root_port = 0;
  475                 else
  476                         brop->ifbop_root_port = bp->bp_ifindex;
  477                 brop->ifbop_maxage = bs->bs_bridge_max_age >> 8;
  478                 brop->ifbop_hellotime = bs->bs_bridge_htime >> 8;
  479                 brop->ifbop_fwddelay = bs->bs_bridge_fdelay >> 8;
  480                 brop->ifbop_holdcount = bs->bs_txholdcount;
  481                 brop->ifbop_priority = bs->bs_bridge_priority;
  482                 brop->ifbop_protocol = bs->bs_protover;
  483                 brop->ifbop_root_bridge = bs->bs_root_pv.pv_root_id;
  484                 brop->ifbop_root_path_cost = bs->bs_root_pv.pv_cost;
  485                 brop->ifbop_root_port = bs->bs_root_pv.pv_port_id;
  486                 brop->ifbop_desg_bridge = bs->bs_root_pv.pv_dbridge_id;
  487                 brop->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec;
  488                 brop->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec;
  489                 break;
  490         case SIOCBRDGSIFPROT:
  491                 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
  492                 if (error != 0)
  493                         break;
  494                 bif->bif_protected = req->ifbr_protected;
  495                 break;
  496         case SIOCBRDGRTS:
  497         case SIOCBRDGGCACHE:
  498         case SIOCBRDGGPRI:
  499         case SIOCBRDGGMA:
  500         case SIOCBRDGGHT:
  501         case SIOCBRDGGFD:
  502         case SIOCBRDGGTO:
  503         case SIOCBRDGGRL:
  504                 break;
  505         case SIOCBRDGFLUSH:
  506         case SIOCBRDGSADDR:
  507         case SIOCBRDGDADDR:
  508         case SIOCBRDGSCACHE:
  509         case SIOCBRDGSTO:
  510         case SIOCBRDGARL:
  511         case SIOCBRDGFRL:
  512         case SIOCBRDGSPRI:
  513         case SIOCBRDGSFD:
  514         case SIOCBRDGSMA:
  515         case SIOCBRDGSHT:
  516         case SIOCBRDGSTXHC:
  517         case SIOCBRDGSPROTO:
  518         case SIOCBRDGSIFPRIO:
  519         case SIOCBRDGSIFCOST:
  520                 error = suser(curproc);
  521                 break;
  522         default:
  523                 error = ENOTTY;
  524                 break;
  525         }
  526 
  527         if (!error)
  528                 error = bridgectl_ioctl(ifp, cmd, data);
  529 
  530         if (!error)
  531                 error = bstp_ioctl(ifp, cmd, data);
  532 
  533         NET_LOCK();
  534         return (error);
  535 }
  536 
  537 /* Detach an interface from a bridge.  */
  538 int
  539 bridge_ifremove(struct bridge_iflist *bif)
  540 {
  541         struct bridge_softc *sc = bif->bridge_sc;
  542         int error;
  543 
  544         SMR_SLIST_REMOVE_LOCKED(&sc->sc_iflist, bif, bridge_iflist, bif_next);
  545         if_detachhook_del(bif->ifp, &bif->bif_dtask);
  546         ether_brport_clr(bif->ifp);
  547 
  548         smr_barrier();
  549 
  550         if (bif->bif_flags & IFBIF_STP) {
  551                 bstp_delete(bif->bif_stp);
  552                 bif->bif_stp = NULL;
  553         }
  554 
  555         bif->ifp->if_bridgeidx = 0;
  556         NET_LOCK();
  557         error = ifpromisc(bif->ifp, 0);
  558         NET_UNLOCK();
  559 
  560         bridge_rtdelete(sc, bif->ifp, 0);
  561         bridge_flushrule(bif);
  562 
  563         if_put(bif->ifp);
  564         bif->ifp = NULL;
  565         free(bif, M_DEVBUF, sizeof(*bif));
  566 
  567         return (error);
  568 }
  569 
  570 void
  571 bridge_spanremove(struct bridge_iflist *bif)
  572 {
  573         struct bridge_softc *sc = bif->bridge_sc;
  574 
  575         SMR_SLIST_REMOVE_LOCKED(&sc->sc_spanlist, bif, bridge_iflist, bif_next);
  576         if_detachhook_del(bif->ifp, &bif->bif_dtask);
  577 
  578         smr_barrier();
  579 
  580         if_put(bif->ifp);
  581         bif->ifp = NULL;
  582         free(bif, M_DEVBUF, sizeof(*bif));
  583 }
  584 
  585 void
  586 bridge_ifdetach(void *xbif)
  587 {
  588         struct bridge_iflist *bif = xbif;
  589 
  590         /*
  591          * bridge(4) detach hook doesn't need the NET_LOCK(), worst the
  592          * use of smr_barrier() while holding the lock might lead to a
  593          * deadlock situation.
  594          */
  595         NET_UNLOCK();
  596         bridge_ifremove(bif);
  597         NET_LOCK();
  598 }
  599 
  600 void
  601 bridge_spandetach(void *xbif)
  602 {
  603         struct bridge_iflist *bif = xbif;
  604 
  605         /*
  606          * bridge(4) detach hook doesn't need the NET_LOCK(), worst the
  607          * use of smr_barrier() while holding the lock might lead to a
  608          * deadlock situation.
  609          */
  610         NET_UNLOCK();
  611         bridge_spanremove(bif);
  612         NET_LOCK();
  613 }
  614 
  615 void
  616 bridge_bifgetstp(struct bridge_softc *sc, struct bridge_iflist *bif,
  617     struct ifbreq *breq)
  618 {
  619         struct bstp_state *bs = sc->sc_stp;
  620         struct bstp_port *bp = bif->bif_stp;
  621 
  622         breq->ifbr_state = bstp_getstate(bs, bp);
  623         breq->ifbr_priority = bp->bp_priority;
  624         breq->ifbr_path_cost = bp->bp_path_cost;
  625         breq->ifbr_proto = bp->bp_protover;
  626         breq->ifbr_role = bp->bp_role;
  627         breq->ifbr_stpflags = bp->bp_flags;
  628         breq->ifbr_fwd_trans = bp->bp_forward_transitions;
  629         breq->ifbr_root_bridge = bs->bs_root_pv.pv_root_id;
  630         breq->ifbr_root_cost = bs->bs_root_pv.pv_cost;
  631         breq->ifbr_root_port = bs->bs_root_pv.pv_port_id;
  632         breq->ifbr_desg_bridge = bs->bs_root_pv.pv_dbridge_id;
  633         breq->ifbr_desg_port = bs->bs_root_pv.pv_dport_id;
  634 
  635         /* Copy STP state options as flags */
  636         if (bp->bp_operedge)
  637                 breq->ifbr_ifsflags |= IFBIF_BSTP_EDGE;
  638         if (bp->bp_flags & BSTP_PORT_AUTOEDGE)
  639                 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE;
  640         if (bp->bp_ptp_link)
  641                 breq->ifbr_ifsflags |= IFBIF_BSTP_PTP;
  642         if (bp->bp_flags & BSTP_PORT_AUTOPTP)
  643                 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP;
  644 }
  645 
  646 int
  647 bridge_bifconf(struct bridge_softc *sc, struct ifbifconf *bifc)
  648 {
  649         struct bridge_iflist *bif;
  650         u_int32_t total = 0, i = 0;
  651         int error = 0;
  652         struct ifbreq *breq, *breqs = NULL;
  653 
  654         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next)
  655                 total++;
  656 
  657         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next)
  658                 total++;
  659 
  660         if (bifc->ifbic_len == 0) {
  661                 i = total;
  662                 goto done;
  663         }
  664 
  665         breqs = mallocarray(total, sizeof(*breqs), M_TEMP, M_NOWAIT|M_ZERO);
  666         if (breqs == NULL)
  667                 goto done;
  668 
  669         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
  670                 if (bifc->ifbic_len < (i + 1) * sizeof(*breqs))
  671                         break;
  672                 breq = &breqs[i];
  673                 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
  674                 strlcpy(breq->ifbr_ifsname, bif->ifp->if_xname, IFNAMSIZ);
  675                 breq->ifbr_ifsflags = bif->bif_flags;
  676                 breq->ifbr_portno = bif->ifp->if_index & 0xfff;
  677                 breq->ifbr_protected = bif->bif_protected;
  678                 if (bif->bif_flags & IFBIF_STP)
  679                         bridge_bifgetstp(sc, bif, breq);
  680                 i++;
  681         }
  682         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
  683                 if (bifc->ifbic_len < (i + 1) * sizeof(*breqs))
  684                         break;
  685                 breq = &breqs[i];
  686                 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
  687                 strlcpy(breq->ifbr_ifsname, bif->ifp->if_xname, IFNAMSIZ);
  688                 breq->ifbr_ifsflags = bif->bif_flags | IFBIF_SPAN;
  689                 breq->ifbr_portno = bif->ifp->if_index & 0xfff;
  690                 i++;
  691         }
  692 
  693         error = copyout(breqs, bifc->ifbic_req, i * sizeof(*breqs));
  694 done:
  695         free(breqs, M_TEMP, total * sizeof(*breq));
  696         bifc->ifbic_len = i * sizeof(*breq);
  697         return (error);
  698 }
  699 
  700 int
  701 bridge_findbif(struct bridge_softc *sc, const char *name,
  702     struct bridge_iflist **rbif)
  703 {
  704         struct ifnet *ifp;
  705         struct bridge_iflist *bif;
  706         int error = 0;
  707 
  708         KERNEL_ASSERT_LOCKED();
  709 
  710         if ((ifp = if_unit(name)) == NULL)
  711                 return (ENOENT);
  712 
  713         if (ifp->if_bridgeidx != sc->sc_if.if_index) {
  714                 error = ESRCH;
  715                 goto put;
  716         }
  717 
  718         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
  719                 if (bif->ifp == ifp)
  720                         break;
  721         }
  722 
  723         if (bif == NULL) {
  724                 error = ENOENT;
  725                 goto put;
  726         }
  727 
  728         *rbif = bif;
  729 put:
  730         if_put(ifp);
  731 
  732         return (error);
  733 }
  734 
  735 struct bridge_iflist *
  736 bridge_getbif(struct ifnet *ifp)
  737 {
  738         struct bridge_iflist *bif;
  739         struct bridge_softc *sc;
  740         struct ifnet *bifp;
  741 
  742         KERNEL_ASSERT_LOCKED();
  743 
  744         bifp = if_get(ifp->if_bridgeidx);
  745         if (bifp == NULL)
  746                 return (NULL);
  747 
  748         sc = bifp->if_softc;
  749         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
  750                 if (bif->ifp == ifp)
  751                         break;
  752         }
  753 
  754         if_put(bifp);
  755 
  756         return (bif);
  757 }
  758 
  759 void
  760 bridge_init(struct bridge_softc *sc)
  761 {
  762         struct ifnet *ifp = &sc->sc_if;
  763 
  764         if (ISSET(ifp->if_flags, IFF_RUNNING))
  765                 return;
  766 
  767         bstp_enable(sc->sc_stp, ifp->if_index);
  768 
  769         if (sc->sc_brttimeout != 0)
  770                 timeout_add_sec(&sc->sc_brtimeout, sc->sc_brttimeout);
  771 
  772         SET(ifp->if_flags, IFF_RUNNING);
  773 }
  774 
  775 /*
  776  * Stop the bridge and deallocate the routing table.
  777  */
  778 void
  779 bridge_stop(struct bridge_softc *sc)
  780 {
  781         struct ifnet *ifp = &sc->sc_if;
  782 
  783         if (!ISSET(ifp->if_flags, IFF_RUNNING))
  784                 return;
  785 
  786         CLR(ifp->if_flags, IFF_RUNNING);
  787 
  788         bstp_disable(sc->sc_stp);
  789 
  790         timeout_del_barrier(&sc->sc_brtimeout);
  791 
  792         bridge_rtflush(sc, IFBF_FLUSHDYN);
  793 }
  794 
  795 /*
  796  * Send output from the bridge.  The mbuf has the ethernet header
  797  * already attached.  We must enqueue or free the mbuf before exiting.
  798  */
  799 int
  800 bridge_enqueue(struct ifnet *ifp, struct mbuf *m)
  801 {
  802         struct ifnet *brifp;
  803         struct ether_header *eh;
  804         struct ifnet *dst_if = NULL;
  805         unsigned int dst_ifidx = 0;
  806 #if NBPFILTER > 0
  807         caddr_t if_bpf;
  808 #endif
  809         int error = 0;
  810 
  811         if (m->m_len < sizeof(*eh)) {
  812                 m = m_pullup(m, sizeof(*eh));
  813                 if (m == NULL)
  814                         return (ENOBUFS);
  815         }
  816 
  817         /* ifp must be a member interface of the bridge. */
  818         brifp = if_get(ifp->if_bridgeidx);
  819         if (brifp == NULL) {
  820                 m_freem(m);
  821                 return (EINVAL);
  822         }
  823 
  824         /*
  825          * If bridge is down, but original output interface is up,
  826          * go ahead and send out that interface.  Otherwise the packet
  827          * is dropped below.
  828          */
  829         if (!ISSET(brifp->if_flags, IFF_RUNNING)) {
  830                 /* Loop prevention. */
  831                 m->m_flags |= M_PROTO1;
  832                 error = if_enqueue(ifp, m);
  833                 if_put(brifp);
  834                 return (error);
  835         }
  836 
  837 #if NBPFILTER > 0
  838         if_bpf = brifp->if_bpf;
  839         if (if_bpf)
  840                 bpf_mtap(if_bpf, m, BPF_DIRECTION_OUT);
  841 #endif
  842         ifp->if_opackets++;
  843         ifp->if_obytes += m->m_pkthdr.len;
  844 
  845         bridge_span(brifp, m);
  846 
  847         eh = mtod(m, struct ether_header *);
  848         if (!ETHER_IS_MULTICAST(eh->ether_dhost)) {
  849                 struct ether_addr *dst;
  850 
  851                 dst = (struct ether_addr *)&eh->ether_dhost[0];
  852                 dst_ifidx = bridge_rtlookup(brifp, dst, m);
  853         }
  854 
  855         /*
  856          * If the packet is a broadcast or we don't know a better way to
  857          * get there, send to all interfaces.
  858          */
  859         if (dst_ifidx == 0) {
  860                 struct bridge_softc *sc = brifp->if_softc;
  861                 struct bridge_iflist *bif;
  862                 struct mbuf *mc;
  863 
  864                 smr_read_enter();
  865                 SMR_SLIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
  866                         dst_if = bif->ifp;
  867                         if ((dst_if->if_flags & IFF_RUNNING) == 0)
  868                                 continue;
  869 
  870                         /*
  871                          * If this is not the original output interface,
  872                          * and the interface is participating in spanning
  873                          * tree, make sure the port is in a state that
  874                          * allows forwarding.
  875                          */
  876                         if (dst_if != ifp &&
  877                             (bif->bif_flags & IFBIF_STP) &&
  878                             (bif->bif_state == BSTP_IFSTATE_DISCARDING))
  879                                 continue;
  880                         if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
  881                             (m->m_flags & (M_BCAST | M_MCAST)) == 0)
  882                                 continue;
  883 
  884                         if (bridge_filterrule(&bif->bif_brlout, eh, m) ==
  885                             BRL_ACTION_BLOCK)
  886                                 continue;
  887 
  888                         mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
  889                         if (mc == NULL) {
  890                                 brifp->if_oerrors++;
  891                                 continue;
  892                         }
  893 
  894                         error = bridge_ifenqueue(brifp, dst_if, mc);
  895                         if (error)
  896                                 continue;
  897                 }
  898                 smr_read_leave();
  899                 m_freem(m);
  900                 goto out;
  901         }
  902 
  903         dst_if = if_get(dst_ifidx);
  904         if ((dst_if == NULL) || !ISSET(dst_if->if_flags, IFF_RUNNING)) {
  905                 m_freem(m);
  906                 if_put(dst_if);
  907                 error = ENETDOWN;
  908                 goto out;
  909         }
  910 
  911         bridge_ifenqueue(brifp, dst_if, m);
  912         if_put(dst_if);
  913 out:
  914         if_put(brifp);
  915         return (error);
  916 }
  917 
  918 /*
  919  * Loop through each bridge interface and process their input queues.
  920  */
  921 void
  922 bridgeintr(void)
  923 {
  924         struct mbuf_list ml;
  925         struct mbuf *m;
  926         struct ifnet *ifp;
  927 
  928         niq_delist(&bridgeintrq, &ml);
  929         if (ml_empty(&ml))
  930                 return;
  931 
  932         KERNEL_LOCK();
  933         while ((m = ml_dequeue(&ml)) != NULL) {
  934 
  935                 ifp = if_get(m->m_pkthdr.ph_ifidx);
  936                 if (ifp == NULL) {
  937                         m_freem(m);
  938                         continue;
  939                 }
  940 
  941                 bridge_process(ifp, m);
  942 
  943                 if_put(ifp);
  944         }
  945         KERNEL_UNLOCK();
  946 }
  947 
  948 /*
  949  * Process a single frame.  Frame must be freed or queued before returning.
  950  */
  951 void
  952 bridgeintr_frame(struct ifnet *brifp, struct ifnet *src_if, struct mbuf *m)
  953 {
  954         struct bridge_softc *sc = brifp->if_softc;
  955         struct ifnet *dst_if = NULL;
  956         struct bridge_iflist *bif;
  957         struct ether_addr *dst, *src;
  958         struct ether_header eh;
  959         unsigned int dst_ifidx;
  960         u_int32_t protected;
  961         int len;
  962 
  963 
  964         sc->sc_if.if_ipackets++;
  965         sc->sc_if.if_ibytes += m->m_pkthdr.len;
  966 
  967         bif = bridge_getbif(src_if);
  968         KASSERT(bif != NULL);
  969 
  970         m_copydata(m, 0, ETHER_HDR_LEN, &eh);
  971         dst = (struct ether_addr *)&eh.ether_dhost[0];
  972         src = (struct ether_addr *)&eh.ether_shost[0];
  973 
  974         /*
  975          * If interface is learning, and if source address
  976          * is not broadcast or multicast, record its address.
  977          */
  978         if ((bif->bif_flags & IFBIF_LEARNING) &&
  979             !ETHER_IS_MULTICAST(eh.ether_shost) &&
  980             !ETHER_IS_ANYADDR(eh.ether_shost))
  981                 bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC, m);
  982 
  983         if ((bif->bif_flags & IFBIF_STP) &&
  984             (bif->bif_state == BSTP_IFSTATE_LEARNING)) {
  985                 m_freem(m);
  986                 return;
  987         }
  988 
  989         /*
  990          * At this point, the port either doesn't participate in stp or
  991          * it's in the forwarding state
  992          */
  993 
  994         /*
  995          * If packet is unicast, destined for someone on "this"
  996          * side of the bridge, drop it.
  997          */
  998         if (!ETHER_IS_MULTICAST(eh.ether_dhost)) {
  999                 dst_ifidx = bridge_rtlookup(brifp, dst, NULL);
 1000                 if (dst_ifidx == src_if->if_index) {
 1001                         m_freem(m);
 1002                         return;
 1003                 }
 1004         } else {
 1005                 if (ETHER_IS_BROADCAST(eh.ether_dhost))
 1006                         m->m_flags |= M_BCAST;
 1007                 else
 1008                         m->m_flags |= M_MCAST;
 1009         }
 1010 
 1011         /*
 1012          * Multicast packets get handled a little differently:
 1013          * If interface is:
 1014          *      -link0,-link1   (default) Forward all multicast
 1015          *                      as broadcast.
 1016          *      -link0,link1    Drop non-IP multicast, forward
 1017          *                      as broadcast IP multicast.
 1018          *      link0,-link1    Drop IP multicast, forward as
 1019          *                      broadcast non-IP multicast.
 1020          *      link0,link1     Drop all multicast.
 1021          */
 1022         if (m->m_flags & M_MCAST) {
 1023                 if ((sc->sc_if.if_flags &
 1024                     (IFF_LINK0 | IFF_LINK1)) ==
 1025                     (IFF_LINK0 | IFF_LINK1)) {
 1026                         m_freem(m);
 1027                         return;
 1028                 }
 1029                 if (sc->sc_if.if_flags & IFF_LINK0 &&
 1030                     ETHERADDR_IS_IP_MCAST(dst)) {
 1031                         m_freem(m);
 1032                         return;
 1033                 }
 1034                 if (sc->sc_if.if_flags & IFF_LINK1 &&
 1035                     !ETHERADDR_IS_IP_MCAST(dst)) {
 1036                         m_freem(m);
 1037                         return;
 1038                 }
 1039         }
 1040 
 1041         if (bif->bif_flags & IFBIF_BLOCKNONIP && bridge_blocknonip(&eh, m)) {
 1042                 m_freem(m);
 1043                 return;
 1044         }
 1045 
 1046         if (bridge_filterrule(&bif->bif_brlin, &eh, m) == BRL_ACTION_BLOCK) {
 1047                 m_freem(m);
 1048                 return;
 1049         }
 1050         m = bridge_ip(&sc->sc_if, BRIDGE_IN, src_if, &eh, m);
 1051         if (m == NULL)
 1052                 return;
 1053         /*
 1054          * If the packet is a multicast or broadcast OR if we don't
 1055          * know any better, forward it to all interfaces.
 1056          */
 1057         if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_ifidx == 0) {
 1058                 sc->sc_if.if_imcasts++;
 1059                 bridge_broadcast(sc, src_if, &eh, m);
 1060                 return;
 1061         }
 1062         protected = bif->bif_protected;
 1063 
 1064         dst_if = if_get(dst_ifidx);
 1065         if (dst_if == NULL)
 1066                 goto bad;
 1067 
 1068         /*
 1069          * At this point, we're dealing with a unicast frame going to a
 1070          * different interface
 1071          */
 1072         if (!ISSET(dst_if->if_flags, IFF_RUNNING))
 1073                 goto bad;
 1074         bif = bridge_getbif(dst_if);
 1075         if ((bif == NULL) || ((bif->bif_flags & IFBIF_STP) &&
 1076             (bif->bif_state == BSTP_IFSTATE_DISCARDING)))
 1077                 goto bad;
 1078         /*
 1079          * Do not transmit if both ports are part of the same protected
 1080          * domain.
 1081          */
 1082         if (protected != 0 && (protected & bif->bif_protected))
 1083                 goto bad;
 1084         if (bridge_filterrule(&bif->bif_brlout, &eh, m) == BRL_ACTION_BLOCK)
 1085                 goto bad;
 1086         m = bridge_ip(&sc->sc_if, BRIDGE_OUT, dst_if, &eh, m);
 1087         if (m == NULL)
 1088                 goto bad;
 1089 
 1090         len = m->m_pkthdr.len;
 1091 #if NVLAN > 0
 1092         if ((m->m_flags & M_VLANTAG) &&
 1093             (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0)
 1094                 len += ETHER_VLAN_ENCAP_LEN;
 1095 #endif
 1096         if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
 1097                 bridge_fragment(&sc->sc_if, dst_if, &eh, m);
 1098         else {
 1099                 bridge_ifenqueue(&sc->sc_if, dst_if, m);
 1100         }
 1101         m = NULL;
 1102 bad:
 1103         if_put(dst_if);
 1104         m_freem(m);
 1105 }
 1106 
 1107 /*
 1108  * Return 1 if `ena' belongs to `bif', 0 otherwise.
 1109  */
 1110 int
 1111 bridge_ourether(struct ifnet *ifp, uint8_t *ena)
 1112 {
 1113         struct arpcom *ac = (struct arpcom *)ifp;
 1114 
 1115         if (memcmp(ac->ac_enaddr, ena, ETHER_ADDR_LEN) == 0)
 1116                 return (1);
 1117 
 1118 #if NCARP > 0
 1119         if (carp_ourether(ifp, ena))
 1120                 return (1);
 1121 #endif
 1122 
 1123         return (0);
 1124 }
 1125 
 1126 /*
 1127  * Receive input from an interface.  Queue the packet for bridging if its
 1128  * not for us, and schedule an interrupt.
 1129  */
 1130 struct mbuf *
 1131 bridge_input(struct ifnet *ifp, struct mbuf *m, uint64_t dst, void *null)
 1132 {
 1133         KASSERT(m->m_flags & M_PKTHDR);
 1134 
 1135         if (m->m_flags & M_PROTO1) {
 1136                 m->m_flags &= ~M_PROTO1;
 1137                 return (m);
 1138         }
 1139 
 1140         niq_enqueue(&bridgeintrq, m);
 1141 
 1142         return (NULL);
 1143 }
 1144 
 1145 void
 1146 bridge_process(struct ifnet *ifp, struct mbuf *m)
 1147 {
 1148         struct ifnet *brifp;
 1149         struct bridge_softc *sc;
 1150         struct bridge_iflist *bif = NULL, *bif0 = NULL;
 1151         struct ether_header *eh;
 1152         struct mbuf *mc;
 1153 #if NBPFILTER > 0
 1154         caddr_t if_bpf;
 1155 #endif
 1156 
 1157         KERNEL_ASSERT_LOCKED();
 1158 
 1159         brifp = if_get(ifp->if_bridgeidx);
 1160         if ((brifp == NULL) || !ISSET(brifp->if_flags, IFF_RUNNING))
 1161                 goto reenqueue;
 1162 
 1163         if (m->m_pkthdr.len < sizeof(*eh))
 1164                 goto bad;
 1165 
 1166 #if NVLAN > 0
 1167         /*
 1168          * If the underlying interface removed the VLAN header itself,
 1169          * add it back.
 1170          */
 1171         if (ISSET(m->m_flags, M_VLANTAG)) {
 1172                 m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag);
 1173                 if (m == NULL)
 1174                         goto bad;
 1175         }
 1176 #endif
 1177 
 1178 #if NBPFILTER > 0
 1179         if_bpf = brifp->if_bpf;
 1180         if (if_bpf)
 1181                 bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_IN);
 1182 #endif
 1183 
 1184         eh = mtod(m, struct ether_header *);
 1185 
 1186         sc = brifp->if_softc;
 1187         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
 1188                 struct arpcom *ac = (struct arpcom *)bif->ifp;
 1189                 if (memcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0)
 1190                         goto bad;
 1191                 if (bif->ifp == ifp)
 1192                         bif0 = bif;
 1193         }
 1194         if (bif0 == NULL)
 1195                 goto reenqueue;
 1196 
 1197         bridge_span(brifp, m);
 1198 
 1199         if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
 1200                 /*
 1201                  * Reserved destination MAC addresses (01:80:C2:00:00:0x)
 1202                  * should not be forwarded to bridge members according to
 1203                  * section 7.12.6 of the 802.1D-2004 specification.  The
 1204                  * STP destination address (as stored in bstp_etheraddr)
 1205                  * is the first of these.
 1206                  */
 1207                 if (memcmp(eh->ether_dhost, bstp_etheraddr,
 1208                     ETHER_ADDR_LEN - 1) == 0) {
 1209                         if (eh->ether_dhost[ETHER_ADDR_LEN - 1] == 0) {
 1210                                 /* STP traffic */
 1211                                 m = bstp_input(sc->sc_stp, bif0->bif_stp, eh,
 1212                                     m);
 1213                                 if (m == NULL)
 1214                                         goto bad;
 1215                         } else if (eh->ether_dhost[ETHER_ADDR_LEN - 1] <= 0xf)
 1216                                 goto bad;
 1217                 }
 1218 
 1219                 /*
 1220                  * No need to process frames for ifs in the discarding state
 1221                  */
 1222                 if ((bif0->bif_flags & IFBIF_STP) &&
 1223                     (bif0->bif_state == BSTP_IFSTATE_DISCARDING))
 1224                         goto reenqueue;
 1225 
 1226                 mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
 1227                 if (mc == NULL)
 1228                         goto reenqueue;
 1229 
 1230                 bridge_ifinput(ifp, mc);
 1231 
 1232                 bridgeintr_frame(brifp, ifp, m);
 1233                 if_put(brifp);
 1234                 return;
 1235         }
 1236 
 1237         /*
 1238          * Unicast, make sure it's not for us.
 1239          */
 1240         if (bridge_ourether(bif0->ifp, eh->ether_dhost)) {
 1241                 bif = bif0;
 1242         } else {
 1243                 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
 1244                         if (bif->ifp == ifp)
 1245                                 continue;
 1246                         if (bridge_ourether(bif->ifp, eh->ether_dhost))
 1247                                 break;
 1248                 }
 1249         }
 1250         if (bif != NULL) {
 1251                 if (bif0->bif_flags & IFBIF_LEARNING)
 1252                         bridge_rtupdate(sc,
 1253                             (struct ether_addr *)&eh->ether_shost,
 1254                             ifp, 0, IFBAF_DYNAMIC, m);
 1255                 if (bridge_filterrule(&bif0->bif_brlin, eh, m) ==
 1256                     BRL_ACTION_BLOCK) {
 1257                         goto bad;
 1258                 }
 1259 
 1260                 /* Count for the bridge */
 1261                 brifp->if_ipackets++;
 1262                 brifp->if_ibytes += m->m_pkthdr.len;
 1263 
 1264                 ifp = bif->ifp;
 1265                 goto reenqueue;
 1266         }
 1267 
 1268         bridgeintr_frame(brifp, ifp, m);
 1269         if_put(brifp);
 1270         return;
 1271 
 1272 reenqueue:
 1273         bridge_ifinput(ifp, m);
 1274         m = NULL;
 1275 bad:
 1276         m_freem(m);
 1277         if_put(brifp);
 1278 }
 1279 
 1280 /*
 1281  * Send a frame to all interfaces that are members of the bridge
 1282  * (except the one it came in on).
 1283  */
 1284 void
 1285 bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp,
 1286     struct ether_header *eh, struct mbuf *m)
 1287 {
 1288         struct bridge_iflist *bif;
 1289         struct mbuf *mc;
 1290         struct ifnet *dst_if;
 1291         int len, used = 0;
 1292         u_int32_t protected;
 1293 
 1294         bif = bridge_getbif(ifp);
 1295         KASSERT(bif != NULL);
 1296         protected = bif->bif_protected;
 1297 
 1298         SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
 1299                 dst_if = bif->ifp;
 1300 
 1301                 if ((dst_if->if_flags & IFF_RUNNING) == 0)
 1302                         continue;
 1303 
 1304                 if ((bif->bif_flags & IFBIF_STP) &&
 1305                     (bif->bif_state == BSTP_IFSTATE_DISCARDING))
 1306                         continue;
 1307 
 1308                 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
 1309                     (m->m_flags & (M_BCAST | M_MCAST)) == 0)
 1310                         continue;
 1311 
 1312                 /* Drop non-IP frames if the appropriate flag is set. */
 1313                 if (bif->bif_flags & IFBIF_BLOCKNONIP &&
 1314                     bridge_blocknonip(eh, m))
 1315                         continue;
 1316 
 1317                 /*
 1318                  * Do not transmit if both ports are part of the same
 1319                  * protected domain.
 1320                  */
 1321                 if (protected != 0 && (protected & bif->bif_protected))
 1322                         continue;
 1323 
 1324                 if (bridge_filterrule(&bif->bif_brlout, eh, m) ==
 1325                     BRL_ACTION_BLOCK)
 1326                         continue;
 1327 
 1328                 /*
 1329                  * Don't retransmit out of the same interface where
 1330                  * the packet was received from.
 1331                  */
 1332                 if (dst_if->if_index == ifp->if_index)
 1333                         continue;
 1334 
 1335                 if (bridge_localbroadcast(dst_if, eh, m))
 1336                         sc->sc_if.if_oerrors++;
 1337 
 1338                 /* If last one, reuse the passed-in mbuf */
 1339                 if (SMR_SLIST_NEXT_LOCKED(bif, bif_next) == NULL) {
 1340                         mc = m;
 1341                         used = 1;
 1342                 } else {
 1343                         mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
 1344                         if (mc == NULL) {
 1345                                 sc->sc_if.if_oerrors++;
 1346                                 continue;
 1347                         }
 1348                 }
 1349 
 1350                 mc = bridge_ip(&sc->sc_if, BRIDGE_OUT, dst_if, eh, mc);
 1351                 if (mc == NULL)
 1352                         continue;
 1353 
 1354                 len = mc->m_pkthdr.len;
 1355 #if NVLAN > 0
 1356                 if ((mc->m_flags & M_VLANTAG) &&
 1357                     (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0)
 1358                         len += ETHER_VLAN_ENCAP_LEN;
 1359 #endif
 1360                 if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
 1361                         bridge_fragment(&sc->sc_if, dst_if, eh, mc);
 1362                 else {
 1363                         bridge_ifenqueue(&sc->sc_if, dst_if, mc);
 1364                 }
 1365         }
 1366 
 1367         if (!used)
 1368                 m_freem(m);
 1369 }
 1370 
 1371 int
 1372 bridge_localbroadcast(struct ifnet *ifp, struct ether_header *eh,
 1373     struct mbuf *m)
 1374 {
 1375         struct mbuf *m1;
 1376         u_int16_t etype;
 1377 
 1378         /*
 1379          * quick optimisation, don't send packets up the stack if no
 1380          * corresponding address has been specified.
 1381          */
 1382         etype = ntohs(eh->ether_type);
 1383         if (!(m->m_flags & M_VLANTAG) && etype == ETHERTYPE_IP) {
 1384                 struct ifaddr *ifa;
 1385                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1386                         if (ifa->ifa_addr->sa_family == AF_INET)
 1387                                 break;
 1388                 }
 1389                 if (ifa == NULL)
 1390                         return (0);
 1391         }
 1392 
 1393         m1 = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
 1394         if (m1 == NULL)
 1395                 return (1);
 1396 
 1397 #if NPF > 0
 1398         pf_pkt_addr_changed(m1);
 1399 #endif  /* NPF */
 1400 
 1401         bridge_ifinput(ifp, m1);
 1402 
 1403         return (0);
 1404 }
 1405 
 1406 void
 1407 bridge_span(struct ifnet *brifp, struct mbuf *m)
 1408 {
 1409         struct bridge_softc *sc = brifp->if_softc;
 1410         struct bridge_iflist *bif;
 1411         struct ifnet *ifp;
 1412         struct mbuf *mc;
 1413         int error;
 1414 
 1415         smr_read_enter();
 1416         SMR_SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
 1417                 ifp = bif->ifp;
 1418 
 1419                 if ((ifp->if_flags & IFF_RUNNING) == 0)
 1420                         continue;
 1421 
 1422                 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
 1423                 if (mc == NULL) {
 1424                         brifp->if_oerrors++;
 1425                         continue;
 1426                 }
 1427 
 1428                 error = bridge_ifenqueue(brifp, ifp, mc);
 1429                 if (error)
 1430                         continue;
 1431         }
 1432         smr_read_leave();
 1433 }
 1434 
 1435 /*
 1436  * Block non-ip frames:
 1437  * Returns 0 if frame is ip, and 1 if it should be dropped.
 1438  */
 1439 int
 1440 bridge_blocknonip(struct ether_header *eh, struct mbuf *m)
 1441 {
 1442         struct llc llc;
 1443         u_int16_t etype;
 1444 
 1445         if (m->m_pkthdr.len < ETHER_HDR_LEN)
 1446                 return (1);
 1447 
 1448 #if NVLAN > 0
 1449         if (m->m_flags & M_VLANTAG)
 1450                 return (1);
 1451 #endif
 1452 
 1453         etype = ntohs(eh->ether_type);
 1454         switch (etype) {
 1455         case ETHERTYPE_ARP:
 1456         case ETHERTYPE_REVARP:
 1457         case ETHERTYPE_IP:
 1458         case ETHERTYPE_IPV6:
 1459                 return (0);
 1460         }
 1461 
 1462         if (etype > ETHERMTU)
 1463                 return (1);
 1464 
 1465         if (m->m_pkthdr.len <
 1466             (ETHER_HDR_LEN + LLC_SNAPFRAMELEN))
 1467                 return (1);
 1468 
 1469         m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, &llc);
 1470 
 1471         etype = ntohs(llc.llc_snap.ether_type);
 1472         if (llc.llc_dsap == LLC_SNAP_LSAP &&
 1473             llc.llc_ssap == LLC_SNAP_LSAP &&
 1474             llc.llc_control == LLC_UI &&
 1475             llc.llc_snap.org_code[0] == 0 &&
 1476             llc.llc_snap.org_code[1] == 0 &&
 1477             llc.llc_snap.org_code[2] == 0 &&
 1478             (etype == ETHERTYPE_ARP || etype == ETHERTYPE_REVARP ||
 1479             etype == ETHERTYPE_IP || etype == ETHERTYPE_IPV6)) {
 1480                 return (0);
 1481         }
 1482 
 1483         return (1);
 1484 }
 1485 
 1486 #ifdef IPSEC
 1487 int
 1488 bridge_ipsec(struct ifnet *ifp, struct ether_header *eh, int hassnap,
 1489     struct llc *llc, int dir, int af, int hlen, struct mbuf *m)
 1490 {
 1491         union sockaddr_union dst;
 1492         struct tdb *tdb;
 1493         u_int32_t spi;
 1494         u_int16_t cpi;
 1495         int error, off, prot;
 1496         u_int8_t proto = 0;
 1497         struct ip *ip;
 1498 #ifdef INET6
 1499         struct ip6_hdr *ip6;
 1500 #endif /* INET6 */
 1501 #if NPF > 0
 1502         struct ifnet *encif;
 1503 #endif
 1504 
 1505         if (dir == BRIDGE_IN) {
 1506                 switch (af) {
 1507                 case AF_INET:
 1508                         if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t))
 1509                                 goto skiplookup;
 1510 
 1511                         ip = mtod(m, struct ip *);
 1512                         proto = ip->ip_p;
 1513                         off = offsetof(struct ip, ip_p);
 1514 
 1515                         if (proto != IPPROTO_ESP && proto != IPPROTO_AH &&
 1516                             proto != IPPROTO_IPCOMP)
 1517                                 goto skiplookup;
 1518 
 1519                         bzero(&dst, sizeof(union sockaddr_union));
 1520                         dst.sa.sa_family = AF_INET;
 1521                         dst.sin.sin_len = sizeof(struct sockaddr_in);
 1522                         m_copydata(m, offsetof(struct ip, ip_dst),
 1523                             sizeof(struct in_addr), &dst.sin.sin_addr);
 1524 
 1525                         break;
 1526 #ifdef INET6
 1527                 case AF_INET6:
 1528                         if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t))
 1529                                 goto skiplookup;
 1530 
 1531                         ip6 = mtod(m, struct ip6_hdr *);
 1532 
 1533                         /* XXX We should chase down the header chain */
 1534                         proto = ip6->ip6_nxt;
 1535                         off = offsetof(struct ip6_hdr, ip6_nxt);
 1536 
 1537                         if (proto != IPPROTO_ESP && proto != IPPROTO_AH &&
 1538                             proto != IPPROTO_IPCOMP)
 1539                                 goto skiplookup;
 1540 
 1541                         bzero(&dst, sizeof(union sockaddr_union));
 1542                         dst.sa.sa_family = AF_INET6;
 1543                         dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
 1544                         m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
 1545                             sizeof(struct in6_addr), &dst.sin6.sin6_addr);
 1546 
 1547                         break;
 1548 #endif /* INET6 */
 1549                 default:
 1550                         return (0);
 1551                 }
 1552 
 1553                 switch (proto) {
 1554                 case IPPROTO_ESP:
 1555                         m_copydata(m, hlen, sizeof(u_int32_t), &spi);
 1556                         break;
 1557                 case IPPROTO_AH:
 1558                         m_copydata(m, hlen + sizeof(u_int32_t),
 1559                             sizeof(u_int32_t), &spi);
 1560                         break;
 1561                 case IPPROTO_IPCOMP:
 1562                         m_copydata(m, hlen + sizeof(u_int16_t),
 1563                             sizeof(u_int16_t), &cpi);
 1564                         spi = htonl(ntohs(cpi));
 1565                         break;
 1566                 }
 1567 
 1568                 NET_ASSERT_LOCKED();
 1569 
 1570                 tdb = gettdb(ifp->if_rdomain, spi, &dst, proto);
 1571                 if (tdb != NULL && (tdb->tdb_flags & TDBF_INVALID) == 0 &&
 1572                     tdb->tdb_xform != NULL) {
 1573                         if (tdb->tdb_first_use == 0) {
 1574                                 tdb->tdb_first_use = gettime();
 1575                                 if (tdb->tdb_flags & TDBF_FIRSTUSE) {
 1576                                         if (timeout_add_sec(
 1577                                             &tdb->tdb_first_tmo,
 1578                                             tdb->tdb_exp_first_use))
 1579                                                 tdb_ref(tdb);
 1580                                 }
 1581                                 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) {
 1582                                         if (timeout_add_sec(
 1583                                             &tdb->tdb_sfirst_tmo,
 1584                                             tdb->tdb_soft_first_use))
 1585                                                 tdb_ref(tdb);
 1586                                 }
 1587                         }
 1588 
 1589                         prot = (*(tdb->tdb_xform->xf_input))(&m, tdb, hlen,
 1590                             off);
 1591                         tdb_unref(tdb);
 1592                         if (prot != IPPROTO_DONE)
 1593                                 ip_deliver(&m, &hlen, prot, af);
 1594                         return (1);
 1595                 } else {
 1596                         tdb_unref(tdb);
 1597  skiplookup:
 1598                         /* XXX do an input policy lookup */
 1599                         return (0);
 1600                 }
 1601         } else { /* Outgoing from the bridge. */
 1602                 error = ipsp_spd_lookup(m, af, hlen, IPSP_DIRECTION_OUT,
 1603                     NULL, NULL, &tdb, NULL);
 1604                 if (error == 0 && tdb != NULL) {
 1605                         /*
 1606                          * We don't need to do loop detection, the
 1607                          * bridge will do that for us.
 1608                          */
 1609 #if NPF > 0
 1610                         if ((encif = enc_getif(tdb->tdb_rdomain,
 1611                             tdb->tdb_tap)) == NULL ||
 1612                             pf_test(af, dir, encif, &m) != PF_PASS) {
 1613                                 m_freem(m);
 1614                                 tdb_unref(tdb);
 1615                                 return (1);
 1616                         }
 1617                         if (m == NULL) {
 1618                                 tdb_unref(tdb);
 1619                                 return (1);
 1620                         }
 1621                         if (af == AF_INET)
 1622                                 in_proto_cksum_out(m, encif);
 1623 #ifdef INET6
 1624                         else if (af == AF_INET6)
 1625                                 in6_proto_cksum_out(m, encif);
 1626 #endif /* INET6 */
 1627 #endif /* NPF */
 1628 
 1629                         ip = mtod(m, struct ip *);
 1630                         if ((af == AF_INET) &&
 1631                             ip_mtudisc && (ip->ip_off & htons(IP_DF)) &&
 1632                             tdb->tdb_mtu && ntohs(ip->ip_len) > tdb->tdb_mtu &&
 1633                             tdb->tdb_mtutimeout > gettime()) {
 1634                                 bridge_send_icmp_err(ifp, eh, m,
 1635                                     hassnap, llc, tdb->tdb_mtu,
 1636                                     ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG);
 1637                         } else {
 1638                                 KERNEL_LOCK();
 1639                                 error = ipsp_process_packet(m, tdb, af, 0);
 1640                                 KERNEL_UNLOCK();
 1641                         }
 1642                         tdb_unref(tdb);
 1643                         return (1);
 1644                 } else
 1645                         return (0);
 1646         }
 1647 
 1648         return (0);
 1649 }
 1650 #endif /* IPSEC */
 1651 
 1652 /*
 1653  * Filter IP packets by peeking into the ethernet frame.  This violates
 1654  * the ISO model, but allows us to act as a IP filter at the data link
 1655  * layer.  As a result, most of this code will look familiar to those
 1656  * who've read net/if_ethersubr.c and netinet/ip_input.c
 1657  */
 1658 struct mbuf *
 1659 bridge_ip(struct ifnet *brifp, int dir, struct ifnet *ifp,
 1660     struct ether_header *eh, struct mbuf *m)
 1661 {
 1662         struct llc llc;
 1663         int hassnap = 0;
 1664         struct ip *ip;
 1665         int hlen;
 1666         u_int16_t etype;
 1667 
 1668 #if NVLAN > 0
 1669         if (m->m_flags & M_VLANTAG)
 1670                 return (m);
 1671 #endif
 1672 
 1673         etype = ntohs(eh->ether_type);
 1674 
 1675         if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) {
 1676                 if (etype > ETHERMTU ||
 1677                     m->m_pkthdr.len < (LLC_SNAPFRAMELEN +
 1678                     ETHER_HDR_LEN))
 1679                         return (m);
 1680 
 1681                 m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, &llc);
 1682 
 1683                 if (llc.llc_dsap != LLC_SNAP_LSAP ||
 1684                     llc.llc_ssap != LLC_SNAP_LSAP ||
 1685                     llc.llc_control != LLC_UI ||
 1686                     llc.llc_snap.org_code[0] ||
 1687                     llc.llc_snap.org_code[1] ||
 1688                     llc.llc_snap.org_code[2])
 1689                         return (m);
 1690 
 1691                 etype = ntohs(llc.llc_snap.ether_type);
 1692                 if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6)
 1693                         return (m);
 1694                 hassnap = 1;
 1695         }
 1696 
 1697         m_adj(m, ETHER_HDR_LEN);
 1698         if (hassnap)
 1699                 m_adj(m, LLC_SNAPFRAMELEN);
 1700 
 1701         switch (etype) {
 1702 
 1703         case ETHERTYPE_IP:
 1704                 m = ipv4_check(ifp, m);
 1705                 if (m == NULL)
 1706                         return (NULL);
 1707 
 1708                 ip = mtod(m, struct ip *);
 1709                 hlen = ip->ip_hl << 2;
 1710 
 1711 #ifdef IPSEC
 1712                 if ((brifp->if_flags & IFF_LINK2) == IFF_LINK2 &&
 1713                     bridge_ipsec(ifp, eh, hassnap, &llc, dir, AF_INET, hlen, m))
 1714                         return (NULL);
 1715 #endif /* IPSEC */
 1716 #if NPF > 0
 1717                 /* Finally, we get to filter the packet! */
 1718                 if (pf_test(AF_INET, dir, ifp, &m) != PF_PASS)
 1719                         goto dropit;
 1720                 if (m == NULL)
 1721                         goto dropit;
 1722 #endif /* NPF > 0 */
 1723 
 1724                 /* Rebuild the IP header */
 1725                 if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL))
 1726                         return (NULL);
 1727                 if (m->m_len < sizeof(struct ip))
 1728                         goto dropit;
 1729                 in_proto_cksum_out(m, ifp);
 1730                 ip = mtod(m, struct ip *);
 1731                 ip->ip_sum = 0;
 1732                 if (0 && (ifp->if_capabilities & IFCAP_CSUM_IPv4))
 1733                         m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
 1734                 else {
 1735                         ipstat_inc(ips_outswcsum);
 1736                         ip->ip_sum = in_cksum(m, hlen);
 1737                 }
 1738 
 1739 #if NPF > 0
 1740                 if (dir == BRIDGE_IN &&
 1741                     m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
 1742                         m_resethdr(m);
 1743                         m->m_pkthdr.ph_ifidx = ifp->if_index;
 1744                         m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
 1745                         ipv4_input(ifp, m);
 1746                         return (NULL);
 1747                 }
 1748 #endif /* NPF > 0 */
 1749 
 1750                 break;
 1751 
 1752 #ifdef INET6
 1753         case ETHERTYPE_IPV6:
 1754                 m = ipv6_check(ifp, m);
 1755                 if (m == NULL)
 1756                         return (NULL);
 1757 
 1758 #ifdef IPSEC
 1759                 hlen = sizeof(struct ip6_hdr);
 1760 
 1761                 if ((brifp->if_flags & IFF_LINK2) == IFF_LINK2 &&
 1762                     bridge_ipsec(ifp, eh, hassnap, &llc, dir, AF_INET6, hlen,
 1763                     m))
 1764                         return (NULL);
 1765 #endif /* IPSEC */
 1766 
 1767 #if NPF > 0
 1768                 if (pf_test(AF_INET6, dir, ifp, &m) != PF_PASS)
 1769                         goto dropit;
 1770                 if (m == NULL)
 1771                         return (NULL);
 1772 #endif /* NPF > 0 */
 1773                 in6_proto_cksum_out(m, ifp);
 1774 
 1775 #if NPF > 0
 1776                 if (dir == BRIDGE_IN &&
 1777                     m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
 1778                         m_resethdr(m);
 1779                         m->m_pkthdr.ph_ifidx = ifp->if_index;
 1780                         m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
 1781                         ipv6_input(ifp, m);
 1782                         return (NULL);
 1783                 }
 1784 #endif /* NPF > 0 */
 1785 
 1786                 break;
 1787 #endif /* INET6 */
 1788 
 1789         default:
 1790                 goto dropit;
 1791                 break;
 1792         }
 1793 
 1794         /* Reattach SNAP header */
 1795         if (hassnap) {
 1796                 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
 1797                 if (m == NULL)
 1798                         goto dropit;
 1799                 bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
 1800         }
 1801 
 1802         /* Reattach ethernet header */
 1803         M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
 1804         if (m == NULL)
 1805                 goto dropit;
 1806         bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
 1807 
 1808         return (m);
 1809 
 1810 dropit:
 1811         m_freem(m);
 1812         return (NULL);
 1813 }
 1814 
 1815 void
 1816 bridge_fragment(struct ifnet *brifp, struct ifnet *ifp, struct ether_header *eh,
 1817     struct mbuf *m)
 1818 {
 1819         struct llc llc;
 1820         struct mbuf_list fml;
 1821         int error = 0;
 1822         int hassnap = 0;
 1823         u_int16_t etype;
 1824         struct ip *ip;
 1825 
 1826         etype = ntohs(eh->ether_type);
 1827 #if NVLAN > 0
 1828         if ((m->m_flags & M_VLANTAG) || etype == ETHERTYPE_VLAN ||
 1829             etype == ETHERTYPE_QINQ) {
 1830                 int len = m->m_pkthdr.len;
 1831 
 1832                 if (m->m_flags & M_VLANTAG)
 1833                         len += ETHER_VLAN_ENCAP_LEN;
 1834                 if ((ifp->if_capabilities & IFCAP_VLAN_MTU) &&
 1835                     (len - sizeof(struct ether_vlan_header) <= ifp->if_mtu)) {
 1836                         bridge_ifenqueue(brifp, ifp, m);
 1837                         return;
 1838                 }
 1839                 goto dropit;
 1840         }
 1841 #endif
 1842         if (etype != ETHERTYPE_IP) {
 1843                 if (etype > ETHERMTU ||
 1844                     m->m_pkthdr.len < (LLC_SNAPFRAMELEN +
 1845                     ETHER_HDR_LEN))
 1846                         goto dropit;
 1847 
 1848                 m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, &llc);
 1849 
 1850                 if (llc.llc_dsap != LLC_SNAP_LSAP ||
 1851                     llc.llc_ssap != LLC_SNAP_LSAP ||
 1852                     llc.llc_control != LLC_UI ||
 1853                     llc.llc_snap.org_code[0] ||
 1854                     llc.llc_snap.org_code[1] ||
 1855                     llc.llc_snap.org_code[2] ||
 1856                     llc.llc_snap.ether_type != htons(ETHERTYPE_IP))
 1857                         goto dropit;
 1858 
 1859                 hassnap = 1;
 1860         }
 1861 
 1862         m_adj(m, ETHER_HDR_LEN);
 1863         if (hassnap)
 1864                 m_adj(m, LLC_SNAPFRAMELEN);
 1865 
 1866         if (m->m_len < sizeof(struct ip) &&
 1867             (m = m_pullup(m, sizeof(struct ip))) == NULL)
 1868                 goto dropit;
 1869         ip = mtod(m, struct ip *);
 1870 
 1871         /* Respect IP_DF, return a ICMP_UNREACH_NEEDFRAG. */
 1872         if (ip->ip_off & htons(IP_DF)) {
 1873                 bridge_send_icmp_err(ifp, eh, m, hassnap, &llc,
 1874                     ifp->if_mtu, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG);
 1875                 return;
 1876         }
 1877 
 1878         error = ip_fragment(m, &fml, ifp, ifp->if_mtu);
 1879         if (error)
 1880                 return;
 1881 
 1882         while ((m = ml_dequeue(&fml)) != NULL) {
 1883                 if (hassnap) {
 1884                         M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
 1885                         if (m == NULL) {
 1886                                 error = ENOBUFS;
 1887                                 break;
 1888                         }
 1889                         bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
 1890                 }
 1891                 M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
 1892                 if (m == NULL) {
 1893                         error = ENOBUFS;
 1894                         break;
 1895                 }
 1896                 bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
 1897                 error = bridge_ifenqueue(brifp, ifp, m);
 1898                 if (error)
 1899                         break;
 1900         }
 1901         if (error)
 1902                 ml_purge(&fml);
 1903         else
 1904                 ipstat_inc(ips_fragmented);
 1905 
 1906         return;
 1907  dropit:
 1908         m_freem(m);
 1909 }
 1910 
 1911 int
 1912 bridge_ifenqueue(struct ifnet *brifp, struct ifnet *ifp, struct mbuf *m)
 1913 {
 1914         int error, len;
 1915 
 1916         /* Loop prevention. */
 1917         m->m_flags |= M_PROTO1;
 1918 
 1919         len = m->m_pkthdr.len;
 1920 
 1921         error = if_enqueue(ifp, m);
 1922         if (error) {
 1923                 brifp->if_oerrors++;
 1924                 return (error);
 1925         }
 1926 
 1927         brifp->if_opackets++;
 1928         brifp->if_obytes += len;
 1929 
 1930         return (0);
 1931 }
 1932 
 1933 void
 1934 bridge_ifinput(struct ifnet *ifp, struct mbuf *m)
 1935 {
 1936         struct mbuf_list ml = MBUF_LIST_INITIALIZER();
 1937 
 1938         m->m_flags |= M_PROTO1;
 1939 
 1940         ml_enqueue(&ml, m);
 1941         if_input(ifp, &ml);
 1942 }
 1943 
 1944 void
 1945 bridge_send_icmp_err(struct ifnet *ifp,
 1946     struct ether_header *eh, struct mbuf *n, int hassnap, struct llc *llc,
 1947     int mtu, int type, int code)
 1948 {
 1949         struct ip *ip;
 1950         struct icmp *icp;
 1951         struct in_addr t;
 1952         struct mbuf *m, *n2;
 1953         int hlen;
 1954         u_int8_t ether_tmp[ETHER_ADDR_LEN];
 1955 
 1956         n2 = m_copym(n, 0, M_COPYALL, M_DONTWAIT);
 1957         if (!n2) {
 1958                 m_freem(n);
 1959                 return;
 1960         }
 1961         m = icmp_do_error(n, type, code, 0, mtu);
 1962         if (m == NULL) {
 1963                 m_freem(n2);
 1964                 return;
 1965         }
 1966 
 1967         n = n2;
 1968 
 1969         ip = mtod(m, struct ip *);
 1970         hlen = ip->ip_hl << 2;
 1971         t = ip->ip_dst;
 1972         ip->ip_dst = ip->ip_src;
 1973         ip->ip_src = t;
 1974 
 1975         m->m_data += hlen;
 1976         m->m_len -= hlen;
 1977         icp = mtod(m, struct icmp *);
 1978         icp->icmp_cksum = 0;
 1979         icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen);
 1980         m->m_data -= hlen;
 1981         m->m_len += hlen;
 1982 
 1983         ip->ip_v = IPVERSION;
 1984         ip->ip_off &= htons(IP_DF);
 1985         ip->ip_id = htons(ip_randomid());
 1986         ip->ip_ttl = MAXTTL;
 1987         ip->ip_sum = 0;
 1988         ip->ip_sum = in_cksum(m, hlen);
 1989 
 1990         /* Swap ethernet addresses */
 1991         bcopy(&eh->ether_dhost, &ether_tmp, sizeof(ether_tmp));
 1992         bcopy(&eh->ether_shost, &eh->ether_dhost, sizeof(ether_tmp));
 1993         bcopy(&ether_tmp, &eh->ether_shost, sizeof(ether_tmp));
 1994 
 1995         /* Reattach SNAP header */
 1996         if (hassnap) {
 1997                 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
 1998                 if (m == NULL)
 1999                         goto dropit;
 2000                 bcopy(llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
 2001         }
 2002 
 2003         /* Reattach ethernet header */
 2004         M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
 2005         if (m == NULL)
 2006                 goto dropit;
 2007         bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
 2008 
 2009         bridge_enqueue(ifp, m);
 2010         m_freem(n);
 2011         return;
 2012 
 2013  dropit:
 2014         m_freem(n);
 2015 }
 2016 
 2017 void
 2018 bridge_take(void *unused)
 2019 {
 2020         return;
 2021 }
 2022 
 2023 void
 2024 bridge_rele(void *unused)
 2025 {
 2026         return;
 2027 }

Cache object: 9406d8accf7f507b7d33220ff99bf7f1


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