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