kernel - Major bridging functionality added (bug fixes 2)
[dragonfly.git] / sys / net / bridge / if_bridge.c
CommitLineData
ac93838f
SS
1/*
2 * Copyright 2001 Wasabi Systems, Inc.
3 * All rights reserved.
4 *
5 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
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 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed for the NetBSD Project by
18 * Wasabi Systems, Inc.
19 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
20 * or promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/*
37 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
38 * All rights reserved.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by Jason L. Wright
51 * 4. The name of the author may not be used to endorse or promote products
52 * derived from this software without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
56 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
62 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
63 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
65 *
66 * $OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp $
67 * $NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc Exp $
68 * $FreeBSD: src/sys/net/if_bridge.c,v 1.26 2005/10/13 23:05:55 thompsa Exp $
ac93838f
SS
69 */
70
71/*
72 * Network interface bridge support.
73 *
74 * TODO:
75 *
76 * - Currently only supports Ethernet-like interfaces (Ethernet,
77 * 802.11, VLANs on Ethernet, etc.) Figure out a nice way
78 * to bridge other types of interfaces (FDDI-FDDI, and maybe
79 * consider heterogenous bridges).
4394693c
SZ
80 *
81 *
82 * Bridge's route information is duplicated to each CPUs:
83 *
84 * CPU0 CPU1 CPU2 CPU3
85 * +-----------+ +-----------+ +-----------+ +-----------+
86 * | rtnode | | rtnode | | rtnode | | rtnode |
87 * | | | | | | | |
88 * | dst eaddr | | dst eaddr | | dst eaddr | | dst eaddr |
89 * +-----------+ +-----------+ +-----------+ +-----------+
90 * | | | |
91 * | | | |
92 * | | +----------+ | |
93 * | | | rtinfo | | |
94 * | +---->| |<---+ |
95 * | | flags | |
96 * +-------------->| timeout |<-------------+
97 * | dst_ifp |
98 * +----------+
99 *
100 * We choose to put timeout and dst_ifp into shared part, so updating
101 * them will be cheaper than using message forwarding. Also there is
102 * not need to use spinlock to protect the updating: timeout and dst_ifp
103 * is not related and specific field's updating order has no importance.
104 * The cache pollution by the share part should not be heavy: in a stable
105 * setup, dst_ifp probably will be not changed in rtnode's life time,
106 * while timeout is refreshed once per second; most of the time, timeout
107 * and dst_ifp are read-only accessed.
108 *
109 *
110 * Bridge route information installation on bridge_input path:
111 *
112 * CPU0 CPU1 CPU2 CPU3
113 *
114 * tcp_thread2
115 * |
116 * alloc nmsg
117 * snd nmsg |
118 * w/o rtinfo |
119 * ifnet0<-----------------------+
120 * | :
121 * lookup dst :
122 * rtnode exists?(Y)free nmsg :
123 * |(N) :
124 * |
125 * alloc rtinfo
126 * alloc rtnode
127 * install rtnode
128 * |
129 * +---------->ifnet1
130 * : fwd nmsg |
131 * : w/ rtinfo |
132 * : |
133 * : |
134 * alloc rtnode
135 * (w/ nmsg's rtinfo)
136 * install rtnode
137 * |
138 * +---------->ifnet2
139 * : fwd nmsg |
140 * : w/ rtinfo |
141 * : |
142 * : same as ifnet1
143 * |
144 * +---------->ifnet3
145 * : fwd nmsg |
146 * : w/ rtinfo |
147 * : |
148 * : same as ifnet1
149 * free nmsg
150 * :
151 * :
152 *
153 * The netmsgs forwarded between protocol threads and ifnet threads are
154 * allocated with (M_WAITOK|M_NULLOK), so it will not fail under most
155 * cases (route information is too precious to be not installed :).
156 * Since multiple threads may try to install route information for the
157 * same dst eaddr, we look up route information in ifnet0. However, this
158 * looking up only need to be performed on ifnet0, which is the start
159 * point of the route information installation process.
160 *
161 *
162 * Bridge route information deleting/flushing:
163 *
164 * CPU0 CPU1 CPU2 CPU3
165 *
166 * netisr0
167 * |
168 * find suitable rtnodes,
169 * mark their rtinfo dead
170 * |
171 * | domsg <------------------------------------------+
172 * | | replymsg
173 * | |
174 * V fwdmsg fwdmsg fwdmsg |
175 * ifnet0 --------> ifnet1 --------> ifnet2 --------> ifnet3
176 * delete rtnodes delete rtnodes delete rtnodes delete rtnodes
177 * w/ dead rtinfo w/ dead rtinfo w/ dead rtinfo w/ dead rtinfo
178 * free dead rtinfos
179 *
180 * All deleting/flushing operations are serialized by netisr0, so each
181 * operation only reaps the route information marked dead by itself.
182 *
183 *
184 * Bridge route information adding/deleting/flushing:
185 * Since all operation is serialized by the fixed message flow between
186 * ifnet threads, it is not possible to create corrupted per-cpu route
187 * information.
80ed9a26
SZ
188 *
189 *
190 *
191 * Percpu member interface list iteration with blocking operation:
192 * Since one bridge could only delete one member interface at a time and
193 * the deleted member interface is not freed after netmsg_service_sync(),
194 * following way is used to make sure that even if the certain member
195 * interface is ripped from the percpu list during the blocking operation,
196 * the iteration still could keep going:
197 *
70d9a675 198 * TAILQ_FOREACH_MUTABLE(bif, sc->sc_iflists[mycpuid], bif_next, nbif) {
80ed9a26
SZ
199 * blocking operation;
200 * blocking operation;
201 * ...
202 * ...
203 * if (nbif != NULL && !nbif->bif_onlist) {
204 * KKASSERT(bif->bif_onlist);
70d9a675 205 * nbif = TAILQ_NEXT(bif, bif_next);
80ed9a26
SZ
206 * }
207 * }
208 *
209 * As mentioned above only one member interface could be unlinked from the
210 * percpu member interface list, so either bif or nbif may be not on the list,
211 * but _not_ both. To keep the list iteration, we don't care about bif, but
212 * only nbif. Since removed member interface will only be freed after we
213 * finish our work, it is safe to access any field in an unlinked bif (here
214 * bif_onlist). If nbif is no longer on the list, then bif must be on the
215 * list, so we change nbif to the next element of bif and keep going.
ac93838f
SS
216 */
217
ac93838f
SS
218#include "opt_inet.h"
219#include "opt_inet6.h"
220
221#include <sys/param.h>
222#include <sys/mbuf.h>
223#include <sys/malloc.h>
224#include <sys/protosw.h>
225#include <sys/systm.h>
226#include <sys/time.h>
227#include <sys/socket.h> /* for net/if.h */
228#include <sys/sockio.h>
229#include <sys/ctype.h> /* string functions */
230#include <sys/kernel.h>
231#include <sys/random.h>
232#include <sys/sysctl.h>
233#include <sys/module.h>
234#include <sys/proc.h>
895c1f85 235#include <sys/priv.h>
ac93838f
SS
236#include <sys/lock.h>
237#include <sys/thread.h>
238#include <sys/thread2.h>
239#include <sys/mpipe.h>
240
241#include <net/bpf.h>
242#include <net/if.h>
243#include <net/if_dl.h>
244#include <net/if_types.h>
245#include <net/if_var.h>
246#include <net/pfil.h>
247#include <net/ifq_var.h>
65a24520 248#include <net/if_clone.h>
ac93838f
SS
249
250#include <netinet/in.h> /* for struct arpcom */
251#include <netinet/in_systm.h>
252#include <netinet/in_var.h>
253#include <netinet/ip.h>
254#include <netinet/ip_var.h>
255#ifdef INET6
256#include <netinet/ip6.h>
257#include <netinet6/ip6_var.h>
258#endif
259#include <netinet/if_ether.h> /* for struct arpcom */
260#include <net/bridge/if_bridgevar.h>
261#include <net/if_llc.h>
ecd27a4c 262#include <net/netmsg2.h>
ac93838f
SS
263
264#include <net/route.h>
265#include <sys/in_cksum.h>
266
267/*
268 * Size of the route hash table. Must be a power of two.
269 */
270#ifndef BRIDGE_RTHASH_SIZE
271#define BRIDGE_RTHASH_SIZE 1024
272#endif
273
274#define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1)
275
276/*
277 * Maximum number of addresses to cache.
278 */
279#ifndef BRIDGE_RTABLE_MAX
280#define BRIDGE_RTABLE_MAX 100
281#endif
282
283/*
284 * Spanning tree defaults.
285 */
286#define BSTP_DEFAULT_MAX_AGE (20 * 256)
287#define BSTP_DEFAULT_HELLO_TIME (2 * 256)
288#define BSTP_DEFAULT_FORWARD_DELAY (15 * 256)
289#define BSTP_DEFAULT_HOLD_TIME (1 * 256)
290#define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000
291#define BSTP_DEFAULT_PORT_PRIORITY 0x80
292#define BSTP_DEFAULT_PATH_COST 55
293
294/*
295 * Timeout (in seconds) for entries learned dynamically.
296 */
297#ifndef BRIDGE_RTABLE_TIMEOUT
298#define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */
299#endif
300
301/*
302 * Number of seconds between walks of the route list.
303 */
304#ifndef BRIDGE_RTABLE_PRUNE_PERIOD
305#define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60)
306#endif
307
d217f5e5
SU
308/*
309 * List of capabilities to mask on the member interface.
310 */
311#define BRIDGE_IFCAPS_MASK IFCAP_TXCSUM
312
4394693c
SZ
313typedef int (*bridge_ctl_t)(struct bridge_softc *, void *);
314
315struct netmsg_brctl {
002c1265 316 struct netmsg_base base;
4394693c
SZ
317 bridge_ctl_t bc_func;
318 struct bridge_softc *bc_sc;
319 void *bc_arg;
320};
321
322struct netmsg_brsaddr {
002c1265 323 struct netmsg_base base;
4394693c
SZ
324 struct bridge_softc *br_softc;
325 struct ifnet *br_dst_if;
326 struct bridge_rtinfo *br_rtinfo;
327 int br_setflags;
328 uint8_t br_dst[ETHER_ADDR_LEN];
329 uint8_t br_flags;
330};
331
8f7b13ef 332struct netmsg_braddbif {
002c1265 333 struct netmsg_base base;
8f7b13ef
SZ
334 struct bridge_softc *br_softc;
335 struct bridge_ifinfo *br_bif_info;
336 struct ifnet *br_bif_ifp;
337};
338
339struct netmsg_brdelbif {
002c1265 340 struct netmsg_base base;
8f7b13ef
SZ
341 struct bridge_softc *br_softc;
342 struct bridge_ifinfo *br_bif_info;
343 struct bridge_iflist_head *br_bif_list;
344};
345
346struct netmsg_brsflags {
002c1265 347 struct netmsg_base base;
8f7b13ef
SZ
348 struct bridge_softc *br_softc;
349 struct bridge_ifinfo *br_bif_info;
350 uint32_t br_bif_flags;
351};
352
d217f5e5
SU
353eventhandler_tag bridge_detach_cookie = NULL;
354
ac93838f 355extern struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *);
eb366364 356extern int (*bridge_output_p)(struct ifnet *, struct mbuf *);
ac93838f 357extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
70d9a675 358extern struct ifnet *(*bridge_interface_p)(void *if_bridge);
ac93838f 359
d217f5e5 360static int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
ac93838f 361
d14ef41e 362static int bridge_clone_create(struct if_clone *, int, caddr_t);
a7e9152e 363static int bridge_clone_destroy(struct ifnet *);
ac93838f 364
d217f5e5 365static int bridge_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
8f7b13ef
SZ
366static void bridge_mutecaps(struct bridge_ifinfo *, struct ifnet *, int);
367static void bridge_ifdetach(void *, struct ifnet *);
ac93838f 368static void bridge_init(void *);
70d9a675 369static int bridge_from_us(struct bridge_softc *, struct ether_header *);
867cc45a 370static void bridge_stop(struct ifnet *);
d217f5e5
SU
371static void bridge_start(struct ifnet *);
372static struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
eb366364 373static int bridge_output(struct ifnet *, struct mbuf *);
70d9a675 374static struct ifnet *bridge_interface(void *if_bridge);
d217f5e5
SU
375
376static void bridge_forward(struct bridge_softc *, struct mbuf *m);
377
002c1265 378static void bridge_timer_handler(netmsg_t);
d217f5e5
SU
379static void bridge_timer(void *);
380
137aa7b3 381static void bridge_start_bcast(struct bridge_softc *, struct mbuf *);
d217f5e5 382static void bridge_broadcast(struct bridge_softc *, struct ifnet *,
137aa7b3 383 struct mbuf *);
d217f5e5
SU
384static void bridge_span(struct bridge_softc *, struct mbuf *);
385
386static int bridge_rtupdate(struct bridge_softc *, const uint8_t *,
4394693c 387 struct ifnet *, uint8_t);
d217f5e5 388static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
4394693c 389static void bridge_rtreap(struct bridge_softc *);
30ced003 390static void bridge_rtreap_async(struct bridge_softc *);
d217f5e5 391static void bridge_rttrim(struct bridge_softc *);
4394693c 392static int bridge_rtage_finddead(struct bridge_softc *);
d217f5e5
SU
393static void bridge_rtage(struct bridge_softc *);
394static void bridge_rtflush(struct bridge_softc *, int);
395static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
4394693c
SZ
396static int bridge_rtsaddr(struct bridge_softc *, const uint8_t *,
397 struct ifnet *, uint8_t);
398static void bridge_rtmsg_sync(struct bridge_softc *sc);
002c1265
MD
399static void bridge_rtreap_handler(netmsg_t);
400static void bridge_rtinstall_handler(netmsg_t);
4394693c
SZ
401static int bridge_rtinstall_oncpu(struct bridge_softc *, const uint8_t *,
402 struct ifnet *, int, uint8_t, struct bridge_rtinfo **);
403
404static void bridge_rtable_init(struct bridge_softc *);
d217f5e5
SU
405static void bridge_rtable_fini(struct bridge_softc *);
406
407static int bridge_rtnode_addr_cmp(const uint8_t *, const uint8_t *);
408static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
409 const uint8_t *);
4394693c 410static void bridge_rtnode_insert(struct bridge_softc *,
d217f5e5
SU
411 struct bridge_rtnode *);
412static void bridge_rtnode_destroy(struct bridge_softc *,
413 struct bridge_rtnode *);
414
415static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
416 const char *name);
417static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
418 struct ifnet *ifp);
8f7b13ef
SZ
419static struct bridge_iflist *bridge_lookup_member_ifinfo(struct bridge_softc *,
420 struct bridge_ifinfo *);
d217f5e5
SU
421static void bridge_delete_member(struct bridge_softc *,
422 struct bridge_iflist *, int);
423static void bridge_delete_span(struct bridge_softc *,
424 struct bridge_iflist *);
425
0b326f64
SZ
426static int bridge_control(struct bridge_softc *, u_long,
427 bridge_ctl_t, void *);
d71129d9
SZ
428static int bridge_ioctl_init(struct bridge_softc *, void *);
429static int bridge_ioctl_stop(struct bridge_softc *, void *);
d217f5e5
SU
430static int bridge_ioctl_add(struct bridge_softc *, void *);
431static int bridge_ioctl_del(struct bridge_softc *, void *);
70d9a675
MD
432static void bridge_ioctl_fillflags(struct bridge_softc *sc,
433 struct bridge_iflist *bif, struct ifbreq *req);
d217f5e5
SU
434static int bridge_ioctl_gifflags(struct bridge_softc *, void *);
435static int bridge_ioctl_sifflags(struct bridge_softc *, void *);
436static int bridge_ioctl_scache(struct bridge_softc *, void *);
437static int bridge_ioctl_gcache(struct bridge_softc *, void *);
438static int bridge_ioctl_gifs(struct bridge_softc *, void *);
439static int bridge_ioctl_rts(struct bridge_softc *, void *);
440static int bridge_ioctl_saddr(struct bridge_softc *, void *);
441static int bridge_ioctl_sto(struct bridge_softc *, void *);
442static int bridge_ioctl_gto(struct bridge_softc *, void *);
443static int bridge_ioctl_daddr(struct bridge_softc *, void *);
444static int bridge_ioctl_flush(struct bridge_softc *, void *);
445static int bridge_ioctl_gpri(struct bridge_softc *, void *);
446static int bridge_ioctl_spri(struct bridge_softc *, void *);
9b42fdc9 447static int bridge_ioctl_reinit(struct bridge_softc *, void *);
d217f5e5
SU
448static int bridge_ioctl_ght(struct bridge_softc *, void *);
449static int bridge_ioctl_sht(struct bridge_softc *, void *);
450static int bridge_ioctl_gfd(struct bridge_softc *, void *);
451static int bridge_ioctl_sfd(struct bridge_softc *, void *);
452static int bridge_ioctl_gma(struct bridge_softc *, void *);
453static int bridge_ioctl_sma(struct bridge_softc *, void *);
454static int bridge_ioctl_sifprio(struct bridge_softc *, void *);
455static int bridge_ioctl_sifcost(struct bridge_softc *, void *);
456static int bridge_ioctl_addspan(struct bridge_softc *, void *);
457static int bridge_ioctl_delspan(struct bridge_softc *, void *);
1e858374 458static int bridge_ioctl_sifbondwght(struct bridge_softc *, void *);
d217f5e5
SU
459static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
460 int);
461static int bridge_ip_checkbasic(struct mbuf **mp);
462#ifdef INET6
463static int bridge_ip6_checkbasic(struct mbuf **mp);
464#endif /* INET6 */
465static int bridge_fragment(struct ifnet *, struct mbuf *,
466 struct ether_header *, int, struct llc *);
002c1265 467static void bridge_enqueue_handler(netmsg_t);
70d9a675
MD
468static void bridge_handoff(struct bridge_softc *, struct ifnet *,
469 struct mbuf *, int);
ac93838f 470
002c1265
MD
471static void bridge_del_bif_handler(netmsg_t);
472static void bridge_add_bif_handler(netmsg_t);
8f7b13ef
SZ
473static void bridge_del_bif(struct bridge_softc *, struct bridge_ifinfo *,
474 struct bridge_iflist_head *);
475static void bridge_add_bif(struct bridge_softc *, struct bridge_ifinfo *,
476 struct ifnet *);
8f7b13ef 477
ac93838f
SS
478SYSCTL_DECL(_net_link);
479SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW, 0, "Bridge");
480
d217f5e5 481static int pfil_onlyip = 1; /* only pass IP[46] packets when pfil is enabled */
ac93838f
SS
482static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
483static int pfil_member = 1; /* run pfil hooks on the member interface */
70d9a675 484static int bridge_debug;
d217f5e5
SU
485SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW,
486 &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
ac93838f
SS
487SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
488 &pfil_bridge, 0, "Packet filter on the bridge interface");
489SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
490 &pfil_member, 0, "Packet filter on the member interface");
70d9a675
MD
491SYSCTL_INT(_net_link_bridge, OID_AUTO, debug, CTLFLAG_RW,
492 &bridge_debug, 0, "Bridge debug mode");
ac93838f 493
2d4d3c93
SZ
494struct bridge_control_arg {
495 union {
496 struct ifbreq ifbreq;
497 struct ifbifconf ifbifconf;
498 struct ifbareq ifbareq;
499 struct ifbaconf ifbaconf;
500 struct ifbrparam ifbrparam;
501 } bca_u;
502 int bca_len;
503 void *bca_uptr;
504 void *bca_kptr;
505};
506
ac93838f 507struct bridge_control {
23cf9e67
SZ
508 bridge_ctl_t bc_func;
509 int bc_argsize;
510 int bc_flags;
ac93838f
SS
511};
512
513#define BC_F_COPYIN 0x01 /* copy arguments in */
514#define BC_F_COPYOUT 0x02 /* copy arguments out */
515#define BC_F_SUSER 0x04 /* do super-user check */
516
517const struct bridge_control bridge_control_table[] = {
518 { bridge_ioctl_add, sizeof(struct ifbreq),
519 BC_F_COPYIN|BC_F_SUSER },
520 { bridge_ioctl_del, sizeof(struct ifbreq),
521 BC_F_COPYIN|BC_F_SUSER },
522
523 { bridge_ioctl_gifflags, sizeof(struct ifbreq),
524 BC_F_COPYIN|BC_F_COPYOUT },
525 { bridge_ioctl_sifflags, sizeof(struct ifbreq),
526 BC_F_COPYIN|BC_F_SUSER },
527
528 { bridge_ioctl_scache, sizeof(struct ifbrparam),
529 BC_F_COPYIN|BC_F_SUSER },
530 { bridge_ioctl_gcache, sizeof(struct ifbrparam),
531 BC_F_COPYOUT },
532
533 { bridge_ioctl_gifs, sizeof(struct ifbifconf),
534 BC_F_COPYIN|BC_F_COPYOUT },
535 { bridge_ioctl_rts, sizeof(struct ifbaconf),
536 BC_F_COPYIN|BC_F_COPYOUT },
537
538 { bridge_ioctl_saddr, sizeof(struct ifbareq),
539 BC_F_COPYIN|BC_F_SUSER },
540
541 { bridge_ioctl_sto, sizeof(struct ifbrparam),
542 BC_F_COPYIN|BC_F_SUSER },
543 { bridge_ioctl_gto, sizeof(struct ifbrparam),
544 BC_F_COPYOUT },
545
546 { bridge_ioctl_daddr, sizeof(struct ifbareq),
547 BC_F_COPYIN|BC_F_SUSER },
548
549 { bridge_ioctl_flush, sizeof(struct ifbreq),
550 BC_F_COPYIN|BC_F_SUSER },
551
552 { bridge_ioctl_gpri, sizeof(struct ifbrparam),
553 BC_F_COPYOUT },
554 { bridge_ioctl_spri, sizeof(struct ifbrparam),
555 BC_F_COPYIN|BC_F_SUSER },
556
557 { bridge_ioctl_ght, sizeof(struct ifbrparam),
558 BC_F_COPYOUT },
559 { bridge_ioctl_sht, sizeof(struct ifbrparam),
560 BC_F_COPYIN|BC_F_SUSER },
561
562 { bridge_ioctl_gfd, sizeof(struct ifbrparam),
563 BC_F_COPYOUT },
564 { bridge_ioctl_sfd, sizeof(struct ifbrparam),
565 BC_F_COPYIN|BC_F_SUSER },
566
567 { bridge_ioctl_gma, sizeof(struct ifbrparam),
568 BC_F_COPYOUT },
569 { bridge_ioctl_sma, sizeof(struct ifbrparam),
570 BC_F_COPYIN|BC_F_SUSER },
571
572 { bridge_ioctl_sifprio, sizeof(struct ifbreq),
573 BC_F_COPYIN|BC_F_SUSER },
574
575 { bridge_ioctl_sifcost, sizeof(struct ifbreq),
576 BC_F_COPYIN|BC_F_SUSER },
d217f5e5
SU
577
578 { bridge_ioctl_addspan, sizeof(struct ifbreq),
579 BC_F_COPYIN|BC_F_SUSER },
580 { bridge_ioctl_delspan, sizeof(struct ifbreq),
581 BC_F_COPYIN|BC_F_SUSER },
1e858374
MD
582
583 { bridge_ioctl_sifbondwght, sizeof(struct ifbreq),
584 BC_F_COPYIN|BC_F_SUSER },
585
ac93838f 586};
c157ff7a 587static const int bridge_control_table_size = NELEM(bridge_control_table);
ac93838f 588
ac93838f
SS
589LIST_HEAD(, bridge_softc) bridge_list;
590
591struct if_clone bridge_cloner = IF_CLONE_INITIALIZER("bridge",
d217f5e5 592 bridge_clone_create,
ac93838f
SS
593 bridge_clone_destroy, 0, IF_MAXUNIT);
594
595static int
596bridge_modevent(module_t mod, int type, void *data)
597{
ac93838f
SS
598 switch (type) {
599 case MOD_LOAD:
600 LIST_INIT(&bridge_list);
601 if_clone_attach(&bridge_cloner);
602 bridge_input_p = bridge_input;
e1d2145d 603 bridge_output_p = bridge_output;
70d9a675 604 bridge_interface_p = bridge_interface;
d217f5e5
SU
605 bridge_detach_cookie = EVENTHANDLER_REGISTER(
606 ifnet_detach_event, bridge_ifdetach, NULL,
607 EVENTHANDLER_PRI_ANY);
ac93838f 608#if notyet
ac93838f
SS
609 bstp_linkstate_p = bstp_linkstate;
610#endif
611 break;
612 case MOD_UNLOAD:
613 if (!LIST_EMPTY(&bridge_list))
d217f5e5
SU
614 return (EBUSY);
615 EVENTHANDLER_DEREGISTER(ifnet_detach_event,
616 bridge_detach_cookie);
ac93838f
SS
617 if_clone_detach(&bridge_cloner);
618 bridge_input_p = NULL;
619 bridge_output_p = NULL;
70d9a675 620 bridge_interface_p = NULL;
ac93838f 621#if notyet
ac93838f
SS
622 bstp_linkstate_p = NULL;
623#endif
624 break;
625 default:
d217f5e5 626 return (EOPNOTSUPP);
ac93838f 627 }
d217f5e5 628 return (0);
ac93838f
SS
629}
630
631static moduledata_t bridge_mod = {
d217f5e5
SU
632 "if_bridge",
633 bridge_modevent,
ac93838f
SS
634 0
635};
636
637DECLARE_MODULE(if_bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
638
639
640/*
641 * bridge_clone_create:
642 *
643 * Create a new bridge instance.
644 */
d217f5e5 645static int
d14ef41e 646bridge_clone_create(struct if_clone *ifc, int unit, caddr_t param __unused)
ac93838f
SS
647{
648 struct bridge_softc *sc;
649 struct ifnet *ifp;
650 u_char eaddr[6];
d76dd5c7 651 int cpu, rnd;
ac93838f 652
8f7b13ef 653 sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
ac93838f
SS
654 ifp = sc->sc_ifp = &sc->sc_if;
655
656 sc->sc_brtmax = BRIDGE_RTABLE_MAX;
657 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
658 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
659 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
660 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
661 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
662 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
663
664 /* Initialize our routing table. */
665 bridge_rtable_init(sc);
666
667 callout_init(&sc->sc_brcallout);
48e7b118 668 netmsg_init(&sc->sc_brtimemsg, NULL, &netisr_adone_rport,
b95665d8 669 MSGF_DROPABLE, bridge_timer_handler);
002c1265 670 sc->sc_brtimemsg.lmsg.u.ms_resultp = sc;
e9d22060 671
ac93838f 672 callout_init(&sc->sc_bstpcallout);
48e7b118 673 netmsg_init(&sc->sc_bstptimemsg, NULL, &netisr_adone_rport,
b95665d8 674 MSGF_DROPABLE, bstp_tick_handler);
002c1265 675 sc->sc_bstptimemsg.lmsg.u.ms_resultp = sc;
ac93838f 676
8f7b13ef
SZ
677 /* Initialize per-cpu member iface lists */
678 sc->sc_iflists = kmalloc(sizeof(*sc->sc_iflists) * ncpus,
679 M_DEVBUF, M_WAITOK);
680 for (cpu = 0; cpu < ncpus; ++cpu)
70d9a675 681 TAILQ_INIT(&sc->sc_iflists[cpu]);
8f7b13ef 682
70d9a675 683 TAILQ_INIT(&sc->sc_spanlist);
ac93838f
SS
684
685 ifp->if_softc = sc;
686 if_initname(ifp, ifc->ifc_name, unit);
687 ifp->if_mtu = ETHERMTU;
d217f5e5 688 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
ac93838f
SS
689 ifp->if_ioctl = bridge_ioctl;
690 ifp->if_start = bridge_start;
691 ifp->if_init = bridge_init;
70d9a675 692 ifp->if_type = IFT_ETHER;
ac93838f 693 ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
ac93838f
SS
694 ifq_set_ready(&ifp->if_snd);
695 ifp->if_hdrlen = ETHER_HDR_LEN;
696
697 /*
698 * Generate a random ethernet address and use the private AC:DE:48
699 * OUI code.
700 */
d76dd5c7
SZ
701 rnd = karc4random();
702 bcopy(&rnd, &eaddr[0], 4); /* ETHER_ADDR_LEN == 6 */
703 rnd = karc4random();
704 bcopy(&rnd, &eaddr[2], 4); /* ETHER_ADDR_LEN == 6 */
705
706 eaddr[0] &= ~1; /* clear multicast bit */
707 eaddr[0] |= 2; /* set the LAA bit */
ac93838f
SS
708
709 ether_ifattach(ifp, eaddr, NULL);
710 /* Now undo some of the damage... */
711 ifp->if_baudrate = 0;
70d9a675 712 /*ifp->if_type = IFT_BRIDGE;*/
ac93838f 713
ac308789 714 crit_enter(); /* XXX MP */
ac93838f
SS
715 LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
716 crit_exit();
717
718 return (0);
719}
720
34db64a6 721static void
002c1265 722bridge_delete_dispatch(netmsg_t msg)
34db64a6 723{
002c1265 724 struct bridge_softc *sc = msg->lmsg.u.ms_resultp;
34db64a6
SZ
725 struct ifnet *bifp = sc->sc_ifp;
726 struct bridge_iflist *bif;
727
a3dd34d2 728 ifnet_serialize_all(bifp);
34db64a6 729
70d9a675 730 while ((bif = TAILQ_FIRST(&sc->sc_iflists[mycpuid])) != NULL)
34db64a6
SZ
731 bridge_delete_member(sc, bif, 0);
732
70d9a675 733 while ((bif = TAILQ_FIRST(&sc->sc_spanlist)) != NULL)
34db64a6
SZ
734 bridge_delete_span(sc, bif);
735
a3dd34d2 736 ifnet_deserialize_all(bifp);
34db64a6 737
002c1265 738 lwkt_replymsg(&msg->lmsg, 0);
34db64a6
SZ
739}
740
ac93838f
SS
741/*
742 * bridge_clone_destroy:
743 *
744 * Destroy a bridge instance.
745 */
a7e9152e 746static int
ac93838f
SS
747bridge_clone_destroy(struct ifnet *ifp)
748{
749 struct bridge_softc *sc = ifp->if_softc;
002c1265 750 struct netmsg_base msg;
ac93838f 751
a3dd34d2 752 ifnet_serialize_all(ifp);
ac93838f 753
867cc45a 754 bridge_stop(ifp);
ac93838f
SS
755 ifp->if_flags &= ~IFF_UP;
756
a3dd34d2 757 ifnet_deserialize_all(ifp);
ac93838f 758
002c1265 759 netmsg_init(&msg, NULL, &curthread->td_msgport,
48e7b118 760 0, bridge_delete_dispatch);
002c1265
MD
761 msg.lmsg.u.ms_resultp = sc;
762 lwkt_domsg(BRIDGE_CFGPORT, &msg.lmsg, 0);
34db64a6
SZ
763
764 crit_enter(); /* XXX MP */
ac93838f
SS
765 LIST_REMOVE(sc, sc_list);
766 crit_exit();
767
768 ether_ifdetach(ifp);
769
ac93838f
SS
770 /* Tear down the routing table. */
771 bridge_rtable_fini(sc);
772
8f7b13ef
SZ
773 /* Free per-cpu member iface lists */
774 kfree(sc->sc_iflists, M_DEVBUF);
775
efda3bd0 776 kfree(sc, M_DEVBUF);
a7e9152e
SZ
777
778 return 0;
ac93838f
SS
779}
780
781/*
782 * bridge_ioctl:
783 *
784 * Handle a control request from the operator.
785 */
d217f5e5 786static int
ac93838f
SS
787bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
788{
789 struct bridge_softc *sc = ifp->if_softc;
2d4d3c93 790 struct bridge_control_arg args;
ac93838f
SS
791 struct ifdrv *ifd = (struct ifdrv *) data;
792 const struct bridge_control *bc;
793 int error = 0;
794
2c9effcf 795 ASSERT_IFNET_SERIALIZED_ALL(ifp);
ac93838f 796
867cc45a 797 switch (cmd) {
ac93838f
SS
798 case SIOCADDMULTI:
799 case SIOCDELMULTI:
800 break;
801
802 case SIOCGDRVSPEC:
803 case SIOCSDRVSPEC:
804 if (ifd->ifd_cmd >= bridge_control_table_size) {
805 error = EINVAL;
806 break;
807 }
808 bc = &bridge_control_table[ifd->ifd_cmd];
809
810 if (cmd == SIOCGDRVSPEC &&
811 (bc->bc_flags & BC_F_COPYOUT) == 0) {
812 error = EINVAL;
813 break;
867cc45a 814 } else if (cmd == SIOCSDRVSPEC &&
2d4d3c93 815 (bc->bc_flags & BC_F_COPYOUT)) {
ac93838f
SS
816 error = EINVAL;
817 break;
818 }
819
820 if (bc->bc_flags & BC_F_SUSER) {
895c1f85 821 error = priv_check_cred(cr, PRIV_ROOT, NULL_CRED_OKAY);
ac93838f
SS
822 if (error)
823 break;
824 }
825
826 if (ifd->ifd_len != bc->bc_argsize ||
2d4d3c93 827 ifd->ifd_len > sizeof(args.bca_u)) {
ac93838f
SS
828 error = EINVAL;
829 break;
830 }
831
60d8d1d3 832 memset(&args, 0, sizeof(args));
ac93838f 833 if (bc->bc_flags & BC_F_COPYIN) {
2d4d3c93
SZ
834 error = copyin(ifd->ifd_data, &args.bca_u,
835 ifd->ifd_len);
ac93838f
SS
836 if (error)
837 break;
838 }
839
0b326f64 840 error = bridge_control(sc, cmd, bc->bc_func, &args);
2d4d3c93
SZ
841 if (error) {
842 KKASSERT(args.bca_len == 0 && args.bca_kptr == NULL);
ac93838f 843 break;
2d4d3c93 844 }
ac93838f 845
2d4d3c93 846 if (bc->bc_flags & BC_F_COPYOUT) {
ac93838f 847 error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
2d4d3c93
SZ
848 if (args.bca_len != 0) {
849 KKASSERT(args.bca_kptr != NULL);
850 if (!error) {
851 error = copyout(args.bca_kptr,
852 args.bca_uptr, args.bca_len);
853 }
854 kfree(args.bca_kptr, M_TEMP);
855 } else {
856 KKASSERT(args.bca_kptr == NULL);
857 }
858 } else {
859 KKASSERT(args.bca_len == 0 && args.bca_kptr == NULL);
860 }
ac93838f
SS
861 break;
862
863 case SIOCSIFFLAGS:
864 if (!(ifp->if_flags & IFF_UP) &&
865 (ifp->if_flags & IFF_RUNNING)) {
866 /*
867 * If interface is marked down and it is running,
867cc45a 868 * then stop it.
ac93838f 869 */
867cc45a 870 bridge_stop(ifp);
ac93838f
SS
871 } else if ((ifp->if_flags & IFF_UP) &&
872 !(ifp->if_flags & IFF_RUNNING)) {
873 /*
874 * If interface is marked up and it is stopped, then
875 * start it.
876 */
867cc45a 877 ifp->if_init(sc);
ac93838f 878 }
9b42fdc9
MD
879
880 /*
881 * If running and link flag state change we have to
882 * reinitialize as well.
883 */
884 if ((ifp->if_flags & IFF_RUNNING) &&
885 (ifp->if_flags & (IFF_LINK0|IFF_LINK1|IFF_LINK2)) !=
886 sc->sc_copy_flags) {
887 sc->sc_copy_flags = ifp->if_flags &
888 (IFF_LINK0|IFF_LINK1|IFF_LINK2);
889 bridge_control(sc, 0, bridge_ioctl_reinit, NULL);
890 }
891
ac93838f
SS
892 break;
893
894 case SIOCSIFMTU:
895 /* Do not allow the MTU to be changed on the bridge */
896 error = EINVAL;
897 break;
898
899 default:
ac93838f
SS
900 error = ether_ioctl(ifp, cmd, data);
901 break;
902 }
ac93838f
SS
903 return (error);
904}
905
906/*
d217f5e5
SU
907 * bridge_mutecaps:
908 *
909 * Clear or restore unwanted capabilities on the member interface
910 */
911static void
8f7b13ef 912bridge_mutecaps(struct bridge_ifinfo *bif_info, struct ifnet *ifp, int mute)
d217f5e5 913{
d217f5e5
SU
914 struct ifreq ifr;
915 int error;
916
917 if (ifp->if_ioctl == NULL)
918 return;
919
920 bzero(&ifr, sizeof(ifr));
921 ifr.ifr_reqcap = ifp->if_capenable;
922
923 if (mute) {
924 /* mask off and save capabilities */
8f7b13ef
SZ
925 bif_info->bifi_mutecap = ifr.ifr_reqcap & BRIDGE_IFCAPS_MASK;
926 if (bif_info->bifi_mutecap != 0)
d217f5e5 927 ifr.ifr_reqcap &= ~BRIDGE_IFCAPS_MASK;
68b979e7 928 } else {
d217f5e5 929 /* restore muted capabilities */
8f7b13ef 930 ifr.ifr_reqcap |= bif_info->bifi_mutecap;
68b979e7 931 }
d217f5e5 932
8f7b13ef 933 if (bif_info->bifi_mutecap != 0) {
a3dd34d2 934 ifnet_serialize_all(ifp);
68b979e7 935 error = ifp->if_ioctl(ifp, SIOCSIFCAP, (caddr_t)&ifr, NULL);
a3dd34d2 936 ifnet_deserialize_all(ifp);
d217f5e5
SU
937 }
938}
939
940/*
ac93838f
SS
941 * bridge_lookup_member:
942 *
943 * Lookup a bridge member interface.
944 */
d217f5e5 945static struct bridge_iflist *
ac93838f
SS
946bridge_lookup_member(struct bridge_softc *sc, const char *name)
947{
948 struct bridge_iflist *bif;
ac93838f 949
70d9a675 950 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next) {
8f7b13ef 951 if (strcmp(bif->bif_ifp->if_xname, name) == 0)
ac93838f
SS
952 return (bif);
953 }
ac93838f
SS
954 return (NULL);
955}
956
957/*
958 * bridge_lookup_member_if:
959 *
960 * Lookup a bridge member interface by ifnet*.
961 */
d217f5e5 962static struct bridge_iflist *
ac93838f
SS
963bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
964{
965 struct bridge_iflist *bif;
966
70d9a675 967 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next) {
ac93838f
SS
968 if (bif->bif_ifp == member_ifp)
969 return (bif);
970 }
8f7b13ef
SZ
971 return (NULL);
972}
ac93838f 973
8f7b13ef
SZ
974/*
975 * bridge_lookup_member_ifinfo:
976 *
977 * Lookup a bridge member interface by bridge_ifinfo.
978 */
979static struct bridge_iflist *
980bridge_lookup_member_ifinfo(struct bridge_softc *sc,
981 struct bridge_ifinfo *bif_info)
982{
983 struct bridge_iflist *bif;
984
70d9a675 985 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next) {
8f7b13ef
SZ
986 if (bif->bif_info == bif_info)
987 return (bif);
988 }
ac93838f
SS
989 return (NULL);
990}
991
992/*
993 * bridge_delete_member:
994 *
995 * Delete the specified member interface.
996 */
d217f5e5
SU
997static void
998bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
999 int gone)
ac93838f
SS
1000{
1001 struct ifnet *ifs = bif->bif_ifp;
bdfc79d0 1002 struct ifnet *bifp = sc->sc_ifp;
8f7b13ef
SZ
1003 struct bridge_ifinfo *bif_info = bif->bif_info;
1004 struct bridge_iflist_head saved_bifs;
bdfc79d0 1005
2c9effcf 1006 ASSERT_IFNET_SERIALIZED_ALL(bifp);
8f7b13ef 1007 KKASSERT(bif_info != NULL);
bdfc79d0
SZ
1008
1009 ifs->if_bridge = NULL;
297c8124
SZ
1010
1011 /*
1012 * Release bridge interface's serializer:
1013 * - To avoid possible dead lock.
8f7b13ef 1014 * - Various sync operation will block the current thread.
297c8124 1015 */
a3dd34d2 1016 ifnet_deserialize_all(bifp);
297c8124 1017
d217f5e5
SU
1018 if (!gone) {
1019 switch (ifs->if_type) {
1020 case IFT_ETHER:
1021 case IFT_L2VLAN:
1022 /*
1023 * Take the interface out of promiscuous mode.
1024 */
bdfc79d0 1025 ifpromisc(ifs, 0);
8f7b13ef 1026 bridge_mutecaps(bif_info, ifs, 0);
d217f5e5 1027 break;
ac93838f 1028
d217f5e5
SU
1029 case IFT_GIF:
1030 break;
ac93838f 1031
d217f5e5 1032 default:
d217f5e5 1033 panic("bridge_delete_member: impossible");
d217f5e5
SU
1034 break;
1035 }
ac93838f
SS
1036 }
1037
8f7b13ef
SZ
1038 /*
1039 * Remove bifs from percpu linked list.
1040 *
1041 * Removed bifs are not freed immediately, instead,
1042 * they are saved in saved_bifs. They will be freed
1043 * after we make sure that no one is accessing them,
1044 * i.e. after following netmsg_service_sync()
1045 */
70d9a675 1046 TAILQ_INIT(&saved_bifs);
8f7b13ef
SZ
1047 bridge_del_bif(sc, bif_info, &saved_bifs);
1048
1049 /*
1050 * Make sure that all protocol threads:
1051 * o see 'ifs' if_bridge is changed
1052 * o know that bif is removed from the percpu linked list
1053 */
1054 netmsg_service_sync();
1055
1056 /*
1057 * Free the removed bifs
1058 */
70d9a675
MD
1059 KKASSERT(!TAILQ_EMPTY(&saved_bifs));
1060 while ((bif = TAILQ_FIRST(&saved_bifs)) != NULL) {
1061 TAILQ_REMOVE(&saved_bifs, bif, bif_next);
8f7b13ef
SZ
1062 kfree(bif, M_DEVBUF);
1063 }
1064
4394693c
SZ
1065 /* See the comment in bridge_ioctl_stop() */
1066 bridge_rtmsg_sync(sc);
30ced003 1067 bridge_rtdelete(sc, ifs, IFBF_FLUSHALL | IFBF_FLUSHSYNC);
4394693c 1068
a3dd34d2 1069 ifnet_serialize_all(bifp);
297c8124 1070
8f7b13ef 1071 if (bifp->if_flags & IFF_RUNNING)
ac93838f 1072 bstp_initialization(sc);
8f7b13ef
SZ
1073
1074 /*
1075 * Free the bif_info after bstp_initialization(), so that
1076 * bridge_softc.sc_root_port will not reference a dangling
1077 * pointer.
1078 */
1079 kfree(bif_info, M_DEVBUF);
ac93838f
SS
1080}
1081
d217f5e5
SU
1082/*
1083 * bridge_delete_span:
1084 *
1085 * Delete the specified span interface.
1086 */
1087static void
1088bridge_delete_span(struct bridge_softc *sc, struct bridge_iflist *bif)
1089{
1090 KASSERT(bif->bif_ifp->if_bridge == NULL,
1091 ("%s: not a span interface", __func__));
1092
70d9a675 1093 TAILQ_REMOVE(&sc->sc_iflists[mycpuid], bif, bif_next);
efda3bd0 1094 kfree(bif, M_DEVBUF);
d217f5e5
SU
1095}
1096
1097static int
d71129d9
SZ
1098bridge_ioctl_init(struct bridge_softc *sc, void *arg __unused)
1099{
1100 struct ifnet *ifp = sc->sc_ifp;
1101
1102 if (ifp->if_flags & IFF_RUNNING)
1103 return 0;
1104
1105 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
1106 bridge_timer, sc);
1107
1108 ifp->if_flags |= IFF_RUNNING;
1109 bstp_initialization(sc);
1110 return 0;
1111}
1112
1113static int
1114bridge_ioctl_stop(struct bridge_softc *sc, void *arg __unused)
1115{
1116 struct ifnet *ifp = sc->sc_ifp;
e9d22060 1117 struct lwkt_msg *lmsg;
d71129d9
SZ
1118
1119 if ((ifp->if_flags & IFF_RUNNING) == 0)
1120 return 0;
1121
1122 callout_stop(&sc->sc_brcallout);
e9d22060
SZ
1123
1124 crit_enter();
002c1265 1125 lmsg = &sc->sc_brtimemsg.lmsg;
e9d22060
SZ
1126 if ((lmsg->ms_flags & MSGF_DONE) == 0) {
1127 /* Pending to be processed; drop it */
1128 lwkt_dropmsg(lmsg);
1129 }
1130 crit_exit();
1131
d71129d9
SZ
1132 bstp_stop(sc);
1133
1134 ifp->if_flags &= ~IFF_RUNNING;
1135
a3dd34d2 1136 ifnet_deserialize_all(ifp);
4394693c
SZ
1137
1138 /* Let everyone know that we are stopped */
1139 netmsg_service_sync();
1140
1141 /*
1142 * Sync ifnetX msgports in the order we forward rtnode
1143 * installation message. This is used to make sure that
1144 * all rtnode installation messages sent by bridge_rtupdate()
1145 * during above netmsg_service_sync() are flushed.
1146 */
1147 bridge_rtmsg_sync(sc);
30ced003 1148 bridge_rtflush(sc, IFBF_FLUSHDYN | IFBF_FLUSHSYNC);
4394693c 1149
a3dd34d2 1150 ifnet_serialize_all(ifp);
d71129d9
SZ
1151 return 0;
1152}
1153
1154static int
ac93838f
SS
1155bridge_ioctl_add(struct bridge_softc *sc, void *arg)
1156{
1157 struct ifbreq *req = arg;
8f7b13ef
SZ
1158 struct bridge_iflist *bif;
1159 struct bridge_ifinfo *bif_info;
68b979e7 1160 struct ifnet *ifs, *bifp;
ac93838f
SS
1161 int error = 0;
1162
68b979e7 1163 bifp = sc->sc_ifp;
2c9effcf 1164 ASSERT_IFNET_SERIALIZED_ALL(bifp);
68b979e7 1165
ac93838f
SS
1166 ifs = ifunit(req->ifbr_ifsname);
1167 if (ifs == NULL)
1168 return (ENOENT);
1169
d217f5e5 1170 /* If it's in the span list, it can't be a member. */
70d9a675 1171 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next)
d217f5e5
SU
1172 if (ifs == bif->bif_ifp)
1173 return (EBUSY);
1174
1175 /* Allow the first Ethernet member to define the MTU */
1176 if (ifs->if_type != IFT_GIF) {
70d9a675 1177 if (TAILQ_EMPTY(&sc->sc_iflists[mycpuid])) {
68b979e7
SZ
1178 bifp->if_mtu = ifs->if_mtu;
1179 } else if (bifp->if_mtu != ifs->if_mtu) {
1180 if_printf(bifp, "invalid MTU for %s\n", ifs->if_xname);
d217f5e5
SU
1181 return (EINVAL);
1182 }
ac93838f
SS
1183 }
1184
1185 if (ifs->if_bridge == sc)
1186 return (EEXIST);
1187
1188 if (ifs->if_bridge != NULL)
1189 return (EBUSY);
1190
8f7b13ef
SZ
1191 bif_info = kmalloc(sizeof(*bif_info), M_DEVBUF, M_WAITOK | M_ZERO);
1192 bif_info->bifi_priority = BSTP_DEFAULT_PORT_PRIORITY;
1193 bif_info->bifi_path_cost = BSTP_DEFAULT_PATH_COST;
1194 bif_info->bifi_ifp = ifs;
1e858374 1195 bif_info->bifi_bond_weight = 1;
8f7b13ef
SZ
1196
1197 /*
1198 * Release bridge interface's serializer:
1199 * - To avoid possible dead lock.
1200 * - Various sync operation will block the current thread.
1201 */
a3dd34d2 1202 ifnet_deserialize_all(bifp);
d217f5e5 1203
ac93838f
SS
1204 switch (ifs->if_type) {
1205 case IFT_ETHER:
1206 case IFT_L2VLAN:
1207 /*
1208 * Place the interface into promiscuous mode.
1209 */
1210 error = ifpromisc(ifs, 1);
68b979e7 1211 if (error) {
a3dd34d2 1212 ifnet_serialize_all(bifp);
ac93838f 1213 goto out;
68b979e7 1214 }
8f7b13ef 1215 bridge_mutecaps(bif_info, ifs, 1);
ac93838f
SS
1216 break;
1217
1218 case IFT_GIF: /* :^) */
1219 break;
1220
1221 default:
1222 error = EINVAL;
a3dd34d2 1223 ifnet_serialize_all(bifp);
ac93838f
SS
1224 goto out;
1225 }
1226
8f7b13ef
SZ
1227 /*
1228 * Add bifs to percpu linked lists
1229 */
1230 bridge_add_bif(sc, bif_info, ifs);
1231
a3dd34d2 1232 ifnet_serialize_all(bifp);
ac93838f 1233
68b979e7 1234 if (bifp->if_flags & IFF_RUNNING)
ac93838f
SS
1235 bstp_initialization(sc);
1236 else
1237 bstp_stop(sc);
1238
68b979e7
SZ
1239 /*
1240 * Everything has been setup, so let the member interface
1241 * deliver packets to this bridge on its input/output path.
1242 */
1243 ifs->if_bridge = sc;
d217f5e5 1244out:
ac93838f 1245 if (error) {
8f7b13ef
SZ
1246 if (bif_info != NULL)
1247 kfree(bif_info, M_DEVBUF);
ac93838f
SS
1248 }
1249 return (error);
1250}
1251
d217f5e5 1252static int
ac93838f
SS
1253bridge_ioctl_del(struct bridge_softc *sc, void *arg)
1254{
1255 struct ifbreq *req = arg;
1256 struct bridge_iflist *bif;
1257
1258 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1259 if (bif == NULL)
1260 return (ENOENT);
1261
d217f5e5 1262 bridge_delete_member(sc, bif, 0);
ac93838f
SS
1263
1264 return (0);
1265}
1266
d217f5e5 1267static int
ac93838f
SS
1268bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
1269{
1270 struct ifbreq *req = arg;
1271 struct bridge_iflist *bif;
1272
1273 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1274 if (bif == NULL)
1275 return (ENOENT);
70d9a675
MD
1276 bridge_ioctl_fillflags(sc, bif, req);
1277 return (0);
1278}
ac93838f 1279
70d9a675
MD
1280static void
1281bridge_ioctl_fillflags(struct bridge_softc *sc, struct bridge_iflist *bif,
1282 struct ifbreq *req)
1283{
ac93838f
SS
1284 req->ifbr_ifsflags = bif->bif_flags;
1285 req->ifbr_state = bif->bif_state;
1286 req->ifbr_priority = bif->bif_priority;
1287 req->ifbr_path_cost = bif->bif_path_cost;
1e858374 1288 req->ifbr_bond_weight = bif->bif_bond_weight;
ac93838f 1289 req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
70d9a675
MD
1290 if (bif->bif_flags & IFBIF_STP) {
1291 req->ifbr_peer_root = bif->bif_peer_root;
1292 req->ifbr_peer_bridge = bif->bif_peer_bridge;
1293 req->ifbr_peer_cost = bif->bif_peer_cost;
1294 req->ifbr_peer_port = bif->bif_peer_port;
1295 if (bstp_supersedes_port_info(sc, bif)) {
1296 req->ifbr_designated_root = bif->bif_peer_root;
1297 req->ifbr_designated_bridge = bif->bif_peer_bridge;
1298 req->ifbr_designated_cost = bif->bif_peer_cost;
1299 req->ifbr_designated_port = bif->bif_peer_port;
1300 } else {
1301 req->ifbr_designated_root = sc->sc_bridge_id;
1302 req->ifbr_designated_bridge = sc->sc_bridge_id;
1303 req->ifbr_designated_cost = bif->bif_path_cost +
1304 bif->bif_peer_cost;
1305 req->ifbr_designated_port = bif->bif_port_id;
1306 }
1307 } else {
1308 req->ifbr_peer_root = 0;
1309 req->ifbr_peer_bridge = 0;
1310 req->ifbr_peer_cost = 0;
1311 req->ifbr_peer_port = 0;
1312 req->ifbr_designated_root = 0;
1313 req->ifbr_designated_bridge = 0;
1314 req->ifbr_designated_cost = 0;
1315 req->ifbr_designated_port = 0;
1316 }
ac93838f
SS
1317}
1318
d217f5e5 1319static int
ac93838f
SS
1320bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
1321{
1322 struct ifbreq *req = arg;
1323 struct bridge_iflist *bif;
8f7b13ef 1324 struct ifnet *bifp = sc->sc_ifp;
ac93838f
SS
1325
1326 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1327 if (bif == NULL)
1328 return (ENOENT);
1329
8f7b13ef 1330 if (req->ifbr_ifsflags & IFBIF_SPAN) {
d217f5e5
SU
1331 /* SPAN is readonly */
1332 return (EINVAL);
8f7b13ef 1333 }
d217f5e5 1334
ac93838f
SS
1335 if (req->ifbr_ifsflags & IFBIF_STP) {
1336 switch (bif->bif_ifp->if_type) {
1337 case IFT_ETHER:
1338 /* These can do spanning tree. */
1339 break;
1340
1341 default:
1342 /* Nothing else can. */
1343 return (EINVAL);
1344 }
1345 }
1346
70d9a675
MD
1347 bif->bif_flags = (bif->bif_flags & IFBIF_KEEPMASK) |
1348 (req->ifbr_ifsflags & ~IFBIF_KEEPMASK);
8f7b13ef 1349 if (bifp->if_flags & IFF_RUNNING)
ac93838f
SS
1350 bstp_initialization(sc);
1351
1352 return (0);
1353}
1354
d217f5e5 1355static int
ac93838f
SS
1356bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
1357{
1358 struct ifbrparam *param = arg;
4394693c 1359 struct ifnet *ifp = sc->sc_ifp;
ac93838f
SS
1360
1361 sc->sc_brtmax = param->ifbrp_csize;
4394693c 1362
a3dd34d2 1363 ifnet_deserialize_all(ifp);
ac93838f 1364 bridge_rttrim(sc);
a3dd34d2 1365 ifnet_serialize_all(ifp);
ac93838f
SS
1366
1367 return (0);
1368}
1369
d217f5e5 1370static int
ac93838f
SS
1371bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
1372{
1373 struct ifbrparam *param = arg;
1374
1375 param->ifbrp_csize = sc->sc_brtmax;
1376
1377 return (0);
1378}
1379
d217f5e5 1380static int
ac93838f
SS
1381bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
1382{
2d4d3c93 1383 struct bridge_control_arg *bc_arg = arg;
ac93838f
SS
1384 struct ifbifconf *bifc = arg;
1385 struct bridge_iflist *bif;
2d4d3c93
SZ
1386 struct ifbreq *breq;
1387 int count, len;
ac93838f
SS
1388
1389 count = 0;
70d9a675 1390 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next)
ac93838f 1391 count++;
70d9a675 1392 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next)
d217f5e5 1393 count++;
ac93838f
SS
1394
1395 if (bifc->ifbic_len == 0) {
2d4d3c93
SZ
1396 bifc->ifbic_len = sizeof(*breq) * count;
1397 return 0;
1398 } else if (count == 0 || bifc->ifbic_len < sizeof(*breq)) {
1399 bifc->ifbic_len = 0;
1400 return 0;
1401 }
1402
1403 len = min(bifc->ifbic_len, sizeof(*breq) * count);
1404 KKASSERT(len >= sizeof(*breq));
1405
d15c1fc9 1406 breq = kmalloc(len, M_TEMP, M_WAITOK | M_NULLOK | M_ZERO);
2d4d3c93
SZ
1407 if (breq == NULL) {
1408 bifc->ifbic_len = 0;
1409 return ENOMEM;
ac93838f 1410 }
2d4d3c93 1411 bc_arg->bca_kptr = breq;
ac93838f
SS
1412
1413 count = 0;
70d9a675 1414 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next) {
2d4d3c93 1415 if (len < sizeof(*breq))
ac93838f
SS
1416 break;
1417
2d4d3c93
SZ
1418 strlcpy(breq->ifbr_ifsname, bif->bif_ifp->if_xname,
1419 sizeof(breq->ifbr_ifsname));
70d9a675 1420 bridge_ioctl_fillflags(sc, bif, breq);
2d4d3c93 1421 breq++;
ac93838f 1422 count++;
2d4d3c93 1423 len -= sizeof(*breq);
ac93838f 1424 }
70d9a675 1425 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) {
2d4d3c93 1426 if (len < sizeof(*breq))
d217f5e5
SU
1427 break;
1428
2d4d3c93
SZ
1429 strlcpy(breq->ifbr_ifsname, bif->bif_ifp->if_xname,
1430 sizeof(breq->ifbr_ifsname));
1431 breq->ifbr_ifsflags = bif->bif_flags;
2d4d3c93
SZ
1432 breq->ifbr_portno = bif->bif_ifp->if_index & 0xff;
1433 breq++;
d217f5e5 1434 count++;
2d4d3c93 1435 len -= sizeof(*breq);
d217f5e5 1436 }
ac93838f 1437
2d4d3c93
SZ
1438 bifc->ifbic_len = sizeof(*breq) * count;
1439 KKASSERT(bifc->ifbic_len > 0);
1440
1441 bc_arg->bca_len = bifc->ifbic_len;
1442 bc_arg->bca_uptr = bifc->ifbic_req;
1443 return 0;
ac93838f
SS
1444}
1445
d217f5e5 1446static int
ac93838f
SS
1447bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
1448{
2d4d3c93 1449 struct bridge_control_arg *bc_arg = arg;
ac93838f
SS
1450 struct ifbaconf *bac = arg;
1451 struct bridge_rtnode *brt;
2d4d3c93
SZ
1452 struct ifbareq *bareq;
1453 int count, len;
ac93838f 1454
2d4d3c93 1455 count = 0;
4394693c 1456 LIST_FOREACH(brt, &sc->sc_rtlists[mycpuid], brt_list)
2d4d3c93 1457 count++;
ac93838f 1458
2d4d3c93
SZ
1459 if (bac->ifbac_len == 0) {
1460 bac->ifbac_len = sizeof(*bareq) * count;
1461 return 0;
1462 } else if (count == 0 || bac->ifbac_len < sizeof(*bareq)) {
1463 bac->ifbac_len = 0;
1464 return 0;
1465 }
1466
1467 len = min(bac->ifbac_len, sizeof(*bareq) * count);
1468 KKASSERT(len >= sizeof(*bareq));
1469
d15c1fc9 1470 bareq = kmalloc(len, M_TEMP, M_WAITOK | M_NULLOK | M_ZERO);
2d4d3c93
SZ
1471 if (bareq == NULL) {
1472 bac->ifbac_len = 0;
1473 return ENOMEM;
1474 }
1475 bc_arg->bca_kptr = bareq;
1476
1477 count = 0;
4394693c
SZ
1478 LIST_FOREACH(brt, &sc->sc_rtlists[mycpuid], brt_list) {
1479 struct bridge_rtinfo *bri = brt->brt_info;
1480 unsigned long expire;
1481
2d4d3c93
SZ
1482 if (len < sizeof(*bareq))
1483 break;
1484
4394693c 1485 strlcpy(bareq->ifba_ifsname, bri->bri_ifp->if_xname,
2d4d3c93
SZ
1486 sizeof(bareq->ifba_ifsname));
1487 memcpy(bareq->ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
4394693c
SZ
1488 expire = bri->bri_expire;
1489 if ((bri->bri_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
1490 time_second < expire)
1491 bareq->ifba_expire = expire - time_second;
ac93838f 1492 else
2d4d3c93 1493 bareq->ifba_expire = 0;
4394693c 1494 bareq->ifba_flags = bri->bri_flags;
2d4d3c93 1495 bareq++;
ac93838f 1496 count++;
2d4d3c93 1497 len -= sizeof(*bareq);
ac93838f 1498 }
2d4d3c93
SZ
1499
1500 bac->ifbac_len = sizeof(*bareq) * count;
1501 KKASSERT(bac->ifbac_len > 0);
1502
1503 bc_arg->bca_len = bac->ifbac_len;
1504 bc_arg->bca_uptr = bac->ifbac_req;
1505 return 0;
ac93838f
SS
1506}
1507
d217f5e5 1508static int
ac93838f
SS
1509bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
1510{
1511 struct ifbareq *req = arg;
1512 struct bridge_iflist *bif;
4394693c 1513 struct ifnet *ifp = sc->sc_ifp;
ac93838f
SS
1514 int error;
1515
2c9effcf 1516 ASSERT_IFNET_SERIALIZED_ALL(ifp);
4394693c 1517
ac93838f
SS
1518 bif = bridge_lookup_member(sc, req->ifba_ifsname);
1519 if (bif == NULL)
1520 return (ENOENT);
1521
a3dd34d2 1522 ifnet_deserialize_all(ifp);
4394693c
SZ
1523 error = bridge_rtsaddr(sc, req->ifba_dst, bif->bif_ifp,
1524 req->ifba_flags);
a3dd34d2 1525 ifnet_serialize_all(ifp);
ac93838f
SS
1526 return (error);
1527}
1528
d217f5e5 1529static int
ac93838f
SS
1530bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
1531{
1532 struct ifbrparam *param = arg;
1533
1534 sc->sc_brttimeout = param->ifbrp_ctime;
1535
1536 return (0);
1537}
1538
d217f5e5 1539static int
ac93838f
SS
1540bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
1541{
1542 struct ifbrparam *param = arg;
1543
1544 param->ifbrp_ctime = sc->sc_brttimeout;
1545
1546 return (0);
1547}
1548
d217f5e5 1549static int
ac93838f
SS
1550bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
1551{
1552 struct ifbareq *req = arg;
4394693c
SZ
1553 struct ifnet *ifp = sc->sc_ifp;
1554 int error;
ac93838f 1555
a3dd34d2 1556 ifnet_deserialize_all(ifp);
4394693c 1557 error = bridge_rtdaddr(sc, req->ifba_dst);
a3dd34d2 1558 ifnet_serialize_all(ifp);
4394693c 1559 return error;
ac93838f
SS
1560}
1561
d217f5e5 1562static int
ac93838f
SS
1563bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
1564{
1565 struct ifbreq *req = arg;
4394693c 1566 struct ifnet *ifp = sc->sc_ifp;
ac93838f 1567
a3dd34d2 1568 ifnet_deserialize_all(ifp);
30ced003 1569 bridge_rtflush(sc, req->ifbr_ifsflags | IFBF_FLUSHSYNC);
a3dd34d2 1570 ifnet_serialize_all(ifp);
ac93838f
SS
1571
1572 return (0);
1573}
1574
d217f5e5 1575static int
ac93838f
SS
1576bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
1577{
1578 struct ifbrparam *param = arg;
1579
1580 param->ifbrp_prio = sc->sc_bridge_priority;
1581
1582 return (0);
1583}
1584
d217f5e5 1585static int
ac93838f
SS
1586bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
1587{
1588 struct ifbrparam *param = arg;
1589
1590 sc->sc_bridge_priority = param->ifbrp_prio;
1591
1592 if (sc->sc_ifp->if_flags & IFF_RUNNING)
1593 bstp_initialization(sc);
1594
1595 return (0);
1596}
1597
d217f5e5 1598static int
9b42fdc9
MD
1599bridge_ioctl_reinit(struct bridge_softc *sc, void *arg __unused)
1600{
1601 if (sc->sc_ifp->if_flags & IFF_RUNNING)
1602 bstp_initialization(sc);
1603 return (0);
1604}
1605
1606static int
ac93838f
SS
1607bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
1608{
1609 struct ifbrparam *param = arg;
1610
1611 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
1612
1613 return (0);
1614}
1615
d217f5e5 1616static int
ac93838f
SS
1617bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
1618{
1619 struct ifbrparam *param = arg;
1620
1621 if (param->ifbrp_hellotime == 0)
1622 return (EINVAL);
1623 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
1624
1625 if (sc->sc_ifp->if_flags & IFF_RUNNING)
1626 bstp_initialization(sc);
1627
1628 return (0);
1629}
1630
d217f5e5 1631static int
ac93838f
SS
1632bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
1633{
1634 struct ifbrparam *param = arg;
1635
1636 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
1637
1638 return (0);
1639}
1640
d217f5e5 1641static int
ac93838f
SS
1642bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
1643{
1644 struct ifbrparam *param = arg;
1645
1646 if (param->ifbrp_fwddelay == 0)
1647 return (EINVAL);
1648 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
1649
1650 if (sc->sc_ifp->if_flags & IFF_RUNNING)
1651 bstp_initialization(sc);
1652
1653 return (0);
1654}
1655
d217f5e5 1656static int
ac93838f
SS
1657bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
1658{
1659 struct ifbrparam *param = arg;
1660
1661 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
1662
1663 return (0);
1664}
1665
d217f5e5 1666static int
ac93838f
SS
1667bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
1668{
1669 struct ifbrparam *param = arg;
1670
1671 if (param->ifbrp_maxage == 0)
1672 return (EINVAL);
1673 sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
1674
1675 if (sc->sc_ifp->if_flags & IFF_RUNNING)
1676 bstp_initialization(sc);
1677
1678 return (0);
1679}
1680
d217f5e5 1681static int
ac93838f
SS
1682bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
1683{
1684 struct ifbreq *req = arg;
1685 struct bridge_iflist *bif;
1686
1687 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1688 if (bif == NULL)
1689 return (ENOENT);
1690
1691 bif->bif_priority = req->ifbr_priority;
1692
1693 if (sc->sc_ifp->if_flags & IFF_RUNNING)
1694 bstp_initialization(sc);
1695
1696 return (0);
1697}
1698
d217f5e5 1699static int
ac93838f
SS
1700bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
1701{
1702 struct ifbreq *req = arg;
1703 struct bridge_iflist *bif;
1704
1705 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1706 if (bif == NULL)
1707 return (ENOENT);
1708
1709 bif->bif_path_cost = req->ifbr_path_cost;
1710
1711 if (sc->sc_ifp->if_flags & IFF_RUNNING)
1712 bstp_initialization(sc);
1713
1714 return (0);
1715}
1716
d217f5e5 1717static int
1e858374
MD
1718bridge_ioctl_sifbondwght(struct bridge_softc *sc, void *arg)
1719{
1720 struct ifbreq *req = arg;
1721 struct bridge_iflist *bif;
1722
1723 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1724 if (bif == NULL)
1725 return (ENOENT);
1726
1727 bif->bif_bond_weight = req->ifbr_bond_weight;
1728
1729 /* no reinit needed */
1730
1731 return (0);
1732}
1733
1734static int
d217f5e5
SU
1735bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
1736{
1737 struct ifbreq *req = arg;
8f7b13ef 1738 struct bridge_iflist *bif;
d217f5e5 1739 struct ifnet *ifs;
70d9a675 1740 struct bridge_ifinfo *bif_info;
d217f5e5
SU
1741
1742 ifs = ifunit(req->ifbr_ifsname);
1743 if (ifs == NULL)
1744 return (ENOENT);
1745
70d9a675 1746 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next)
d217f5e5
SU
1747 if (ifs == bif->bif_ifp)
1748 return (EBUSY);
1749
1750 if (ifs->if_bridge != NULL)
1751 return (EBUSY);
1752
1753 switch (ifs->if_type) {
d76dd5c7
SZ
1754 case IFT_ETHER:
1755 case IFT_GIF:
1756 case IFT_L2VLAN:
1757 break;
1758
1759 default:
1760 return (EINVAL);
d217f5e5
SU
1761 }
1762
70d9a675
MD
1763 /*
1764 * bif_info is needed for bif_flags
1765 */
1766 bif_info = kmalloc(sizeof(*bif_info), M_DEVBUF, M_WAITOK | M_ZERO);
1767 bif_info->bifi_ifp = ifs;
1768
8f7b13ef 1769 bif = kmalloc(sizeof(*bif), M_DEVBUF, M_WAITOK | M_ZERO);
d217f5e5 1770 bif->bif_ifp = ifs;
70d9a675 1771 bif->bif_info = bif_info;
d217f5e5 1772 bif->bif_flags = IFBIF_SPAN;
8f7b13ef 1773 /* NOTE: span bif does not need bridge_ifinfo */
d217f5e5 1774
70d9a675 1775 TAILQ_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next);
d217f5e5 1776
d895303b
SZ
1777 sc->sc_span = 1;
1778
d217f5e5
SU
1779 return (0);
1780}
1781
1782static int
1783bridge_ioctl_delspan(struct bridge_softc *sc, void *arg)
1784{
1785 struct ifbreq *req = arg;
1786 struct bridge_iflist *bif;
1787 struct ifnet *ifs;
1788
1789 ifs = ifunit(req->ifbr_ifsname);
1790 if (ifs == NULL)
1791 return (ENOENT);
1792
70d9a675 1793 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next)
d217f5e5
SU
1794 if (ifs == bif->bif_ifp)
1795 break;
1796
1797 if (bif == NULL)
1798 return (ENOENT);
1799
1800 bridge_delete_span(sc, bif);
1801
70d9a675 1802 if (TAILQ_EMPTY(&sc->sc_spanlist))
d895303b
SZ
1803 sc->sc_span = 0;
1804
d217f5e5
SU
1805 return (0);
1806}
1807
d217f5e5 1808static void
002c1265 1809bridge_ifdetach_dispatch(netmsg_t msg)
ac93838f 1810{
ac308789
SZ
1811 struct ifnet *ifp, *bifp;
1812 struct bridge_softc *sc;
d217f5e5 1813 struct bridge_iflist *bif;
ac308789 1814
002c1265 1815 ifp = msg->lmsg.u.ms_resultp;
ac308789 1816 sc = ifp->if_bridge;
ac93838f 1817
d217f5e5
SU
1818 /* Check if the interface is a bridge member */
1819 if (sc != NULL) {
bdfc79d0
SZ
1820 bifp = sc->sc_ifp;
1821
a3dd34d2 1822 ifnet_serialize_all(bifp);
ac93838f 1823
d217f5e5 1824 bif = bridge_lookup_member_if(sc, ifp);
ac308789 1825 if (bif != NULL) {
d217f5e5 1826 bridge_delete_member(sc, bif, 1);
ac308789
SZ
1827 } else {
1828 /* XXX Why bif will be NULL? */
1829 }
d217f5e5 1830
a3dd34d2 1831 ifnet_deserialize_all(bifp);
ac308789 1832 goto reply;
d217f5e5
SU
1833 }
1834
ac308789
SZ
1835 crit_enter(); /* XXX MP */
1836
d217f5e5
SU
1837 /* Check if the interface is a span port */
1838 LIST_FOREACH(sc, &bridge_list, sc_list) {
bdfc79d0
SZ
1839 bifp = sc->sc_ifp;
1840
a3dd34d2 1841 ifnet_serialize_all(bifp);
bdfc79d0 1842
70d9a675 1843 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next)
d217f5e5
SU
1844 if (ifp == bif->bif_ifp) {
1845 bridge_delete_span(sc, bif);
1846 break;
1847 }
bdfc79d0 1848
a3dd34d2 1849 ifnet_deserialize_all(bifp);
d217f5e5 1850 }
ac308789
SZ
1851
1852 crit_exit();
1853
1854reply:
002c1265 1855 lwkt_replymsg(&msg->lmsg, 0);
ac308789
SZ
1856}
1857
1858/*
1859 * bridge_ifdetach:
1860 *
1861 * Detach an interface from a bridge. Called when a member
1862 * interface is detaching.
1863 */
1864static void
1865bridge_ifdetach(void *arg __unused, struct ifnet *ifp)
1866{
002c1265 1867 struct netmsg_base msg;
ac308789 1868
002c1265 1869 netmsg_init(&msg, NULL, &curthread->td_msgport,
48e7b118 1870 0, bridge_ifdetach_dispatch);
002c1265 1871 msg.lmsg.u.ms_resultp = ifp;
ac308789 1872
002c1265 1873 lwkt_domsg(BRIDGE_CFGPORT, &msg.lmsg, 0);
ac93838f
SS
1874}
1875
1876/*
1877 * bridge_init:
1878 *
1879 * Initialize a bridge interface.
1880 */
1881static void
1882bridge_init(void *xsc)
1883{
d71129d9 1884 bridge_control(xsc, SIOCSIFFLAGS, bridge_ioctl_init, NULL);
ac93838f
SS
1885}
1886
1887/*
1888 * bridge_stop:
1889 *
1890 * Stop the bridge interface.
1891 */
d217f5e5 1892static void
867cc45a 1893bridge_stop(struct ifnet *ifp)
ac93838f 1894{
d71129d9 1895 bridge_control(ifp->if_softc, SIOCSIFFLAGS, bridge_ioctl_stop, NULL);
ac93838f
SS
1896}
1897
ecd27a4c 1898/*
70d9a675
MD
1899 * Returns TRUE if the packet is being sent 'from us'... from our bridge
1900 * interface or from any member of our bridge interface. This is used
1901 * later on to force the MAC to be the MAC of our bridge interface.
1902 */
1903static int
1904bridge_from_us(struct bridge_softc *sc, struct ether_header *eh)
1905{
1906 struct bridge_iflist *bif;
1907
1908 if (memcmp(eh->ether_shost, IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN) == 0)
1909 return (1);
1910
1911 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next) {
1912 if (memcmp(eh->ether_shost, IF_LLADDR(bif->bif_ifp),
1913 ETHER_ADDR_LEN) == 0) {
1914 return (1);
1915 }
1916 }
1917 return (0);
1918}
1919
1920/*
ecd27a4c
SZ
1921 * bridge_enqueue:
1922 *
1923 * Enqueue a packet on a bridge member interface.
1924 *
1925 */
1926void
1927bridge_enqueue(struct ifnet *dst_ifp, struct mbuf *m)
1928{
137aa7b3 1929 struct netmsg_packet *nmp;
137aa7b3
SZ
1930
1931 nmp = &m->m_hdr.mh_netmsg;
002c1265 1932 netmsg_init(&nmp->base, NULL, &netisr_apanic_rport,
48e7b118 1933 0, bridge_enqueue_handler);
137aa7b3 1934 nmp->nm_packet = m;
002c1265 1935 nmp->base.lmsg.u.ms_resultp = dst_ifp;
137aa7b3 1936
002c1265 1937 lwkt_sendmsg(ifnet_portfn(mycpu->gd_cpuid), &nmp->base.lmsg);
ac93838f
SS
1938}
1939
1940/*
e1d2145d 1941 * bridge_output:
ac93838f
SS
1942 *
1943 * Send output from a bridge member interface. This
1944 * performs the bridging function for locally originated
1945 * packets.
1946 *
1947 * The mbuf has the Ethernet header already attached. We must
1948 * enqueue or free the mbuf before returning.
1949 */
a18eb4b7 1950static int
eb366364 1951bridge_output(struct ifnet *ifp, struct mbuf *m)
ac93838f 1952{
89ea766d 1953 struct bridge_softc *sc = ifp->if_bridge;
3677aae9 1954 struct bridge_iflist *bif, *nbif;
ac93838f 1955 struct ether_header *eh;
1e858374 1956 struct ifnet *dst_if, *alt_if, *bifp;
4ee4f753 1957 int from_us;
70d9a675 1958 int priority;
1e858374 1959 int alt_priority;
ac93838f 1960
2c9effcf 1961 ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp);
ac93838f 1962
89ea766d
SZ
1963 /*
1964 * Make sure that we are still a member of a bridge interface.
1965 */
1966 if (sc == NULL) {
1967 m_freem(m);
1968 return (0);
1969 }
137aa7b3 1970 bifp = sc->sc_ifp;
89ea766d 1971
70d9a675
MD
1972 /*
1973 * Acquire header
1974 */
ac93838f
SS
1975 if (m->m_len < ETHER_HDR_LEN) {
1976 m = m_pullup(m, ETHER_HDR_LEN);
70d9a675
MD
1977 if (m == NULL) {
1978 bifp->if_oerrors++;
ac93838f 1979 return (0);
70d9a675 1980 }
ac93838f 1981 }
ac93838f 1982 eh = mtod(m, struct ether_header *);
70d9a675 1983 from_us = bridge_from_us(sc, eh);
be02a6a0
MD
1984
1985 /*
ac93838f
SS
1986 * If bridge is down, but the original output interface is up,
1987 * go ahead and send out that interface. Otherwise, the packet
1988 * is dropped below.
1989 */
137aa7b3 1990 if ((bifp->if_flags & IFF_RUNNING) == 0) {
ac93838f
SS
1991 dst_if = ifp;
1992 goto sendunicast;
1993 }
1994
1995 /*
1996 * If the packet is a multicast, or we don't know a better way to
1997 * get there, send to all interfaces.
1998 */
1999 if (ETHER_IS_MULTICAST(eh->ether_dhost))
2000 dst_if = NULL;
2001 else
2002 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
70d9a675 2003
ac93838f 2004 if (dst_if == NULL) {
ac93838f
SS
2005 struct mbuf *mc;
2006 int used = 0;
1e858374 2007 int found = 0;
ac93838f 2008
d895303b
SZ
2009 if (sc->sc_span)
2010 bridge_span(sc, m);
d217f5e5 2011
1e858374
MD
2012 alt_if = NULL;
2013 alt_priority = 0;
70d9a675 2014 TAILQ_FOREACH_MUTABLE(bif, &sc->sc_iflists[mycpuid],
137aa7b3 2015 bif_next, nbif) {
ac93838f 2016 dst_if = bif->bif_ifp;
1e858374 2017
ac93838f
SS
2018 if ((dst_if->if_flags & IFF_RUNNING) == 0)
2019 continue;
2020
2021 /*
2022 * If this is not the original output interface,
2023 * and the interface is participating in spanning
2024 * tree, make sure the port is in a state that
2025 * allows forwarding.
1e858374
MD
2026 *
2027 * We keep track of a possible backup IF if we are
2028 * unable to find any interfaces to forward through.
2029 *
2030 * NOTE: Currently round-robining is not implemented
2031 * across bonded interface groups (needs an
2032 * algorithm to track each group somehow).
2033 *
2034 * Similarly we track only one alternative
2035 * interface if no suitable interfaces are
2036 * found.
ac93838f
SS
2037 */
2038 if (dst_if != ifp &&
2039 (bif->bif_flags & IFBIF_STP) != 0) {
2040 switch (bif->bif_state) {
1e858374
MD
2041 case BSTP_IFSTATE_BONDED:
2042 if (bif->bif_priority + 512 >
2043 alt_priority) {
2044 alt_priority =
2045 bif->bif_priority + 512;
2046 alt_if = bif->bif_ifp;
2047 }
2048 continue;
ac93838f 2049 case BSTP_IFSTATE_BLOCKING:
1e858374
MD
2050 if (bif->bif_priority + 256 >
2051 alt_priority) {
2052 alt_priority =
2053 bif->bif_priority + 256;
2054 alt_if = bif->bif_ifp;
2055 }
2056 continue;
2057 case BSTP_IFSTATE_LEARNING:
2058 if (bif->bif_priority > alt_priority) {
2059 alt_priority =
2060 bif->bif_priority;
2061 alt_if = bif->bif_ifp;
2062 }
2063 continue;
2064 case BSTP_IFSTATE_L1BLOCKING:
ac93838f
SS
2065 case BSTP_IFSTATE_LISTENING:
2066 case BSTP_IFSTATE_DISABLED:
2067 continue;
1e858374
MD
2068 default:
2069 /* FORWARDING */
2070 break;
ac93838f
SS
2071 }
2072 }
2073
1e858374 2074 KKASSERT(used == 0);
70d9a675 2075 if (TAILQ_NEXT(bif, bif_next) == NULL) {
ac93838f
SS
2076 used = 1;
2077 mc = m;
2078 } else {
2079 mc = m_copypacket(m, MB_DONTWAIT);
2080 if (mc == NULL) {
137aa7b3 2081 bifp->if_oerrors++;
ac93838f
SS
2082 continue;
2083 }
2084 }
4ee4f753
MD
2085
2086 /*
2087 * If the packet is 'from' us override ether_shost.
2088 */
70d9a675 2089 bridge_handoff(sc, dst_if, mc, from_us);
1e858374 2090 found = 1;
137aa7b3
SZ
2091
2092 if (nbif != NULL && !nbif->bif_onlist) {
2093 KKASSERT(bif->bif_onlist);
70d9a675 2094 nbif = TAILQ_NEXT(bif, bif_next);
137aa7b3 2095 }
ac93838f 2096 }
1e858374
MD
2097
2098 /*
2099 * If we couldn't find anything use the backup interface
2100 * if we have one.
2101 */
2102 if (found == 0 && alt_if) {
2103 KKASSERT(used == 0);
2104 mc = m;
2105 used = 1;
2106 bridge_handoff(sc, alt_if, mc, from_us);
2107 }
2108
ac93838f
SS
2109 if (used == 0)
2110 m_freem(m);
ad8c8b44 2111 return (0);
ac93838f
SS
2112 }
2113
d217f5e5 2114sendunicast:
ac93838f 2115 /*
70d9a675
MD
2116 * If STP is enabled on the target we are an equal opportunity
2117 * employer and do not necessarily output to dst_if. Instead
2118 * scan available links with the same MAC as the current dst_if
2119 * and choose the best one.
3677aae9 2120 *
70d9a675 2121 * We also need to do this because arp entries tag onto a particular
3677aae9
MD
2122 * interface and if it happens to be dead then the packets will
2123 * go into a bit bucket.
70d9a675
MD
2124 *
2125 * If LINK2 is set the matching links are bonded and we-round robin.
2126 * (the MAC address must be the same for the participating links).
1e858374
MD
2127 * In this case links in a STP FORWARDING or BONDED state are
2128 * allowed for unicast packets.
ac93838f 2129 */
3677aae9
MD
2130 bif = bridge_lookup_member_if(sc, dst_if);
2131 if (bif->bif_flags & IFBIF_STP) {
1e858374 2132 alt_if = NULL;
70d9a675 2133 priority = 0;
1e858374
MD
2134 alt_priority = 0;
2135
70d9a675
MD
2136 TAILQ_FOREACH_MUTABLE(bif, &sc->sc_iflists[mycpuid],
2137 bif_next, nbif) {
1e858374
MD
2138 /*
2139 * Ignore member interfaces which aren't running.
2140 */
2141 if ((bif->bif_ifp->if_flags & IFF_RUNNING) == 0)
2142 continue;
2143
2144 /*
2145 * member interfaces with the same MAC (usually TAPs)
2146 * are considered to be the same. Select the best
2147 * one from BONDED or FORWARDING and keep track of
2148 * the best one in the BLOCKING state if no
2149 * candidates are available otherwise.
2150 */
70d9a675
MD
2151 if (memcmp(IF_LLADDR(bif->bif_ifp),
2152 IF_LLADDR(dst_if),
2153 ETHER_ADDR_LEN) != 0) {
2154 continue;
2155 }
2156
2157 switch(bif->bif_state) {
2158 case BSTP_IFSTATE_BLOCKING:
1e858374
MD
2159 if (bif->bif_priority > alt_priority + 256) {
2160 alt_priority = bif->bif_priority + 256;
2161 alt_if = bif->bif_ifp;
2162 }
2163 continue;
2164 case BSTP_IFSTATE_LEARNING:
2165 if (bif->bif_priority > alt_priority) {
2166 alt_priority = bif->bif_priority;
2167 alt_if = bif->bif_ifp;
2168 }
2169 continue;
70d9a675
MD
2170 case BSTP_IFSTATE_L1BLOCKING:
2171 case BSTP_IFSTATE_LISTENING:
2172 case BSTP_IFSTATE_DISABLED:
2173 continue;
2174 default:
1e858374 2175 /* bonded, forwarding */
70d9a675
MD
2176 break;
2177 }
70d9a675
MD
2178
2179 /*
2180 * XXX we need to use the toepliz hash or
2181 * something like that instead of
2182 * round-robining.
2183 */
2184 if (sc->sc_ifp->if_flags & IFF_LINK2) {
3677aae9 2185 dst_if = bif->bif_ifp;
1e858374
MD
2186 if (++bif->bif_bond_count >=
2187 bif->bif_bond_weight) {
2188 bif->bif_bond_count = 0;
2189 TAILQ_REMOVE(&sc->sc_iflists[mycpuid],
2190 bif, bif_next);
2191 TAILQ_INSERT_TAIL(
2192 &sc->sc_iflists[mycpuid],
2193 bif, bif_next);
2194 }
2195 priority = 1;
3677aae9
MD
2196 break;
2197 }
70d9a675
MD
2198 if (bif->bif_priority > priority) {
2199 priority = bif->bif_priority;
2200 dst_if = bif->bif_ifp;
2201 }
3677aae9 2202 }
1e858374
MD
2203
2204 /*
2205 * Interface of last resort if nothing was found.
2206 */
2207 if (priority == 0 && alt_if)
2208 dst_if = alt_if;
3677aae9
MD
2209 }
2210
d895303b
SZ
2211 if (sc->sc_span)
2212 bridge_span(sc, m);
ad8c8b44 2213 if ((dst_if->if_flags & IFF_RUNNING) == 0)
ac93838f 2214 m_freem(m);
ad8c8b44 2215 else
70d9a675 2216 bridge_handoff(sc, dst_if, m, from_us);
ac93838f
SS
2217 return (0);
2218}
2219
2220/*
70d9a675
MD
2221 * Returns the bridge interface associated with an ifc.
2222 * Pass ifp->if_bridge (must not be NULL). Used by the ARP
2223 * code to supply the bridge for the is-at info, making
2224 * the bridge responsible for matching local addresses.
2225 *
2226 * Without this the ARP code will supply bridge member interfaces
2227 * for the is-at which makes it difficult the bridge to fail-over
2228 * interfaces (amoung other things).
2229 */
2230static struct ifnet *
2231bridge_interface(void *if_bridge)
2232{
2233 struct bridge_softc *sc = if_bridge;
2234 return (sc->sc_ifp);
2235}
2236
2237/*
ac93838f
SS
2238 * bridge_start:
2239 *
2240 * Start output on a bridge.
ac93838f 2241 */
d217f5e5 2242static void
ac93838f
SS
2243bridge_start(struct ifnet *ifp)
2244{
867cc45a 2245 struct bridge_softc *sc = ifp->if_softc;
ac93838f 2246
2c9effcf 2247 ASSERT_IFNET_SERIALIZED_TX(ifp);
ac93838f
SS
2248
2249 ifp->if_flags |= IFF_OACTIVE;
2250 for (;;) {
867cc45a
SZ
2251 struct ifnet *dst_if = NULL;
2252 struct ether_header *eh;
2253 struct mbuf *m;
2254
ac93838f 2255 m = ifq_dequeue(&ifp->if_snd, NULL);
867cc45a 2256 if (m == NULL)
ac93838f 2257 break;
ac93838f 2258
867cc45a
SZ
2259 if (m->m_len < sizeof(*eh)) {
2260 m = m_pullup(m, sizeof(*eh));
2261 if (m == NULL) {
2262 ifp->if_oerrors++;
2263 continue;
2264 }
2265 }
ac93838f 2266 eh = mtod(m, struct ether_header *);
ac93838f 2267
867cc45a
SZ
2268 BPF_MTAP(ifp, m);
2269 ifp->if_opackets++;
2270
2271 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0)
ac93838f 2272 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
ac93838f
SS
2273
2274 if (dst_if == NULL)
137aa7b3 2275 bridge_start_bcast(sc, m);
ac93838f 2276 else
708a3bfa 2277 bridge_enqueue(dst_if, m);
ac93838f
SS
2278 }
2279 ifp->if_flags &= ~IFF_OACTIVE;
ac93838f
SS
2280}
2281
2282/*
2283 * bridge_forward:
2284 *
4ee4f753
MD
2285 * Forward packets received on a bridge interface via the input
2286 * path.
2287 *
1e858374 2288 * This implements the forwarding function of the bridge.
ac93838f 2289 */
d217f5e5 2290static void
ac93838f
SS
2291bridge_forward(struct bridge_softc *sc, struct mbuf *m)
2292{
70d9a675 2293 struct bridge_iflist *bif, *nbif;
1e858374 2294 struct ifnet *src_if, *dst_if, *alt_if, *ifp;
ac93838f 2295 struct ether_header *eh;
70d9a675 2296 int priority;
1e858374
MD
2297 int alt_priority;
2298 int from_blocking;
ac93838f
SS
2299
2300 src_if = m->m_pkthdr.rcvif;
2301 ifp = sc->sc_ifp;
2302
2c9effcf 2303 ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp);
ac93838f 2304
ecd27a4c
SZ
2305 ifp->if_ipackets++;
2306 ifp->if_ibytes += m->m_pkthdr.len;
ac93838f
SS
2307
2308 /*
2309 * Look up the bridge_iflist.
2310 */
2311 bif = bridge_lookup_member_if(sc, src_if);
2312 if (bif == NULL) {
2313 /* Interface is not a bridge member (anymore?) */
2314 m_freem(m);
2315 return;
2316 }
2317
1e858374
MD
2318 /*
2319 * In spanning tree mode receiving a packet from an interface
2320 * in a BLOCKING state is allowed, it could be a member of last
2321 * resort from the sender's point of view, but forwarding it is
2322 * not allowed.
2323 *
2324 * The sender's spanning tree will eventually sync up and the
2325 * sender will go into a BLOCKING state too (but this still may be
2326 * an interface of last resort during state changes).
2327 */
ac93838f
SS
2328 if (bif->bif_flags & IFBIF_STP) {
2329 switch (bif->bif_state) {
70d9a675 2330 case BSTP_IFSTATE_L1BLOCKING:
ac93838f
SS
2331 case BSTP_IFSTATE_LISTENING:
2332 case BSTP_IFSTATE_DISABLED:
2333 m_freem(m);
2334 return;
70d9a675 2335 default:
1e858374 2336 /* learning, blocking, bonded, forwarding */
70d9a675 2337 break;
ac93838f
SS
2338 }
2339 }
1e858374 2340 from_blocking = (bif->bif_state == BSTP_IFSTATE_BLOCKING);
ac93838f
SS
2341
2342 eh = mtod(m, struct ether_header *);
2343
2344 /*
2345 * If the interface is learning, and the source
2346 * address is valid and not multicast, record
2347 * the address.
2348 */
2349 if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
1e858374 2350 from_blocking == 0 &&
ac93838f
SS
2351 ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
2352 (eh->ether_shost[0] == 0 &&
2353 eh->ether_shost[1] == 0 &&
2354 eh->ether_shost[2] == 0 &&
2355 eh->ether_shost[3] == 0 &&
2356 eh->ether_shost[4] == 0 &&
70d9a675 2357 eh->ether_shost[5] == 0) == 0) {
4394693c 2358 bridge_rtupdate(sc, eh->ether_shost, src_if, IFBAF_DYNAMIC);
70d9a675 2359 }
ac93838f 2360
1e858374
MD
2361 /*
2362 * Don't forward from an interface in the listening or learning
2363 * state. That is, in the learning state we learn information
2364 * but we throw away the packets.
2365 *
2366 * We let through packets on interfaces in the blocking state.
2367 * The blocking state is applicable to the send side, not the
2368 * receive side.
2369 */
ac93838f 2370 if ((bif->bif_flags & IFBIF_STP) != 0 &&
1e858374
MD
2371 (bif->bif_state == BSTP_IFSTATE_LISTENING ||
2372 bif->bif_state == BSTP_IFSTATE_LEARNING)) {
ac93838f 2373 m_freem(m);
ecd27a4c 2374 return;
ac93838f
SS
2375 }
2376
2377 /*
2378 * At this point, the port either doesn't participate
2379 * in spanning tree or it is in the forwarding state.
2380 */
2381
2382 /*
2383 * If the packet is unicast, destined for someone on
2384 * "this" side of the bridge, drop it.
2385 */
2386 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
2387 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
2388 if (src_if == dst_if) {
2389 m_freem(m);
ecd27a4c 2390 return;
ac93838f
SS
2391 }
2392 } else {
2393 /* ...forward it to all interfaces. */
137aa7b3 2394 ifp->if_imcasts++;
ac93838f
SS
2395 dst_if = NULL;
2396 }
2397
1e858374
MD
2398 /*
2399 * Brodcast if we do not have forwarding information. However, if
2400 * we received the packet on a blocking interface we do not do this
2401 * (unless you really want to blow up your network).
2402 */
ac93838f 2403 if (dst_if == NULL) {
1e858374
MD
2404 if (from_blocking)
2405 m_freem(m);
2406 else
2407 bridge_broadcast(sc, src_if, m);
ecd27a4c 2408 return;
ac93838f
SS
2409 }
2410
2411 /*
70d9a675 2412 * Unicast, kinda replicates the output side of bridge_output().
ac93838f 2413 */
ac93838f
SS
2414 bif = bridge_lookup_member_if(sc, dst_if);
2415 if (bif == NULL) {
2416 /* Not a member of the bridge (anymore?) */
2417 m_freem(m);
ecd27a4c 2418 return;
ac93838f
SS
2419 }
2420
2421 if (bif->bif_flags & IFBIF_STP) {
1e858374
MD
2422 alt_if = NULL;
2423 alt_priority = 0;
70d9a675 2424 priority = 0;
1e858374 2425
70d9a675
MD
2426 TAILQ_FOREACH_MUTABLE(bif, &sc->sc_iflists[mycpuid],
2427 bif_next, nbif) {
2428 if (memcmp(IF_LLADDR(bif->bif_ifp),
2429 IF_LLADDR(dst_if),
2430 ETHER_ADDR_LEN) != 0) {
2431 continue;
2432 }
2433
1e858374
MD
2434 if ((bif->bif_ifp->if_flags & IFF_RUNNING) == 0)
2435 continue;
2436
2437 /*
2438 * NOTE: We allow tranmissions through a BLOCKING
2439 * or LEARNING interface only as a last resort.
2440 * We DISALLOW both cases if the receiving
2441 *
2442 * NOTE: If we send a packet through a learning
2443 * interface the receiving end (if also in
2444 * LEARNING) will throw it away, so this is
2445 * the ultimate last resort.
2446 */
70d9a675
MD
2447 switch(bif->bif_state) {
2448 case BSTP_IFSTATE_BLOCKING:
1e858374
MD
2449 if (from_blocking == 0 &&
2450 bif->bif_priority + 256 > alt_priority) {
2451 alt_priority = bif->bif_priority + 256;
2452 alt_if = bif->bif_ifp;
2453 }
2454 continue;
2455 case BSTP_IFSTATE_LEARNING:
2456 if (from_blocking == 0 &&
2457 bif->bif_priority > alt_priority) {
2458 alt_priority = bif->bif_priority;
2459 alt_if = bif->bif_ifp;
2460 }
2461 continue;
70d9a675
MD
2462 case BSTP_IFSTATE_L1BLOCKING:
2463 case BSTP_IFSTATE_LISTENING:
2464 case BSTP_IFSTATE_DISABLED:
2465 continue;
2466 default:
1e858374 2467 /* FORWARDING, BONDED */
70d9a675
MD
2468 break;
2469 }
2470
70d9a675
MD
2471 /*
2472 * XXX we need to use the toepliz hash or
2473 * something like that instead of
2474 * round-robining.
2475 */
2476 if (sc->sc_ifp->if_flags & IFF_LINK2) {
2477 dst_if = bif->bif_ifp;
1e858374
MD
2478 if (++bif->bif_bond_count >=
2479 bif->bif_bond_weight) {
2480 bif->bif_bond_count = 0;
2481 TAILQ_REMOVE(&sc->sc_iflists[mycpuid],
2482 bif, bif_next);
2483 TAILQ_INSERT_TAIL(
2484 &sc->sc_iflists[mycpuid],
2485 bif, bif_next);
2486 }
2487 priority = 1;
70d9a675
MD
2488 break;
2489 }
1e858374
MD
2490
2491 /*
2492 * Select best interface in the FORWARDING or
2493 * BONDED set. Well, there shouldn't be any
2494 * in a BONDED state if LINK2 is not set (they
2495 * will all be in a BLOCKING) state, but there
2496 * could be a transitory condition here.
2497 */
70d9a675
MD
2498 if (bif->bif_priority > priority) {
2499 priority = bif->bif_priority;
2500 dst_if = bif->bif_ifp;
2501 }
ac93838f 2502 }
1e858374
MD
2503
2504 /*
2505 * If no suitable interfaces were found but a suitable
2506 * alternative interface was found, use the alternative
2507 * interface.
2508 */
2509 if (priority == 0 && alt_if)
2510 dst_if = alt_if;
ac93838f
SS
2511 }
2512
70d9a675
MD
2513 /*
2514 * At this point, we're dealing with a unicast frame
2515 * going to a different interface.
2516 */
2517 if ((dst_if->if_flags & IFF_RUNNING) == 0) {
2518 m_freem(m);
2519 return;
2520 }
2521
ac93838f
SS
2522 if (inet_pfil_hook.ph_hashooks > 0
2523#ifdef INET6
2524 || inet6_pfil_hook.ph_hashooks > 0
2525#endif
2526 ) {
ecd27a4c 2527 if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0)
137aa7b3 2528 return;
ecd27a4c 2529 if (m == NULL)
137aa7b3 2530 return;
ecd27a4c
SZ
2531
2532 if (bridge_pfil(&m, ifp, dst_if, PFIL_OUT) != 0)
137aa7b3 2533 return;
ac93838f 2534 if (m == NULL)
137aa7b3 2535 return;
ac93838f 2536 }
70d9a675 2537 bridge_handoff(sc, dst_if, m, 0);
ac93838f
SS
2538}
2539
2540/*
2541 * bridge_input:
2542 *
2543 * Receive input from a member interface. Queue the packet for
2544 * bridging if it is not for us.
2545 */
a18eb4b7 2546static struct mbuf *
ac93838f
SS
2547bridge_input(struct ifnet *ifp, struct mbuf *m)
2548{
2549 struct bridge_softc *sc = ifp->if_bridge;
2550 struct bridge_iflist *bif;
3ce67233 2551 struct ifnet *bifp, *new_ifp;
ac93838f
SS
2552 struct ether_header *eh;
2553 struct mbuf *mc, *mc2;
1e858374 2554 int from_blocking;
ac93838f 2555
2c9effcf 2556 ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp);
137aa7b3 2557
89ea766d
SZ
2558 /*
2559 * Make sure that we are still a member of a bridge interface.
2560 */
2561 if (sc == NULL)
2562 return m;
2563
3ce67233 2564 new_ifp = NULL;
ac93838f 2565 bifp = sc->sc_ifp;
3ce67233 2566
ac91a939 2567 if ((bifp->if_flags & IFF_RUNNING) == 0)
ac93838f
SS
2568 goto out;
2569
3a593c54 2570 /*
0f6ada01 2571 * Implement support for bridge monitoring. If this flag has been
3a593c54 2572 * set on this interface, discard the packet once we push it through
0f6ada01
SZ
2573 * the bpf(4) machinery, but before we do, increment various counters
2574 * associated with this bridge.
3a593c54 2575 */
0f6ada01
SZ
2576 if (bifp->if_flags & IFF_MONITOR) {
2577 /* Change input interface to this bridge */
2578 m->m_pkthdr.rcvif = bifp;
2579
3a593c54 2580 BPF_MTAP(bifp, m);
0f6ada01
SZ
2581
2582 /* Update bridge's ifnet statistics */
3a593c54
MD
2583 bifp->if_ipackets++;
2584 bifp->if_ibytes += m->m_pkthdr.len;
0f6ada01
SZ
2585 if (m->m_flags & (M_MCAST | M_BCAST))
2586 bifp->if_imcasts++;
2587
3a593c54 2588 m_freem(m);
ac91a939 2589 m = NULL;
3a593c54
MD
2590 goto out;
2591 }
2592
be02a6a0
MD
2593 /*
2594 * Handle the ether_header
b7441d0c
MD
2595 *
2596 * In all cases if the packet is destined for us via our MAC
2597 * we must clear BRIDGE_MBUF_TAGGED to ensure that we don't
2598 * repeat the source MAC out the same interface.
70d9a675
MD
2599 *
2600 * This first test against our bridge MAC is the fast-path.
2601 *
2602 * NOTE! The bridge interface can serve as an endpoint for
2603 * communication but normally there are no IPs associated
2604 * with it so you cannot route through it. Instead what
2605 * you do is point your default route *THROUGH* the bridge
2606 * to the actual default router for one of the bridged spaces.
2607 *
2608 * Another possibility is to put all your IP specifications
2609 * on the bridge instead of on the individual interfaces. If
2610 * you do this it should be possible to use the bridge as an
2611 * end point and route (rather than switch) through it using
2612 * the default route or ipfw forwarding rules.
be02a6a0 2613 */
70d9a675
MD
2614
2615 /*
2616 * Acquire header
2617 */
2618 if (m->m_len < ETHER_HDR_LEN) {
2619 m = m_pullup(m, ETHER_HDR_LEN);
2620 if (m == NULL)
2621 goto out;
2622 }
ac93838f 2623 eh = mtod(m, struct ether_header *);
be02a6a0
MD
2624 m->m_pkthdr.fw_flags |= BRIDGE_MBUF_TAGGED;
2625 bcopy(eh, &m->m_pkthdr.br.ether, sizeof(*eh));
ac93838f 2626
70d9a675
MD
2627 if ((bridge_debug & 1) &&
2628 (ntohs(eh->ether_type) == ETHERTYPE_ARP ||
2629 ntohs(eh->ether_type) == ETHERTYPE_REVARP)) {
2630 kprintf("%02x:%02x:%02x:%02x:%02x:%02x "
2631 "%02x:%02x:%02x:%02x:%02x:%02x type %04x "
2632 "lla %02x:%02x:%02x:%02x:%02x:%02x\n",
2633 eh->ether_dhost[0],
2634 eh->ether_dhost[1],
2635 eh->ether_dhost[2],
2636 eh->ether_dhost[3],
2637 eh->ether_dhost[4],
2638 eh->ether_dhost[5],
2639 eh->ether_shost[0],
2640 eh->ether_shost[1],
2641 eh->ether_shost[2],
2642 eh->ether_shost[3],
2643 eh->ether_shost[4],
2644 eh->ether_shost[5],
2645 eh->ether_type,
2646 ((u_char *)IF_LLADDR(bifp))[0],
2647 ((u_char *)IF_LLADDR(bifp))[1],
2648 ((u_char *)IF_LLADDR(bifp))[2],
2649 ((u_char *)IF_LLADDR(bifp))[3],
2650 ((u_char *)IF_LLADDR(bifp))[4],
2651 ((u_char *)IF_LLADDR(bifp))[5]
2652 );
2653 }
2654
3ce67233 2655 if (memcmp(eh->ether_dhost, IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0) {
ac93838f
SS
2656 /*
2657 * If the packet is for us, set the packets source as the
3ce67233 2658 * bridge, and return the packet back to ifnet.if_input for
ac93838f
SS
2659 * local processing.
2660 */
b7441d0c 2661 m->m_pkthdr.fw_flags &= ~BRIDGE_MBUF_TAGGED;
3ce67233
SZ
2662 KASSERT(bifp->if_bridge == NULL,
2663 ("loop created in bridge_input"));
02b0fa02
MD
2664 if (pfil_member != 0) {
2665 if (inet_pfil_hook.ph_hashooks > 0
2666#ifdef INET6
2667 || inet6_pfil_hook.ph_hashooks > 0
2668#endif
2669 ) {
2670 if (bridge_pfil(&m, NULL, ifp, PFIL_IN) != 0)
2671 goto out;
2672 if (m == NULL)
2673 goto out;
2674 }
2675 }
3ce67233
SZ
2676 new_ifp = bifp;
2677 goto out;
2678 }
ac93838f 2679
3ce67233
SZ
2680 /*
2681 * Tap all packets arriving on the bridge, no matter if
2682 * they are local destinations or not. In is in.
2683 */
2684 BPF_MTAP(bifp, m);
ac93838f 2685
3ce67233
SZ
2686 bif = bridge_lookup_member_if(sc, ifp);
2687 if (bif == NULL)
ac93838f 2688 goto out;
ac93838f 2689
d895303b
SZ
2690 if (sc->sc_span)
2691 bridge_span(sc, m);
d217f5e5 2692
f581b688 2693 if (m->m_flags & (M_BCAST | M_MCAST)) {
70d9a675
MD
2694 /*
2695 * Tap off 802.1D packets; they do not get forwarded.
2696 */
ac93838f 2697 if (memcmp(eh->ether_dhost, bstp_etheraddr,
3677aae9 2698 ETHER_ADDR_LEN) == 0) {
a3dd34d2 2699 ifnet_serialize_all(bifp);
b2417333 2700 bstp_input(sc, bif, m);
a3dd34d2 2701 ifnet_deserialize_all(bifp);
137aa7b3 2702
b2417333
SZ
2703 /* m is freed by bstp_input */
2704 m = NULL;
f2c22bba 2705 goto out;
ac93838f
SS
2706 }
2707
70d9a675
MD
2708 /*
2709 * Other than 802.11d packets, ignore packets if the
2710 * interface is not in a good state.
1e858374
MD
2711 *
2712 * NOTE: Broadcast/mcast packets received on a blocking or
2713 * learning interface are allowed for local processing.
2714 *
2715 * The sending side of a blocked port will stop
2716 * transmitting when a better alternative is found.
2717 * However, later on we will disallow the forwarding
2718 * of bcast/mcsat packets over a blocking interface.
70d9a675 2719 */
ac93838f
SS
2720 if (bif->bif_flags & IFBIF_STP) {
2721 switch (bif->bif_state) {
3677aae9 2722 case BSTP_IFSTATE_L1BLOCKING:
ac93838f
SS
2723 case BSTP_IFSTATE_LISTENING:
2724 case BSTP_IFSTATE_DISABLED:
2725 goto out;
1e858374
MD
2726 default:
2727 /* blocking, learning, bonded, forwarding */
2728 break;
ac93838f
SS
2729 }
2730 }
2731
ac93838f
SS
2732 /*
2733 * Make a deep copy of the packet and enqueue the copy
2734 * for bridge processing; return the original packet for
2735 * local processing.
2736 */
2737 mc = m_dup(m, MB_DONTWAIT);
2738 if (mc == NULL)
2739 goto out;
2740
1e858374
MD
2741 /*
2742 * It's just too dangerous to allow bcast/mcast over a
2743 * blocked interface, eventually the network will sort
2744 * itself out and a better path will be found.
2745 */
2746 if ((bif->bif_flags & IFBIF_STP) == 0 ||
2747 bif->bif_state != BSTP_IFSTATE_BLOCKING) {
2748 bridge_forward(sc, mc);
2749 }
ac93838f
SS
2750
2751 /*
2752 * Reinject the mbuf as arriving on the bridge so we have a
2753 * chance at claiming multicast packets. We can not loop back
2754 * here from ether_input as a bridge is never a member of a
2755 * bridge.
2756 */
2757 KASSERT(bifp->if_bridge == NULL,
3ce67233 2758 ("loop created in bridge_input"));
d217f5e5
SU
2759 mc2 = m_dup(m, MB_DONTWAIT);
2760#ifdef notyet
2761 if (mc2 != NULL) {
2762 /* Keep the layer3 header aligned */
2763 int i = min(mc2->m_pkthdr.len, max_protohdr);
2764 mc2 = m_copyup(mc2, i, ETHER_ALIGN);
2765 }
2766#endif
ac93838f 2767 if (mc2 != NULL) {
137aa7b3 2768 /*
4ee4f753
MD
2769 * Don't tap to bpf(4) again; we have already done
2770 * the tapping.
2771 *
2772 * Leave m_pkthdr.rcvif alone, so ARP replies are
2773 * processed as coming in on the correct interface.
b7441d0c
MD
2774 *
2775 * Clear the bridge flag for local processing in
2776 * case the packet gets routed.
137aa7b3 2777 */
b7441d0c 2778 mc2->m_pkthdr.fw_flags &= ~BRIDGE_MBUF_TAGGED;
70d9a675 2779 ether_reinput_oncpu(bifp, mc2, 0);
ac93838f
SS
2780 }
2781
2782 /* Return the original packet for local processing. */
2783 goto out;
2784 }
2785
70d9a675
MD
2786 /*
2787 * Input of a unicast packet. We have to allow unicast packets
1e858374
MD
2788 * input from links in the BLOCKING state as this might be an
2789 * interface of last resort.
70d9a675
MD
2790 *
2791 * NOTE: We explicitly ignore normal packets received on a link
2792 * in the BLOCKING state. The point of being in that state
2793 * is to avoid getting duplicate packets.
2794 *
2795 * HOWEVER, if LINK2 is set the normal spanning tree code
2796 * will mark an interface BLOCKING to avoid multi-cast/broadcast
2797 * loops. Unicast packets CAN still loop if we allow the
2798 * case (hence we only do it in LINK2), but it isn't quite as
2799 * bad as a broadcast packet looping.
2800 */
1e858374 2801 from_blocking = 0;
ac93838f
SS
2802 if (bif->bif_flags & IFBIF_STP) {
2803 switch (bif->bif_state) {
70d9a675 2804 case BSTP_IFSTATE_L1BLOCKING:
ac93838f
SS
2805 case BSTP_IFSTATE_LISTENING:
2806 case BSTP_IFSTATE_DISABLED:
2807 goto out;
1e858374
MD
2808 case BSTP_IFSTATE_BLOCKING:
2809 from_blocking = 1;
2810 /* fall through */
70d9a675 2811 default:
1e858374 2812 /* blocking, bonded, forwarding, learning */
70d9a675 2813 break;
ac93838f
SS
2814 }
2815 }
2816
2817 /*
2818 * Unicast. Make sure it's not for us.
8f7b13ef
SZ
2819 *
2820 * This loop is MPSAFE; the only blocking operation (bridge_rtupdate)
2821 * is followed by breaking out of the loop.
ac93838f 2822 */
70d9a675 2823 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next) {
ac93838f
SS
2824 if (bif->bif_ifp->if_type != IFT_ETHER)
2825 continue;
3ce67233 2826
4ee4f753 2827 /*
70d9a675
MD
2828 * It is destined for an interface linked to the bridge.
2829 * We want the bridge itself to take care of link level
2830 * forwarding to member interfaces so reinput on the bridge.
2831 * i.e. if you ping an IP on a target interface associated
2832 * with the bridge, the arp is-at response should indicate
2833 * the bridge MAC.
1e858374
MD
2834 *
2835 * Only update our addr list when learning if the port
2836 * is not in a blocking state. If it is we still allow
2837 * the packet but we do not try to learn from it.
4ee4f753 2838 */
ac93838f 2839 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_dhost,
70d9a675 2840 ETHER_ADDR_LEN) == 0) {
ecd27a4c
SZ
2841 if (bif->bif_ifp != ifp) {
2842 /* XXX loop prevention */
0899cb3e 2843 m->m_flags |= M_ETHER_BRIDGED;
ecd27a4c 2844 }
1e858374
MD
2845 if ((bif->bif_flags & IFBIF_LEARNING) &&
2846 bif->bif_state != BSTP_IFSTATE_BLOCKING) {
8f7b13ef
SZ
2847 bridge_rtupdate(sc, eh->ether_shost,
2848 ifp, IFBAF_DYNAMIC);
2849 }
70d9a675 2850 new_ifp = bifp; /* not bif->bif_ifp */
b7441d0c 2851 m->m_pkthdr.fw_flags &= ~BRIDGE_MBUF_TAGGED;
ac93838f
SS
2852 goto out;
2853 }
2854
70d9a675
MD
2855 /*
2856 * Ignore received packets that were sent by us.
2857 */
ac93838f 2858 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_shost,
70d9a675 2859 ETHER_ADDR_LEN) == 0) {
ac93838f
SS
2860 m_freem(m);
2861 m = NULL;
2862 goto out;
2863 }
2864 }
2865
1e858374
MD
2866 /*
2867 * It isn't for us.
2868 *
2869 * Perform the bridge forwarding function, but disallow bridging
2870 * to interfaces in the blocking state if the packet came in on
2871 * an interface in the blocking state.
2872 */
ac93838f
SS
2873 bridge_forward(sc, m);
2874 m = NULL;
4ee4f753
MD
2875
2876 /*
70d9a675
MD
2877 * ether_reinput_oncpu() will reprocess rcvif as
2878 * coming from new_ifp (since we do not specify
2879 * REINPUT_KEEPRCVIF).
4ee4f753 2880 */
ac93838f 2881out:
3ce67233 2882 if (new_ifp != NULL) {
b7441d0c
MD
2883 /*
2884 * Clear the bridge flag for local processing in
2885 * case the packet gets routed.
2886 */
70d9a675 2887 ether_reinput_oncpu(new_ifp, m, REINPUT_RUNBPF);
3ce67233 2888 m = NULL;
3ce67233 2889 }
d217f5e5 2890 return (m);
ac93838f
SS
2891}
2892
2893/*
137aa7b3
SZ
2894 * bridge_start_bcast:
2895 *
2896 * Broadcast the packet sent from bridge to all member
2897 * interfaces.
2898 * This is a simplified version of bridge_broadcast(), however,
2899 * this function expects caller to hold bridge's serializer.
2900 */
2901static void
2902bridge_start_bcast(struct bridge_softc *sc, struct mbuf *m)
2903{
2904 struct bridge_iflist *bif;
2905 struct mbuf *mc;
1e858374 2906 struct ifnet *dst_if, *alt_if, *bifp;
137aa7b3 2907 int used = 0;
1e858374
MD
2908 int found = 0;
2909 int alt_priority;
137aa7b3
SZ
2910
2911 bifp = sc->sc_ifp;
2c9effcf 2912 ASSERT_IFNET_SERIALIZED_ALL(bifp);
137aa7b3
SZ
2913
2914 /*
2915 * Following loop is MPSAFE; nothing is blocking
2916 * in the loop body.
1e858374
MD
2917 *
2918 * NOTE: We transmit through an member in the BLOCKING state only
2919 * as a last resort.
137aa7b3 2920 */
1e858374
MD
2921 alt_if = NULL;
2922 alt_priority = 0;
2923
70d9a675 2924 TAILQ_FOREACH(bif, &sc->sc_iflists[mycpuid], bif_next) {
137aa7b3
SZ
2925 dst_if = bif->bif_ifp;
2926
2927 if (bif->bif_flags & IFBIF_STP) {
2928 switch (bif->bif_state) {
2929 case BSTP_IFSTATE_BLOCKING:
1e858374
MD
2930 if (bif->bif_priority > alt_priority) {
2931 alt_priority = bif->bif_priority;
2932 alt_if = bif->bif_ifp;
2933 }
2934 /* fall through */
2935 case BSTP_IFSTATE_L1BLOCKING:
137aa7b3
SZ
2936 case BSTP_IFSTATE_DISABLED:
2937 continue;
1e858374
MD
2938 default:
2939 /* listening, learning, bonded, forwarding */
2940 break;
137aa7b3
SZ
2941 }
2942 }
2943
2944 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
2945 (m->m_flags & (M_BCAST|M_MCAST)) == 0)
2946 continue;
2947
2948 if ((dst_if->if_flags & IFF_RUNNING) == 0)
2949 continue;
2950
70d9a675 2951 if (TAILQ_NEXT(bif, bif_next) == NULL) {
137aa7b3
SZ
2952 mc = m;
2953 used = 1;
2954 } else {
2955 mc = m_copypacket(m, MB_DONTWAIT);
2956 if (mc == NULL) {
2957 bifp->if_oerrors++;
2958 continue;
2959 }
2960 }
1e858374 2961 found = 1;
137aa7b3
SZ
2962 bridge_enqueue(dst_if, mc);
2963 }
1e858374
MD
2964
2965 if (found == 0 && alt_if) {
2966 KKASSERT(used == 0);
2967 mc = m;
2968 used = 1;
2969 bridge_enqueue(alt_if, mc);
2970 }
2971
137aa7b3
SZ
2972 if (used == 0)
2973 m_freem(m);
2974}
2975
2976/*
ac93838f
SS
2977 * bridge_broadcast:
2978 *
2979 * Send a frame to all interfaces that are members of
2980 * the bridge, except for the one on which the packet
2981 * arrived.
2982 */
d217f5e5 2983static void
ac93838f 2984bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
4ee4f753 2985 struct mbuf *m)
ac93838f 2986{
137aa7b3 2987 struct bridge_iflist *bif, *nbif;
4ee4f753 2988 struct ether_header *eh;
ac93838f 2989 struct mbuf *mc;
1e858374
MD
2990 struct ifnet *dst_if, *alt_if, *bifp;
2991 int used;
2992 int found;
2993 int alt_priority;
4ee4f753 2994 int from_us;
ac93838f 2995
ecd27a4c 2996 bifp = sc->sc_ifp;
2c9effcf 2997 ASSERT_IFNET_NOT_SERIALIZED_ALL(bifp);
ecd27a4c 2998
4ee4f753 2999 eh = mtod(m, struct ether_header *);
70d9a675 3000 from_us = bridge_from_us(sc, eh);
4ee4f753 3001
137aa7b3 3002 if (inet_pfil_hook.ph_hashooks > 0
ac93838f 3003#ifdef INET6
d217f5e5 3004 || inet6_pfil_hook.ph_hashooks > 0
ac93838f 3005#endif
137aa7b3 3006 ) {
ecd27a4c 3007 if (bridge_pfil(&m, bifp, src_if, PFIL_IN) != 0)
137aa7b3 3008 return;
ecd27a4c 3009 if (m == NULL)
137aa7b3 3010 return;
ecd27a4c 3011
137aa7b3 3012 /* Filter on the bridge interface before broadcasting */
ecd27a4c 3013 if (bridge_pfil(&m, bifp, NULL, PFIL_OUT) != 0)
137aa7b3 3014 return;
ac93838f
SS
3015 if (m == NULL)
3016 return;
3017 }
3018
1e858374
MD
3019 alt_if = 0;
3020 alt_priority = 0;
3021 found = 0;
3022 used = 0;
3023
70d9a675 3024 TAILQ_FOREACH_MUTABLE(bif, &sc->sc_iflists[mycpuid], bif_next, nbif) {
ac93838f
SS
3025 dst_if = bif->bif_ifp;
3026 if (dst_if == src_if)
3027 continue;
3028
1e858374
MD
3029 if ((dst_if->if_flags & IFF_RUNNING) == 0)
3030 continue;
3031
3032 /*
3033 * Generally speaking we only broadcast through forwarding
3034 * interfaces. If no interfaces are available we select
3035 * a BONDED, BLOCKING, or LEARNING interface to forward
3036 * through.
3037 */
ac93838f
SS
3038 if (bif->bif_flags & IFBIF_STP) {
3039 switch (bif->bif_state) {
1e858374
MD
3040 case BSTP_IFSTATE_BONDED:
3041 if (bif->bif_priority + 512 > alt_priority) {
3042 alt_priority = bif->bif_priority + 512;
3043 alt_if = bif->bif_ifp;
3044 }
3045 continue;
ac93838f 3046 case BSTP_IFSTATE_BLOCKING:
1e858374
MD
3047 if (bif->bif_priority + 256 > alt_priority) {
3048 alt_priority = bif->bif_priority + 256;
3049 alt_if = bif->bif_ifp;
3050 }
3051 continue;
3052 case BSTP_IFSTATE_LEARNING:
3053 if (bif->bif_priority > alt_priority) {
3054 alt_priority = bif->bif_priority;
3055 alt_if = bif->bif_ifp;
3056 }
3057 continue;
3058 case BSTP_IFSTATE_L1BLOCKING:
ac93838f 3059 case BSTP_IFSTATE_DISABLED:
1e858374 3060 case BSTP_IFSTATE_LISTENING:
ac93838f 3061 continue;
1e858374
MD
3062 default:
3063 /* forwarding */
3064 break;
ac93838f
SS
3065 }
3066 }
3067
3068 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
1e858374 3069 (m->m_flags & (M_BCAST|M_MCAST)) == 0) {
ac93838f 3070 continue;
1e858374 3071 }
ac93838f 3072
70d9a675 3073 if (TAILQ_NEXT(bif, bif_next) == NULL) {
ac93838f
SS
3074 mc = m;
3075 used = 1;
3076 } else {
3077 mc = m_copypacket(m, MB_DONTWAIT);
3078 if (mc == NULL) {
3079 sc->sc_ifp->if_oerrors++;
3080 continue;
3081 }
3082 }
1e858374 3083 found = 1;
137aa7b3
SZ
3084
3085 /*
3086 * Filter on the output interface. Pass a NULL bridge
3087 * interface pointer so we do not redundantly filter on
3088 * the bridge for each interface we broadcast on.
3089 */
3090 if (inet_pfil_hook.ph_hashooks > 0
3091#ifdef INET6
3092 || inet6_pfil_hook.ph_hashooks > 0
3093#endif
3094 ) {
3095 if (bridge_pfil(&mc, NULL, dst_if, PFIL_OUT) != 0)
3096 continue;
3097 if (mc == NULL)
3098 continue;
3099 }
70d9a675 3100 bridge_handoff(sc, dst_if, mc, from_us);
137aa7b3
SZ
3101
3102 if (nbif != NULL && !nbif->bif_onlist) {
3103 KKASSERT(bif->bif_onlist);
70d9a675 3104 nbif = TAILQ_NEXT(bif, bif_next);
137aa7b3 3105 }
ac93838f 3106 }
1e858374
MD
3107
3108 if (found == 0 && alt_if) {
3109 KKASSERT(used == 0);
3110 mc = m;
3111 used = 1;
3112 bridge_enqueue(alt_if, mc);
3113 }
3114
ac93838f
SS
3115 if (used == 0)
3116 m_freem(m);
3117}
3118
3119/*
d217f5e5
SU
3120 * bridge_span:
3121 *
3122 * Duplicate a packet out one or more interfaces that are in span mode,
3123 * the original mbuf is unmodified.
3124 */
3125static void
3126bridge_span(struct bridge_softc *sc, struct mbuf *m)
3127{
3128 struct bridge_iflist *bif;
137aa7b3 3129 struct ifnet *dst_if, *bifp;
d217f5e5
SU
3130 struct mbuf *mc;
3131
137aa7b3 3132 bifp = sc->sc_ifp;
a3dd34d2 3133 ifnet_serialize_all(bifp);
137aa7b3 3134
70d9a675 3135 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) {
d217f5e5
SU
3136 dst_if = bif->bif_ifp;
3137
3138 if ((dst_if->if_flags & IFF_RUNNING) == 0)
3139 continue;
3140
3141 mc = m_copypacket(m, MB_DONTWAIT);
3142 if (mc == NULL) {
3143 sc->sc_ifp->if_oerrors++;
3144 continue;
3145 }
708a3bfa 3146 bridge_enqueue(dst_if, mc);
d217f5e5 3147 }
137aa7b3 3148
a3dd34d2 3149 ifnet_deserialize_all(bifp);
d217f5e5
SU
3150}
3151
4394693c 3152static void
002c1265 3153bridge_rtmsg_sync_handler(netmsg_t msg)
4394693c 3154{
002c1265 3155 ifnet_forwardmsg(&msg->lmsg, mycpuid + 1);
4394693c
SZ
3156}
3157
3158static void
3159bridge_rtmsg_sync(struct bridge_softc *sc)
3160{
002c1265 3161 struct netmsg_base msg;
4394693c 3162
2c9effcf 3163 ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
4394693c 3164
002c1265 3165 netmsg_init(&msg, NULL, &curthread->td_msgport,
48e7b118 3166 0, bridge_rtmsg_sync_handler);
002c1265 3167 ifnet_domsg(&msg.lmsg, 0);
4394693c
SZ
3168}
3169
3170static __inline void
3171bridge_rtinfo_update(struct bridge_rtinfo *bri, struct ifnet *dst_if,
3172 int setflags, uint8_t flags, uint32_t timeo)
3173{
3174 if ((bri->bri_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
3175 bri->bri_ifp != dst_if)
3176 bri->bri_ifp = dst_if;
3177 if ((flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
3178 bri->bri_expire != time_second + timeo)
3179 bri->bri_expire = time_second + timeo;
3180 if (setflags)
3181 bri->bri_flags = flags;
3182}
3183
3184static int
3185bridge_rtinstall_oncpu(struct bridge_softc *sc, const uint8_t *dst,
3186 struct ifnet *dst_if, int setflags, uint8_t flags,
3187 struct bridge_rtinfo **bri0)
3188{
3189 struct bridge_rtnode *brt;
3190 struct bridge_rtinfo *bri;
3191
3192 if (mycpuid == 0) {
3193 brt = bridge_rtnode_lookup(sc, dst);
3194 if (brt != NULL) {
3195 /*
3196 * rtnode for 'dst' already exists. We inform the
3197 * caller about this by leaving bri0 as NULL. The
3198 * caller will terminate the intallation upon getting
3199 * NULL bri0. However, we still need to update the
3200 * rtinfo.
3201 */
3202 KKASSERT(*bri0 == NULL);
3203
3204 /* Update rtinfo */
3205 bridge_rtinfo_update(brt->brt_info, dst_if, setflags,
3206 flags, sc->sc_brttimeout);
3207 return 0;
3208 }
3209
3210 /*
3211 * We only need to check brtcnt on CPU0, since if limit
3212 * is to be exceeded, ENOSPC is returned. Caller knows
3213 * this and will terminate the installation.
3214 */
3215 if (sc->sc_brtcnt >= sc->sc_brtmax)
3216 return ENOSPC;
3217
3218 KKASSERT(*bri0 == NULL);
3219 bri = kmalloc(sizeof(struct bridge_rtinfo), M_DEVBUF,
3220 M_WAITOK | M_ZERO);
3221 *bri0 = bri;
3222
3223 /* Setup rtinfo */
3224 bri->bri_flags = IFBAF_DYNAMIC;
3225 bridge_rtinfo_update(bri, dst_if, setflags, flags,
3226 sc->sc_brttimeout);
3227 } else {
3228 bri = *bri0;
3229 KKASSERT(bri != NULL);
3230 }
3231
3232 brt = kmalloc(sizeof(struct bridge_rtnode), M_DEVBUF,
3233 M_WAITOK | M_ZERO);
3234 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
3235 brt->brt_info = bri;
3236
3237 bridge_rtnode_insert(sc, brt);
3238 return 0;
3239}
3240
3241static void
002c1265 3242bridge_rtinstall_handler(netmsg_t msg)
4394693c 3243{
002c1265 3244 struct netmsg_brsaddr *brmsg = (struct netmsg_brsaddr *)msg;
4394693c
SZ
3245 int error;
3246
3247 error = bridge_rtinstall_oncpu(brmsg->br_softc,
3248 brmsg->br_dst, brmsg->br_dst_if,
3249 brmsg->br_setflags, brmsg->br_flags,
3250 &brmsg->br_rtinfo);
3251 if (error) {
3252 KKASSERT(mycpuid == 0 && brmsg->br_rtinfo == NULL);
002c1265 3253 lwkt_replymsg(&brmsg->base.lmsg, error);
4394693c
SZ
3254 return;
3255 } else if (brmsg->br_rtinfo == NULL) {
3256 /* rtnode already exists for 'dst' */
3257 KKASSERT(mycpuid == 0);
002c1265 3258 lwkt_replymsg(&brmsg->base.lmsg, 0);
4394693c
SZ
3259 return;
3260 }
002c1265 3261 ifnet_forwardmsg(&brmsg->base.lmsg, mycpuid + 1);
4394693c
SZ
3262}
3263
d217f5e5 3264/*
ac93838f
SS
3265 * bridge_rtupdate:
3266 *
4394693c 3267 * Add/Update a bridge routing entry.
ac93838f 3268 */
d217f5e5 3269static int
ac93838f 3270bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
4394693c 3271 struct ifnet *dst_if, uint8_t flags)
ac93838f
SS
3272{
3273 struct bridge_rtnode *brt;
ac93838f
SS
3274
3275 /*
3276 * A route for this destination might already exist. If so,
3277 * update it, otherwise create a new one.
3278 */
3279 if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
4394693c 3280 struct netmsg_brsaddr *brmsg;
ac93838f 3281
4394693c
SZ
3282 if (sc->sc_brtcnt >= sc->sc_brtmax)
3283 return ENOSPC;
3284
3285 brmsg = kmalloc(sizeof(*brmsg), M_LWKTMSG, M_WAITOK | M_NULLOK);
3286 if (brmsg == NULL)
3287 return ENOMEM;
3288
002c1265 3289 netmsg_init(&brmsg->base, NULL, &netisr_afree_rport,
48e7b118 3290 0, bridge_rtinstall_handler);
4394693c
SZ
3291 memcpy(brmsg->br_dst, dst, ETHER_ADDR_LEN);
3292 brmsg->br_dst_if = dst_if;
3293 brmsg->br_flags = flags;
3294 brmsg->br_setflags = 0;
3295 brmsg->br_softc = sc;
3296 brmsg->br_rtinfo = NULL;
3297
002c1265 3298 ifnet_sendmsg(&brmsg->base.lmsg, 0);
4394693c
SZ
3299 return 0;
3300 }
3301 bridge_rtinfo_update(brt->brt_info, dst_if, 0, flags,
3302 sc->sc_brttimeout);
3303 return 0;
3304}
ac93838f 3305
4394693c
SZ
3306static int
3307bridge_rtsaddr(struct bridge_softc *sc, const uint8_t *dst,
3308 struct ifnet *dst_if, uint8_t flags)
3309{
3310 struct netmsg_brsaddr brmsg;
ac93838f 3311
2c9effcf 3312 ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
ac93838f 3313
002c1265 3314 netmsg_init(&brmsg.base, NULL, &curthread->td_msgport,
48e7b118 3315 0, bridge_rtinstall_handler);
4394693c
SZ
3316 memcpy(brmsg.br_dst, dst, ETHER_ADDR_LEN);
3317 brmsg.br_dst_if = dst_if;
3318 brmsg.br_flags = flags;
3319 brmsg.br_setflags = 1;
3320 brmsg.br_softc = sc;
3321 brmsg.br_rtinfo = NULL;
ac93838f 3322
002c1265 3323 return ifnet_domsg(&brmsg.base.lmsg, 0);
ac93838f
SS
3324}
3325
3326/*
3327 * bridge_rtlookup:
3328 *
3329 * Lookup the destination interface for an address.
3330 */
d217f5e5 3331static struct ifnet *
ac93838f
SS
3332bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
3333{
3334 struct bridge_rtnode *brt;
3335
3336 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
4394693c
SZ
3337 return NULL;
3338 return brt->brt_info->bri_ifp;
3339}
ac93838f 3340
4394693c 3341static void
002c1265 3342bridge_rtreap_handler(netmsg_t msg)
4394693c 3343{
002c1265 3344 struct bridge_softc *sc = msg->lmsg.u.ms_resultp;
4394693c
SZ
3345 struct bridge_rtnode *brt, *nbrt;
3346
3347 LIST_FOREACH_MUTABLE(brt, &sc->sc_rtlists[mycpuid], brt_list, nbrt) {
3348 if (brt->brt_info->bri_dead)
3349 bridge_rtnode_destroy(sc, brt);
3350 }
002c1265 3351 ifnet_forwardmsg(&msg->lmsg, mycpuid + 1);
4394693c
SZ
3352}
3353
3354static void
3355bridge_rtreap(struct bridge_softc *sc)
3356{
002c1265 3357 struct netmsg_base msg;
4394693c 3358
2c9effcf 3359 ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
4394693c 3360
002c1265 3361 netmsg_init(&msg, NULL, &curthread->td_msgport,
48e7b118 3362 0, bridge_rtreap_handler);
002c1265 3363 msg.lmsg.u.ms_resultp = sc;
4394693c 3364
002c1265 3365 ifnet_domsg(&msg.lmsg, 0);
ac93838f
SS
3366}
3367
30ced003
SZ
3368static void
3369bridge_rtreap_async(struct bridge_softc *sc)
3370{
002c1265 3371 struct netmsg_base *msg;
30ced003 3372
002c1265 3373 msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_WAITOK);
30ced003 3374
002c1265 3375 netmsg_init(msg, NULL, &netisr_afree_rport,
48e7b118 3376 0, bridge_rtreap_handler);
002c1265 3377 msg->lmsg.u.ms_resultp = sc;
30ced003 3378
002c1265 3379 ifnet_sendmsg(&msg->lmsg, 0);
30ced003
SZ
3380}
3381
ac93838f
SS
3382/*
3383 * bridge_rttrim:
3384 *
3385 * Trim the routine table so that we have a number
3386 * of routing entries less than or equal to the
3387 * maximum number.
3388 */
d217f5e5 3389static void
ac93838f
SS
3390bridge_rttrim(struct bridge_softc *sc)
3391{
4394693c
SZ
3392 struct bridge_rtnode *brt;
3393 int dead;
3394
2c9effcf 3395 ASSERT_IFNET_NOT_SERIALIZED_ALL(sc->sc_ifp);
ac93838f
SS
3396
3397 /* Make sure we actually need to do this. */
3398 if (sc->sc_brtcnt <= sc->sc_brtmax)
3399 return;
3400
4394693c
SZ
3401 /*
3402 * Find out how many rtnodes are dead
3403 */
3404 dead = bridge_rtage_finddead(sc);
3405 KKASSERT(dead <= sc->sc_brtcnt);
3406
3407 if (sc->sc_brtcnt - dead <= sc->sc_brtmax) {
3408 /* Enough dead rtnodes are found */
3409 bridge_rtreap(sc);
ac93838f 3410 return;
4394693c 3411 }
ac93838f 3412
4394693c
SZ
3413 /*
3414 * Kill some dynamic rtnodes to meet the brtmax
3415 */
3416 LIST_FOREACH(brt, &sc->sc_rtlists[mycpuid], brt_list) {
3417 struct bridge_rtinfo *bri = brt->brt_info;
3418
3419 if (bri->bri_dead) {
3420 /*
3421 * We have counted this rtnode in
3422 * bridge_rtage_finddead()
3423 */
3424 continue;
3425 }
3426
3427 if ((bri->bri_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
3428 bri->bri_dead = 1;
3429 ++dead;
3430 KKASSERT(dead <= sc->sc_brtcnt);
3431
3432 if (sc->sc_brtcnt - dead <= sc->sc_brtmax) {
3433 /* Enough rtnodes are collected */
3434 break;
3435 }
ac93838f
SS
3436 }
3437 }
4394693c
SZ
3438 if (dead)
3439 bridge_rtreap(sc);
ac93838f
SS
3440}
3441