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