FreeBSD/Linux Kernel Cross Reference
sys/net/if_bridge.c
1 /* $OpenBSD: if_bridge.c,v 1.364 2022/08/07 00:57:43 bluhm Exp $ */
2
3 /*
4 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Effort sponsored in part by the Defense Advanced Research Projects
29 * Agency (DARPA) and Air Force Research Laboratory, Air Force
30 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
31 *
32 */
33
34 #include "bpfilter.h"
35 #include "gif.h"
36 #include "pf.h"
37 #include "carp.h"
38 #include "vlan.h"
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/mbuf.h>
43 #include <sys/socket.h>
44 #include <sys/ioctl.h>
45 #include <sys/kernel.h>
46
47 #include <net/if.h>
48 #include <net/if_types.h>
49 #include <net/if_llc.h>
50 #include <net/netisr.h>
51
52 #include <netinet/in.h>
53 #include <netinet/ip.h>
54 #include <netinet/ip_var.h>
55 #include <netinet/if_ether.h>
56 #include <netinet/ip_icmp.h>
57
58 #ifdef IPSEC
59 #include <netinet/ip_ipsp.h>
60 #include <net/if_enc.h>
61 #endif
62
63 #ifdef INET6
64 #include <netinet6/in6_var.h>
65 #include <netinet/ip6.h>
66 #include <netinet6/ip6_var.h>
67 #endif
68
69 #if NPF > 0
70 #include <net/pfvar.h>
71 #define BRIDGE_IN PF_IN
72 #define BRIDGE_OUT PF_OUT
73 #else
74 #define BRIDGE_IN 0
75 #define BRIDGE_OUT 1
76 #endif
77
78 #if NBPFILTER > 0
79 #include <net/bpf.h>
80 #endif
81
82 #if NCARP > 0
83 #include <netinet/ip_carp.h>
84 #endif
85
86 #if NVLAN > 0
87 #include <net/if_vlan_var.h>
88 #endif
89
90 #include <net/if_bridge.h>
91
92 /*
93 * Maximum number of addresses to cache
94 */
95 #ifndef BRIDGE_RTABLE_MAX
96 #define BRIDGE_RTABLE_MAX 100
97 #endif
98
99 /*
100 * Timeout (in seconds) for entries learned dynamically
101 */
102 #ifndef BRIDGE_RTABLE_TIMEOUT
103 #define BRIDGE_RTABLE_TIMEOUT 240
104 #endif
105
106 void bridgeattach(int);
107 int bridge_ioctl(struct ifnet *, u_long, caddr_t);
108 void bridge_ifdetach(void *);
109 void bridge_spandetach(void *);
110 int bridge_ifremove(struct bridge_iflist *);
111 void bridge_spanremove(struct bridge_iflist *);
112 struct mbuf *
113 bridge_input(struct ifnet *, struct mbuf *, uint64_t, void *);
114 void bridge_process(struct ifnet *, struct mbuf *);
115 void bridgeintr_frame(struct ifnet *, struct ifnet *, struct mbuf *);
116 void bridge_bifgetstp(struct bridge_softc *, struct bridge_iflist *,
117 struct ifbreq *);
118 void bridge_broadcast(struct bridge_softc *, struct ifnet *,
119 struct ether_header *, struct mbuf *);
120 int bridge_localbroadcast(struct ifnet *, struct ether_header *,
121 struct mbuf *);
122 void bridge_span(struct ifnet *, struct mbuf *);
123 void bridge_stop(struct bridge_softc *);
124 void bridge_init(struct bridge_softc *);
125 int bridge_bifconf(struct bridge_softc *, struct ifbifconf *);
126 int bridge_blocknonip(struct ether_header *, struct mbuf *);
127 void bridge_ifinput(struct ifnet *, struct mbuf *);
128 int bridge_dummy_output(struct ifnet *, struct mbuf *, struct sockaddr *,
129 struct rtentry *);
130 void bridge_send_icmp_err(struct ifnet *, struct ether_header *,
131 struct mbuf *, int, struct llc *, int, int, int);
132 int bridge_ifenqueue(struct ifnet *, struct ifnet *, struct mbuf *);
133 struct mbuf *bridge_ip(struct ifnet *, int, struct ifnet *,
134 struct ether_header *, struct mbuf *);
135 #ifdef IPSEC
136 int bridge_ipsec(struct ifnet *, struct ether_header *, int, struct llc *,
137 int, int, int, struct mbuf *);
138 #endif
139 int bridge_clone_create(struct if_clone *, int);
140 int bridge_clone_destroy(struct ifnet *);
141 void bridge_take(void *);
142 void bridge_rele(void *);
143
144 #define ETHERADDR_IS_IP_MCAST(a) \
145 /* struct etheraddr *a; */ \
146 ((a)->ether_addr_octet[0] == 0x01 && \
147 (a)->ether_addr_octet[1] == 0x00 && \
148 (a)->ether_addr_octet[2] == 0x5e)
149
150 struct niqueue bridgeintrq = NIQUEUE_INITIALIZER(1024, NETISR_BRIDGE);
151
152 struct if_clone bridge_cloner =
153 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
154
155 const struct ether_brport bridge_brport = {
156 bridge_input,
157 bridge_take,
158 bridge_rele,
159 NULL,
160 };
161
162 void
163 bridgeattach(int n)
164 {
165 if_clone_attach(&bridge_cloner);
166 }
167
168 int
169 bridge_clone_create(struct if_clone *ifc, int unit)
170 {
171 struct bridge_softc *sc;
172 struct ifnet *ifp;
173 int i;
174
175 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
176 sc->sc_stp = bstp_create();
177 if (!sc->sc_stp) {
178 free(sc, M_DEVBUF, sizeof *sc);
179 return (ENOMEM);
180 }
181
182 sc->sc_brtmax = BRIDGE_RTABLE_MAX;
183 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
184 timeout_set(&sc->sc_brtimeout, bridge_rtage, sc);
185 SMR_SLIST_INIT(&sc->sc_iflist);
186 SMR_SLIST_INIT(&sc->sc_spanlist);
187 mtx_init(&sc->sc_mtx, IPL_MPFLOOR);
188 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++)
189 LIST_INIT(&sc->sc_rts[i]);
190 arc4random_buf(&sc->sc_hashkey, sizeof(sc->sc_hashkey));
191 ifp = &sc->sc_if;
192 snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
193 unit);
194 ifp->if_softc = sc;
195 ifp->if_mtu = ETHERMTU;
196 ifp->if_ioctl = bridge_ioctl;
197 ifp->if_output = bridge_dummy_output;
198 ifp->if_xflags = IFXF_CLONED;
199 ifp->if_start = NULL;
200 ifp->if_type = IFT_BRIDGE;
201 ifp->if_hdrlen = ETHER_HDR_LEN;
202
203 if_attach(ifp);
204 if_alloc_sadl(ifp);
205
206 #if NBPFILTER > 0
207 bpfattach(&sc->sc_if.if_bpf, ifp,
208 DLT_EN10MB, ETHER_HDR_LEN);
209 #endif
210
211 return (0);
212 }
213
214 int
215 bridge_dummy_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
216 struct rtentry *rt)
217 {
218 m_freem(m);
219 return (EAFNOSUPPORT);
220 }
221
222 int
223 bridge_clone_destroy(struct ifnet *ifp)
224 {
225 struct bridge_softc *sc = ifp->if_softc;
226 struct bridge_iflist *bif;
227
228 /*
229 * bridge(4) detach hook doesn't need the NET_LOCK(), worst the
230 * use of smr_barrier() while holding the lock might lead to a
231 * deadlock situation.
232 */
233 NET_ASSERT_UNLOCKED();
234
235 bridge_stop(sc);
236 bridge_rtflush(sc, IFBF_FLUSHALL);
237 while ((bif = SMR_SLIST_FIRST_LOCKED(&sc->sc_iflist)) != NULL)
238 bridge_ifremove(bif);
239 while ((bif = SMR_SLIST_FIRST_LOCKED(&sc->sc_spanlist)) != NULL)
240 bridge_spanremove(bif);
241
242 bstp_destroy(sc->sc_stp);
243
244 if_detach(ifp);
245
246 free(sc, M_DEVBUF, sizeof *sc);
247 return (0);
248 }
249
250 int
251 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
252 {
253 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc;
254 struct ifbreq *req = (struct ifbreq *)data;
255 struct ifbropreq *brop = (struct ifbropreq *)data;
256 struct ifnet *ifs;
257 struct bridge_iflist *bif;
258 struct bstp_port *bp;
259 struct bstp_state *bs = sc->sc_stp;
260 int error = 0;
261
262 /*
263 * bridge(4) data structure aren't protected by the NET_LOCK().
264 * Idealy it shouldn't be taken before calling `ifp->if_ioctl'
265 * but we aren't there yet. Media ioctl run without netlock.
266 */
267 switch (cmd) {
268 case SIOCSIFMEDIA:
269 case SIOCGIFMEDIA:
270 return (ENOTTY);
271 }
272 NET_UNLOCK();
273
274 switch (cmd) {
275 case SIOCBRDGADD:
276 /* bridge(4) does not distinguish between routing/forwarding ports */
277 case SIOCBRDGADDL:
278 if ((error = suser(curproc)) != 0)
279 break;
280
281 ifs = if_unit(req->ifbr_ifsname);
282 if (ifs == NULL) { /* no such interface */
283 error = ENOENT;
284 break;
285 }
286 if (ifs->if_type != IFT_ETHER) {
287 if_put(ifs);
288 error = EINVAL;
289 break;
290 }
291 if (ifs->if_bridgeidx != 0) {
292 if (ifs->if_bridgeidx == ifp->if_index)
293 error = EEXIST;
294 else
295 error = EBUSY;
296 if_put(ifs);
297 break;
298 }
299
300 error = ether_brport_isset(ifs);
301 if (error != 0) {
302 if_put(ifs);
303 break;
304 }
305
306 /* If it's in the span list, it can't be a member. */
307 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
308 if (bif->ifp == ifs)
309 break;
310 }
311 if (bif != NULL) {
312 if_put(ifs);
313 error = EBUSY;
314 break;
315 }
316
317 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
318 if (bif == NULL) {
319 if_put(ifs);
320 error = ENOMEM;
321 break;
322 }
323
324 NET_LOCK();
325 error = ifpromisc(ifs, 1);
326 NET_UNLOCK();
327 if (error != 0) {
328 if_put(ifs);
329 free(bif, M_DEVBUF, sizeof(*bif));
330 break;
331 }
332
333 /*
334 * XXX If the NET_LOCK() or ifpromisc() calls above
335 * had to sleep, then something else could have come
336 * along and taken over ifs while the kernel lock was
337 * released.
338 */
339
340 bif->bridge_sc = sc;
341 bif->ifp = ifs;
342 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
343 SIMPLEQ_INIT(&bif->bif_brlin);
344 SIMPLEQ_INIT(&bif->bif_brlout);
345 ifs->if_bridgeidx = ifp->if_index;
346 task_set(&bif->bif_dtask, bridge_ifdetach, bif);
347 if_detachhook_add(ifs, &bif->bif_dtask);
348 ether_brport_set(bif->ifp, &bridge_brport);
349 SMR_SLIST_INSERT_HEAD_LOCKED(&sc->sc_iflist, bif, bif_next);
350 break;
351 case SIOCBRDGDEL:
352 if ((error = suser(curproc)) != 0)
353 break;
354 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
355 if (error != 0)
356 break;
357 bridge_ifremove(bif);
358 break;
359 case SIOCBRDGIFS:
360 error = bridge_bifconf(sc, (struct ifbifconf *)data);
361 break;
362 case SIOCBRDGADDS:
363 if ((error = suser(curproc)) != 0)
364 break;
365 ifs = if_unit(req->ifbr_ifsname);
366 if (ifs == NULL) { /* no such interface */
367 error = ENOENT;
368 break;
369 }
370 if (ifs->if_type != IFT_ETHER) {
371 if_put(ifs);
372 error = EINVAL;
373 break;
374 }
375 if (ifs->if_bridgeidx != 0) {
376 if (ifs->if_bridgeidx == ifp->if_index)
377 error = EEXIST;
378 else
379 error = EBUSY;
380 if_put(ifs);
381 break;
382 }
383 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
384 if (bif->ifp == ifs)
385 break;
386 }
387 if (bif != NULL) {
388 if_put(ifs);
389 error = EEXIST;
390 break;
391 }
392 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
393 if (bif == NULL) {
394 if_put(ifs);
395 error = ENOMEM;
396 break;
397 }
398 bif->bridge_sc = sc;
399 bif->ifp = ifs;
400 bif->bif_flags = IFBIF_SPAN;
401 SIMPLEQ_INIT(&bif->bif_brlin);
402 SIMPLEQ_INIT(&bif->bif_brlout);
403 task_set(&bif->bif_dtask, bridge_spandetach, bif);
404 if_detachhook_add(ifs, &bif->bif_dtask);
405 SMR_SLIST_INSERT_HEAD_LOCKED(&sc->sc_spanlist, bif, bif_next);
406 break;
407 case SIOCBRDGDELS:
408 if ((error = suser(curproc)) != 0)
409 break;
410 ifs = if_unit(req->ifbr_ifsname);
411 if (ifs == NULL) {
412 error = ENOENT;
413 break;
414 }
415 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
416 if (bif->ifp == ifs)
417 break;
418 }
419 if_put(ifs);
420 if (bif == NULL) {
421 error = ESRCH;
422 break;
423 }
424 bridge_spanremove(bif);
425 break;
426 case SIOCBRDGGIFFLGS:
427 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
428 if (error != 0)
429 break;
430 req->ifbr_ifsflags = bif->bif_flags;
431 req->ifbr_portno = bif->ifp->if_index & 0xfff;
432 req->ifbr_protected = bif->bif_protected;
433 if (bif->bif_flags & IFBIF_STP)
434 bridge_bifgetstp(sc, bif, req);
435 break;
436 case SIOCBRDGSIFFLGS:
437 if (req->ifbr_ifsflags & IFBIF_RO_MASK) {
438 error = EINVAL;
439 break;
440 }
441 if ((error = suser(curproc)) != 0)
442 break;
443 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
444 if (error != 0)
445 break;
446 if (req->ifbr_ifsflags & IFBIF_STP) {
447 if ((bif->bif_flags & IFBIF_STP) == 0) {
448 /* Enable STP */
449 if ((bif->bif_stp = bstp_add(sc->sc_stp,
450 bif->ifp)) == NULL) {
451 error = ENOMEM;
452 break;
453 }
454 } else {
455 /* Update STP flags */
456 bstp_ifsflags(bif->bif_stp, req->ifbr_ifsflags);
457 }
458 } else if (bif->bif_flags & IFBIF_STP) {
459 bstp_delete(bif->bif_stp);
460 bif->bif_stp = NULL;
461 }
462 bif->bif_flags = req->ifbr_ifsflags;
463 break;
464 case SIOCSIFFLAGS:
465 if ((ifp->if_flags & IFF_UP) == IFF_UP)
466 bridge_init(sc);
467
468 if ((ifp->if_flags & IFF_UP) == 0)
469 bridge_stop(sc);
470
471 break;
472 case SIOCBRDGGPARAM:
473 if ((bp = bs->bs_root_port) == NULL)
474 brop->ifbop_root_port = 0;
475 else
476 brop->ifbop_root_port = bp->bp_ifindex;
477 brop->ifbop_maxage = bs->bs_bridge_max_age >> 8;
478 brop->ifbop_hellotime = bs->bs_bridge_htime >> 8;
479 brop->ifbop_fwddelay = bs->bs_bridge_fdelay >> 8;
480 brop->ifbop_holdcount = bs->bs_txholdcount;
481 brop->ifbop_priority = bs->bs_bridge_priority;
482 brop->ifbop_protocol = bs->bs_protover;
483 brop->ifbop_root_bridge = bs->bs_root_pv.pv_root_id;
484 brop->ifbop_root_path_cost = bs->bs_root_pv.pv_cost;
485 brop->ifbop_root_port = bs->bs_root_pv.pv_port_id;
486 brop->ifbop_desg_bridge = bs->bs_root_pv.pv_dbridge_id;
487 brop->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec;
488 brop->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec;
489 break;
490 case SIOCBRDGSIFPROT:
491 error = bridge_findbif(sc, req->ifbr_ifsname, &bif);
492 if (error != 0)
493 break;
494 bif->bif_protected = req->ifbr_protected;
495 break;
496 case SIOCBRDGRTS:
497 case SIOCBRDGGCACHE:
498 case SIOCBRDGGPRI:
499 case SIOCBRDGGMA:
500 case SIOCBRDGGHT:
501 case SIOCBRDGGFD:
502 case SIOCBRDGGTO:
503 case SIOCBRDGGRL:
504 break;
505 case SIOCBRDGFLUSH:
506 case SIOCBRDGSADDR:
507 case SIOCBRDGDADDR:
508 case SIOCBRDGSCACHE:
509 case SIOCBRDGSTO:
510 case SIOCBRDGARL:
511 case SIOCBRDGFRL:
512 case SIOCBRDGSPRI:
513 case SIOCBRDGSFD:
514 case SIOCBRDGSMA:
515 case SIOCBRDGSHT:
516 case SIOCBRDGSTXHC:
517 case SIOCBRDGSPROTO:
518 case SIOCBRDGSIFPRIO:
519 case SIOCBRDGSIFCOST:
520 error = suser(curproc);
521 break;
522 default:
523 error = ENOTTY;
524 break;
525 }
526
527 if (!error)
528 error = bridgectl_ioctl(ifp, cmd, data);
529
530 if (!error)
531 error = bstp_ioctl(ifp, cmd, data);
532
533 NET_LOCK();
534 return (error);
535 }
536
537 /* Detach an interface from a bridge. */
538 int
539 bridge_ifremove(struct bridge_iflist *bif)
540 {
541 struct bridge_softc *sc = bif->bridge_sc;
542 int error;
543
544 SMR_SLIST_REMOVE_LOCKED(&sc->sc_iflist, bif, bridge_iflist, bif_next);
545 if_detachhook_del(bif->ifp, &bif->bif_dtask);
546 ether_brport_clr(bif->ifp);
547
548 smr_barrier();
549
550 if (bif->bif_flags & IFBIF_STP) {
551 bstp_delete(bif->bif_stp);
552 bif->bif_stp = NULL;
553 }
554
555 bif->ifp->if_bridgeidx = 0;
556 NET_LOCK();
557 error = ifpromisc(bif->ifp, 0);
558 NET_UNLOCK();
559
560 bridge_rtdelete(sc, bif->ifp, 0);
561 bridge_flushrule(bif);
562
563 if_put(bif->ifp);
564 bif->ifp = NULL;
565 free(bif, M_DEVBUF, sizeof(*bif));
566
567 return (error);
568 }
569
570 void
571 bridge_spanremove(struct bridge_iflist *bif)
572 {
573 struct bridge_softc *sc = bif->bridge_sc;
574
575 SMR_SLIST_REMOVE_LOCKED(&sc->sc_spanlist, bif, bridge_iflist, bif_next);
576 if_detachhook_del(bif->ifp, &bif->bif_dtask);
577
578 smr_barrier();
579
580 if_put(bif->ifp);
581 bif->ifp = NULL;
582 free(bif, M_DEVBUF, sizeof(*bif));
583 }
584
585 void
586 bridge_ifdetach(void *xbif)
587 {
588 struct bridge_iflist *bif = xbif;
589
590 /*
591 * bridge(4) detach hook doesn't need the NET_LOCK(), worst the
592 * use of smr_barrier() while holding the lock might lead to a
593 * deadlock situation.
594 */
595 NET_UNLOCK();
596 bridge_ifremove(bif);
597 NET_LOCK();
598 }
599
600 void
601 bridge_spandetach(void *xbif)
602 {
603 struct bridge_iflist *bif = xbif;
604
605 /*
606 * bridge(4) detach hook doesn't need the NET_LOCK(), worst the
607 * use of smr_barrier() while holding the lock might lead to a
608 * deadlock situation.
609 */
610 NET_UNLOCK();
611 bridge_spanremove(bif);
612 NET_LOCK();
613 }
614
615 void
616 bridge_bifgetstp(struct bridge_softc *sc, struct bridge_iflist *bif,
617 struct ifbreq *breq)
618 {
619 struct bstp_state *bs = sc->sc_stp;
620 struct bstp_port *bp = bif->bif_stp;
621
622 breq->ifbr_state = bstp_getstate(bs, bp);
623 breq->ifbr_priority = bp->bp_priority;
624 breq->ifbr_path_cost = bp->bp_path_cost;
625 breq->ifbr_proto = bp->bp_protover;
626 breq->ifbr_role = bp->bp_role;
627 breq->ifbr_stpflags = bp->bp_flags;
628 breq->ifbr_fwd_trans = bp->bp_forward_transitions;
629 breq->ifbr_root_bridge = bs->bs_root_pv.pv_root_id;
630 breq->ifbr_root_cost = bs->bs_root_pv.pv_cost;
631 breq->ifbr_root_port = bs->bs_root_pv.pv_port_id;
632 breq->ifbr_desg_bridge = bs->bs_root_pv.pv_dbridge_id;
633 breq->ifbr_desg_port = bs->bs_root_pv.pv_dport_id;
634
635 /* Copy STP state options as flags */
636 if (bp->bp_operedge)
637 breq->ifbr_ifsflags |= IFBIF_BSTP_EDGE;
638 if (bp->bp_flags & BSTP_PORT_AUTOEDGE)
639 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE;
640 if (bp->bp_ptp_link)
641 breq->ifbr_ifsflags |= IFBIF_BSTP_PTP;
642 if (bp->bp_flags & BSTP_PORT_AUTOPTP)
643 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP;
644 }
645
646 int
647 bridge_bifconf(struct bridge_softc *sc, struct ifbifconf *bifc)
648 {
649 struct bridge_iflist *bif;
650 u_int32_t total = 0, i = 0;
651 int error = 0;
652 struct ifbreq *breq, *breqs = NULL;
653
654 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next)
655 total++;
656
657 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next)
658 total++;
659
660 if (bifc->ifbic_len == 0) {
661 i = total;
662 goto done;
663 }
664
665 breqs = mallocarray(total, sizeof(*breqs), M_TEMP, M_NOWAIT|M_ZERO);
666 if (breqs == NULL)
667 goto done;
668
669 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
670 if (bifc->ifbic_len < (i + 1) * sizeof(*breqs))
671 break;
672 breq = &breqs[i];
673 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
674 strlcpy(breq->ifbr_ifsname, bif->ifp->if_xname, IFNAMSIZ);
675 breq->ifbr_ifsflags = bif->bif_flags;
676 breq->ifbr_portno = bif->ifp->if_index & 0xfff;
677 breq->ifbr_protected = bif->bif_protected;
678 if (bif->bif_flags & IFBIF_STP)
679 bridge_bifgetstp(sc, bif, breq);
680 i++;
681 }
682 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) {
683 if (bifc->ifbic_len < (i + 1) * sizeof(*breqs))
684 break;
685 breq = &breqs[i];
686 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
687 strlcpy(breq->ifbr_ifsname, bif->ifp->if_xname, IFNAMSIZ);
688 breq->ifbr_ifsflags = bif->bif_flags | IFBIF_SPAN;
689 breq->ifbr_portno = bif->ifp->if_index & 0xfff;
690 i++;
691 }
692
693 error = copyout(breqs, bifc->ifbic_req, i * sizeof(*breqs));
694 done:
695 free(breqs, M_TEMP, total * sizeof(*breq));
696 bifc->ifbic_len = i * sizeof(*breq);
697 return (error);
698 }
699
700 int
701 bridge_findbif(struct bridge_softc *sc, const char *name,
702 struct bridge_iflist **rbif)
703 {
704 struct ifnet *ifp;
705 struct bridge_iflist *bif;
706 int error = 0;
707
708 KERNEL_ASSERT_LOCKED();
709
710 if ((ifp = if_unit(name)) == NULL)
711 return (ENOENT);
712
713 if (ifp->if_bridgeidx != sc->sc_if.if_index) {
714 error = ESRCH;
715 goto put;
716 }
717
718 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
719 if (bif->ifp == ifp)
720 break;
721 }
722
723 if (bif == NULL) {
724 error = ENOENT;
725 goto put;
726 }
727
728 *rbif = bif;
729 put:
730 if_put(ifp);
731
732 return (error);
733 }
734
735 struct bridge_iflist *
736 bridge_getbif(struct ifnet *ifp)
737 {
738 struct bridge_iflist *bif;
739 struct bridge_softc *sc;
740 struct ifnet *bifp;
741
742 KERNEL_ASSERT_LOCKED();
743
744 bifp = if_get(ifp->if_bridgeidx);
745 if (bifp == NULL)
746 return (NULL);
747
748 sc = bifp->if_softc;
749 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
750 if (bif->ifp == ifp)
751 break;
752 }
753
754 if_put(bifp);
755
756 return (bif);
757 }
758
759 void
760 bridge_init(struct bridge_softc *sc)
761 {
762 struct ifnet *ifp = &sc->sc_if;
763
764 if (ISSET(ifp->if_flags, IFF_RUNNING))
765 return;
766
767 bstp_enable(sc->sc_stp, ifp->if_index);
768
769 if (sc->sc_brttimeout != 0)
770 timeout_add_sec(&sc->sc_brtimeout, sc->sc_brttimeout);
771
772 SET(ifp->if_flags, IFF_RUNNING);
773 }
774
775 /*
776 * Stop the bridge and deallocate the routing table.
777 */
778 void
779 bridge_stop(struct bridge_softc *sc)
780 {
781 struct ifnet *ifp = &sc->sc_if;
782
783 if (!ISSET(ifp->if_flags, IFF_RUNNING))
784 return;
785
786 CLR(ifp->if_flags, IFF_RUNNING);
787
788 bstp_disable(sc->sc_stp);
789
790 timeout_del_barrier(&sc->sc_brtimeout);
791
792 bridge_rtflush(sc, IFBF_FLUSHDYN);
793 }
794
795 /*
796 * Send output from the bridge. The mbuf has the ethernet header
797 * already attached. We must enqueue or free the mbuf before exiting.
798 */
799 int
800 bridge_enqueue(struct ifnet *ifp, struct mbuf *m)
801 {
802 struct ifnet *brifp;
803 struct ether_header *eh;
804 struct ifnet *dst_if = NULL;
805 unsigned int dst_ifidx = 0;
806 #if NBPFILTER > 0
807 caddr_t if_bpf;
808 #endif
809 int error = 0;
810
811 if (m->m_len < sizeof(*eh)) {
812 m = m_pullup(m, sizeof(*eh));
813 if (m == NULL)
814 return (ENOBUFS);
815 }
816
817 /* ifp must be a member interface of the bridge. */
818 brifp = if_get(ifp->if_bridgeidx);
819 if (brifp == NULL) {
820 m_freem(m);
821 return (EINVAL);
822 }
823
824 /*
825 * If bridge is down, but original output interface is up,
826 * go ahead and send out that interface. Otherwise the packet
827 * is dropped below.
828 */
829 if (!ISSET(brifp->if_flags, IFF_RUNNING)) {
830 /* Loop prevention. */
831 m->m_flags |= M_PROTO1;
832 error = if_enqueue(ifp, m);
833 if_put(brifp);
834 return (error);
835 }
836
837 #if NBPFILTER > 0
838 if_bpf = brifp->if_bpf;
839 if (if_bpf)
840 bpf_mtap(if_bpf, m, BPF_DIRECTION_OUT);
841 #endif
842 ifp->if_opackets++;
843 ifp->if_obytes += m->m_pkthdr.len;
844
845 bridge_span(brifp, m);
846
847 eh = mtod(m, struct ether_header *);
848 if (!ETHER_IS_MULTICAST(eh->ether_dhost)) {
849 struct ether_addr *dst;
850
851 dst = (struct ether_addr *)&eh->ether_dhost[0];
852 dst_ifidx = bridge_rtlookup(brifp, dst, m);
853 }
854
855 /*
856 * If the packet is a broadcast or we don't know a better way to
857 * get there, send to all interfaces.
858 */
859 if (dst_ifidx == 0) {
860 struct bridge_softc *sc = brifp->if_softc;
861 struct bridge_iflist *bif;
862 struct mbuf *mc;
863
864 smr_read_enter();
865 SMR_SLIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
866 dst_if = bif->ifp;
867 if ((dst_if->if_flags & IFF_RUNNING) == 0)
868 continue;
869
870 /*
871 * If this is not the original output interface,
872 * and the interface is participating in spanning
873 * tree, make sure the port is in a state that
874 * allows forwarding.
875 */
876 if (dst_if != ifp &&
877 (bif->bif_flags & IFBIF_STP) &&
878 (bif->bif_state == BSTP_IFSTATE_DISCARDING))
879 continue;
880 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
881 (m->m_flags & (M_BCAST | M_MCAST)) == 0)
882 continue;
883
884 if (bridge_filterrule(&bif->bif_brlout, eh, m) ==
885 BRL_ACTION_BLOCK)
886 continue;
887
888 mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
889 if (mc == NULL) {
890 brifp->if_oerrors++;
891 continue;
892 }
893
894 error = bridge_ifenqueue(brifp, dst_if, mc);
895 if (error)
896 continue;
897 }
898 smr_read_leave();
899 m_freem(m);
900 goto out;
901 }
902
903 dst_if = if_get(dst_ifidx);
904 if ((dst_if == NULL) || !ISSET(dst_if->if_flags, IFF_RUNNING)) {
905 m_freem(m);
906 if_put(dst_if);
907 error = ENETDOWN;
908 goto out;
909 }
910
911 bridge_ifenqueue(brifp, dst_if, m);
912 if_put(dst_if);
913 out:
914 if_put(brifp);
915 return (error);
916 }
917
918 /*
919 * Loop through each bridge interface and process their input queues.
920 */
921 void
922 bridgeintr(void)
923 {
924 struct mbuf_list ml;
925 struct mbuf *m;
926 struct ifnet *ifp;
927
928 niq_delist(&bridgeintrq, &ml);
929 if (ml_empty(&ml))
930 return;
931
932 KERNEL_LOCK();
933 while ((m = ml_dequeue(&ml)) != NULL) {
934
935 ifp = if_get(m->m_pkthdr.ph_ifidx);
936 if (ifp == NULL) {
937 m_freem(m);
938 continue;
939 }
940
941 bridge_process(ifp, m);
942
943 if_put(ifp);
944 }
945 KERNEL_UNLOCK();
946 }
947
948 /*
949 * Process a single frame. Frame must be freed or queued before returning.
950 */
951 void
952 bridgeintr_frame(struct ifnet *brifp, struct ifnet *src_if, struct mbuf *m)
953 {
954 struct bridge_softc *sc = brifp->if_softc;
955 struct ifnet *dst_if = NULL;
956 struct bridge_iflist *bif;
957 struct ether_addr *dst, *src;
958 struct ether_header eh;
959 unsigned int dst_ifidx;
960 u_int32_t protected;
961 int len;
962
963
964 sc->sc_if.if_ipackets++;
965 sc->sc_if.if_ibytes += m->m_pkthdr.len;
966
967 bif = bridge_getbif(src_if);
968 KASSERT(bif != NULL);
969
970 m_copydata(m, 0, ETHER_HDR_LEN, &eh);
971 dst = (struct ether_addr *)&eh.ether_dhost[0];
972 src = (struct ether_addr *)&eh.ether_shost[0];
973
974 /*
975 * If interface is learning, and if source address
976 * is not broadcast or multicast, record its address.
977 */
978 if ((bif->bif_flags & IFBIF_LEARNING) &&
979 !ETHER_IS_MULTICAST(eh.ether_shost) &&
980 !ETHER_IS_ANYADDR(eh.ether_shost))
981 bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC, m);
982
983 if ((bif->bif_flags & IFBIF_STP) &&
984 (bif->bif_state == BSTP_IFSTATE_LEARNING)) {
985 m_freem(m);
986 return;
987 }
988
989 /*
990 * At this point, the port either doesn't participate in stp or
991 * it's in the forwarding state
992 */
993
994 /*
995 * If packet is unicast, destined for someone on "this"
996 * side of the bridge, drop it.
997 */
998 if (!ETHER_IS_MULTICAST(eh.ether_dhost)) {
999 dst_ifidx = bridge_rtlookup(brifp, dst, NULL);
1000 if (dst_ifidx == src_if->if_index) {
1001 m_freem(m);
1002 return;
1003 }
1004 } else {
1005 if (ETHER_IS_BROADCAST(eh.ether_dhost))
1006 m->m_flags |= M_BCAST;
1007 else
1008 m->m_flags |= M_MCAST;
1009 }
1010
1011 /*
1012 * Multicast packets get handled a little differently:
1013 * If interface is:
1014 * -link0,-link1 (default) Forward all multicast
1015 * as broadcast.
1016 * -link0,link1 Drop non-IP multicast, forward
1017 * as broadcast IP multicast.
1018 * link0,-link1 Drop IP multicast, forward as
1019 * broadcast non-IP multicast.
1020 * link0,link1 Drop all multicast.
1021 */
1022 if (m->m_flags & M_MCAST) {
1023 if ((sc->sc_if.if_flags &
1024 (IFF_LINK0 | IFF_LINK1)) ==
1025 (IFF_LINK0 | IFF_LINK1)) {
1026 m_freem(m);
1027 return;
1028 }
1029 if (sc->sc_if.if_flags & IFF_LINK0 &&
1030 ETHERADDR_IS_IP_MCAST(dst)) {
1031 m_freem(m);
1032 return;
1033 }
1034 if (sc->sc_if.if_flags & IFF_LINK1 &&
1035 !ETHERADDR_IS_IP_MCAST(dst)) {
1036 m_freem(m);
1037 return;
1038 }
1039 }
1040
1041 if (bif->bif_flags & IFBIF_BLOCKNONIP && bridge_blocknonip(&eh, m)) {
1042 m_freem(m);
1043 return;
1044 }
1045
1046 if (bridge_filterrule(&bif->bif_brlin, &eh, m) == BRL_ACTION_BLOCK) {
1047 m_freem(m);
1048 return;
1049 }
1050 m = bridge_ip(&sc->sc_if, BRIDGE_IN, src_if, &eh, m);
1051 if (m == NULL)
1052 return;
1053 /*
1054 * If the packet is a multicast or broadcast OR if we don't
1055 * know any better, forward it to all interfaces.
1056 */
1057 if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_ifidx == 0) {
1058 sc->sc_if.if_imcasts++;
1059 bridge_broadcast(sc, src_if, &eh, m);
1060 return;
1061 }
1062 protected = bif->bif_protected;
1063
1064 dst_if = if_get(dst_ifidx);
1065 if (dst_if == NULL)
1066 goto bad;
1067
1068 /*
1069 * At this point, we're dealing with a unicast frame going to a
1070 * different interface
1071 */
1072 if (!ISSET(dst_if->if_flags, IFF_RUNNING))
1073 goto bad;
1074 bif = bridge_getbif(dst_if);
1075 if ((bif == NULL) || ((bif->bif_flags & IFBIF_STP) &&
1076 (bif->bif_state == BSTP_IFSTATE_DISCARDING)))
1077 goto bad;
1078 /*
1079 * Do not transmit if both ports are part of the same protected
1080 * domain.
1081 */
1082 if (protected != 0 && (protected & bif->bif_protected))
1083 goto bad;
1084 if (bridge_filterrule(&bif->bif_brlout, &eh, m) == BRL_ACTION_BLOCK)
1085 goto bad;
1086 m = bridge_ip(&sc->sc_if, BRIDGE_OUT, dst_if, &eh, m);
1087 if (m == NULL)
1088 goto bad;
1089
1090 len = m->m_pkthdr.len;
1091 #if NVLAN > 0
1092 if ((m->m_flags & M_VLANTAG) &&
1093 (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0)
1094 len += ETHER_VLAN_ENCAP_LEN;
1095 #endif
1096 if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
1097 bridge_fragment(&sc->sc_if, dst_if, &eh, m);
1098 else {
1099 bridge_ifenqueue(&sc->sc_if, dst_if, m);
1100 }
1101 m = NULL;
1102 bad:
1103 if_put(dst_if);
1104 m_freem(m);
1105 }
1106
1107 /*
1108 * Return 1 if `ena' belongs to `bif', 0 otherwise.
1109 */
1110 int
1111 bridge_ourether(struct ifnet *ifp, uint8_t *ena)
1112 {
1113 struct arpcom *ac = (struct arpcom *)ifp;
1114
1115 if (memcmp(ac->ac_enaddr, ena, ETHER_ADDR_LEN) == 0)
1116 return (1);
1117
1118 #if NCARP > 0
1119 if (carp_ourether(ifp, ena))
1120 return (1);
1121 #endif
1122
1123 return (0);
1124 }
1125
1126 /*
1127 * Receive input from an interface. Queue the packet for bridging if its
1128 * not for us, and schedule an interrupt.
1129 */
1130 struct mbuf *
1131 bridge_input(struct ifnet *ifp, struct mbuf *m, uint64_t dst, void *null)
1132 {
1133 KASSERT(m->m_flags & M_PKTHDR);
1134
1135 if (m->m_flags & M_PROTO1) {
1136 m->m_flags &= ~M_PROTO1;
1137 return (m);
1138 }
1139
1140 niq_enqueue(&bridgeintrq, m);
1141
1142 return (NULL);
1143 }
1144
1145 void
1146 bridge_process(struct ifnet *ifp, struct mbuf *m)
1147 {
1148 struct ifnet *brifp;
1149 struct bridge_softc *sc;
1150 struct bridge_iflist *bif = NULL, *bif0 = NULL;
1151 struct ether_header *eh;
1152 struct mbuf *mc;
1153 #if NBPFILTER > 0
1154 caddr_t if_bpf;
1155 #endif
1156
1157 KERNEL_ASSERT_LOCKED();
1158
1159 brifp = if_get(ifp->if_bridgeidx);
1160 if ((brifp == NULL) || !ISSET(brifp->if_flags, IFF_RUNNING))
1161 goto reenqueue;
1162
1163 if (m->m_pkthdr.len < sizeof(*eh))
1164 goto bad;
1165
1166 #if NVLAN > 0
1167 /*
1168 * If the underlying interface removed the VLAN header itself,
1169 * add it back.
1170 */
1171 if (ISSET(m->m_flags, M_VLANTAG)) {
1172 m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag);
1173 if (m == NULL)
1174 goto bad;
1175 }
1176 #endif
1177
1178 #if NBPFILTER > 0
1179 if_bpf = brifp->if_bpf;
1180 if (if_bpf)
1181 bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_IN);
1182 #endif
1183
1184 eh = mtod(m, struct ether_header *);
1185
1186 sc = brifp->if_softc;
1187 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
1188 struct arpcom *ac = (struct arpcom *)bif->ifp;
1189 if (memcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0)
1190 goto bad;
1191 if (bif->ifp == ifp)
1192 bif0 = bif;
1193 }
1194 if (bif0 == NULL)
1195 goto reenqueue;
1196
1197 bridge_span(brifp, m);
1198
1199 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1200 /*
1201 * Reserved destination MAC addresses (01:80:C2:00:00:0x)
1202 * should not be forwarded to bridge members according to
1203 * section 7.12.6 of the 802.1D-2004 specification. The
1204 * STP destination address (as stored in bstp_etheraddr)
1205 * is the first of these.
1206 */
1207 if (memcmp(eh->ether_dhost, bstp_etheraddr,
1208 ETHER_ADDR_LEN - 1) == 0) {
1209 if (eh->ether_dhost[ETHER_ADDR_LEN - 1] == 0) {
1210 /* STP traffic */
1211 m = bstp_input(sc->sc_stp, bif0->bif_stp, eh,
1212 m);
1213 if (m == NULL)
1214 goto bad;
1215 } else if (eh->ether_dhost[ETHER_ADDR_LEN - 1] <= 0xf)
1216 goto bad;
1217 }
1218
1219 /*
1220 * No need to process frames for ifs in the discarding state
1221 */
1222 if ((bif0->bif_flags & IFBIF_STP) &&
1223 (bif0->bif_state == BSTP_IFSTATE_DISCARDING))
1224 goto reenqueue;
1225
1226 mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
1227 if (mc == NULL)
1228 goto reenqueue;
1229
1230 bridge_ifinput(ifp, mc);
1231
1232 bridgeintr_frame(brifp, ifp, m);
1233 if_put(brifp);
1234 return;
1235 }
1236
1237 /*
1238 * Unicast, make sure it's not for us.
1239 */
1240 if (bridge_ourether(bif0->ifp, eh->ether_dhost)) {
1241 bif = bif0;
1242 } else {
1243 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
1244 if (bif->ifp == ifp)
1245 continue;
1246 if (bridge_ourether(bif->ifp, eh->ether_dhost))
1247 break;
1248 }
1249 }
1250 if (bif != NULL) {
1251 if (bif0->bif_flags & IFBIF_LEARNING)
1252 bridge_rtupdate(sc,
1253 (struct ether_addr *)&eh->ether_shost,
1254 ifp, 0, IFBAF_DYNAMIC, m);
1255 if (bridge_filterrule(&bif0->bif_brlin, eh, m) ==
1256 BRL_ACTION_BLOCK) {
1257 goto bad;
1258 }
1259
1260 /* Count for the bridge */
1261 brifp->if_ipackets++;
1262 brifp->if_ibytes += m->m_pkthdr.len;
1263
1264 ifp = bif->ifp;
1265 goto reenqueue;
1266 }
1267
1268 bridgeintr_frame(brifp, ifp, m);
1269 if_put(brifp);
1270 return;
1271
1272 reenqueue:
1273 bridge_ifinput(ifp, m);
1274 m = NULL;
1275 bad:
1276 m_freem(m);
1277 if_put(brifp);
1278 }
1279
1280 /*
1281 * Send a frame to all interfaces that are members of the bridge
1282 * (except the one it came in on).
1283 */
1284 void
1285 bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp,
1286 struct ether_header *eh, struct mbuf *m)
1287 {
1288 struct bridge_iflist *bif;
1289 struct mbuf *mc;
1290 struct ifnet *dst_if;
1291 int len, used = 0;
1292 u_int32_t protected;
1293
1294 bif = bridge_getbif(ifp);
1295 KASSERT(bif != NULL);
1296 protected = bif->bif_protected;
1297
1298 SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_iflist, bif_next) {
1299 dst_if = bif->ifp;
1300
1301 if ((dst_if->if_flags & IFF_RUNNING) == 0)
1302 continue;
1303
1304 if ((bif->bif_flags & IFBIF_STP) &&
1305 (bif->bif_state == BSTP_IFSTATE_DISCARDING))
1306 continue;
1307
1308 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
1309 (m->m_flags & (M_BCAST | M_MCAST)) == 0)
1310 continue;
1311
1312 /* Drop non-IP frames if the appropriate flag is set. */
1313 if (bif->bif_flags & IFBIF_BLOCKNONIP &&
1314 bridge_blocknonip(eh, m))
1315 continue;
1316
1317 /*
1318 * Do not transmit if both ports are part of the same
1319 * protected domain.
1320 */
1321 if (protected != 0 && (protected & bif->bif_protected))
1322 continue;
1323
1324 if (bridge_filterrule(&bif->bif_brlout, eh, m) ==
1325 BRL_ACTION_BLOCK)
1326 continue;
1327
1328 /*
1329 * Don't retransmit out of the same interface where
1330 * the packet was received from.
1331 */
1332 if (dst_if->if_index == ifp->if_index)
1333 continue;
1334
1335 if (bridge_localbroadcast(dst_if, eh, m))
1336 sc->sc_if.if_oerrors++;
1337
1338 /* If last one, reuse the passed-in mbuf */
1339 if (SMR_SLIST_NEXT_LOCKED(bif, bif_next) == NULL) {
1340 mc = m;
1341 used = 1;
1342 } else {
1343 mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
1344 if (mc == NULL) {
1345 sc->sc_if.if_oerrors++;
1346 continue;
1347 }
1348 }
1349
1350 mc = bridge_ip(&sc->sc_if, BRIDGE_OUT, dst_if, eh, mc);
1351 if (mc == NULL)
1352 continue;
1353
1354 len = mc->m_pkthdr.len;
1355 #if NVLAN > 0
1356 if ((mc->m_flags & M_VLANTAG) &&
1357 (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0)
1358 len += ETHER_VLAN_ENCAP_LEN;
1359 #endif
1360 if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
1361 bridge_fragment(&sc->sc_if, dst_if, eh, mc);
1362 else {
1363 bridge_ifenqueue(&sc->sc_if, dst_if, mc);
1364 }
1365 }
1366
1367 if (!used)
1368 m_freem(m);
1369 }
1370
1371 int
1372 bridge_localbroadcast(struct ifnet *ifp, struct ether_header *eh,
1373 struct mbuf *m)
1374 {
1375 struct mbuf *m1;
1376 u_int16_t etype;
1377
1378 /*
1379 * quick optimisation, don't send packets up the stack if no
1380 * corresponding address has been specified.
1381 */
1382 etype = ntohs(eh->ether_type);
1383 if (!(m->m_flags & M_VLANTAG) && etype == ETHERTYPE_IP) {
1384 struct ifaddr *ifa;
1385 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1386 if (ifa->ifa_addr->sa_family == AF_INET)
1387 break;
1388 }
1389 if (ifa == NULL)
1390 return (0);
1391 }
1392
1393 m1 = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
1394 if (m1 == NULL)
1395 return (1);
1396
1397 #if NPF > 0
1398 pf_pkt_addr_changed(m1);
1399 #endif /* NPF */
1400
1401 bridge_ifinput(ifp, m1);
1402
1403 return (0);
1404 }
1405
1406 void
1407 bridge_span(struct ifnet *brifp, struct mbuf *m)
1408 {
1409 struct bridge_softc *sc = brifp->if_softc;
1410 struct bridge_iflist *bif;
1411 struct ifnet *ifp;
1412 struct mbuf *mc;
1413 int error;
1414
1415 smr_read_enter();
1416 SMR_SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
1417 ifp = bif->ifp;
1418
1419 if ((ifp->if_flags & IFF_RUNNING) == 0)
1420 continue;
1421
1422 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1423 if (mc == NULL) {
1424 brifp->if_oerrors++;
1425 continue;
1426 }
1427
1428 error = bridge_ifenqueue(brifp, ifp, mc);
1429 if (error)
1430 continue;
1431 }
1432 smr_read_leave();
1433 }
1434
1435 /*
1436 * Block non-ip frames:
1437 * Returns 0 if frame is ip, and 1 if it should be dropped.
1438 */
1439 int
1440 bridge_blocknonip(struct ether_header *eh, struct mbuf *m)
1441 {
1442 struct llc llc;
1443 u_int16_t etype;
1444
1445 if (m->m_pkthdr.len < ETHER_HDR_LEN)
1446 return (1);
1447
1448 #if NVLAN > 0
1449 if (m->m_flags & M_VLANTAG)
1450 return (1);
1451 #endif
1452
1453 etype = ntohs(eh->ether_type);
1454 switch (etype) {
1455 case ETHERTYPE_ARP:
1456 case ETHERTYPE_REVARP:
1457 case ETHERTYPE_IP:
1458 case ETHERTYPE_IPV6:
1459 return (0);
1460 }
1461
1462 if (etype > ETHERMTU)
1463 return (1);
1464
1465 if (m->m_pkthdr.len <
1466 (ETHER_HDR_LEN + LLC_SNAPFRAMELEN))
1467 return (1);
1468
1469 m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, &llc);
1470
1471 etype = ntohs(llc.llc_snap.ether_type);
1472 if (llc.llc_dsap == LLC_SNAP_LSAP &&
1473 llc.llc_ssap == LLC_SNAP_LSAP &&
1474 llc.llc_control == LLC_UI &&
1475 llc.llc_snap.org_code[0] == 0 &&
1476 llc.llc_snap.org_code[1] == 0 &&
1477 llc.llc_snap.org_code[2] == 0 &&
1478 (etype == ETHERTYPE_ARP || etype == ETHERTYPE_REVARP ||
1479 etype == ETHERTYPE_IP || etype == ETHERTYPE_IPV6)) {
1480 return (0);
1481 }
1482
1483 return (1);
1484 }
1485
1486 #ifdef IPSEC
1487 int
1488 bridge_ipsec(struct ifnet *ifp, struct ether_header *eh, int hassnap,
1489 struct llc *llc, int dir, int af, int hlen, struct mbuf *m)
1490 {
1491 union sockaddr_union dst;
1492 struct tdb *tdb;
1493 u_int32_t spi;
1494 u_int16_t cpi;
1495 int error, off, prot;
1496 u_int8_t proto = 0;
1497 struct ip *ip;
1498 #ifdef INET6
1499 struct ip6_hdr *ip6;
1500 #endif /* INET6 */
1501 #if NPF > 0
1502 struct ifnet *encif;
1503 #endif
1504
1505 if (dir == BRIDGE_IN) {
1506 switch (af) {
1507 case AF_INET:
1508 if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t))
1509 goto skiplookup;
1510
1511 ip = mtod(m, struct ip *);
1512 proto = ip->ip_p;
1513 off = offsetof(struct ip, ip_p);
1514
1515 if (proto != IPPROTO_ESP && proto != IPPROTO_AH &&
1516 proto != IPPROTO_IPCOMP)
1517 goto skiplookup;
1518
1519 bzero(&dst, sizeof(union sockaddr_union));
1520 dst.sa.sa_family = AF_INET;
1521 dst.sin.sin_len = sizeof(struct sockaddr_in);
1522 m_copydata(m, offsetof(struct ip, ip_dst),
1523 sizeof(struct in_addr), &dst.sin.sin_addr);
1524
1525 break;
1526 #ifdef INET6
1527 case AF_INET6:
1528 if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t))
1529 goto skiplookup;
1530
1531 ip6 = mtod(m, struct ip6_hdr *);
1532
1533 /* XXX We should chase down the header chain */
1534 proto = ip6->ip6_nxt;
1535 off = offsetof(struct ip6_hdr, ip6_nxt);
1536
1537 if (proto != IPPROTO_ESP && proto != IPPROTO_AH &&
1538 proto != IPPROTO_IPCOMP)
1539 goto skiplookup;
1540
1541 bzero(&dst, sizeof(union sockaddr_union));
1542 dst.sa.sa_family = AF_INET6;
1543 dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
1544 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
1545 sizeof(struct in6_addr), &dst.sin6.sin6_addr);
1546
1547 break;
1548 #endif /* INET6 */
1549 default:
1550 return (0);
1551 }
1552
1553 switch (proto) {
1554 case IPPROTO_ESP:
1555 m_copydata(m, hlen, sizeof(u_int32_t), &spi);
1556 break;
1557 case IPPROTO_AH:
1558 m_copydata(m, hlen + sizeof(u_int32_t),
1559 sizeof(u_int32_t), &spi);
1560 break;
1561 case IPPROTO_IPCOMP:
1562 m_copydata(m, hlen + sizeof(u_int16_t),
1563 sizeof(u_int16_t), &cpi);
1564 spi = htonl(ntohs(cpi));
1565 break;
1566 }
1567
1568 NET_ASSERT_LOCKED();
1569
1570 tdb = gettdb(ifp->if_rdomain, spi, &dst, proto);
1571 if (tdb != NULL && (tdb->tdb_flags & TDBF_INVALID) == 0 &&
1572 tdb->tdb_xform != NULL) {
1573 if (tdb->tdb_first_use == 0) {
1574 tdb->tdb_first_use = gettime();
1575 if (tdb->tdb_flags & TDBF_FIRSTUSE) {
1576 if (timeout_add_sec(
1577 &tdb->tdb_first_tmo,
1578 tdb->tdb_exp_first_use))
1579 tdb_ref(tdb);
1580 }
1581 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) {
1582 if (timeout_add_sec(
1583 &tdb->tdb_sfirst_tmo,
1584 tdb->tdb_soft_first_use))
1585 tdb_ref(tdb);
1586 }
1587 }
1588
1589 prot = (*(tdb->tdb_xform->xf_input))(&m, tdb, hlen,
1590 off);
1591 tdb_unref(tdb);
1592 if (prot != IPPROTO_DONE)
1593 ip_deliver(&m, &hlen, prot, af);
1594 return (1);
1595 } else {
1596 tdb_unref(tdb);
1597 skiplookup:
1598 /* XXX do an input policy lookup */
1599 return (0);
1600 }
1601 } else { /* Outgoing from the bridge. */
1602 error = ipsp_spd_lookup(m, af, hlen, IPSP_DIRECTION_OUT,
1603 NULL, NULL, &tdb, NULL);
1604 if (error == 0 && tdb != NULL) {
1605 /*
1606 * We don't need to do loop detection, the
1607 * bridge will do that for us.
1608 */
1609 #if NPF > 0
1610 if ((encif = enc_getif(tdb->tdb_rdomain,
1611 tdb->tdb_tap)) == NULL ||
1612 pf_test(af, dir, encif, &m) != PF_PASS) {
1613 m_freem(m);
1614 tdb_unref(tdb);
1615 return (1);
1616 }
1617 if (m == NULL) {
1618 tdb_unref(tdb);
1619 return (1);
1620 }
1621 if (af == AF_INET)
1622 in_proto_cksum_out(m, encif);
1623 #ifdef INET6
1624 else if (af == AF_INET6)
1625 in6_proto_cksum_out(m, encif);
1626 #endif /* INET6 */
1627 #endif /* NPF */
1628
1629 ip = mtod(m, struct ip *);
1630 if ((af == AF_INET) &&
1631 ip_mtudisc && (ip->ip_off & htons(IP_DF)) &&
1632 tdb->tdb_mtu && ntohs(ip->ip_len) > tdb->tdb_mtu &&
1633 tdb->tdb_mtutimeout > gettime()) {
1634 bridge_send_icmp_err(ifp, eh, m,
1635 hassnap, llc, tdb->tdb_mtu,
1636 ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG);
1637 } else {
1638 KERNEL_LOCK();
1639 error = ipsp_process_packet(m, tdb, af, 0);
1640 KERNEL_UNLOCK();
1641 }
1642 tdb_unref(tdb);
1643 return (1);
1644 } else
1645 return (0);
1646 }
1647
1648 return (0);
1649 }
1650 #endif /* IPSEC */
1651
1652 /*
1653 * Filter IP packets by peeking into the ethernet frame. This violates
1654 * the ISO model, but allows us to act as a IP filter at the data link
1655 * layer. As a result, most of this code will look familiar to those
1656 * who've read net/if_ethersubr.c and netinet/ip_input.c
1657 */
1658 struct mbuf *
1659 bridge_ip(struct ifnet *brifp, int dir, struct ifnet *ifp,
1660 struct ether_header *eh, struct mbuf *m)
1661 {
1662 struct llc llc;
1663 int hassnap = 0;
1664 struct ip *ip;
1665 int hlen;
1666 u_int16_t etype;
1667
1668 #if NVLAN > 0
1669 if (m->m_flags & M_VLANTAG)
1670 return (m);
1671 #endif
1672
1673 etype = ntohs(eh->ether_type);
1674
1675 if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) {
1676 if (etype > ETHERMTU ||
1677 m->m_pkthdr.len < (LLC_SNAPFRAMELEN +
1678 ETHER_HDR_LEN))
1679 return (m);
1680
1681 m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, &llc);
1682
1683 if (llc.llc_dsap != LLC_SNAP_LSAP ||
1684 llc.llc_ssap != LLC_SNAP_LSAP ||
1685 llc.llc_control != LLC_UI ||
1686 llc.llc_snap.org_code[0] ||
1687 llc.llc_snap.org_code[1] ||
1688 llc.llc_snap.org_code[2])
1689 return (m);
1690
1691 etype = ntohs(llc.llc_snap.ether_type);
1692 if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6)
1693 return (m);
1694 hassnap = 1;
1695 }
1696
1697 m_adj(m, ETHER_HDR_LEN);
1698 if (hassnap)
1699 m_adj(m, LLC_SNAPFRAMELEN);
1700
1701 switch (etype) {
1702
1703 case ETHERTYPE_IP:
1704 m = ipv4_check(ifp, m);
1705 if (m == NULL)
1706 return (NULL);
1707
1708 ip = mtod(m, struct ip *);
1709 hlen = ip->ip_hl << 2;
1710
1711 #ifdef IPSEC
1712 if ((brifp->if_flags & IFF_LINK2) == IFF_LINK2 &&
1713 bridge_ipsec(ifp, eh, hassnap, &llc, dir, AF_INET, hlen, m))
1714 return (NULL);
1715 #endif /* IPSEC */
1716 #if NPF > 0
1717 /* Finally, we get to filter the packet! */
1718 if (pf_test(AF_INET, dir, ifp, &m) != PF_PASS)
1719 goto dropit;
1720 if (m == NULL)
1721 goto dropit;
1722 #endif /* NPF > 0 */
1723
1724 /* Rebuild the IP header */
1725 if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL))
1726 return (NULL);
1727 if (m->m_len < sizeof(struct ip))
1728 goto dropit;
1729 in_proto_cksum_out(m, ifp);
1730 ip = mtod(m, struct ip *);
1731 ip->ip_sum = 0;
1732 if (0 && (ifp->if_capabilities & IFCAP_CSUM_IPv4))
1733 m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
1734 else {
1735 ipstat_inc(ips_outswcsum);
1736 ip->ip_sum = in_cksum(m, hlen);
1737 }
1738
1739 #if NPF > 0
1740 if (dir == BRIDGE_IN &&
1741 m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
1742 m_resethdr(m);
1743 m->m_pkthdr.ph_ifidx = ifp->if_index;
1744 m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
1745 ipv4_input(ifp, m);
1746 return (NULL);
1747 }
1748 #endif /* NPF > 0 */
1749
1750 break;
1751
1752 #ifdef INET6
1753 case ETHERTYPE_IPV6:
1754 m = ipv6_check(ifp, m);
1755 if (m == NULL)
1756 return (NULL);
1757
1758 #ifdef IPSEC
1759 hlen = sizeof(struct ip6_hdr);
1760
1761 if ((brifp->if_flags & IFF_LINK2) == IFF_LINK2 &&
1762 bridge_ipsec(ifp, eh, hassnap, &llc, dir, AF_INET6, hlen,
1763 m))
1764 return (NULL);
1765 #endif /* IPSEC */
1766
1767 #if NPF > 0
1768 if (pf_test(AF_INET6, dir, ifp, &m) != PF_PASS)
1769 goto dropit;
1770 if (m == NULL)
1771 return (NULL);
1772 #endif /* NPF > 0 */
1773 in6_proto_cksum_out(m, ifp);
1774
1775 #if NPF > 0
1776 if (dir == BRIDGE_IN &&
1777 m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
1778 m_resethdr(m);
1779 m->m_pkthdr.ph_ifidx = ifp->if_index;
1780 m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
1781 ipv6_input(ifp, m);
1782 return (NULL);
1783 }
1784 #endif /* NPF > 0 */
1785
1786 break;
1787 #endif /* INET6 */
1788
1789 default:
1790 goto dropit;
1791 break;
1792 }
1793
1794 /* Reattach SNAP header */
1795 if (hassnap) {
1796 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
1797 if (m == NULL)
1798 goto dropit;
1799 bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
1800 }
1801
1802 /* Reattach ethernet header */
1803 M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
1804 if (m == NULL)
1805 goto dropit;
1806 bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
1807
1808 return (m);
1809
1810 dropit:
1811 m_freem(m);
1812 return (NULL);
1813 }
1814
1815 void
1816 bridge_fragment(struct ifnet *brifp, struct ifnet *ifp, struct ether_header *eh,
1817 struct mbuf *m)
1818 {
1819 struct llc llc;
1820 struct mbuf_list fml;
1821 int error = 0;
1822 int hassnap = 0;
1823 u_int16_t etype;
1824 struct ip *ip;
1825
1826 etype = ntohs(eh->ether_type);
1827 #if NVLAN > 0
1828 if ((m->m_flags & M_VLANTAG) || etype == ETHERTYPE_VLAN ||
1829 etype == ETHERTYPE_QINQ) {
1830 int len = m->m_pkthdr.len;
1831
1832 if (m->m_flags & M_VLANTAG)
1833 len += ETHER_VLAN_ENCAP_LEN;
1834 if ((ifp->if_capabilities & IFCAP_VLAN_MTU) &&
1835 (len - sizeof(struct ether_vlan_header) <= ifp->if_mtu)) {
1836 bridge_ifenqueue(brifp, ifp, m);
1837 return;
1838 }
1839 goto dropit;
1840 }
1841 #endif
1842 if (etype != ETHERTYPE_IP) {
1843 if (etype > ETHERMTU ||
1844 m->m_pkthdr.len < (LLC_SNAPFRAMELEN +
1845 ETHER_HDR_LEN))
1846 goto dropit;
1847
1848 m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, &llc);
1849
1850 if (llc.llc_dsap != LLC_SNAP_LSAP ||
1851 llc.llc_ssap != LLC_SNAP_LSAP ||
1852 llc.llc_control != LLC_UI ||
1853 llc.llc_snap.org_code[0] ||
1854 llc.llc_snap.org_code[1] ||
1855 llc.llc_snap.org_code[2] ||
1856 llc.llc_snap.ether_type != htons(ETHERTYPE_IP))
1857 goto dropit;
1858
1859 hassnap = 1;
1860 }
1861
1862 m_adj(m, ETHER_HDR_LEN);
1863 if (hassnap)
1864 m_adj(m, LLC_SNAPFRAMELEN);
1865
1866 if (m->m_len < sizeof(struct ip) &&
1867 (m = m_pullup(m, sizeof(struct ip))) == NULL)
1868 goto dropit;
1869 ip = mtod(m, struct ip *);
1870
1871 /* Respect IP_DF, return a ICMP_UNREACH_NEEDFRAG. */
1872 if (ip->ip_off & htons(IP_DF)) {
1873 bridge_send_icmp_err(ifp, eh, m, hassnap, &llc,
1874 ifp->if_mtu, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG);
1875 return;
1876 }
1877
1878 error = ip_fragment(m, &fml, ifp, ifp->if_mtu);
1879 if (error)
1880 return;
1881
1882 while ((m = ml_dequeue(&fml)) != NULL) {
1883 if (hassnap) {
1884 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
1885 if (m == NULL) {
1886 error = ENOBUFS;
1887 break;
1888 }
1889 bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
1890 }
1891 M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
1892 if (m == NULL) {
1893 error = ENOBUFS;
1894 break;
1895 }
1896 bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
1897 error = bridge_ifenqueue(brifp, ifp, m);
1898 if (error)
1899 break;
1900 }
1901 if (error)
1902 ml_purge(&fml);
1903 else
1904 ipstat_inc(ips_fragmented);
1905
1906 return;
1907 dropit:
1908 m_freem(m);
1909 }
1910
1911 int
1912 bridge_ifenqueue(struct ifnet *brifp, struct ifnet *ifp, struct mbuf *m)
1913 {
1914 int error, len;
1915
1916 /* Loop prevention. */
1917 m->m_flags |= M_PROTO1;
1918
1919 len = m->m_pkthdr.len;
1920
1921 error = if_enqueue(ifp, m);
1922 if (error) {
1923 brifp->if_oerrors++;
1924 return (error);
1925 }
1926
1927 brifp->if_opackets++;
1928 brifp->if_obytes += len;
1929
1930 return (0);
1931 }
1932
1933 void
1934 bridge_ifinput(struct ifnet *ifp, struct mbuf *m)
1935 {
1936 struct mbuf_list ml = MBUF_LIST_INITIALIZER();
1937
1938 m->m_flags |= M_PROTO1;
1939
1940 ml_enqueue(&ml, m);
1941 if_input(ifp, &ml);
1942 }
1943
1944 void
1945 bridge_send_icmp_err(struct ifnet *ifp,
1946 struct ether_header *eh, struct mbuf *n, int hassnap, struct llc *llc,
1947 int mtu, int type, int code)
1948 {
1949 struct ip *ip;
1950 struct icmp *icp;
1951 struct in_addr t;
1952 struct mbuf *m, *n2;
1953 int hlen;
1954 u_int8_t ether_tmp[ETHER_ADDR_LEN];
1955
1956 n2 = m_copym(n, 0, M_COPYALL, M_DONTWAIT);
1957 if (!n2) {
1958 m_freem(n);
1959 return;
1960 }
1961 m = icmp_do_error(n, type, code, 0, mtu);
1962 if (m == NULL) {
1963 m_freem(n2);
1964 return;
1965 }
1966
1967 n = n2;
1968
1969 ip = mtod(m, struct ip *);
1970 hlen = ip->ip_hl << 2;
1971 t = ip->ip_dst;
1972 ip->ip_dst = ip->ip_src;
1973 ip->ip_src = t;
1974
1975 m->m_data += hlen;
1976 m->m_len -= hlen;
1977 icp = mtod(m, struct icmp *);
1978 icp->icmp_cksum = 0;
1979 icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen);
1980 m->m_data -= hlen;
1981 m->m_len += hlen;
1982
1983 ip->ip_v = IPVERSION;
1984 ip->ip_off &= htons(IP_DF);
1985 ip->ip_id = htons(ip_randomid());
1986 ip->ip_ttl = MAXTTL;
1987 ip->ip_sum = 0;
1988 ip->ip_sum = in_cksum(m, hlen);
1989
1990 /* Swap ethernet addresses */
1991 bcopy(&eh->ether_dhost, ðer_tmp, sizeof(ether_tmp));
1992 bcopy(&eh->ether_shost, &eh->ether_dhost, sizeof(ether_tmp));
1993 bcopy(ðer_tmp, &eh->ether_shost, sizeof(ether_tmp));
1994
1995 /* Reattach SNAP header */
1996 if (hassnap) {
1997 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
1998 if (m == NULL)
1999 goto dropit;
2000 bcopy(llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
2001 }
2002
2003 /* Reattach ethernet header */
2004 M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
2005 if (m == NULL)
2006 goto dropit;
2007 bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
2008
2009 bridge_enqueue(ifp, m);
2010 m_freem(n);
2011 return;
2012
2013 dropit:
2014 m_freem(n);
2015 }
2016
2017 void
2018 bridge_take(void *unused)
2019 {
2020 return;
2021 }
2022
2023 void
2024 bridge_rele(void *unused)
2025 {
2026 return;
2027 }
Cache object: 9406d8accf7f507b7d33220ff99bf7f1
|