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