1 /*	$OpenBSD: if_bridge.c,v 1.134 2004/05/04 18:03:58 canacar Exp $	*/
2 
3 /*
4  * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Effort sponsored in part by the Defense Advanced Research Projects
29  * Agency (DARPA) and Air Force Research Laboratory, Air Force
30  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
31  *
32  */
33 
34 #include "bpfilter.h"
35 #include "gif.h"
36 #include "pf.h"
37 #include "vlan.h"
38 
39 #include <sys/param.h>
40 #include <sys/proc.h>
41 #include <sys/systm.h>
42 #include <sys/mbuf.h>
43 #include <sys/socket.h>
44 #include <sys/ioctl.h>
45 #include <sys/errno.h>
46 #include <sys/kernel.h>
47 #include <machine/cpu.h>
48 #include <dev/rndvar.h>
49 
50 #include <net/if.h>
51 #include <net/if_types.h>
52 #include <net/if_llc.h>
53 #include <net/route.h>
54 #include <net/netisr.h>
55 
56 #ifdef INET
57 #include <netinet/in.h>
58 #include <netinet/in_systm.h>
59 #include <netinet/in_var.h>
60 #include <netinet/ip.h>
61 #include <netinet/ip_var.h>
62 #include <netinet/if_ether.h>
63 #include <netinet/ip_icmp.h>
64 #endif
65 
66 #ifdef IPSEC
67 #include <netinet/ip_ipsp.h>
68 
69 #include <net/if_enc.h>
70 #endif
71 
72 #ifdef INET6
73 #include <netinet/ip6.h>
74 #include <netinet6/ip6_var.h>
75 #endif
76 
77 #if NPF > 0
78 #include <net/pfvar.h>
79 #define	BRIDGE_IN	PF_IN
80 #define	BRIDGE_OUT	PF_OUT
81 #else
82 #define	BRIDGE_IN	0
83 #define	BRIDGE_OUT	1
84 #endif
85 
86 #if NBPFILTER > 0
87 #include <net/bpf.h>
88 #endif
89 
90 #if NVLAN > 0
91 #include <net/if_vlan_var.h>
92 #endif
93 
94 #include <net/if_bridge.h>
95 
96 #ifndef	BRIDGE_RTABLE_SIZE
97 #define	BRIDGE_RTABLE_SIZE	1024
98 #endif
99 #define	BRIDGE_RTABLE_MASK	(BRIDGE_RTABLE_SIZE - 1)
100 
101 /*
102  * Maximum number of addresses to cache
103  */
104 #ifndef	BRIDGE_RTABLE_MAX
105 #define	BRIDGE_RTABLE_MAX	100
106 #endif
107 
108 /* spanning tree defaults */
109 #define	BSTP_DEFAULT_MAX_AGE		(20 * 256)
110 #define	BSTP_DEFAULT_HELLO_TIME		(2 * 256)
111 #define	BSTP_DEFAULT_FORWARD_DELAY	(15 * 256)
112 #define	BSTP_DEFAULT_HOLD_TIME		(1 * 256)
113 #define	BSTP_DEFAULT_BRIDGE_PRIORITY	0x8000
114 #define	BSTP_DEFAULT_PORT_PRIORITY	0x80
115 #define	BSTP_DEFAULT_PATH_COST		55
116 
117 /*
118  * Timeout (in seconds) for entries learned dynamically
119  */
120 #ifndef	BRIDGE_RTABLE_TIMEOUT
121 #define	BRIDGE_RTABLE_TIMEOUT	240
122 #endif
123 
124 extern int ifqmaxlen;
125 
126 void	bridgeattach(int);
127 int	bridge_ioctl(struct ifnet *, u_long, caddr_t);
128 void	bridge_start(struct ifnet *);
129 void	bridgeintr_frame(struct bridge_softc *, struct mbuf *);
130 void	bridge_broadcast(struct bridge_softc *, struct ifnet *,
131     struct ether_header *, struct mbuf *);
132 void	bridge_span(struct bridge_softc *, struct ether_header *,
133     struct mbuf *);
134 void	bridge_stop(struct bridge_softc *);
135 void	bridge_init(struct bridge_softc *);
136 int	bridge_bifconf(struct bridge_softc *, struct ifbifconf *);
137 
138 void	bridge_timer(void *);
139 int	bridge_rtfind(struct bridge_softc *, struct ifbaconf *);
140 void	bridge_rtage(struct bridge_softc *);
141 void	bridge_rttrim(struct bridge_softc *);
142 int	bridge_rtdaddr(struct bridge_softc *, struct ether_addr *);
143 int	bridge_rtflush(struct bridge_softc *, int);
144 struct ifnet *	bridge_rtupdate(struct bridge_softc *,
145     struct ether_addr *, struct ifnet *ifp, int, u_int8_t);
146 struct ifnet *	bridge_rtlookup(struct bridge_softc *,
147     struct ether_addr *);
148 u_int32_t	bridge_hash(struct bridge_softc *, struct ether_addr *);
149 int bridge_blocknonip(struct ether_header *, struct mbuf *);
150 int		bridge_addrule(struct bridge_iflist *,
151     struct ifbrlreq *, int out);
152 int		bridge_flushrule(struct bridge_iflist *);
153 int	bridge_brlconf(struct bridge_softc *, struct ifbrlconf *);
154 u_int8_t bridge_filterrule(struct brl_head *, struct ether_header *,
155     struct mbuf *);
156 #if NPF > 0
157 struct mbuf *bridge_filter(struct bridge_softc *, int, struct ifnet *,
158     struct ether_header *, struct mbuf *m);
159 #endif
160 int	bridge_ifenqueue(struct bridge_softc *, struct ifnet *, struct mbuf *);
161 void	bridge_fragment(struct bridge_softc *, struct ifnet *,
162     struct ether_header *, struct mbuf *);
163 #ifdef INET
164 void	bridge_send_icmp_err(struct bridge_softc *, struct ifnet *,
165     struct ether_header *, struct mbuf *, int, struct llc *, int, int);
166 #endif
167 #ifdef IPSEC
168 int bridge_ipsec(int, int, int, struct mbuf *);
169 #endif
170 int     bridge_clone_create(struct if_clone *, int);
171 int	bridge_clone_destroy(struct ifnet *ifp);
172 
173 #define	ETHERADDR_IS_IP_MCAST(a) \
174 	/* struct etheraddr *a;	*/				\
175 	((a)->ether_addr_octet[0] == 0x01 &&			\
176 	 (a)->ether_addr_octet[1] == 0x00 &&			\
177 	 (a)->ether_addr_octet[2] == 0x5e)
178 
179 LIST_HEAD(, bridge_softc) bridge_list;
180 
181 struct if_clone bridge_cloner =
182     IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
183 
184 /* ARGSUSED */
185 void
bridgeattach(int n)186 bridgeattach(int n)
187 {
188 	LIST_INIT(&bridge_list);
189 	if_clone_attach(&bridge_cloner);
190 }
191 
192 int
bridge_clone_create(struct if_clone * ifc,int unit)193 bridge_clone_create(struct if_clone *ifc, int unit)
194 {
195 	struct bridge_softc *sc;
196 	struct ifnet *ifp;
197 	int s;
198 
199 	sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
200 	if (!sc)
201 		return (ENOMEM);
202 	bzero(sc, sizeof(*sc));
203 
204 	sc->sc_brtmax = BRIDGE_RTABLE_MAX;
205 	sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
206 	sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
207 	sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
208 	sc->sc_bridge_forward_delay= BSTP_DEFAULT_FORWARD_DELAY;
209 	sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
210 	sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
211 	timeout_set(&sc->sc_brtimeout, bridge_timer, sc);
212 	LIST_INIT(&sc->sc_iflist);
213 	LIST_INIT(&sc->sc_spanlist);
214 	ifp = &sc->sc_if;
215 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
216 	    unit);
217 	ifp->if_softc = sc;
218 	ifp->if_mtu = ETHERMTU;
219 	ifp->if_ioctl = bridge_ioctl;
220 	ifp->if_output = bridge_output;
221 	ifp->if_start = bridge_start;
222 	ifp->if_type = IFT_BRIDGE;
223 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
224 	ifp->if_hdrlen = sizeof(struct ether_header);
225 	if_attach(ifp);
226 	if_alloc_sadl(ifp);
227 #if NBPFILTER > 0
228 	bpfattach(&sc->sc_if.if_bpf, ifp,
229 	    DLT_EN10MB, sizeof(struct ether_header));
230 #endif
231 	s = splnet();
232 	LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
233 	splx(s);
234 
235 	return (0);
236 }
237 
238 int
bridge_clone_destroy(struct ifnet * ifp)239 bridge_clone_destroy(struct ifnet *ifp)
240 {
241 	struct bridge_softc *sc = ifp->if_softc;
242 	struct bridge_iflist *bif;
243 	int s;
244 
245 	bridge_stop(sc);
246 	while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) {
247 		/* XXX shared with ioctl and detach */
248 		/* XXX promisc disable? */
249 		LIST_REMOVE(bif, next);
250 		bridge_rtdelete(sc, bif->ifp, 0);
251 		bridge_flushrule(bif);
252 		bif->ifp->if_bridge = NULL;
253 		free(bif, M_DEVBUF);
254 	}
255 	while ((bif = LIST_FIRST(&sc->sc_spanlist)) != NULL) {
256 		LIST_REMOVE(bif, next);
257 		free(bif, M_DEVBUF);
258 	}
259 
260 	s = splnet();
261 	LIST_REMOVE(sc, sc_list);
262 	splx(s);
263 
264 #if NBPFILTER > 0
265 	bpfdetach(ifp);
266 #endif
267 	if_detach(ifp);
268 
269 	free(sc, M_DEVBUF);
270 	return (0);
271 }
272 
273 int
bridge_ioctl(struct ifnet * ifp,u_long cmd,caddr_t data)274 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
275 {
276 	struct proc *prc = curproc;		/* XXX */
277 	struct ifnet *ifs;
278 	struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc;
279 	struct ifbreq *req = (struct ifbreq *)data;
280 	struct ifbaconf *baconf = (struct ifbaconf *)data;
281 	struct ifbareq *bareq = (struct ifbareq *)data;
282 	struct ifbrparam *bparam = (struct ifbrparam *)data;
283 	struct ifbifconf *bifconf = (struct ifbifconf *)data;
284 	struct ifbrlreq *brlreq = (struct ifbrlreq *)data;
285 	struct ifbrlconf *brlconf = (struct ifbrlconf *)data;
286 	struct ifreq ifreq;
287 	int error = 0, s;
288 	struct bridge_iflist *p;
289 
290 	s = splnet();
291 	switch (cmd) {
292 	case SIOCBRDGADD:
293 		if ((error = suser(prc, 0)) != 0)
294 			break;
295 
296 		ifs = ifunit(req->ifbr_ifsname);
297 		if (ifs == NULL) {			/* no such interface */
298 			error = ENOENT;
299 			break;
300 		}
301 		if (ifs->if_bridge == (caddr_t)sc) {
302 			error = EEXIST;
303 			break;
304 		}
305 		if (ifs->if_bridge != NULL) {
306 			error = EBUSY;
307 			break;
308 		}
309 
310 		/* If it's in the span list, it can't be a member. */
311 		LIST_FOREACH(p, &sc->sc_spanlist, next)
312 			if (p->ifp == ifs)
313 				break;
314 
315 		if (p != LIST_END(&sc->sc_spanlist)) {
316 			error = EBUSY;
317 			break;
318 		}
319 
320 		if (ifs->if_type == IFT_ETHER) {
321 			if ((ifs->if_flags & IFF_UP) == 0) {
322 				/*
323 				 * Bring interface up long enough to set
324 				 * promiscuous flag, then shut it down again.
325 				 */
326 				strlcpy(ifreq.ifr_name, req->ifbr_ifsname,
327 				    IFNAMSIZ);
328 				ifs->if_flags |= IFF_UP;
329 				ifreq.ifr_flags = ifs->if_flags;
330 				error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS,
331 				    (caddr_t)&ifreq);
332 				if (error != 0)
333 					break;
334 
335 				error = ifpromisc(ifs, 1);
336 				if (error != 0)
337 					break;
338 
339 				strlcpy(ifreq.ifr_name, req->ifbr_ifsname,
340 				    IFNAMSIZ);
341 				ifs->if_flags &= ~IFF_UP;
342 				ifreq.ifr_flags = ifs->if_flags;
343 				error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS,
344 				    (caddr_t)&ifreq);
345 				if (error != 0) {
346 					ifpromisc(ifs, 0);
347 					break;
348 				}
349 			} else {
350 				error = ifpromisc(ifs, 1);
351 				if (error != 0)
352 					break;
353 			}
354 		}
355 #if NGIF > 0
356 		else if (ifs->if_type == IFT_GIF) {
357 			/* Nothing needed */
358 		}
359 #endif /* NGIF */
360 		else {
361 			error = EINVAL;
362 			break;
363 		}
364 
365 		p = (struct bridge_iflist *) malloc(
366 		    sizeof(struct bridge_iflist), M_DEVBUF, M_NOWAIT);
367 		if (p == NULL) {
368 			if (ifs->if_type == IFT_ETHER)
369 				ifpromisc(ifs, 0);
370 			error = ENOMEM;
371 			break;
372 		}
373 		bzero(p, sizeof(struct bridge_iflist));
374 
375 		p->ifp = ifs;
376 		p->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
377 		p->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
378 		p->bif_path_cost = BSTP_DEFAULT_PATH_COST;
379 		SIMPLEQ_INIT(&p->bif_brlin);
380 		SIMPLEQ_INIT(&p->bif_brlout);
381 		LIST_INSERT_HEAD(&sc->sc_iflist, p, next);
382 		ifs->if_bridge = (caddr_t)sc;
383 		break;
384 	case SIOCBRDGDEL:
385 		if ((error = suser(prc, 0)) != 0)
386 			break;
387 
388 		LIST_FOREACH(p, &sc->sc_iflist, next) {
389 			if (strncmp(p->ifp->if_xname, req->ifbr_ifsname,
390 			    sizeof(p->ifp->if_xname)) == 0) {
391 				p->ifp->if_bridge = NULL;
392 
393 				error = ifpromisc(p->ifp, 0);
394 
395 				LIST_REMOVE(p, next);
396 				bridge_rtdelete(sc, p->ifp, 0);
397 				bridge_flushrule(p);
398 				free(p, M_DEVBUF);
399 				break;
400 			}
401 		}
402 		if (p == LIST_END(&sc->sc_iflist)) {
403 			error = ENOENT;
404 			break;
405 		}
406 		break;
407 	case SIOCBRDGIFS:
408 		error = bridge_bifconf(sc, bifconf);
409 		break;
410 	case SIOCBRDGADDS:
411 		if ((error = suser(prc, 0)) != 0)
412 			break;
413 		ifs = ifunit(req->ifbr_ifsname);
414 		if (ifs == NULL) {			/* no such interface */
415 			error = ENOENT;
416 			break;
417 		}
418 		if (ifs->if_bridge == (caddr_t)sc) {
419 			error = EEXIST;
420 			break;
421 		}
422 		if (ifs->if_bridge != NULL) {
423 			error = EBUSY;
424 			break;
425 		}
426 		LIST_FOREACH(p, &sc->sc_spanlist, next) {
427 			if (p->ifp == ifs)
428 				break;
429 		}
430 		if (p != LIST_END(&sc->sc_spanlist)) {
431 			error = EBUSY;
432 			break;
433 		}
434 		p = (struct bridge_iflist *)malloc(
435 		    sizeof(struct bridge_iflist), M_DEVBUF, M_NOWAIT);
436 		if (p == NULL) {
437 			error = ENOMEM;
438 			break;
439 		}
440 		bzero(p, sizeof(struct bridge_iflist));
441 		p->ifp = ifs;
442 		SIMPLEQ_INIT(&p->bif_brlin);
443 		SIMPLEQ_INIT(&p->bif_brlout);
444 		LIST_INSERT_HEAD(&sc->sc_spanlist, p, next);
445 		break;
446 	case SIOCBRDGDELS:
447 		if ((error = suser(prc, 0)) != 0)
448 			break;
449 		LIST_FOREACH(p, &sc->sc_spanlist, next) {
450 			if (strncmp(p->ifp->if_xname, req->ifbr_ifsname,
451 			    sizeof(p->ifp->if_xname)) == 0) {
452 				LIST_REMOVE(p, next);
453 				free(p, M_DEVBUF);
454 				break;
455 			}
456 		}
457 		if (p == LIST_END(&sc->sc_spanlist)) {
458 			error = ENOENT;
459 			break;
460 		}
461 		break;
462 	case SIOCBRDGGIFFLGS:
463 		ifs = ifunit(req->ifbr_ifsname);
464 		if (ifs == NULL) {
465 			error = ENOENT;
466 			break;
467 		}
468 		if ((caddr_t)sc != ifs->if_bridge) {
469 			error = ESRCH;
470 			break;
471 		}
472 		LIST_FOREACH(p, &sc->sc_iflist, next) {
473 			if (p->ifp == ifs)
474 				break;
475 		}
476 		if (p == LIST_END(&sc->sc_iflist)) {
477 			error = ESRCH;
478 			break;
479 		}
480 		req->ifbr_ifsflags = p->bif_flags;
481 		req->ifbr_state = p->bif_state;
482 		req->ifbr_priority = p->bif_priority;
483 		req->ifbr_path_cost = p->bif_path_cost;
484 		req->ifbr_portno = p->ifp->if_index & 0xff;
485 		break;
486 	case SIOCBRDGSIFFLGS:
487 		if ((error = suser(prc, 0)) != 0)
488 			break;
489 		ifs = ifunit(req->ifbr_ifsname);
490 		if (ifs == NULL) {
491 			error = ENOENT;
492 			break;
493 		}
494 		if ((caddr_t)sc != ifs->if_bridge) {
495 			error = ESRCH;
496 			break;
497 		}
498 		LIST_FOREACH(p, &sc->sc_iflist, next) {
499 			if (p->ifp == ifs)
500 				break;
501 		}
502 		if (p == LIST_END(&sc->sc_iflist)) {
503 			error = ESRCH;
504 			break;
505 		}
506 		if (req->ifbr_ifsflags & IFBIF_RO_MASK) {
507 			error = EINVAL;
508 			break;
509 		}
510 		if ((req->ifbr_ifsflags & IFBIF_STP) &&
511 		    (ifs->if_type != IFT_ETHER)) {
512 			error = EINVAL;
513 			break;
514 		}
515 		p->bif_flags = req->ifbr_ifsflags;
516 		break;
517 	case SIOCBRDGSIFPRIO:
518 	case SIOCBRDGSIFCOST:
519 		if ((error = suser(prc, 0)) != 0)
520 			break;
521 		ifs = ifunit(req->ifbr_ifsname);
522 		if (ifs == NULL) {
523 			error = ENOENT;
524 			break;
525 		}
526 		if ((caddr_t)sc != ifs->if_bridge) {
527 			error = ESRCH;
528 			break;
529 		}
530 		LIST_FOREACH(p, &sc->sc_iflist, next) {
531 			if (p->ifp == ifs)
532 				break;
533 		}
534 		if (p == LIST_END(&sc->sc_iflist)) {
535 			error = ESRCH;
536 			break;
537 		}
538 		if (cmd == SIOCBRDGSIFPRIO)
539 			p->bif_priority = req->ifbr_priority;
540 		else {
541 			if (req->ifbr_path_cost < 1)
542 				error = EINVAL;
543 			else
544 				p->bif_path_cost = req->ifbr_path_cost;
545 		}
546 		break;
547 	case SIOCBRDGRTS:
548 		error = bridge_rtfind(sc, baconf);
549 		break;
550 	case SIOCBRDGFLUSH:
551 		if ((error = suser(prc, 0)) != 0)
552 			break;
553 
554 		error = bridge_rtflush(sc, req->ifbr_ifsflags);
555 		break;
556 	case SIOCBRDGSADDR:
557 		if ((error = suser(prc, 0)) != 0)
558 			break;
559 
560 		ifs = ifunit(bareq->ifba_ifsname);
561 		if (ifs == NULL) {			/* no such interface */
562 			error = ENOENT;
563 			break;
564 		}
565 
566 		if (ifs->if_bridge == NULL ||
567 		    ifs->if_bridge != (caddr_t)sc) {
568 			error = ESRCH;
569 			break;
570 		}
571 
572 		ifs = bridge_rtupdate(sc, &bareq->ifba_dst, ifs, 1,
573 		    bareq->ifba_flags);
574 		if (ifs == NULL)
575 			error = ENOMEM;
576 		break;
577 	case SIOCBRDGDADDR:
578 		if ((error = suser(prc, 0)) != 0)
579 			break;
580 		error = bridge_rtdaddr(sc, &bareq->ifba_dst);
581 		break;
582 	case SIOCBRDGGCACHE:
583 		bparam->ifbrp_csize = sc->sc_brtmax;
584 		break;
585 	case SIOCBRDGSCACHE:
586 		if ((error = suser(prc, 0)) != 0)
587 			break;
588 		sc->sc_brtmax = bparam->ifbrp_csize;
589 		bridge_rttrim(sc);
590 		break;
591 	case SIOCBRDGSTO:
592 		if ((error = suser(prc, 0)) != 0)
593 			break;
594 		if (bparam->ifbrp_ctime < 0 ||
595 		    bparam->ifbrp_ctime > INT_MAX / hz) {
596 			error = EINVAL;
597 			break;
598 		}
599 		sc->sc_brttimeout = bparam->ifbrp_ctime;
600 		timeout_del(&sc->sc_brtimeout);
601 		if (bparam->ifbrp_ctime != 0)
602 			timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz);
603 		break;
604 	case SIOCBRDGGTO:
605 		bparam->ifbrp_ctime = sc->sc_brttimeout;
606 		break;
607 	case SIOCSIFFLAGS:
608 		if ((ifp->if_flags & IFF_UP) == IFF_UP)
609 			bridge_init(sc);
610 
611 		if ((ifp->if_flags & IFF_UP) == 0)
612 			bridge_stop(sc);
613 
614 		break;
615 	case SIOCBRDGARL:
616 		if ((error = suser(prc, 0)) != 0)
617 			break;
618 		ifs = ifunit(brlreq->ifbr_ifsname);
619 		if (ifs == NULL) {
620 			error = ENOENT;
621 			break;
622 		}
623 		if (ifs->if_bridge == NULL ||
624 		    ifs->if_bridge != (caddr_t)sc) {
625 			error = ESRCH;
626 			break;
627 		}
628 		LIST_FOREACH(p, &sc->sc_iflist, next) {
629 			if (p->ifp == ifs)
630 				break;
631 		}
632 		if (p == LIST_END(&sc->sc_iflist)) {
633 			error = ESRCH;
634 			break;
635 		}
636 		if ((brlreq->ifbr_action != BRL_ACTION_BLOCK &&
637 		    brlreq->ifbr_action != BRL_ACTION_PASS) ||
638 		    (brlreq->ifbr_flags & (BRL_FLAG_IN|BRL_FLAG_OUT)) == 0) {
639 			error = EINVAL;
640 			break;
641 		}
642 		if (brlreq->ifbr_flags & BRL_FLAG_IN) {
643 			error = bridge_addrule(p, brlreq, 0);
644 			if (error)
645 				break;
646 		}
647 		if (brlreq->ifbr_flags & BRL_FLAG_OUT) {
648 			error = bridge_addrule(p, brlreq, 1);
649 			if (error)
650 				break;
651 		}
652 		break;
653 	case SIOCBRDGFRL:
654 		if ((error = suser(prc, 0)) != 0)
655 			break;
656 		ifs = ifunit(brlreq->ifbr_ifsname);
657 		if (ifs == NULL) {
658 			error = ENOENT;
659 			break;
660 		}
661 		if (ifs->if_bridge == NULL ||
662 		    ifs->if_bridge != (caddr_t)sc) {
663 			error = ESRCH;
664 			break;
665 		}
666 		LIST_FOREACH(p, &sc->sc_iflist, next) {
667 			if (p->ifp == ifs)
668 				break;
669 		}
670 		if (p == LIST_END(&sc->sc_iflist)) {
671 			error = ESRCH;
672 			break;
673 		}
674 		error = bridge_flushrule(p);
675 		break;
676 	case SIOCBRDGGRL:
677 		error = bridge_brlconf(sc, brlconf);
678 		break;
679 	case SIOCBRDGGPRI:
680 	case SIOCBRDGGMA:
681 	case SIOCBRDGGHT:
682 	case SIOCBRDGGFD:
683 		break;
684 	case SIOCBRDGSPRI:
685 	case SIOCBRDGSFD:
686 	case SIOCBRDGSMA:
687 	case SIOCBRDGSHT:
688 		error = suser(prc, 0);
689 		break;
690 	default:
691 		error = EINVAL;
692 	}
693 
694 	if (!error)
695 		error = bstp_ioctl(ifp, cmd, data);
696 
697 	splx(s);
698 	return (error);
699 }
700 
701 /* Detach an interface from a bridge.  */
702 void
bridge_ifdetach(struct ifnet * ifp)703 bridge_ifdetach(struct ifnet *ifp)
704 {
705 	struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge;
706 	struct bridge_iflist *bif;
707 
708 	LIST_FOREACH(bif, &sc->sc_iflist, next)
709 		if (bif->ifp == ifp) {
710 			LIST_REMOVE(bif, next);
711 			bridge_rtdelete(sc, ifp, 0);
712 			bridge_flushrule(bif);
713 			free(bif, M_DEVBUF);
714 			ifp->if_bridge = NULL;
715 			break;
716 		}
717 }
718 
719 int
bridge_bifconf(struct bridge_softc * sc,struct ifbifconf * bifc)720 bridge_bifconf(struct bridge_softc *sc, struct ifbifconf *bifc)
721 {
722 	struct bridge_iflist *p;
723 	u_int32_t total = 0, i = 0;
724 	int error = 0;
725 	struct ifbreq breq;
726 
727 	LIST_FOREACH(p, &sc->sc_iflist, next)
728 		total++;
729 
730 	LIST_FOREACH(p, &sc->sc_spanlist, next)
731 		total++;
732 
733 	if (bifc->ifbic_len == 0) {
734 		i = total;
735 		goto done;
736 	}
737 
738 	LIST_FOREACH(p, &sc->sc_iflist, next) {
739 		if (bifc->ifbic_len < sizeof(breq))
740 			break;
741 		strlcpy(breq.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
742 		strlcpy(breq.ifbr_ifsname, p->ifp->if_xname, IFNAMSIZ);
743 		breq.ifbr_ifsflags = p->bif_flags;
744 		breq.ifbr_state = p->bif_state;
745 		breq.ifbr_priority = p->bif_priority;
746 		breq.ifbr_path_cost = p->bif_path_cost;
747 		breq.ifbr_portno = p->ifp->if_index & 0xff;
748 		error = copyout((caddr_t)&breq,
749 		    (caddr_t)(bifc->ifbic_req + i), sizeof(breq));
750 		if (error)
751 			goto done;
752 		i++;
753 		bifc->ifbic_len -= sizeof(breq);
754 	}
755 	LIST_FOREACH(p, &sc->sc_spanlist, next) {
756 		if (bifc->ifbic_len < sizeof(breq))
757 			break;
758 		strlcpy(breq.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
759 		strlcpy(breq.ifbr_ifsname, p->ifp->if_xname, IFNAMSIZ);
760 		breq.ifbr_ifsflags = p->bif_flags | IFBIF_SPAN;
761 		breq.ifbr_state = p->bif_state;
762 		breq.ifbr_priority = p->bif_priority;
763 		breq.ifbr_path_cost = p->bif_path_cost;
764 		breq.ifbr_portno = p->ifp->if_index & 0xff;
765 		error = copyout((caddr_t)&breq,
766 		    (caddr_t)(bifc->ifbic_req + i), sizeof(breq));
767 		if (error)
768 			goto done;
769 		i++;
770 		bifc->ifbic_len -= sizeof(breq);
771 	}
772 
773 done:
774 	bifc->ifbic_len = i * sizeof(breq);
775 	return (error);
776 }
777 
778 int
bridge_brlconf(struct bridge_softc * sc,struct ifbrlconf * bc)779 bridge_brlconf(struct bridge_softc *sc, struct ifbrlconf *bc)
780 {
781 	struct ifnet *ifp;
782 	struct bridge_iflist *ifl;
783 	struct brl_node *n;
784 	struct ifbrlreq req;
785 	int error = 0;
786 	u_int32_t i = 0, total = 0;
787 
788 	ifp = ifunit(bc->ifbrl_ifsname);
789 	if (ifp == NULL)
790 		return (ENOENT);
791 	if (ifp->if_bridge == NULL || ifp->if_bridge != (caddr_t)sc)
792 		return (ESRCH);
793 	LIST_FOREACH(ifl, &sc->sc_iflist, next) {
794 		if (ifl->ifp == ifp)
795 			break;
796 	}
797 	if (ifl == LIST_END(&sc->sc_iflist))
798 		return (ESRCH);
799 
800 	SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) {
801 		total++;
802 	}
803 	SIMPLEQ_FOREACH(n, &ifl->bif_brlout, brl_next) {
804 		total++;
805 	}
806 
807 	if (bc->ifbrl_len == 0) {
808 		i = total;
809 		goto done;
810 	}
811 
812 	SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) {
813 		if (bc->ifbrl_len < sizeof(req))
814 			goto done;
815 		strlcpy(req.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
816 		strlcpy(req.ifbr_ifsname, ifl->ifp->if_xname, IFNAMSIZ);
817 		req.ifbr_action = n->brl_action;
818 		req.ifbr_flags = n->brl_flags;
819 		req.ifbr_src = n->brl_src;
820 		req.ifbr_dst = n->brl_dst;
821 #if NPF > 0
822 		req.ifbr_tagname[0] = '\0';
823 		if (n->brl_tag)
824 			pf_tag2tagname(n->brl_tag, req.ifbr_tagname);
825 #endif
826 		error = copyout((caddr_t)&req,
827 		    (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req));
828 		if (error)
829 			goto done;
830 		i++;
831 		bc->ifbrl_len -= sizeof(req);
832 	}
833 
834 	SIMPLEQ_FOREACH(n, &ifl->bif_brlout, brl_next) {
835 		if (bc->ifbrl_len < sizeof(req))
836 			goto done;
837 		strlcpy(req.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
838 		strlcpy(req.ifbr_ifsname, ifl->ifp->if_xname, IFNAMSIZ);
839 		req.ifbr_action = n->brl_action;
840 		req.ifbr_flags = n->brl_flags;
841 		req.ifbr_src = n->brl_src;
842 		req.ifbr_dst = n->brl_dst;
843 #if NPF > 0
844 		req.ifbr_tagname[0] = '\0';
845 		if (n->brl_tag)
846 			pf_tag2tagname(n->brl_tag, req.ifbr_tagname);
847 #endif
848 		error = copyout((caddr_t)&req,
849 		    (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req));
850 		if (error)
851 			goto done;
852 		i++;
853 		bc->ifbrl_len -= sizeof(req);
854 	}
855 
856 done:
857 	bc->ifbrl_len = i * sizeof(req);
858 	return (error);
859 }
860 
861 void
bridge_init(struct bridge_softc * sc)862 bridge_init(struct bridge_softc *sc)
863 {
864 	struct ifnet *ifp = &sc->sc_if;
865 	int i;
866 
867 	if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING)
868 		return;
869 
870 	if (sc->sc_rts == NULL) {
871 		sc->sc_rts = (struct bridge_rthead *)malloc(
872 		    BRIDGE_RTABLE_SIZE * (sizeof(struct bridge_rthead)),
873 		    M_DEVBUF, M_NOWAIT);
874 		if (sc->sc_rts == NULL)
875 			return;
876 		for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
877 			LIST_INIT(&sc->sc_rts[i]);
878 		}
879 		sc->sc_hashkey = arc4random();
880 	}
881 	ifp->if_flags |= IFF_RUNNING;
882 	bstp_initialization(sc);
883 
884 	if (sc->sc_brttimeout != 0)
885 		timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz);
886 }
887 
888 /*
889  * Stop the bridge and deallocate the routing table.
890  */
891 void
bridge_stop(struct bridge_softc * sc)892 bridge_stop(struct bridge_softc *sc)
893 {
894 	struct ifnet *ifp = &sc->sc_if;
895 
896 	/*
897 	 * If we're not running, there's nothing to do.
898 	 */
899 	if ((ifp->if_flags & IFF_RUNNING) == 0)
900 		return;
901 
902 	timeout_del(&sc->sc_brtimeout);
903 
904 	bridge_rtflush(sc, IFBF_FLUSHDYN);
905 
906 	ifp->if_flags &= ~IFF_RUNNING;
907 }
908 
909 /*
910  * Send output from the bridge.  The mbuf has the ethernet header
911  * already attached.  We must enqueue or free the mbuf before exiting.
912  */
913 int
bridge_output(struct ifnet * ifp,struct mbuf * m,struct sockaddr * sa,struct rtentry * rt)914 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
915     struct rtentry *rt)
916 {
917 	struct ether_header *eh;
918 	struct ifnet *dst_if;
919 	struct ether_addr *src, *dst;
920 	struct bridge_softc *sc;
921 	int s, error, len;
922 #ifdef IPSEC
923 	struct m_tag *mtag;
924 #endif /* IPSEC */
925 
926 	if (m->m_len < sizeof(*eh)) {
927 		m = m_pullup(m, sizeof(*eh));
928 		if (m == NULL)
929 			return (0);
930 	}
931 	eh = mtod(m, struct ether_header *);
932 	dst = (struct ether_addr *)&eh->ether_dhost[0];
933 	src = (struct ether_addr *)&eh->ether_shost[0];
934 	sc = (struct bridge_softc *)ifp->if_bridge;
935 
936 	s = splimp();
937 
938 	/*
939 	 * If bridge is down, but original output interface is up,
940 	 * go ahead and send out that interface.  Otherwise the packet
941 	 * is dropped below.
942 	 */
943 	if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
944 		dst_if = ifp;
945 		goto sendunicast;
946 	}
947 
948 	/*
949 	 * If the packet is a broadcast or we don't know a better way to
950 	 * get there, send to all interfaces.
951 	 */
952 	dst_if = bridge_rtlookup(sc, dst);
953 	if (dst_if == NULL || ETHER_IS_MULTICAST(eh->ether_dhost)) {
954 		struct bridge_iflist *p;
955 		struct mbuf *mc;
956 		int used = 0;
957 
958 #ifdef IPSEC
959 		/*
960 		 * Don't send out the packet if IPsec is needed, and
961 		 * notify IPsec to do its own crypto for now.
962 		 */
963 		if ((mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED,
964 		    NULL)) != NULL) {
965 			ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
966 			m_freem(m);
967 			splx(s);
968 			return (0);
969 		}
970 #endif /* IPSEC */
971 
972 		/* Catch packets that need TCP/UDP/IP hardware checksumming */
973 		if (m->m_pkthdr.csum & M_IPV4_CSUM_OUT ||
974 		    m->m_pkthdr.csum & M_TCPV4_CSUM_OUT ||
975 		    m->m_pkthdr.csum & M_UDPV4_CSUM_OUT) {
976 			m_freem(m);
977 			splx(s);
978 			return (0);
979 		}
980 
981 		bridge_span(sc, NULL, m);
982 
983 		LIST_FOREACH(p, &sc->sc_iflist, next) {
984 			dst_if = p->ifp;
985 			if ((dst_if->if_flags & IFF_RUNNING) == 0)
986 				continue;
987 
988 			/*
989 			 * If this is not the original output interface,
990 			 * and the interface is participating in spanning
991 			 * tree, make sure the port is in a state that
992 			 * allows forwarding.
993 			 */
994 			if (dst_if != ifp &&
995 			    (p->bif_flags & IFBIF_STP) &&
996 			    (p->bif_state != BSTP_IFSTATE_FORWARDING))
997 				continue;
998 
999 			if ((p->bif_flags & IFBIF_DISCOVER) == 0 &&
1000 			    (m->m_flags & (M_BCAST | M_MCAST)) == 0)
1001 				continue;
1002 
1003 #ifdef ALTQ
1004 			if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0)
1005 #endif
1006 			if (IF_QFULL(&dst_if->if_snd)) {
1007 				IF_DROP(&dst_if->if_snd);
1008 				sc->sc_if.if_oerrors++;
1009 				continue;
1010 			}
1011 			if (LIST_NEXT(p, next) == LIST_END(&sc->sc_iflist)) {
1012 				used = 1;
1013 				mc = m;
1014 			} else {
1015 				struct mbuf *m1, *m2, *mx;
1016 
1017 				m1 = m_copym2(m, 0, sizeof(struct ether_header),
1018 				    M_DONTWAIT);
1019 				if (m1 == NULL) {
1020 					sc->sc_if.if_oerrors++;
1021 					continue;
1022 				}
1023 				m2 = m_copym2(m, sizeof(struct ether_header),
1024 				    M_COPYALL, M_DONTWAIT);
1025 				if (m2 == NULL) {
1026 					m_freem(m1);
1027 					sc->sc_if.if_oerrors++;
1028 					continue;
1029 				}
1030 
1031 				for (mx = m1; mx->m_next != NULL; mx = mx->m_next)
1032 					/*EMPTY*/;
1033 				mx->m_next = m2;
1034 
1035 				if (m1->m_flags & M_PKTHDR) {
1036 					len = 0;
1037 					for (mx = m1; mx != NULL; mx = mx->m_next)
1038 						len += mx->m_len;
1039 					m1->m_pkthdr.len = len;
1040 				}
1041 				mc = m1;
1042 			}
1043 
1044 			error = bridge_ifenqueue(sc, dst_if, mc);
1045 			if (error)
1046 				continue;
1047 		}
1048 		if (!used)
1049 			m_freem(m);
1050 		splx(s);
1051 		return (0);
1052 	}
1053 
1054 sendunicast:
1055 	bridge_span(sc, NULL, m);
1056 	if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1057 		m_freem(m);
1058 		splx(s);
1059 		return (0);
1060 	}
1061 	bridge_ifenqueue(sc, dst_if, m);
1062 	splx(s);
1063 	return (0);
1064 }
1065 
1066 /*
1067  * Start output on the bridge.  This function should never be called.
1068  */
1069 void
bridge_start(struct ifnet * ifp)1070 bridge_start(struct ifnet *ifp)
1071 {
1072 }
1073 
1074 /*
1075  * Loop through each bridge interface and process their input queues.
1076  */
1077 void
bridgeintr(void)1078 bridgeintr(void)
1079 {
1080 	struct bridge_softc *sc;
1081 	struct mbuf *m;
1082 	int s;
1083 
1084 	LIST_FOREACH(sc, &bridge_list, sc_list) {
1085 		for (;;) {
1086 			s = splimp();
1087 			IF_DEQUEUE(&sc->sc_if.if_snd, m);
1088 			splx(s);
1089 			if (m == NULL)
1090 				break;
1091 			bridgeintr_frame(sc, m);
1092 		}
1093 	}
1094 }
1095 
1096 /*
1097  * Process a single frame.  Frame must be freed or queued before returning.
1098  */
1099 void
bridgeintr_frame(struct bridge_softc * sc,struct mbuf * m)1100 bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
1101 {
1102 	int s, len;
1103 	struct ifnet *src_if, *dst_if;
1104 	struct bridge_iflist *ifl;
1105 	struct ether_addr *dst, *src;
1106 	struct ether_header eh;
1107 
1108 	if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1109 		m_freem(m);
1110 		return;
1111 	}
1112 
1113 	src_if = m->m_pkthdr.rcvif;
1114 
1115 #if NBPFILTER > 0
1116 	if (sc->sc_if.if_bpf)
1117 		bpf_mtap(sc->sc_if.if_bpf, m);
1118 #endif
1119 
1120 	sc->sc_if.if_ipackets++;
1121 	sc->sc_if.if_ibytes += m->m_pkthdr.len;
1122 
1123 	LIST_FOREACH(ifl, &sc->sc_iflist, next)
1124 		if (ifl->ifp == src_if)
1125 			break;
1126 
1127 	if (ifl == LIST_END(&sc->sc_iflist)) {
1128 		m_freem(m);
1129 		return;
1130 	}
1131 
1132 	if ((ifl->bif_flags & IFBIF_STP) &&
1133 	    (ifl->bif_state == BSTP_IFSTATE_BLOCKING ||
1134 	    ifl->bif_state == BSTP_IFSTATE_LISTENING ||
1135 	    ifl->bif_state == BSTP_IFSTATE_DISABLED)) {
1136 		m_freem(m);
1137 		return;
1138 	}
1139 
1140 	if (m->m_pkthdr.len < sizeof(eh)) {
1141 		m_freem(m);
1142 		return;
1143 	}
1144 	m_copydata(m, 0, sizeof(struct ether_header), (caddr_t)&eh);
1145 	dst = (struct ether_addr *)&eh.ether_dhost[0];
1146 	src = (struct ether_addr *)&eh.ether_shost[0];
1147 
1148 	/*
1149 	 * If interface is learning, and if source address
1150 	 * is not broadcast or multicast, record it's address.
1151 	 */
1152 	if ((ifl->bif_flags & IFBIF_LEARNING) &&
1153 	    (eh.ether_shost[0] & 1) == 0 &&
1154 	    !(eh.ether_shost[0] == 0 && eh.ether_shost[1] == 0 &&
1155 	    eh.ether_shost[2] == 0 && eh.ether_shost[3] == 0 &&
1156 	    eh.ether_shost[4] == 0 && eh.ether_shost[5] == 0))
1157 		bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC);
1158 
1159 	if ((ifl->bif_flags & IFBIF_STP) &&
1160 	    (ifl->bif_state == BSTP_IFSTATE_LEARNING)) {
1161 		m_freem(m);
1162 		return;
1163 	}
1164 
1165 	/*
1166 	 * At this point, the port either doesn't participate in stp or
1167 	 * it's in the forwarding state
1168 	 */
1169 
1170 	/*
1171 	 * If packet is unicast, destined for someone on "this"
1172 	 * side of the bridge, drop it.
1173 	 */
1174 	if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) {
1175 		dst_if = bridge_rtlookup(sc, dst);
1176 		if (dst_if == src_if) {
1177 			m_freem(m);
1178 			return;
1179 		}
1180 	} else
1181 		dst_if = NULL;
1182 
1183 	/*
1184 	 * Multicast packets get handled a little differently:
1185 	 * If interface is:
1186 	 *	-link0,-link1	(default) Forward all multicast
1187 	 *			as broadcast.
1188 	 *	-link0,link1	Drop non-IP multicast, forward
1189 	 *			as broadcast IP multicast.
1190 	 *	link0,-link1	Drop IP multicast, forward as
1191 	 *			broadcast non-IP multicast.
1192 	 *	link0,link1	Drop all multicast.
1193 	 */
1194 	if (m->m_flags & M_MCAST) {
1195 		if ((sc->sc_if.if_flags &
1196 		    (IFF_LINK0 | IFF_LINK1)) ==
1197 		    (IFF_LINK0 | IFF_LINK1)) {
1198 			m_freem(m);
1199 			return;
1200 		}
1201 		if (sc->sc_if.if_flags & IFF_LINK0 &&
1202 		    ETHERADDR_IS_IP_MCAST(dst)) {
1203 			m_freem(m);
1204 			return;
1205 		}
1206 		if (sc->sc_if.if_flags & IFF_LINK1 &&
1207 		    !ETHERADDR_IS_IP_MCAST(dst)) {
1208 			m_freem(m);
1209 			return;
1210 		}
1211 	}
1212 
1213 	if (ifl->bif_flags & IFBIF_BLOCKNONIP && bridge_blocknonip(&eh, m)) {
1214 		m_freem(m);
1215 		return;
1216 	}
1217 
1218 	if (bridge_filterrule(&ifl->bif_brlin, &eh, m) == BRL_ACTION_BLOCK) {
1219 		m_freem(m);
1220 		return;
1221 	}
1222 #if NPF > 0
1223 	m = bridge_filter(sc, BRIDGE_IN, src_if, &eh, m);
1224 	if (m == NULL)
1225 		return;
1226 #endif
1227 	/*
1228 	 * If the packet is a multicast or broadcast OR if we don't
1229 	 * know any better, forward it to all interfaces.
1230 	 */
1231 	if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_if == NULL) {
1232 		sc->sc_if.if_imcasts++;
1233 		s = splimp();
1234 		bridge_broadcast(sc, src_if, &eh, m);
1235 		splx(s);
1236 		return;
1237 	}
1238 
1239 	/*
1240 	 * At this point, we're dealing with a unicast frame going to a
1241 	 * different interface
1242 	 */
1243 	if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1244 		m_freem(m);
1245 		return;
1246 	}
1247 	LIST_FOREACH(ifl, &sc->sc_iflist, next) {
1248 		if (ifl->ifp == dst_if)
1249 			break;
1250 	}
1251 	if (ifl == LIST_END(&sc->sc_iflist)) {
1252 		m_freem(m);
1253 		return;
1254 	}
1255 	if ((ifl->bif_flags & IFBIF_STP) &&
1256 	    (ifl->bif_state == BSTP_IFSTATE_DISABLED ||
1257 	    ifl->bif_state == BSTP_IFSTATE_BLOCKING)) {
1258 		m_freem(m);
1259 		return;
1260 	}
1261 	if (bridge_filterrule(&ifl->bif_brlout, &eh, m) == BRL_ACTION_BLOCK) {
1262 		m_freem(m);
1263 		return;
1264 	}
1265 #if NPF > 0
1266 	m = bridge_filter(sc, BRIDGE_OUT, dst_if, &eh, m);
1267 	if (m == NULL)
1268 		return;
1269 #endif
1270 
1271 	len = m->m_pkthdr.len;
1272 	if ((len - sizeof(struct ether_header)) > dst_if->if_mtu)
1273 		bridge_fragment(sc, dst_if, &eh, m);
1274 	else {
1275 		s = splimp();
1276 		bridge_ifenqueue(sc, dst_if, m);
1277 		splx(s);
1278 	}
1279 }
1280 
1281 /*
1282  * Receive input from an interface.  Queue the packet for bridging if its
1283  * not for us, and schedule an interrupt.
1284  */
1285 struct mbuf *
bridge_input(struct ifnet * ifp,struct ether_header * eh,struct mbuf * m)1286 bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
1287 {
1288 	struct bridge_softc *sc;
1289 	int s;
1290 	struct bridge_iflist *ifl, *srcifl;
1291 	struct arpcom *ac;
1292 	struct mbuf *mc;
1293 
1294 	/*
1295 	 * Make sure this interface is a bridge member.
1296 	 */
1297 	if (ifp == NULL || ifp->if_bridge == NULL || m == NULL)
1298 		return (m);
1299 
1300 	if ((m->m_flags & M_PKTHDR) == 0)
1301 		panic("bridge_input(): no HDR");
1302 
1303 	m->m_flags &= ~M_PROTO1;	/* Loop prevention */
1304 
1305 	sc = (struct bridge_softc *)ifp->if_bridge;
1306 	if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
1307 		return (m);
1308 
1309 	LIST_FOREACH(ifl, &sc->sc_iflist, next) {
1310 		if (ifl->ifp == ifp)
1311 			break;
1312 	}
1313 	if (ifl == LIST_END(&sc->sc_iflist))
1314 		return (m);
1315 
1316 	bridge_span(sc, eh, m);
1317 
1318 	if (m->m_flags & (M_BCAST | M_MCAST)) {
1319 		/* Tap off 802.1D packets, they do not get forwarded */
1320 		if (bcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) {
1321 			m = bstp_input(sc, ifp, eh, m);
1322 			if (m == NULL)
1323 				return (NULL);
1324 		}
1325 
1326 		/*
1327 		 * No need to queue frames for ifs in the blocking, disabled,
1328 		 *  or listening state
1329 		 */
1330 		if ((ifl->bif_flags & IFBIF_STP) &&
1331 		    ((ifl->bif_state == BSTP_IFSTATE_BLOCKING) ||
1332 		    (ifl->bif_state == BSTP_IFSTATE_LISTENING) ||
1333 		    (ifl->bif_state == BSTP_IFSTATE_DISABLED)))
1334 			return (m);
1335 
1336 		/*
1337 		 * make a copy of 'm' with 'eh' tacked on to the
1338 		 * beginning.  Return 'm' for local processing
1339 		 * and enqueue the copy.  Schedule netisr.
1340 		 */
1341 		mc = m_copym2(m, 0, M_COPYALL, M_NOWAIT);
1342 		if (mc == NULL)
1343 			return (m);
1344 		M_PREPEND(mc, sizeof(struct ether_header), M_DONTWAIT);
1345 		if (mc == NULL)
1346 			return (m);
1347 		bcopy(eh, mtod(mc, caddr_t), sizeof(struct ether_header));
1348 		s = splimp();
1349 		if (IF_QFULL(&sc->sc_if.if_snd)) {
1350 			m_freem(mc);
1351 			splx(s);
1352 			return (m);
1353 		}
1354 		IF_ENQUEUE(&sc->sc_if.if_snd, mc);
1355 		splx(s);
1356 		schednetisr(NETISR_BRIDGE);
1357 		if (ifp->if_type == IFT_GIF) {
1358 			LIST_FOREACH(ifl, &sc->sc_iflist, next) {
1359 				if (ifl->ifp->if_type == IFT_ETHER)
1360 					break;
1361 			}
1362 			if (ifl != LIST_END(&sc->sc_iflist)) {
1363 				m->m_flags |= M_PROTO1;
1364 				m->m_pkthdr.rcvif = ifl->ifp;
1365 				ether_input(ifl->ifp, eh, m);
1366 				m = NULL;
1367 			}
1368 		}
1369 		return (m);
1370 	}
1371 
1372 	/*
1373 	 * No need to queue frames for ifs in the blocking, disabled, or
1374 	 * listening state
1375 	 */
1376 	if ((ifl->bif_flags & IFBIF_STP) &&
1377 	    ((ifl->bif_state == BSTP_IFSTATE_BLOCKING) ||
1378 	    (ifl->bif_state == BSTP_IFSTATE_LISTENING) ||
1379 	    (ifl->bif_state == BSTP_IFSTATE_DISABLED)))
1380 		return (m);
1381 
1382 
1383 	/*
1384 	 * Unicast, make sure it's not for us.
1385 	 */
1386 	srcifl = ifl;
1387 	LIST_FOREACH(ifl, &sc->sc_iflist, next) {
1388 		if (ifl->ifp->if_type != IFT_ETHER)
1389 			continue;
1390 		ac = (struct arpcom *)ifl->ifp;
1391 		if (bcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) == 0) {
1392 			if (srcifl->bif_flags & IFBIF_LEARNING)
1393 				bridge_rtupdate(sc,
1394 				    (struct ether_addr *)&eh->ether_shost,
1395 				    ifp, 0, IFBAF_DYNAMIC);
1396 			if (bridge_filterrule(&srcifl->bif_brlin, eh, m) ==
1397 			    BRL_ACTION_BLOCK) {
1398 				m_freem(m);
1399 				return (NULL);
1400 			}
1401 			m->m_pkthdr.rcvif = ifl->ifp;
1402 			if (ifp->if_type == IFT_GIF) {
1403 				m->m_flags |= M_PROTO1;
1404 				ether_input(ifl->ifp, eh, m);
1405 				m = NULL;
1406 			}
1407 			return (m);
1408 		}
1409 		if (bcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0) {
1410 			m_freem(m);
1411 			return (NULL);
1412 		}
1413 	}
1414 	M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
1415 	if (m == NULL)
1416 		return (NULL);
1417 	bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header));
1418 	s = splimp();
1419 	if (IF_QFULL(&sc->sc_if.if_snd)) {
1420 		m_freem(m);
1421 		splx(s);
1422 		return (NULL);
1423 	}
1424 	IF_ENQUEUE(&sc->sc_if.if_snd, m);
1425 	splx(s);
1426 	schednetisr(NETISR_BRIDGE);
1427 	return (NULL);
1428 }
1429 
1430 /*
1431  * Send a frame to all interfaces that are members of the bridge
1432  * (except the one it came in on).  This code assumes that it is
1433  * running at splnet or higher.
1434  */
1435 void
bridge_broadcast(struct bridge_softc * sc,struct ifnet * ifp,struct ether_header * eh,struct mbuf * m)1436 bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp,
1437     struct ether_header *eh, struct mbuf *m)
1438 {
1439 	struct bridge_iflist *p;
1440 	struct mbuf *mc;
1441 	struct ifnet *dst_if;
1442 	int len = m->m_pkthdr.len, used = 0;
1443 
1444 	splassert(IPL_NET);
1445 
1446 	LIST_FOREACH(p, &sc->sc_iflist, next) {
1447 		/*
1448 		 * Don't retransmit out of the same interface where
1449 		 * the packet was received from.
1450 		 */
1451 		dst_if = p->ifp;
1452 		if (dst_if->if_index == ifp->if_index)
1453 			continue;
1454 
1455 		if ((p->bif_flags & IFBIF_STP) &&
1456 		    (p->bif_state != BSTP_IFSTATE_FORWARDING))
1457 			continue;
1458 
1459 		if ((p->bif_flags & IFBIF_DISCOVER) == 0 &&
1460 		    (m->m_flags & (M_BCAST | M_MCAST)) == 0)
1461 			continue;
1462 
1463 		if ((dst_if->if_flags & IFF_RUNNING) == 0)
1464 			continue;
1465 
1466 #ifdef ALTQ
1467 		if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0)
1468 #endif
1469 		if (IF_QFULL(&dst_if->if_snd)) {
1470 			IF_DROP(&dst_if->if_snd);
1471 			sc->sc_if.if_oerrors++;
1472 			continue;
1473 		}
1474 
1475 		/* Drop non-IP frames if the appropriate flag is set. */
1476 		if (p->bif_flags & IFBIF_BLOCKNONIP &&
1477 		    bridge_blocknonip(eh, m))
1478 			continue;
1479 
1480 		if (bridge_filterrule(&p->bif_brlout, eh, m) == BRL_ACTION_BLOCK)
1481 			continue;
1482 
1483 		/* If last one, reuse the passed-in mbuf */
1484 		if (LIST_NEXT(p, next) == LIST_END(&sc->sc_iflist)) {
1485 			mc = m;
1486 			used = 1;
1487 		} else {
1488 			struct mbuf *m1, *m2, *mx;
1489 
1490 			m1 = m_copym2(m, 0, sizeof(struct ether_header),
1491 			    M_DONTWAIT);
1492 			if (m1 == NULL) {
1493 				sc->sc_if.if_oerrors++;
1494 				continue;
1495 			}
1496 			m2 = m_copym2(m, sizeof(struct ether_header),
1497 			    M_COPYALL, M_DONTWAIT);
1498 			if (m2 == NULL) {
1499 				m_freem(m1);
1500 				sc->sc_if.if_oerrors++;
1501 				continue;
1502 			}
1503 
1504 			for (mx = m1; mx->m_next != NULL; mx = mx->m_next)
1505 				/*EMPTY*/;
1506 			mx->m_next = m2;
1507 
1508 			if (m1->m_flags & M_PKTHDR) {
1509 				int len = 0;
1510 
1511 				for (mx = m1; mx != NULL; mx = mx->m_next)
1512 					len += mx->m_len;
1513 				m1->m_pkthdr.len = len;
1514 			}
1515 			mc = m1;
1516 		}
1517 
1518 #if NPF > 0
1519 		mc = bridge_filter(sc, BRIDGE_OUT, dst_if, eh, mc);
1520 		if (mc == NULL)
1521 			continue;
1522 #endif
1523 
1524 		if ((len - sizeof(struct ether_header)) > dst_if->if_mtu)
1525 			bridge_fragment(sc, dst_if, eh, mc);
1526 		else {
1527 			bridge_ifenqueue(sc, dst_if, mc);
1528 		}
1529 	}
1530 
1531 	if (!used)
1532 		m_freem(m);
1533 }
1534 
1535 void
bridge_span(struct bridge_softc * sc,struct ether_header * eh,struct mbuf * morig)1536 bridge_span(struct bridge_softc *sc, struct ether_header *eh,
1537     struct mbuf *morig)
1538 {
1539 	struct bridge_iflist *p;
1540 	struct ifnet *ifp;
1541 	struct mbuf *mc, *m;
1542 	int error;
1543 
1544 	if (LIST_EMPTY(&sc->sc_spanlist))
1545 		return;
1546 
1547 	m = m_copym2(morig, 0, M_COPYALL, M_NOWAIT);
1548 	if (m == NULL)
1549 		return;
1550 	if (eh != NULL) {
1551 		M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
1552 		if (m == NULL)
1553 			return;
1554 		bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header));
1555 	}
1556 
1557 	LIST_FOREACH(p, &sc->sc_spanlist, next) {
1558 		ifp = p->ifp;
1559 
1560 		if ((ifp->if_flags & IFF_RUNNING) == 0)
1561 			continue;
1562 
1563 #ifdef ALTQ
1564 		if (ALTQ_IS_ENABLED(&ifp->if_snd) == 0)
1565 #endif
1566 			if (IF_QFULL(&ifp->if_snd)) {
1567 				IF_DROP(&ifp->if_snd);
1568 				sc->sc_if.if_oerrors++;
1569 				continue;
1570 			}
1571 
1572 		mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1573 		if (mc == NULL) {
1574 			sc->sc_if.if_oerrors++;
1575 			continue;
1576 		}
1577 
1578 		error = bridge_ifenqueue(sc, ifp, mc);
1579 		if (error)
1580 			continue;
1581 	}
1582 	m_freem(m);
1583 }
1584 
1585 struct ifnet *
bridge_rtupdate(struct bridge_softc * sc,struct ether_addr * ea,struct ifnet * ifp,int setflags,u_int8_t flags)1586 bridge_rtupdate(struct bridge_softc *sc, struct ether_addr *ea,
1587     struct ifnet *ifp, int setflags, u_int8_t flags)
1588 {
1589 	struct bridge_rtnode *p, *q;
1590 	u_int32_t h;
1591 	int dir;
1592 
1593 	if (sc->sc_rts == NULL) {
1594 		if (setflags && flags == IFBAF_STATIC) {
1595 			sc->sc_rts = (struct bridge_rthead *)malloc(
1596 			    BRIDGE_RTABLE_SIZE *
1597 			    (sizeof(struct bridge_rthead)),M_DEVBUF,M_NOWAIT);
1598 			if (sc->sc_rts == NULL)
1599 				goto done;
1600 
1601 			for (h = 0; h < BRIDGE_RTABLE_SIZE; h++) {
1602 				LIST_INIT(&sc->sc_rts[h]);
1603 			}
1604 			sc->sc_hashkey = arc4random();
1605 		} else
1606 			goto done;
1607 	}
1608 
1609 	h = bridge_hash(sc, ea);
1610 	p = LIST_FIRST(&sc->sc_rts[h]);
1611 	if (p == LIST_END(&sc->sc_rts[h])) {
1612 		if (sc->sc_brtcnt >= sc->sc_brtmax)
1613 			goto done;
1614 		p = (struct bridge_rtnode *)malloc(
1615 		    sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT);
1616 		if (p == NULL)
1617 			goto done;
1618 
1619 		bcopy(ea, &p->brt_addr, sizeof(p->brt_addr));
1620 		p->brt_if = ifp;
1621 		p->brt_age = 1;
1622 
1623 		if (setflags)
1624 			p->brt_flags = flags;
1625 		else
1626 			p->brt_flags = IFBAF_DYNAMIC;
1627 
1628 		LIST_INSERT_HEAD(&sc->sc_rts[h], p, brt_next);
1629 		sc->sc_brtcnt++;
1630 		goto want;
1631 	}
1632 
1633 	do {
1634 		q = p;
1635 		p = LIST_NEXT(p, brt_next);
1636 
1637 		dir = memcmp(ea, &q->brt_addr, sizeof(q->brt_addr));
1638 		if (dir == 0) {
1639 			if (setflags) {
1640 				q->brt_if = ifp;
1641 				q->brt_flags = flags;
1642 			}
1643 
1644 			if (q->brt_if == ifp)
1645 				q->brt_age = 1;
1646 			ifp = q->brt_if;
1647 			goto want;
1648 		}
1649 
1650 		if (dir > 0) {
1651 			if (sc->sc_brtcnt >= sc->sc_brtmax)
1652 				goto done;
1653 			p = (struct bridge_rtnode *)malloc(
1654 			    sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT);
1655 			if (p == NULL)
1656 				goto done;
1657 
1658 			bcopy(ea, &p->brt_addr, sizeof(p->brt_addr));
1659 			p->brt_if = ifp;
1660 			p->brt_age = 1;
1661 
1662 			if (setflags)
1663 				p->brt_flags = flags;
1664 			else
1665 				p->brt_flags = IFBAF_DYNAMIC;
1666 
1667 			LIST_INSERT_BEFORE(q, p, brt_next);
1668 			sc->sc_brtcnt++;
1669 			goto want;
1670 		}
1671 
1672 		if (p == LIST_END(&sc->sc_rts[h])) {
1673 			if (sc->sc_brtcnt >= sc->sc_brtmax)
1674 				goto done;
1675 			p = (struct bridge_rtnode *)malloc(
1676 			    sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT);
1677 			if (p == NULL)
1678 				goto done;
1679 
1680 			bcopy(ea, &p->brt_addr, sizeof(p->brt_addr));
1681 			p->brt_if = ifp;
1682 			p->brt_age = 1;
1683 
1684 			if (setflags)
1685 				p->brt_flags = flags;
1686 			else
1687 				p->brt_flags = IFBAF_DYNAMIC;
1688 			LIST_INSERT_AFTER(q, p, brt_next);
1689 			sc->sc_brtcnt++;
1690 			goto want;
1691 		}
1692 	} while (p != LIST_END(&sc->sc_rts[h]));
1693 
1694 done:
1695 	ifp = NULL;
1696 want:
1697 	return (ifp);
1698 }
1699 
1700 struct ifnet *
bridge_rtlookup(struct bridge_softc * sc,struct ether_addr * ea)1701 bridge_rtlookup(struct bridge_softc *sc, struct ether_addr *ea)
1702 {
1703 	struct bridge_rtnode *p;
1704 	u_int32_t h;
1705 	int dir;
1706 
1707 	if (sc->sc_rts == NULL)
1708 		goto fail;
1709 
1710 	h = bridge_hash(sc, ea);
1711 	LIST_FOREACH(p, &sc->sc_rts[h], brt_next) {
1712 		dir = memcmp(ea, &p->brt_addr, sizeof(p->brt_addr));
1713 		if (dir == 0)
1714 			return (p->brt_if);
1715 		if (dir > 0)
1716 			goto fail;
1717 	}
1718 fail:
1719 	return (NULL);
1720 }
1721 
1722 /*
1723  * The following hash function is adapted from 'Hash Functions' by Bob Jenkins
1724  * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
1725  * "You may use this code any way you wish, private, educational, or
1726  *  commercial.  It's free."
1727  */
1728 #define	mix(a,b,c) \
1729 	do {						\
1730 		a -= b; a -= c; a ^= (c >> 13);		\
1731 		b -= c; b -= a; b ^= (a << 8);		\
1732 		c -= a; c -= b; c ^= (b >> 13);		\
1733 		a -= b; a -= c; a ^= (c >> 12);		\
1734 		b -= c; b -= a; b ^= (a << 16);		\
1735 		c -= a; c -= b; c ^= (b >> 5);		\
1736 		a -= b; a -= c; a ^= (c >> 3);		\
1737 		b -= c; b -= a; b ^= (a << 10);		\
1738 		c -= a; c -= b; c ^= (b >> 15);		\
1739 	} while (0)
1740 
1741 u_int32_t
bridge_hash(struct bridge_softc * sc,struct ether_addr * addr)1742 bridge_hash(struct bridge_softc *sc, struct ether_addr *addr)
1743 {
1744 	u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_hashkey;
1745 
1746 	b += addr->ether_addr_octet[5] << 8;
1747 	b += addr->ether_addr_octet[4];
1748 	a += addr->ether_addr_octet[3] << 24;
1749 	a += addr->ether_addr_octet[2] << 16;
1750 	a += addr->ether_addr_octet[1] << 8;
1751 	a += addr->ether_addr_octet[0];
1752 
1753 	mix(a, b, c);
1754 	return (c & BRIDGE_RTABLE_MASK);
1755 }
1756 
1757 /*
1758  * Trim the routing table so that we've got a number of routes
1759  * less than or equal to the maximum.
1760  */
1761 void
bridge_rttrim(struct bridge_softc * sc)1762 bridge_rttrim(struct bridge_softc *sc)
1763 {
1764 	struct bridge_rtnode *n, *p;
1765 	int i;
1766 
1767 	if (sc->sc_rts == NULL)
1768 		goto done;
1769 
1770 	/*
1771 	 * Make sure we have to trim the address table
1772 	 */
1773 	if (sc->sc_brtcnt <= sc->sc_brtmax)
1774 		goto done;
1775 
1776 	/*
1777 	 * Force an aging cycle, this might trim enough addresses.
1778 	 */
1779 	bridge_rtage(sc);
1780 
1781 	if (sc->sc_brtcnt <= sc->sc_brtmax)
1782 		goto done;
1783 
1784 	for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
1785 		n = LIST_FIRST(&sc->sc_rts[i]);
1786 		while (n != LIST_END(&sc->sc_rts[i])) {
1787 			p = LIST_NEXT(n, brt_next);
1788 			if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1789 				LIST_REMOVE(n, brt_next);
1790 				sc->sc_brtcnt--;
1791 				free(n, M_DEVBUF);
1792 				n = p;
1793 				if (sc->sc_brtcnt <= sc->sc_brtmax)
1794 					goto done;
1795 			}
1796 		}
1797 	}
1798 
1799 done:
1800 	if (sc->sc_rts != NULL && sc->sc_brtcnt == 0 &&
1801 	    (sc->sc_if.if_flags & IFF_UP) == 0) {
1802 		free(sc->sc_rts, M_DEVBUF);
1803 		sc->sc_rts = NULL;
1804 	}
1805 }
1806 
1807 void
bridge_timer(void * vsc)1808 bridge_timer(void *vsc)
1809 {
1810 	struct bridge_softc *sc = vsc;
1811 	int s;
1812 
1813 	s = splsoftnet();
1814 	bridge_rtage(sc);
1815 	splx(s);
1816 }
1817 
1818 /*
1819  * Perform an aging cycle
1820  */
1821 void
bridge_rtage(struct bridge_softc * sc)1822 bridge_rtage(struct bridge_softc *sc)
1823 {
1824 	struct bridge_rtnode *n, *p;
1825 	int i;
1826 
1827 	if (sc->sc_rts == NULL)
1828 		return;
1829 
1830 	for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
1831 		n = LIST_FIRST(&sc->sc_rts[i]);
1832 		while (n != LIST_END(&sc->sc_rts[i])) {
1833 			if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_STATIC) {
1834 				n->brt_age = !n->brt_age;
1835 				if (n->brt_age)
1836 					n->brt_age = 0;
1837 				n = LIST_NEXT(n, brt_next);
1838 			} else if (n->brt_age) {
1839 				n->brt_age = 0;
1840 				n = LIST_NEXT(n, brt_next);
1841 			} else {
1842 				p = LIST_NEXT(n, brt_next);
1843 				LIST_REMOVE(n, brt_next);
1844 				sc->sc_brtcnt--;
1845 				free(n, M_DEVBUF);
1846 				n = p;
1847 			}
1848 		}
1849 	}
1850 
1851 	if (sc->sc_brttimeout != 0)
1852 		timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz);
1853 }
1854 
1855 /*
1856  * Remove all dynamic addresses from the cache
1857  */
1858 int
bridge_rtflush(struct bridge_softc * sc,int full)1859 bridge_rtflush(struct bridge_softc *sc, int full)
1860 {
1861 	int i;
1862 	struct bridge_rtnode *p, *n;
1863 
1864 	if (sc->sc_rts == NULL)
1865 		return (0);
1866 
1867 	for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
1868 		n = LIST_FIRST(&sc->sc_rts[i]);
1869 		while (n != LIST_END(&sc->sc_rts[i])) {
1870 			if (full ||
1871 			    (n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1872 				p = LIST_NEXT(n, brt_next);
1873 				LIST_REMOVE(n, brt_next);
1874 				sc->sc_brtcnt--;
1875 				free(n, M_DEVBUF);
1876 				n = p;
1877 			} else
1878 				n = LIST_NEXT(n, brt_next);
1879 		}
1880 	}
1881 
1882 	if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) {
1883 		free(sc->sc_rts, M_DEVBUF);
1884 		sc->sc_rts = NULL;
1885 	}
1886 
1887 	return (0);
1888 }
1889 
1890 /*
1891  * Remove an address from the cache
1892  */
1893 int
bridge_rtdaddr(struct bridge_softc * sc,struct ether_addr * ea)1894 bridge_rtdaddr(struct bridge_softc *sc, struct ether_addr *ea)
1895 {
1896 	int h;
1897 	struct bridge_rtnode *p;
1898 
1899 	if (sc->sc_rts == NULL)
1900 		return (ENOENT);
1901 
1902 	h = bridge_hash(sc, ea);
1903 	LIST_FOREACH(p, &sc->sc_rts[h], brt_next) {
1904 		if (bcmp(ea, &p->brt_addr, sizeof(p->brt_addr)) == 0) {
1905 			LIST_REMOVE(p, brt_next);
1906 			sc->sc_brtcnt--;
1907 			free(p, M_DEVBUF);
1908 			if (sc->sc_brtcnt == 0 &&
1909 			    (sc->sc_if.if_flags & IFF_UP) == 0) {
1910 				free(sc->sc_rts, M_DEVBUF);
1911 				sc->sc_rts = NULL;
1912 			}
1913 			return (0);
1914 		}
1915 	}
1916 
1917 	return (ENOENT);
1918 }
1919 /*
1920  * Delete routes to a specific interface member.
1921  */
1922 void
bridge_rtdelete(struct bridge_softc * sc,struct ifnet * ifp,int dynonly)1923 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int dynonly)
1924 {
1925 	int i;
1926 	struct bridge_rtnode *n, *p;
1927 
1928 	if (sc->sc_rts == NULL)
1929 		return;
1930 
1931 	/*
1932 	 * Loop through all of the hash buckets and traverse each
1933 	 * chain looking for routes to this interface.
1934 	 */
1935 	for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
1936 		n = LIST_FIRST(&sc->sc_rts[i]);
1937 		while (n != LIST_END(&sc->sc_rts[i])) {
1938 			if (n->brt_if != ifp) {
1939 				/* Not ours */
1940 				n = LIST_NEXT(n, brt_next);
1941 				continue;
1942 			}
1943 			if (dynonly &&
1944 			    (n->brt_flags & IFBAF_TYPEMASK) != IFBAF_DYNAMIC) {
1945 				/* only deleting dynamics */
1946 				n = LIST_NEXT(n, brt_next);
1947 				continue;
1948 			}
1949 			p = LIST_NEXT(n, brt_next);
1950 			LIST_REMOVE(n, brt_next);
1951 			sc->sc_brtcnt--;
1952 			free(n, M_DEVBUF);
1953 			n = p;
1954 		}
1955 	}
1956 	if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) {
1957 		free(sc->sc_rts, M_DEVBUF);
1958 		sc->sc_rts = NULL;
1959 	}
1960 }
1961 
1962 /*
1963  * Gather all of the routes for this interface.
1964  */
1965 int
bridge_rtfind(struct bridge_softc * sc,struct ifbaconf * baconf)1966 bridge_rtfind(struct bridge_softc *sc, struct ifbaconf *baconf)
1967 {
1968 	int i, error = 0, onlycnt = 0;
1969 	u_int32_t cnt = 0;
1970 	struct bridge_rtnode *n;
1971 	struct ifbareq bareq;
1972 
1973 	if (sc->sc_rts == NULL)
1974 		goto done;
1975 
1976 	if (baconf->ifbac_len == 0)
1977 		onlycnt = 1;
1978 
1979 	for (i = 0, cnt = 0; i < BRIDGE_RTABLE_SIZE; i++) {
1980 		LIST_FOREACH(n, &sc->sc_rts[i], brt_next) {
1981 			if (!onlycnt) {
1982 				if (baconf->ifbac_len < sizeof(struct ifbareq))
1983 					goto done;
1984 				bcopy(sc->sc_if.if_xname, bareq.ifba_name,
1985 				    sizeof(bareq.ifba_name));
1986 				bcopy(n->brt_if->if_xname, bareq.ifba_ifsname,
1987 				    sizeof(bareq.ifba_ifsname));
1988 				bcopy(&n->brt_addr, &bareq.ifba_dst,
1989 				    sizeof(bareq.ifba_dst));
1990 				bareq.ifba_age = n->brt_age;
1991 				bareq.ifba_flags = n->brt_flags;
1992 				error = copyout((caddr_t)&bareq,
1993 				    (caddr_t)(baconf->ifbac_req + cnt), sizeof(bareq));
1994 				if (error)
1995 					goto done;
1996 				baconf->ifbac_len -= sizeof(struct ifbareq);
1997 			}
1998 			cnt++;
1999 		}
2000 	}
2001 done:
2002 	baconf->ifbac_len = cnt * sizeof(struct ifbareq);
2003 	return (error);
2004 }
2005 
2006 /*
2007  * Block non-ip frames:
2008  * Returns 0 if frame is ip, and 1 if it should be dropped.
2009  */
2010 int
bridge_blocknonip(struct ether_header * eh,struct mbuf * m)2011 bridge_blocknonip(struct ether_header *eh, struct mbuf *m)
2012 {
2013 	struct llc llc;
2014 	u_int16_t etype;
2015 
2016 	if (m->m_pkthdr.len < sizeof(struct ether_header))
2017 		return (1);
2018 
2019 	etype = ntohs(eh->ether_type);
2020 	switch (etype) {
2021 	case ETHERTYPE_ARP:
2022 	case ETHERTYPE_REVARP:
2023 	case ETHERTYPE_IP:
2024 	case ETHERTYPE_IPV6:
2025 		return (0);
2026 	}
2027 
2028 	if (etype > ETHERMTU)
2029 		return (1);
2030 
2031 	if (m->m_pkthdr.len <
2032 	    (sizeof(struct ether_header) + LLC_SNAPFRAMELEN))
2033 		return (1);
2034 
2035 	m_copydata(m, sizeof(struct ether_header), LLC_SNAPFRAMELEN,
2036 	    (caddr_t)&llc);
2037 
2038 	etype = ntohs(llc.llc_snap.ether_type);
2039 	if (llc.llc_dsap == LLC_SNAP_LSAP &&
2040 	    llc.llc_ssap == LLC_SNAP_LSAP &&
2041 	    llc.llc_control == LLC_UI &&
2042 	    llc.llc_snap.org_code[0] == 0 &&
2043 	    llc.llc_snap.org_code[1] == 0 &&
2044 	    llc.llc_snap.org_code[2] == 0 &&
2045 	    (etype == ETHERTYPE_ARP || etype == ETHERTYPE_REVARP ||
2046 	    etype == ETHERTYPE_IP || etype == ETHERTYPE_IPV6)) {
2047 		return (0);
2048 	}
2049 
2050 	return (1);
2051 }
2052 
2053 u_int8_t
bridge_filterrule(struct brl_head * h,struct ether_header * eh,struct mbuf * m)2054 bridge_filterrule(struct brl_head *h, struct ether_header *eh, struct mbuf *m)
2055 {
2056 	struct brl_node *n;
2057 	u_int8_t flags;
2058 
2059 	SIMPLEQ_FOREACH(n, h, brl_next) {
2060 		flags = n->brl_flags & (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID);
2061 		if (flags == 0)
2062 			goto return_action;
2063 		if (flags == (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID)) {
2064 			if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN))
2065 				continue;
2066 			if (bcmp(eh->ether_dhost, &n->brl_dst, ETHER_ADDR_LEN))
2067 				continue;
2068 			goto return_action;
2069 		}
2070 		if (flags == BRL_FLAG_SRCVALID) {
2071 			if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN))
2072 				continue;
2073 			goto return_action;
2074 		}
2075 		if (flags == BRL_FLAG_DSTVALID) {
2076 			if (bcmp(eh->ether_dhost, &n->brl_dst, ETHER_ADDR_LEN))
2077 				continue;
2078 			goto return_action;
2079 		}
2080 	}
2081 	return (BRL_ACTION_PASS);
2082 
2083 return_action:
2084 #if NPF > 0
2085 	pf_tag_packet(m, NULL, n->brl_tag);
2086 #endif
2087 	return (n->brl_action);
2088 }
2089 
2090 int
bridge_addrule(struct bridge_iflist * bif,struct ifbrlreq * req,int out)2091 bridge_addrule(struct bridge_iflist *bif, struct ifbrlreq *req, int out)
2092 {
2093 	struct brl_node *n;
2094 
2095 	n = (struct brl_node *)malloc(sizeof(struct brl_node), M_DEVBUF, M_NOWAIT);
2096 	if (n == NULL)
2097 		return (ENOMEM);
2098 	bcopy(&req->ifbr_src, &n->brl_src, sizeof(struct ether_addr));
2099 	bcopy(&req->ifbr_dst, &n->brl_dst, sizeof(struct ether_addr));
2100 	n->brl_action = req->ifbr_action;
2101 	n->brl_flags = req->ifbr_flags;
2102 #if NPF > 0
2103 	if (req->ifbr_tagname[0])
2104 		n->brl_tag = pf_tagname2tag(req->ifbr_tagname);
2105 	else
2106 		n->brl_tag = 0;
2107 #endif
2108 	if (out) {
2109 		n->brl_flags &= ~BRL_FLAG_IN;
2110 		n->brl_flags |= BRL_FLAG_OUT;
2111 		SIMPLEQ_INSERT_TAIL(&bif->bif_brlout, n, brl_next);
2112 	} else {
2113 		n->brl_flags &= ~BRL_FLAG_OUT;
2114 		n->brl_flags |= BRL_FLAG_IN;
2115 		SIMPLEQ_INSERT_TAIL(&bif->bif_brlin, n, brl_next);
2116 	}
2117 	return (0);
2118 }
2119 
2120 int
bridge_flushrule(struct bridge_iflist * bif)2121 bridge_flushrule(struct bridge_iflist *bif)
2122 {
2123 	struct brl_node *p;
2124 
2125 	while (!SIMPLEQ_EMPTY(&bif->bif_brlin)) {
2126 		p = SIMPLEQ_FIRST(&bif->bif_brlin);
2127 		SIMPLEQ_REMOVE_HEAD(&bif->bif_brlin, brl_next);
2128 #if NPF > 0
2129 		pf_tag_unref(p->brl_tag);
2130 #endif
2131 		free(p, M_DEVBUF);
2132 	}
2133 	while (!SIMPLEQ_EMPTY(&bif->bif_brlout)) {
2134 		p = SIMPLEQ_FIRST(&bif->bif_brlout);
2135 		SIMPLEQ_REMOVE_HEAD(&bif->bif_brlout, brl_next);
2136 #if NPF > 0
2137 		pf_tag_unref(p->brl_tag);
2138 #endif
2139 		free(p, M_DEVBUF);
2140 	}
2141 	return (0);
2142 }
2143 
2144 #ifdef IPSEC
2145 int
bridge_ipsec(int dir,int af,int hlen,struct mbuf * m)2146 bridge_ipsec(int dir, int af, int hlen, struct mbuf *m)
2147 {
2148 	union sockaddr_union dst;
2149 	struct timeval tv;
2150 	struct tdb *tdb;
2151 	u_int32_t spi;
2152 	u_int16_t cpi;
2153 	int error, off = 0, s;
2154 	u_int8_t proto = 0;
2155 #ifdef INET
2156 	struct ip *ip;
2157 #endif /* INET */
2158 #ifdef INET6
2159 	struct ip6_hdr *ip6;
2160 #endif /* INET6 */
2161 
2162 	if (dir == BRIDGE_IN) {
2163 		switch (af) {
2164 #ifdef INET
2165 		case AF_INET:
2166 			if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t))
2167 				break;
2168 
2169 			ip = mtod(m, struct ip *);
2170 			proto = ip->ip_p;
2171 			off = offsetof(struct ip, ip_p);
2172 
2173 			if (proto != IPPROTO_ESP && proto != IPPROTO_AH &&
2174 			    proto != IPPROTO_IPCOMP)
2175 				goto skiplookup;
2176 
2177 			bzero(&dst, sizeof(union sockaddr_union));
2178 			dst.sa.sa_family = AF_INET;
2179 			dst.sin.sin_len = sizeof(struct sockaddr_in);
2180 			m_copydata(m, offsetof(struct ip, ip_dst),
2181 			    sizeof(struct in_addr),
2182 			    (caddr_t)&dst.sin.sin_addr);
2183 
2184 			if (ip->ip_p == IPPROTO_ESP)
2185 				m_copydata(m, hlen, sizeof(u_int32_t),
2186 				    (caddr_t)&spi);
2187 			else if (ip->ip_p == IPPROTO_AH)
2188 				m_copydata(m, hlen + sizeof(u_int32_t),
2189 				    sizeof(u_int32_t), (caddr_t)&spi);
2190 			else if (ip->ip_p == IPPROTO_IPCOMP) {
2191 				m_copydata(m, hlen + sizeof(u_int16_t),
2192 				    sizeof(u_int16_t), (caddr_t)&cpi);
2193 				spi = ntohl(htons(cpi));
2194 			}
2195 			break;
2196 #endif /* INET */
2197 #ifdef INET6
2198 		case AF_INET6:
2199 			if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t))
2200 				break;
2201 
2202 			ip6 = mtod(m, struct ip6_hdr *);
2203 
2204 			/* XXX We should chase down the header chain */
2205 			proto = ip6->ip6_nxt;
2206 			off = offsetof(struct ip6_hdr, ip6_nxt);
2207 
2208 			if (proto != IPPROTO_ESP && proto != IPPROTO_AH &&
2209 			    proto != IPPROTO_IPCOMP)
2210 				goto skiplookup;
2211 
2212 			bzero(&dst, sizeof(union sockaddr_union));
2213 			dst.sa.sa_family = AF_INET6;
2214 			dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
2215 			m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt),
2216 			    sizeof(struct in6_addr),
2217 			    (caddr_t)&dst.sin6.sin6_addr);
2218 
2219 			if (proto == IPPROTO_ESP)
2220 				m_copydata(m, hlen, sizeof(u_int32_t),
2221 				    (caddr_t)&spi);
2222 			else if (proto == IPPROTO_AH)
2223 				m_copydata(m, hlen + sizeof(u_int32_t),
2224 				    sizeof(u_int32_t), (caddr_t)&spi);
2225 			else if (proto == IPPROTO_IPCOMP) {
2226 				m_copydata(m, hlen + sizeof(u_int16_t),
2227 				    sizeof(u_int16_t), (caddr_t)&cpi);
2228 				spi = ntohl(htons(cpi));
2229 			}
2230 			break;
2231 #endif /* INET6 */
2232 		default:
2233 			return (0);
2234 		}
2235 
2236 		if (proto == 0)
2237 			goto skiplookup;
2238 
2239 		s = spltdb();
2240 
2241 		tdb = gettdb(spi, &dst, proto);
2242 		if (tdb != NULL && (tdb->tdb_flags & TDBF_INVALID) == 0 &&
2243 		    tdb->tdb_xform != NULL) {
2244 			if (tdb->tdb_first_use == 0) {
2245 				int pri;
2246 
2247 				pri = splhigh();
2248 				tdb->tdb_first_use = time.tv_sec;
2249 				splx(pri);
2250 
2251 				tv.tv_usec = 0;
2252 
2253 				/* Check for wrap-around. */
2254 				if (tdb->tdb_exp_first_use + tdb->tdb_first_use
2255 				    < tdb->tdb_first_use)
2256 					tv.tv_sec = ((unsigned long)-1) / 2;
2257 				else
2258 					tv.tv_sec = tdb->tdb_exp_first_use +
2259 					    tdb->tdb_first_use;
2260 
2261 				if (tdb->tdb_flags & TDBF_FIRSTUSE)
2262 					timeout_add(&tdb->tdb_first_tmo,
2263 					    hzto(&tv));
2264 
2265 				/* Check for wrap-around. */
2266 				if (tdb->tdb_first_use +
2267 				    tdb->tdb_soft_first_use
2268 				    < tdb->tdb_first_use)
2269 					tv.tv_sec = ((unsigned long)-1) / 2;
2270 				else
2271 					tv.tv_sec = tdb->tdb_first_use +
2272 					    tdb->tdb_soft_first_use;
2273 
2274 				if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
2275 					timeout_add(&tdb->tdb_sfirst_tmo,
2276 					    hzto(&tv));
2277 			}
2278 
2279 			(*(tdb->tdb_xform->xf_input))(m, tdb, hlen, off);
2280 			splx(s);
2281 			return (1);
2282 		} else {
2283 			splx(s);
2284  skiplookup:
2285 			/* XXX do an input policy lookup */
2286 			return (0);
2287 		}
2288 	} else { /* Outgoing from the bridge. */
2289 		tdb = ipsp_spd_lookup(m, af, hlen, &error,
2290 		    IPSP_DIRECTION_OUT, NULL, NULL);
2291 		if (tdb != NULL) {
2292 			/*
2293 			 * We don't need to do loop detection, the
2294 			 * bridge will do that for us.
2295 			 */
2296 #if NPF > 0
2297 			switch (af) {
2298 #ifdef INET
2299 			case AF_INET:
2300 				if (pf_test(dir, &encif[0].sc_if,
2301 				    &m) != PF_PASS) {
2302 					m_freem(m);
2303 					return (1);
2304 				}
2305 				break;
2306 #endif /* INET */
2307 #ifdef INET6
2308 			case AF_INET6:
2309 				if (pf_test6(dir, &encif[0].sc_if,
2310 				    &m) != PF_PASS) {
2311 					m_freem(m);
2312 					return (1);
2313 				}
2314 				break;
2315 #endif /* INET6 */
2316 			}
2317 			if (m == NULL)
2318 				return (1);
2319 #endif /* NPF */
2320 			error = ipsp_process_packet(m, tdb, af, 0);
2321 			return (1);
2322 		} else
2323 			return (0);
2324 	}
2325 
2326 	return (0);
2327 }
2328 #endif /* IPSEC */
2329 
2330 #if NPF > 0
2331 /*
2332  * Filter IP packets by peeking into the ethernet frame.  This violates
2333  * the ISO model, but allows us to act as a IP filter at the data link
2334  * layer.  As a result, most of this code will look familiar to those
2335  * who've read net/if_ethersubr.c and netinet/ip_input.c
2336  */
2337 struct mbuf *
bridge_filter(struct bridge_softc * sc,int dir,struct ifnet * ifp,struct ether_header * eh,struct mbuf * m)2338 bridge_filter(struct bridge_softc *sc, int dir, struct ifnet *ifp,
2339     struct ether_header *eh, struct mbuf *m)
2340 {
2341 	struct llc llc;
2342 	int hassnap = 0;
2343 	struct ip *ip;
2344 	int hlen;
2345 	u_int16_t etype;
2346 
2347 	etype = ntohs(eh->ether_type);
2348 
2349 	if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) {
2350 		if (etype > ETHERMTU ||
2351 		    m->m_pkthdr.len < (LLC_SNAPFRAMELEN +
2352 		    sizeof(struct ether_header)))
2353 			return (m);
2354 
2355 		m_copydata(m, sizeof(struct ether_header),
2356 		    LLC_SNAPFRAMELEN, (caddr_t)&llc);
2357 
2358 		if (llc.llc_dsap != LLC_SNAP_LSAP ||
2359 		    llc.llc_ssap != LLC_SNAP_LSAP ||
2360 		    llc.llc_control != LLC_UI ||
2361 		    llc.llc_snap.org_code[0] ||
2362 		    llc.llc_snap.org_code[1] ||
2363 		    llc.llc_snap.org_code[2])
2364 			return (m);
2365 
2366 		etype = ntohs(llc.llc_snap.ether_type);
2367 		if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6)
2368 			return (m);
2369 		hassnap = 1;
2370 	}
2371 
2372 	m_adj(m, sizeof(struct ether_header));
2373 	if (hassnap)
2374 		m_adj(m, LLC_SNAPFRAMELEN);
2375 
2376 	switch (etype) {
2377 
2378 	case ETHERTYPE_IP:
2379 		if (m->m_pkthdr.len < sizeof(struct ip))
2380 			goto dropit;
2381 
2382 		/* Copy minimal header, and drop invalids */
2383 		if (m->m_len < sizeof(struct ip) &&
2384 		    (m = m_pullup(m, sizeof(struct ip))) == NULL) {
2385 			ipstat.ips_toosmall++;
2386 			return (NULL);
2387 		}
2388 		ip = mtod(m, struct ip *);
2389 
2390 		if (ip->ip_v != IPVERSION) {
2391 			ipstat.ips_badvers++;
2392 			goto dropit;
2393 		}
2394 
2395 		hlen = ip->ip_hl << 2;	/* get whole header length */
2396 		if (hlen < sizeof(struct ip)) {
2397 			ipstat.ips_badhlen++;
2398 			goto dropit;
2399 		}
2400 
2401 		if (hlen > m->m_len) {
2402 			if ((m = m_pullup(m, hlen)) == NULL) {
2403 				ipstat.ips_badhlen++;
2404 				return (NULL);
2405 			}
2406 			ip = mtod(m, struct ip *);
2407 		}
2408 
2409 		if ((ip->ip_sum = in_cksum(m, hlen)) != 0) {
2410 			ipstat.ips_badsum++;
2411 			goto dropit;
2412 		}
2413 
2414 		if (ntohs(ip->ip_len) < hlen)
2415 			goto dropit;
2416 
2417 		if (m->m_pkthdr.len < ntohs(ip->ip_len))
2418 			goto dropit;
2419 		if (m->m_pkthdr.len > ntohs(ip->ip_len)) {
2420 			if (m->m_len == m->m_pkthdr.len) {
2421 				m->m_len = ntohs(ip->ip_len);
2422 				m->m_pkthdr.len = ntohs(ip->ip_len);
2423 			} else
2424 				m_adj(m, ntohs(ip->ip_len) - m->m_pkthdr.len);
2425 		}
2426 
2427 #ifdef IPSEC
2428 		if ((sc->sc_if.if_flags & IFF_LINK2) == IFF_LINK2 &&
2429 		    bridge_ipsec(dir, AF_INET, hlen, m))
2430 			return (NULL);
2431 #endif /* IPSEC */
2432 
2433 #if NPF > 0
2434 		/* Finally, we get to filter the packet! */
2435 		m->m_pkthdr.rcvif = ifp;
2436 		if (pf_test_eh(dir, ifp, &m, eh) != PF_PASS)
2437 			goto dropit;
2438 		if (m == NULL)
2439 			goto dropit;
2440 #endif /* NPF */
2441 
2442 		/* Rebuild the IP header */
2443 		if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL))
2444 			return (NULL);
2445 		if (m->m_len < sizeof(struct ip))
2446 			goto dropit;
2447 		ip = mtod(m, struct ip *);
2448 		ip->ip_sum = 0;
2449 		ip->ip_sum = in_cksum(m, hlen);
2450 
2451 		break;
2452 
2453 #ifdef INET6
2454 	case ETHERTYPE_IPV6: {
2455 		struct ip6_hdr *ip6;
2456 
2457 		if (m->m_len < sizeof(struct ip6_hdr)) {
2458 			if ((m = m_pullup(m, sizeof(struct ip6_hdr)))
2459 			    == NULL) {
2460 				ip6stat.ip6s_toosmall++;
2461 				return (NULL);
2462 			}
2463 		}
2464 
2465 		ip6 = mtod(m, struct ip6_hdr *);
2466 
2467 		if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
2468 			ip6stat.ip6s_badvers++;
2469 			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
2470 			goto dropit;
2471 		}
2472 
2473 #ifdef IPSEC
2474 		hlen = sizeof(struct ip6_hdr);
2475 
2476 		if ((sc->sc_if.if_flags & IFF_LINK2) == IFF_LINK2 &&
2477 		    bridge_ipsec(dir, AF_INET6, hlen, m))
2478 			return (NULL);
2479 #endif /* IPSEC */
2480 
2481 #if NPF > 0
2482 		if (pf_test6_eh(dir, ifp, &m, eh) != PF_PASS)
2483 			goto dropit;
2484 		if (m == NULL)
2485 			return (NULL);
2486 #endif /* NPF */
2487 
2488 		break;
2489 	}
2490 #endif /* INET6 */
2491 
2492 	default:
2493 		goto dropit;
2494 		break;
2495 	}
2496 
2497 	/* Reattach SNAP header */
2498 	if (hassnap) {
2499 		M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
2500 		if (m == NULL)
2501 			goto dropit;
2502 		bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
2503 	}
2504 
2505 	/* Reattach ethernet header */
2506 	M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
2507 	if (m == NULL)
2508 		goto dropit;
2509 	bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
2510 
2511 	return (m);
2512 
2513 dropit:
2514 	if (m != NULL)
2515 		m_freem(m);
2516 	return (NULL);
2517 }
2518 #endif /* NPF > 0 */
2519 
2520 void
bridge_fragment(struct bridge_softc * sc,struct ifnet * ifp,struct ether_header * eh,struct mbuf * m)2521 bridge_fragment(struct bridge_softc *sc, struct ifnet *ifp,
2522     struct ether_header *eh, struct mbuf *m)
2523 {
2524 	struct llc llc;
2525 	struct mbuf *m0;
2526 	int s, len, error = 0;
2527 	int hassnap = 0;
2528 #ifdef INET
2529 	u_int16_t etype;
2530 	struct ip *ip;
2531 #endif
2532 
2533 #ifndef INET
2534 	goto dropit;
2535 #else
2536 	etype = ntohs(eh->ether_type);
2537 #if NVLAN > 0
2538 	if (etype == ETHERTYPE_8021Q &&
2539 	    (ifp->if_capabilities & IFCAP_VLAN_MTU) &&
2540 	    ((m->m_pkthdr.len - sizeof(struct ether_vlan_header)) <=
2541 	    ifp->if_mtu)) {
2542 		s = splimp();
2543 		bridge_ifenqueue(sc, ifp, m);
2544 		splx(s);
2545 		return;
2546 	}
2547 #endif
2548 	if (etype != ETHERTYPE_IP) {
2549 		if (etype > ETHERMTU ||
2550 		    m->m_pkthdr.len < (LLC_SNAPFRAMELEN +
2551 		    sizeof(struct ether_header)))
2552 			goto dropit;
2553 
2554 		m_copydata(m, sizeof(struct ether_header),
2555 		    LLC_SNAPFRAMELEN, (caddr_t)&llc);
2556 
2557 		if (llc.llc_dsap != LLC_SNAP_LSAP ||
2558 		    llc.llc_ssap != LLC_SNAP_LSAP ||
2559 		    llc.llc_control != LLC_UI ||
2560 		    llc.llc_snap.org_code[0] ||
2561 		    llc.llc_snap.org_code[1] ||
2562 		    llc.llc_snap.org_code[2] ||
2563 		    llc.llc_snap.ether_type != htons(ETHERTYPE_IP))
2564 			goto dropit;
2565 
2566 		hassnap = 1;
2567 	}
2568 
2569 	m_adj(m, sizeof(struct ether_header));
2570 	if (hassnap)
2571 		m_adj(m, LLC_SNAPFRAMELEN);
2572 
2573 	if (m->m_len < sizeof(struct ip) &&
2574 	    (m = m_pullup(m, sizeof(struct ip))) == NULL)
2575 		goto dropit;
2576 	ip = mtod(m, struct ip *);
2577 
2578 	/* Respect IP_DF, return a ICMP_UNREACH_NEEDFRAG. */
2579 	if (ip->ip_off & htons(IP_DF)) {
2580 		bridge_send_icmp_err(sc, ifp, eh, m, hassnap, &llc,
2581 		    ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG);
2582 		return;
2583 	}
2584 
2585 	error = ip_fragment(m, ifp, ifp->if_mtu);
2586 	if (error) {
2587 		m = NULL;
2588 		goto dropit;
2589 	}
2590 
2591 	for (; m; m = m0) {
2592 		m0 = m->m_nextpkt;
2593 		m->m_nextpkt = NULL;
2594 		if (error == 0) {
2595 			if (hassnap) {
2596 				M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
2597 				if (m == NULL) {
2598 					error = ENOBUFS;
2599 					continue;
2600 				}
2601 				bcopy(&llc, mtod(m, caddr_t),
2602 				    LLC_SNAPFRAMELEN);
2603 			}
2604 			M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
2605 			if (m == NULL) {
2606 				error = ENOBUFS;
2607 				continue;
2608 			}
2609 			len = m->m_pkthdr.len;
2610 			bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
2611 			s = splimp();
2612 			error = bridge_ifenqueue(sc, ifp, m);
2613 			if (error) {
2614 				splx(s);
2615 				continue;
2616 			}
2617 			splx(s);
2618 		} else
2619 			m_freem(m);
2620 	}
2621 
2622 	if (error == 0)
2623 		ipstat.ips_fragmented++;
2624 
2625 	return;
2626 #endif /* INET */
2627  dropit:
2628 	if (m != NULL)
2629 		m_freem(m);
2630 }
2631 
2632 int
bridge_ifenqueue(struct bridge_softc * sc,struct ifnet * ifp,struct mbuf * m)2633 bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m)
2634 {
2635 	int error, len;
2636 	short mflags;
2637 
2638 	len = m->m_pkthdr.len;
2639 	mflags = m->m_flags;
2640 	IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
2641 	if (error) {
2642 		sc->sc_if.if_oerrors++;
2643 		return (error);
2644 	}
2645 	sc->sc_if.if_opackets++;
2646 	sc->sc_if.if_obytes += len;
2647 	ifp->if_obytes += len;
2648 	if (mflags & M_MCAST)
2649 		ifp->if_omcasts++;
2650 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
2651 		(*ifp->if_start)(ifp);
2652 
2653 	return (0);
2654 }
2655 
2656 #ifdef INET
2657 void
bridge_send_icmp_err(struct bridge_softc * sc,struct ifnet * ifp,struct ether_header * eh,struct mbuf * n,int hassnap,struct llc * llc,int type,int code)2658 bridge_send_icmp_err(struct bridge_softc *sc, struct ifnet *ifp,
2659     struct ether_header *eh, struct mbuf *n, int hassnap, struct llc *llc,
2660     int type, int code)
2661 {
2662 	struct ip *ip;
2663 	struct icmp *icp;
2664 	struct in_addr t;
2665 	struct mbuf *m, *n2;
2666 	int hlen;
2667 	u_int8_t ether_tmp[ETHER_ADDR_LEN];
2668 
2669 	n2 = m_copym(n, 0, M_COPYALL, M_DONTWAIT);
2670 	if (!n2) {
2671 		m_freem(n);
2672 		return;
2673 	}
2674 	m = icmp_do_error(n, type, code, 0, ifp);
2675 	if (m == NULL) {
2676 		m_freem(n2);
2677 		return;
2678 	}
2679 
2680 	n = n2;
2681 
2682 	ip = mtod(m, struct ip *);
2683 	hlen = ip->ip_hl << 2;
2684 	t = ip->ip_dst;
2685 	ip->ip_dst = ip->ip_src;
2686 	ip->ip_src = t;
2687 
2688 	m->m_data += hlen;
2689 	m->m_len -= hlen;
2690 	icp = mtod(m, struct icmp *);
2691 	icp->icmp_cksum = 0;
2692 	icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen);
2693 	m->m_data -= hlen;
2694 	m->m_len += hlen;
2695 
2696 	ip->ip_v = IPVERSION;
2697 	ip->ip_off &= htons(IP_DF);
2698 	ip->ip_id = htons(ip_randomid());
2699 	ip->ip_ttl = MAXTTL;
2700 	ip->ip_sum = 0;
2701 	ip->ip_sum = in_cksum(m, hlen);
2702 
2703 	/* Swap ethernet addresses */
2704 	bcopy(&eh->ether_dhost, &ether_tmp, sizeof(ether_tmp));
2705 	bcopy(&eh->ether_shost, &eh->ether_dhost, sizeof(ether_tmp));
2706 	bcopy(&ether_tmp, &eh->ether_shost, sizeof(ether_tmp));
2707 
2708 	/* Reattach SNAP header */
2709 	if (hassnap) {
2710 		M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
2711 		if (m == NULL)
2712 			goto dropit;
2713 		bcopy(llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN);
2714 	}
2715 
2716 	/* Reattach ethernet header */
2717 	M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
2718 	if (m == NULL)
2719 		goto dropit;
2720 	bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
2721 
2722 	bridge_output(ifp, m, NULL, NULL);
2723 	m_freem(n);
2724 	return;
2725 
2726  dropit:
2727 	m_freem(n);
2728 }
2729 #endif
2730