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