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