if_bridge.c revision 1.36.4.1 1 /* $NetBSD: if_bridge.c,v 1.36.4.1 2006/02/04 14:18:52 simonb 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.4.1 2006/02/04 14:18:52 simonb 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 - time_uptime;
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 = time_uptime + 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 if (flags & IFBAF_STATIC)
1662 brt->brt_expire = 0;
1663 else
1664 brt->brt_expire = time_uptime + sc->sc_brttimeout;
1665 }
1666
1667 return (0);
1668 }
1669
1670 /*
1671 * bridge_rtlookup:
1672 *
1673 * Lookup the destination interface for an address.
1674 */
1675 static struct ifnet *
1676 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
1677 {
1678 struct bridge_rtnode *brt;
1679
1680 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
1681 return (NULL);
1682
1683 return (brt->brt_ifp);
1684 }
1685
1686 /*
1687 * bridge_rttrim:
1688 *
1689 * Trim the routine table so that we have a number
1690 * of routing entries less than or equal to the
1691 * maximum number.
1692 */
1693 static void
1694 bridge_rttrim(struct bridge_softc *sc)
1695 {
1696 struct bridge_rtnode *brt, *nbrt;
1697
1698 /* Make sure we actually need to do this. */
1699 if (sc->sc_brtcnt <= sc->sc_brtmax)
1700 return;
1701
1702 /* Force an aging cycle; this might trim enough addresses. */
1703 bridge_rtage(sc);
1704 if (sc->sc_brtcnt <= sc->sc_brtmax)
1705 return;
1706
1707 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1708 nbrt = LIST_NEXT(brt, brt_list);
1709 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1710 bridge_rtnode_destroy(sc, brt);
1711 if (sc->sc_brtcnt <= sc->sc_brtmax)
1712 return;
1713 }
1714 }
1715 }
1716
1717 /*
1718 * bridge_timer:
1719 *
1720 * Aging timer for the bridge.
1721 */
1722 static void
1723 bridge_timer(void *arg)
1724 {
1725 struct bridge_softc *sc = arg;
1726 int s;
1727
1728 s = splnet();
1729 bridge_rtage(sc);
1730 splx(s);
1731
1732 if (sc->sc_if.if_flags & IFF_RUNNING)
1733 callout_reset(&sc->sc_brcallout,
1734 bridge_rtable_prune_period * hz, bridge_timer, sc);
1735 }
1736
1737 /*
1738 * bridge_rtage:
1739 *
1740 * Perform an aging cycle.
1741 */
1742 static void
1743 bridge_rtage(struct bridge_softc *sc)
1744 {
1745 struct bridge_rtnode *brt, *nbrt;
1746
1747 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1748 nbrt = LIST_NEXT(brt, brt_list);
1749 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1750 if (time_uptime >= brt->brt_expire)
1751 bridge_rtnode_destroy(sc, brt);
1752 }
1753 }
1754 }
1755
1756 /*
1757 * bridge_rtflush:
1758 *
1759 * Remove all dynamic addresses from the bridge.
1760 */
1761 static void
1762 bridge_rtflush(struct bridge_softc *sc, int full)
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 (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
1769 bridge_rtnode_destroy(sc, brt);
1770 }
1771 }
1772
1773 /*
1774 * bridge_rtdaddr:
1775 *
1776 * Remove an address from the table.
1777 */
1778 static int
1779 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
1780 {
1781 struct bridge_rtnode *brt;
1782
1783 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
1784 return (ENOENT);
1785
1786 bridge_rtnode_destroy(sc, brt);
1787 return (0);
1788 }
1789
1790 /*
1791 * bridge_rtdelete:
1792 *
1793 * Delete routes to a speicifc member interface.
1794 */
1795 static void
1796 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp)
1797 {
1798 struct bridge_rtnode *brt, *nbrt;
1799
1800 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1801 nbrt = LIST_NEXT(brt, brt_list);
1802 if (brt->brt_ifp == ifp)
1803 bridge_rtnode_destroy(sc, brt);
1804 }
1805 }
1806
1807 /*
1808 * bridge_rtable_init:
1809 *
1810 * Initialize the route table for this bridge.
1811 */
1812 static int
1813 bridge_rtable_init(struct bridge_softc *sc)
1814 {
1815 int i;
1816
1817 sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
1818 M_DEVBUF, M_NOWAIT);
1819 if (sc->sc_rthash == NULL)
1820 return (ENOMEM);
1821
1822 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
1823 LIST_INIT(&sc->sc_rthash[i]);
1824
1825 sc->sc_rthash_key = arc4random();
1826
1827 LIST_INIT(&sc->sc_rtlist);
1828
1829 return (0);
1830 }
1831
1832 /*
1833 * bridge_rtable_fini:
1834 *
1835 * Deconstruct the route table for this bridge.
1836 */
1837 static void
1838 bridge_rtable_fini(struct bridge_softc *sc)
1839 {
1840
1841 free(sc->sc_rthash, M_DEVBUF);
1842 }
1843
1844 /*
1845 * The following hash function is adapted from "Hash Functions" by Bob Jenkins
1846 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
1847 */
1848 #define mix(a, b, c) \
1849 do { \
1850 a -= b; a -= c; a ^= (c >> 13); \
1851 b -= c; b -= a; b ^= (a << 8); \
1852 c -= a; c -= b; c ^= (b >> 13); \
1853 a -= b; a -= c; a ^= (c >> 12); \
1854 b -= c; b -= a; b ^= (a << 16); \
1855 c -= a; c -= b; c ^= (b >> 5); \
1856 a -= b; a -= c; a ^= (c >> 3); \
1857 b -= c; b -= a; b ^= (a << 10); \
1858 c -= a; c -= b; c ^= (b >> 15); \
1859 } while (/*CONSTCOND*/0)
1860
1861 static inline uint32_t
1862 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
1863 {
1864 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
1865
1866 b += addr[5] << 8;
1867 b += addr[4];
1868 a += addr[3] << 24;
1869 a += addr[2] << 16;
1870 a += addr[1] << 8;
1871 a += addr[0];
1872
1873 mix(a, b, c);
1874
1875 return (c & BRIDGE_RTHASH_MASK);
1876 }
1877
1878 #undef mix
1879
1880 /*
1881 * bridge_rtnode_lookup:
1882 *
1883 * Look up a bridge route node for the specified destination.
1884 */
1885 static struct bridge_rtnode *
1886 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
1887 {
1888 struct bridge_rtnode *brt;
1889 uint32_t hash;
1890 int dir;
1891
1892 hash = bridge_rthash(sc, addr);
1893 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
1894 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
1895 if (dir == 0)
1896 return (brt);
1897 if (dir > 0)
1898 return (NULL);
1899 }
1900
1901 return (NULL);
1902 }
1903
1904 /*
1905 * bridge_rtnode_insert:
1906 *
1907 * Insert the specified bridge node into the route table. We
1908 * assume the entry is not already in the table.
1909 */
1910 static int
1911 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
1912 {
1913 struct bridge_rtnode *lbrt;
1914 uint32_t hash;
1915 int dir;
1916
1917 hash = bridge_rthash(sc, brt->brt_addr);
1918
1919 lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
1920 if (lbrt == NULL) {
1921 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
1922 goto out;
1923 }
1924
1925 do {
1926 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
1927 if (dir == 0)
1928 return (EEXIST);
1929 if (dir > 0) {
1930 LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
1931 goto out;
1932 }
1933 if (LIST_NEXT(lbrt, brt_hash) == NULL) {
1934 LIST_INSERT_AFTER(lbrt, brt, brt_hash);
1935 goto out;
1936 }
1937 lbrt = LIST_NEXT(lbrt, brt_hash);
1938 } while (lbrt != NULL);
1939
1940 #ifdef DIAGNOSTIC
1941 panic("bridge_rtnode_insert: impossible");
1942 #endif
1943
1944 out:
1945 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
1946 sc->sc_brtcnt++;
1947
1948 return (0);
1949 }
1950
1951 /*
1952 * bridge_rtnode_destroy:
1953 *
1954 * Destroy a bridge rtnode.
1955 */
1956 static void
1957 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
1958 {
1959
1960 LIST_REMOVE(brt, brt_hash);
1961
1962 LIST_REMOVE(brt, brt_list);
1963 sc->sc_brtcnt--;
1964 pool_put(&bridge_rtnode_pool, brt);
1965 }
1966
1967 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
1968 extern struct pfil_head inet_pfil_hook; /* XXX */
1969 extern struct pfil_head inet6_pfil_hook; /* XXX */
1970
1971 /*
1972 * Send bridge packets through IPF if they are one of the types IPF can deal
1973 * with, or if they are ARP or REVARP. (IPF will pass ARP and REVARP without
1974 * question.)
1975 */
1976 static int
1977 bridge_ipf(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
1978 {
1979 int snap, error;
1980 struct ether_header *eh1, eh2;
1981 struct llc llc1;
1982 u_int16_t ether_type;
1983
1984 snap = 0;
1985 error = -1; /* Default error if not error == 0 */
1986 eh1 = mtod(*mp, struct ether_header *);
1987 ether_type = ntohs(eh1->ether_type);
1988
1989 /*
1990 * Check for SNAP/LLC.
1991 */
1992 if (ether_type < ETHERMTU) {
1993 struct llc *llc2 = (struct llc *)(eh1 + 1);
1994
1995 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
1996 llc2->llc_dsap == LLC_SNAP_LSAP &&
1997 llc2->llc_ssap == LLC_SNAP_LSAP &&
1998 llc2->llc_control == LLC_UI) {
1999 ether_type = htons(llc2->llc_un.type_snap.ether_type);
2000 snap = 1;
2001 }
2002 }
2003
2004 /*
2005 * If we're trying to filter bridge traffic, don't look at anything
2006 * other than IP and ARP traffic. If the filter doesn't understand
2007 * IPv6, don't allow IPv6 through the bridge either. This is lame
2008 * since if we really wanted, say, an AppleTalk filter, we are hosed,
2009 * but of course we don't have an AppleTalk filter to begin with.
2010 * (Note that since IPF doesn't understand ARP it will pass *ALL*
2011 * ARP traffic.)
2012 */
2013 switch (ether_type) {
2014 case ETHERTYPE_ARP:
2015 case ETHERTYPE_REVARP:
2016 return 0; /* Automatically pass */
2017 case ETHERTYPE_IP:
2018 # ifdef INET6
2019 case ETHERTYPE_IPV6:
2020 # endif /* INET6 */
2021 break;
2022 default:
2023 goto bad;
2024 }
2025
2026 /* Strip off the Ethernet header and keep a copy. */
2027 m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
2028 m_adj(*mp, ETHER_HDR_LEN);
2029
2030 /* Strip off snap header, if present */
2031 if (snap) {
2032 m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1);
2033 m_adj(*mp, sizeof(struct llc));
2034 }
2035
2036 /*
2037 * Check basic packet sanity and run IPF through pfil.
2038 */
2039 switch (ether_type)
2040 {
2041 case ETHERTYPE_IP :
2042 error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0;
2043 if (error == 0)
2044 error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, dir);
2045 break;
2046 # ifdef INET6
2047 case ETHERTYPE_IPV6 :
2048 error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0;
2049 if (error == 0)
2050 error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, dir);
2051 break;
2052 # endif
2053 default :
2054 error = 0;
2055 break;
2056 }
2057
2058 if (*mp == NULL)
2059 return error;
2060 if (error != 0)
2061 goto bad;
2062
2063 error = -1;
2064
2065 /*
2066 * Finally, put everything back the way it was and return
2067 */
2068 if (snap) {
2069 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
2070 if (*mp == NULL)
2071 return error;
2072 bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc));
2073 }
2074
2075 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2076 if (*mp == NULL)
2077 return error;
2078 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
2079
2080 return 0;
2081
2082 bad:
2083 m_freem(*mp);
2084 *mp = NULL;
2085 return error;
2086 }
2087
2088 /*
2089 * Perform basic checks on header size since
2090 * IPF assumes ip_input has already processed
2091 * it for it. Cut-and-pasted from ip_input.c.
2092 * Given how simple the IPv6 version is,
2093 * does the IPv4 version really need to be
2094 * this complicated?
2095 *
2096 * XXX Should we update ipstat here, or not?
2097 * XXX Right now we update ipstat but not
2098 * XXX csum_counter.
2099 */
2100 static int
2101 bridge_ip_checkbasic(struct mbuf **mp)
2102 {
2103 struct mbuf *m = *mp;
2104 struct ip *ip;
2105 int len, hlen;
2106
2107 if (*mp == NULL)
2108 return -1;
2109
2110 if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2111 if ((m = m_copyup(m, sizeof(struct ip),
2112 (max_linkhdr + 3) & ~3)) == NULL) {
2113 /* XXXJRT new stat, please */
2114 ipstat.ips_toosmall++;
2115 goto bad;
2116 }
2117 } else if (__predict_false(m->m_len < sizeof (struct ip))) {
2118 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
2119 ipstat.ips_toosmall++;
2120 goto bad;
2121 }
2122 }
2123 ip = mtod(m, struct ip *);
2124 if (ip == NULL) goto bad;
2125
2126 if (ip->ip_v != IPVERSION) {
2127 ipstat.ips_badvers++;
2128 goto bad;
2129 }
2130 hlen = ip->ip_hl << 2;
2131 if (hlen < sizeof(struct ip)) { /* minimum header length */
2132 ipstat.ips_badhlen++;
2133 goto bad;
2134 }
2135 if (hlen > m->m_len) {
2136 if ((m = m_pullup(m, hlen)) == 0) {
2137 ipstat.ips_badhlen++;
2138 goto bad;
2139 }
2140 ip = mtod(m, struct ip *);
2141 if (ip == NULL) goto bad;
2142 }
2143
2144 switch (m->m_pkthdr.csum_flags &
2145 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) |
2146 M_CSUM_IPv4_BAD)) {
2147 case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
2148 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */
2149 goto bad;
2150
2151 case M_CSUM_IPv4:
2152 /* Checksum was okay. */
2153 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */
2154 break;
2155
2156 default:
2157 /* Must compute it ourselves. */
2158 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */
2159 if (in_cksum(m, hlen) != 0)
2160 goto bad;
2161 break;
2162 }
2163
2164 /* Retrieve the packet length. */
2165 len = ntohs(ip->ip_len);
2166
2167 /*
2168 * Check for additional length bogosity
2169 */
2170 if (len < hlen) {
2171 ipstat.ips_badlen++;
2172 goto bad;
2173 }
2174
2175 /*
2176 * Check that the amount of data in the buffers
2177 * is as at least much as the IP header would have us expect.
2178 * Drop packet if shorter than we expect.
2179 */
2180 if (m->m_pkthdr.len < len) {
2181 ipstat.ips_tooshort++;
2182 goto bad;
2183 }
2184
2185 /* Checks out, proceed */
2186 *mp = m;
2187 return 0;
2188
2189 bad:
2190 *mp = m;
2191 return -1;
2192 }
2193
2194 # ifdef INET6
2195 /*
2196 * Same as above, but for IPv6.
2197 * Cut-and-pasted from ip6_input.c.
2198 * XXX Should we update ip6stat, or not?
2199 */
2200 static int
2201 bridge_ip6_checkbasic(struct mbuf **mp)
2202 {
2203 struct mbuf *m = *mp;
2204 struct ip6_hdr *ip6;
2205
2206 /*
2207 * If the IPv6 header is not aligned, slurp it up into a new
2208 * mbuf with space for link headers, in the event we forward
2209 * it. Otherwise, if it is aligned, make sure the entire base
2210 * IPv6 header is in the first mbuf of the chain.
2211 */
2212 if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2213 struct ifnet *inifp = m->m_pkthdr.rcvif;
2214 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
2215 (max_linkhdr + 3) & ~3)) == NULL) {
2216 /* XXXJRT new stat, please */
2217 ip6stat.ip6s_toosmall++;
2218 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2219 goto bad;
2220 }
2221 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
2222 struct ifnet *inifp = m->m_pkthdr.rcvif;
2223 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
2224 ip6stat.ip6s_toosmall++;
2225 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2226 goto bad;
2227 }
2228 }
2229
2230 ip6 = mtod(m, struct ip6_hdr *);
2231
2232 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
2233 ip6stat.ip6s_badvers++;
2234 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
2235 goto bad;
2236 }
2237
2238 /* Checks out, proceed */
2239 *mp = m;
2240 return 0;
2241
2242 bad:
2243 *mp = m;
2244 return -1;
2245 }
2246 # endif /* INET6 */
2247 #endif /* BRIDGE_IPF && PFIL_HOOKS */
2248