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