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