2 * Copyright (c) 1998-2001 Luigi Rizzo
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * This code implements bridging in FreeBSD. It only acts on ethernet
30 * type of interfaces (others are still usable for routing).
31 * A bridging table holds the source MAC address/dest. interface for each
32 * known node. The table is indexed using an hash of the source address.
34 * Input packets are tapped near the beginning of ether_input(), and
35 * analysed by calling bridge_in(). Depending on the result, the packet
36 * can be forwarded to one or more output interfaces using bdg_forward(),
37 * and/or sent to the upper layer (e.g. in case of multicast).
39 * Output packets are intercepted near the end of ether_output(),
40 * the correct destination is selected calling bridge_dst_lookup(),
41 * and then forwarding is done using bdg_forward().
42 * Bridging is controlled by the sysctl variable net.link.ether.bridge
44 * The arp code is also modified to let a machine answer to requests
45 * irrespective of the port the request came from.
47 * In case of loops in the bridging topology, the bridge detects this
48 * event and temporarily mutes output bridging on one of the ports.
49 * Periodically, interfaces are unmuted by bdg_timeout().
50 * Muting is only implemented as a safety measure, and also as
51 * a mechanism to support a user-space implementation of the spanning
52 * tree algorithm. In the final release, unmuting will only occur
53 * because of explicit action of the user-level daemon.
55 * To build a bridging kernel, use the following option
57 * and then at runtime set the sysctl variable to enable bridging.
59 * Only one interface is supposed to have addresses set (but
60 * there are no problems in practice if you set addresses for more
61 * than one interface).
62 * Bridging will act before routing, but nothing prevents a machine
63 * from doing both (modulo bugs in the implementation...).
66 * - bridging is incompatible with multicast routing on the same
67 * machine. There is not an easy fix to this.
68 * - loop detection is still not very robust.
69 * - the interface of bdg_forward() could be improved.
72 #include <sys/param.h>
74 #include <sys/malloc.h>
75 #include <sys/systm.h>
76 #include <sys/socket.h> /* for net/if.h */
77 #include <sys/ctype.h> /* string functions */
78 #include <sys/kernel.h>
79 #include <sys/sysctl.h>
82 #include <net/if_types.h>
84 #include <netinet/in.h> /* for struct arpcom */
85 #include <netinet/in_systm.h>
86 #include <netinet/in_var.h>
87 #include <netinet/ip.h>
88 #include <netinet/if_ether.h> /* for struct arpcom */
90 #include <net/route.h>
91 #include <netinet/ip_fw.h>
92 #include <netinet/ip_dummynet.h>
93 #include <net/bridge.h>
95 static struct ifnet *bridge_in(struct ifnet *, struct ether_header *);
96 static struct mbuf *bdg_forward(struct mbuf *,
97 struct ether_header *const, struct ifnet *);
98 static void bdgtakeifaces(void);
101 * For debugging, you can use the following macros.
102 * remember, rdtsc() only works on Pentium-class machines
105 DDB(ticks = rdtsc();)
106 ... interesting code ...
107 DDB(bdg_fw_ticks += (u_long)(rdtsc() - ticks) ; bdg_fw_count++ ;)
115 static int bdginit(void);
116 static void flush_table(void);
117 static void bdg_promisc_on(void);
118 static void parse_bdg_cfg(void);
120 static int bdg_ipfw = 0 ;
121 static bdg_hash_table *bdg_table = NULL ;
123 static char *bdg_dst_names[] = {
135 * System initialization
138 static struct bdg_stats bdg_stats ;
139 static struct callout_handle bdg_timeout_h ;
141 #define IFP_CHK(ifp, x) \
142 if (ifp2sc[ifp->if_index].magic != 0xDEADBEEF) { x ; }
145 * Find the right pkt destination:
146 * BDG_BCAST is a broadcast
147 * BDG_MCAST is a multicast
148 * BDG_LOCAL is for a local address
149 * BDG_DROP must be dropped
150 * other ifp of the dest. interface (incl.self)
152 * We assume this is only called for interfaces for which bridging
153 * is enabled, i.e. BDG_USED(ifp) is true.
157 bridge_dst_lookup(struct ether_header *eh)
163 if (IS_ETHER_BROADCAST(eh->ether_dhost))
165 if (eh->ether_dhost[0] & 1)
168 * Lookup local addresses in case one matches.
170 for (index = bdg_ports, p = bdg_addresses ; index ; index--, p++ )
171 if (BDG_MATCH(p->etheraddr, eh->ether_dhost) )
174 * Look for a possible destination in table
176 index= HASH_FN( eh->ether_dhost );
177 dst = bdg_table[index].name;
178 if ( dst && BDG_MATCH( bdg_table[index].etheraddr, eh->ether_dhost) )
184 * turn off promisc mode, optionally clear the IFF_USED flag.
185 * The flag is turned on by parse_bdg_config
188 bdg_promisc_off(int clear_used)
191 TAILQ_FOREACH(ifp, &ifnet, if_link) {
192 if ( (ifp2sc[ifp->if_index].flags & IFF_BDG_PROMISC) ) {
195 ret = ifpromisc(ifp, 0);
197 ifp2sc[ifp->if_index].flags &= ~(IFF_BDG_PROMISC|IFF_MUTE) ;
198 DEB(printf(">> now %s%d promisc OFF if_flags 0x%x bdg_flags 0x%x\n",
199 ifp->if_name, ifp->if_unit,
200 ifp->if_flags, ifp2sc[ifp->if_index].flags);)
203 ifp2sc[ifp->if_index].flags &= ~(IFF_USED) ;
204 bdg_stats.s[ifp->if_index].name[0] = '\0';
210 * set promisc mode on the interfaces we use.
218 TAILQ_FOREACH(ifp, &ifnet, if_link) {
219 if ( !BDG_USED(ifp) )
221 if ( 0 == ( ifp->if_flags & IFF_UP) ) {
226 if ( !(ifp2sc[ifp->if_index].flags & IFF_BDG_PROMISC) ) {
229 ret = ifpromisc(ifp, 1);
231 ifp2sc[ifp->if_index].flags |= IFF_BDG_PROMISC ;
232 printf(">> now %s%d promisc ON if_flags 0x%x bdg_flags 0x%x\n",
233 ifp->if_name, ifp->if_unit,
234 ifp->if_flags, ifp2sc[ifp->if_index].flags);
236 if (BDG_MUTED(ifp)) {
237 printf(">> unmuting %s%d\n", ifp->if_name, ifp->if_unit);
244 sysctl_bdg(SYSCTL_HANDLER_ARGS)
246 int error, oldval = do_bridge ;
248 error = sysctl_handle_int(oidp,
249 oidp->oid_arg1, oidp->oid_arg2, req);
250 DEB( printf("called sysctl for bridge name %s arg2 %d val %d->%d\n",
251 oidp->oid_name, oidp->oid_arg2,
252 oldval, do_bridge); )
254 if (oldval != do_bridge) {
255 bdg_promisc_off( 1 ); /* reset previously used interfaces */
265 static char bridge_cfg[256] = { "" } ;
268 * parse the config string, set IFF_USED, name and cluster_id
269 * for all interfaces found.
270 * The config string is a list of "if[:cluster]" with
271 * a number of possible separators (see "sep").
279 static char *sep = ", \t";
281 for (p = bridge_cfg; *p ; p++) {
282 if (index(sep, *p)) /* skip separators */
284 /* names are lowercase and digits */
285 for ( beg = p ; islower(*p) || isdigit(*p) ; p++ )
287 l = p - beg ; /* length of name string */
288 if (l == 0) /* invalid name */
290 if ( *p != ':' ) /* no ':', assume default cluster 1 */
292 else /* fetch cluster */
293 cluster = strtoul( p+1, &p, 10);
295 * now search in bridge strings
297 for (i=0, b = ifp2sc ; i < if_index ; i++, b++) {
299 struct ifnet *ifp = b->ifp ;
303 sprintf(buf, "%s%d", ifp->if_name, ifp->if_unit);
304 if (!strncmp(beg, buf, l)) {
305 b->cluster_id = htons(cluster) ;
306 b->flags |= IFF_USED ;
307 sprintf(bdg_stats.s[ifp->if_index].name,
308 "%s%d:%d", ifp->if_name, ifp->if_unit, cluster);
310 DEB(printf("--++ found %s\n",
311 bdg_stats.s[ifp->if_index].name);)
319 sysctl_bdg_cfg(SYSCTL_HANDLER_ARGS)
324 strcpy(oldval, bridge_cfg) ;
326 error = sysctl_handle_string(oidp,
327 bridge_cfg, oidp->oid_arg2, req);
329 printf("called sysctl for bridge name %s arg2 %d err %d val %s->%s\n",
330 oidp->oid_name, oidp->oid_arg2,
334 if (strcmp(oldval, bridge_cfg)) {
335 bdg_promisc_off( 1 ); /* reset previously-used interfaces */
337 parse_bdg_cfg(); /* and set new ones... */
339 bdg_promisc_on(); /* re-enable interfaces */
345 sysctl_refresh(SYSCTL_HANDLER_ARGS)
354 SYSCTL_DECL(_net_link_ether);
355 SYSCTL_PROC(_net_link_ether, OID_AUTO, bridge_cfg, CTLTYPE_STRING|CTLFLAG_RW,
356 &bridge_cfg, sizeof(bridge_cfg), &sysctl_bdg_cfg, "A",
357 "Bridge configuration");
359 SYSCTL_PROC(_net_link_ether, OID_AUTO, bridge, CTLTYPE_INT|CTLFLAG_RW,
360 &do_bridge, 0, &sysctl_bdg, "I", "Bridging");
362 SYSCTL_INT(_net_link_ether, OID_AUTO, bridge_ipfw, CTLFLAG_RW,
363 &bdg_ipfw,0,"Pass bridged pkts through firewall");
366 * The follow macro declares a variable, and maps it to
367 * a SYSCTL_INT entry with the same name.
369 #define SY(parent, var, comment) \
371 SYSCTL_INT(parent, OID_AUTO, var, CTLFLAG_RW, &(var), 0, comment);
374 SYSCTL_INT(_net_link_ether, OID_AUTO, bridge_ipfw_drop,
375 CTLFLAG_RW, &bdg_ipfw_drops,0,"");
378 SYSCTL_INT(_net_link_ether, OID_AUTO, bridge_ipfw_collisions,
379 CTLFLAG_RW, &bdg_ipfw_colls,0,"");
381 SYSCTL_PROC(_net_link_ether, OID_AUTO, bridge_refresh, CTLTYPE_INT|CTLFLAG_WR,
382 NULL, 0, &sysctl_refresh, "I", "iface refresh");
384 #if 1 /* diagnostic vars */
386 SY(_net_link_ether, verbose, "Be verbose");
387 SY(_net_link_ether, bdg_split_pkts, "Packets split in bdg_forward");
389 SY(_net_link_ether, bdg_thru, "Packets through bridge");
391 SY(_net_link_ether, bdg_copied, "Packets copied in bdg_forward");
393 SY(_net_link_ether, bdg_copy, "Force copy in bdg_forward");
394 SY(_net_link_ether, bdg_predict, "Correctly predicted header location");
396 SY(_net_link_ether, bdg_fw_avg, "Cycle counter avg");
397 SY(_net_link_ether, bdg_fw_ticks, "Cycle counter item");
398 SY(_net_link_ether, bdg_fw_count, "Cycle counter count");
401 SYSCTL_STRUCT(_net_link_ether, PF_BDG, bdgstats,
402 CTLFLAG_RD, &bdg_stats , bdg_stats, "bridge statistics");
404 static int bdg_loops ;
407 * completely flush the bridge table.
415 for (i=0; i< HASH_SIZE; i++)
416 bdg_table[i].name= NULL; /* clear table */
421 * called periodically to flush entries etc.
424 bdg_timeout(void *dummy)
426 static int slowtimer = 0 ;
429 static int age_index = 0 ; /* index of table position to age */
430 int l = age_index + HASH_SIZE/4 ;
432 * age entries in the forwarding table.
436 for (; age_index < l ; age_index++)
437 if (bdg_table[age_index].used)
438 bdg_table[age_index].used = 0 ;
439 else if (bdg_table[age_index].name) {
440 /* printf("xx flushing stale entry %d\n", age_index); */
441 bdg_table[age_index].name = NULL ;
443 if (age_index >= HASH_SIZE)
446 if (--slowtimer <= 0 ) {
449 bdg_promisc_on() ; /* we just need unmute, really */
453 bdg_timeout_h = timeout(bdg_timeout, NULL, 2*hz );
457 * local MAC addresses are held in a small array. This makes comparisons
460 bdg_addr bdg_addresses[BDG_MAX_PORTS];
461 static int bdg_ports ;
462 static int bdg_max_ports = BDG_MAX_PORTS ;
465 * initialization of bridge code. This needs to be done after all
466 * interfaces have been configured.
471 bdg_table = (struct hash_table *)
472 malloc(HASH_SIZE * sizeof(struct hash_table),
473 M_IFADDR, M_WAITOK | M_ZERO);
474 if (bdg_table == NULL)
476 ifp2sc = malloc(BDG_MAX_PORTS * sizeof(struct bdg_softc),
477 M_IFADDR, M_WAITOK | M_ZERO );
478 if (ifp2sc == NULL) {
479 free(bdg_table, M_IFADDR);
484 bridge_in_ptr = bridge_in;
485 bdg_forward_ptr = bdg_forward;
486 bdgtakeifaces_ptr = bdgtakeifaces;
490 bzero(&bdg_stats, sizeof(bdg_stats) );
498 * fetch interfaces that can do bridging.
499 * This is re-done every time we attach or detach an interface.
506 bdg_addr *p = bdg_addresses ;
507 struct bdg_softc *bp;
511 printf("BRIDGE 011031, have %d interfaces\n", if_index);
512 TAILQ_FOREACH(ifp, &ifnet, if_link)
513 if (ifp->if_type == IFT_ETHER) { /* ethernet ? */
515 * XXX should try to grow the arrays as needed.
517 bp = &ifp2sc[ifp->if_index] ;
518 ac = (struct arpcom *)ifp;
519 sprintf(bridge_cfg + strlen(bridge_cfg),
520 "%s%d:1,", ifp->if_name, ifp->if_unit);
521 printf("-- index %d %s type %d phy %d addrl %d addr %6D\n",
523 bdg_stats.s[ifp->if_index].name,
524 (int)ifp->if_type, (int) ifp->if_physical,
525 (int)ifp->if_addrlen,
526 ac->ac_enaddr, "." );
527 bcopy(ac->ac_enaddr, p->etheraddr, 6);
530 bp->flags = IFF_USED ;
531 bp->cluster_id = htons(1) ;
532 bp->magic = 0xDEADBEEF ;
534 sprintf(bdg_stats.s[ifp->if_index].name,
535 "%s%d:%d", ifp->if_name, ifp->if_unit,
536 ntohs(bp->cluster_id));
543 * bridge_in() is invoked to perform bridging decision on input packets.
546 * eh Ethernet header of the incoming packet. We only need this.
548 * On Return: destination of packet, one of
549 * BDG_BCAST broadcast
550 * BDG_MCAST multicast
551 * BDG_LOCAL is only for a local address (do not forward)
552 * BDG_DROP drop the packet
553 * ifp ifp of the destination interface.
555 * Forwarding is not done directly to give a chance to some drivers
556 * to fetch more of the packet, or simply drop it completely.
559 static struct ifnet *
560 bridge_in(struct ifnet *ifp, struct ether_header *eh)
563 struct ifnet *dst , *old ;
564 int dropit = BDG_MUTED(ifp) ;
567 * hash the source address
569 index= HASH_FN(eh->ether_shost);
570 bdg_table[index].used = 1 ;
571 old = bdg_table[index].name ;
572 if ( old ) { /* the entry is valid. */
573 IFP_CHK(old, printf("bridge_in-- reading table\n") );
575 if (!BDG_MATCH( eh->ether_shost, bdg_table[index].etheraddr) ) {
577 bdg_table[index].name = NULL ;
578 } else if (old != ifp) {
580 * Found a loop. Either a machine has moved, or there
581 * is a misconfiguration/reconfiguration of the network.
582 * First, do not forward this packet!
583 * Record the relocation anyways; then, if loops persist,
584 * suspect a reconfiguration and disable forwarding
585 * from the old interface.
587 bdg_table[index].name = ifp ; /* relocate address */
588 printf("-- loop (%d) %6D to %s%d from %s%d (%s)\n",
589 bdg_loops, eh->ether_shost, ".",
590 ifp->if_name, ifp->if_unit,
591 old->if_name, old->if_unit,
592 BDG_MUTED(old) ? "muted":"active");
594 if ( !BDG_MUTED(old) ) {
595 if (++bdg_loops > 10)
602 * now write the source address into the table
604 if (bdg_table[index].name == NULL) {
605 DEB(printf("new addr %6D at %d for %s%d\n",
606 eh->ether_shost, ".", index, ifp->if_name, ifp->if_unit);)
607 bcopy(eh->ether_shost, bdg_table[index].etheraddr, 6);
608 bdg_table[index].name = ifp ;
610 dst = bridge_dst_lookup(eh);
612 * bridge_dst_lookup can return the following values:
613 * BDG_BCAST, BDG_MCAST, BDG_LOCAL, BDG_UNKNOWN, BDG_DROP, ifp.
614 * For muted interfaces, or when we detect a loop, the first 3 are
615 * changed in BDG_LOCAL (we still listen to incoming traffic),
616 * and others to BDG_DROP (no use for the local host).
617 * Also, for incoming packets, ifp is changed to BDG_DROP if ifp == src.
618 * These changes are not necessary for outgoing packets from ether_output().
620 BDG_STAT(ifp, BDG_IN);
621 switch ((uintptr_t)dst) {
622 case (uintptr_t) BDG_BCAST:
623 case (uintptr_t) BDG_MCAST:
624 case (uintptr_t) BDG_LOCAL:
625 case (uintptr_t) BDG_UNKNOWN:
626 case (uintptr_t) BDG_DROP:
630 if (dst == ifp || dropit)
631 BDG_STAT(ifp, BDG_DROP);
633 BDG_STAT(ifp, BDG_FORWARD);
638 if (dst == BDG_BCAST || dst == BDG_MCAST || dst == BDG_LOCAL)
646 DEB(printf("bridge_in %6D ->%6D ty 0x%04x dst %s%d\n",
647 eh->ether_shost, ".",
648 eh->ether_dhost, ".",
649 ntohs(eh->ether_type),
650 (dst <= BDG_FORWARD) ? bdg_dst_names[(int)dst] :
652 (dst <= BDG_FORWARD) ? 0 : dst->if_unit); )
658 * Forward a packet to dst -- which can be a single interface or
659 * an entire cluster. The src port and muted interfaces are excluded.
661 * If src == NULL, the pkt comes from ether_output, and dst is the real
662 * interface the packet is originally sent to. In this case, we must forward
663 * it to the whole cluster.
664 * We never call bdg_forward from ether_output on interfaces which are
665 * not part of a cluster.
667 * If possible (i.e. we can determine that the caller does not need
668 * a copy), the packet is consumed here, and bdg_forward returns NULL.
669 * Otherwise, a pointer to a copy of the packet is returned.
671 * XXX be careful with eh, it can be a pointer into *m
674 bdg_forward(struct mbuf *m0, struct ether_header *const eh, struct ifnet *dst)
676 struct ifnet *src = m0->m_pkthdr.rcvif; /* NULL when called by *_output */
677 struct ifnet *ifp, *last = NULL ;
678 int shared = bdg_copy ; /* someone else is using the mbuf */
679 int once = 0; /* loop only once */
680 struct ifnet *real_dst = dst ; /* real dst from ether_output */
681 struct ip_fw *rule = NULL ; /* did we match a firewall rule ? */
684 * XXX eh is usually a pointer within the mbuf (some ethernet drivers
685 * do that), so we better copy it before doing anything with the mbuf,
686 * or we might corrupt the header.
688 struct ether_header save_eh = *eh ;
690 DEB(quad_t ticks; ticks = rdtsc();)
692 if (m0->m_type == MT_DUMMYNET) {
693 /* extract info from dummynet header */
694 rule = (struct ip_fw *)(m0->m_data) ;
696 src = m0->m_pkthdr.rcvif;
697 shared = 0 ; /* For sure this is our own mbuf. */
699 bdg_thru++; /* count packet, only once */
701 if (src == NULL) /* packet from ether_output */
702 dst = bridge_dst_lookup(eh);
704 if (dst == BDG_DROP) { /* this should not happen */
705 printf("xx bdg_forward for BDG_DROP\n");
709 if (dst == BDG_LOCAL) { /* this should not happen as well */
710 printf("xx ouch, bdg_forward for local pkt\n");
713 if (dst == BDG_BCAST || dst == BDG_MCAST || dst == BDG_UNKNOWN) {
714 ifp = TAILQ_FIRST(&ifnet) ; /* scan all ports */
716 if (dst != BDG_UNKNOWN) /* need a copy for the local stack */
722 if (ifp <= BDG_FORWARD)
723 panic("bdg_forward: bad dst");
726 * Do filtering in a very similar way to what is done in ip_output.
727 * Only if firewall is loaded, enabled, and the packet is not
728 * from ether_output() (src==NULL, or we would filter it twice).
729 * Additional restrictions may apply e.g. non-IP, short packets,
730 * and pkts already gone through a pipe.
732 if (IPFW_LOADED && bdg_ipfw != 0 && src != NULL) {
736 if (rule != NULL) /* dummynet packet, already partially processed */
737 goto forward; /* HACK! I should obey the fw_one_pass */
738 if (ntohs(save_eh.ether_type) != ETHERTYPE_IP)
739 goto forward ; /* not an IP packet, ipfw is not appropriate */
740 if (m0->m_pkthdr.len < sizeof(struct ip) )
741 goto forward ; /* header too short for an IP pkt, cannot filter */
743 * i need some amt of data to be contiguous, and in case others need
744 * the packet (shared==1) also better be in the first mbuf.
746 i = min(m0->m_pkthdr.len, max_protohdr) ;
747 if ( shared || m0->m_len < i) {
748 m0 = m_pullup(m0, i) ;
750 printf("-- bdg: pullup failed.\n") ;
756 * before calling the firewall, swap fields the same as IP does.
757 * here we assume the pkt is an IP one and the header is contiguous
759 ip = mtod(m0, struct ip *);
764 * The third parameter to the firewall code is the dst. interface.
765 * Since we apply checks only on input pkts we use NULL.
766 * The firewall knows this is a bridged packet as the cookie ptr
769 i = ip_fw_chk_ptr(&ip, 0, NULL, NULL /* cookie */, &m0, &rule, NULL);
770 if ( (i & IP_FW_PORT_DENY_FLAG) || m0 == NULL) /* drop */
773 * If we get here, the firewall has passed the pkt, but the mbuf
774 * pointer might have changed. Restore ip and the fields NTOHS()'d.
776 ip = mtod(m0, struct ip *);
780 if (i == 0) /* a PASS rule. */
782 if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) {
784 * Pass the pkt to dummynet, which consumes it.
785 * If shared, make a copy and keep the original.
786 * Need to prepend the ethernet header, optimize the common
787 * case of eh pointing already into the original mbuf.
791 m = m_copypacket(m0, M_DONTWAIT);
793 printf("bdg_fwd: copy(1) failed\n");
797 m = m0 ; /* pass the original to dummynet */
798 m0 = NULL ; /* and nothing back to the caller */
800 if ( (void *)(eh + 1) == (void *)m->m_data) {
801 m->m_data -= ETHER_HDR_LEN ;
802 m->m_len += ETHER_HDR_LEN ;
803 m->m_pkthdr.len += ETHER_HDR_LEN ;
806 M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
808 printf("M_PREPEND failed\n");
809 if (m == NULL) /* nope... */
811 bcopy(&save_eh, mtod(m, struct ether_header *), ETHER_HDR_LEN);
813 ip_dn_io_ptr((i & 0xffff),DN_TO_BDG_FWD,m,real_dst,NULL,0,rule,0);
817 * XXX add divert/forward actions...
819 /* if none of the above matches, we have to drop the pkt */
821 printf("bdg_forward: No rules match, so dropping packet!\n");
826 * Again, bring up the headers in case of shared bufs to avoid
827 * corruptions in the future.
830 int i = min(m0->m_pkthdr.len, max_protohdr) ;
832 m0 = m_pullup(m0, i) ;
834 printf("-- bdg: pullup2 failed.\n") ;
838 /* now real_dst is used to determine the cluster where to forward */
839 if (src != NULL) /* pkt comes from ether_input */
842 if (last) { /* need to forward packet leftover from previous loop */
844 if (shared == 0 && once ) { /* no need to copy */
846 m0 = NULL ; /* original is gone */
848 m = m_copypacket(m0, M_DONTWAIT);
850 printf("bdg_forward: sorry, m_copypacket failed!\n");
851 return m0 ; /* the original is still there... */
855 * Add header (optimized for the common case of eh pointing
856 * already into the mbuf) and execute last part of ether_output:
857 * queue pkt and start output if interface not yet active.
859 if ( (void *)(eh + 1) == (void *)m->m_data) {
860 m->m_data -= ETHER_HDR_LEN ;
861 m->m_len += ETHER_HDR_LEN ;
862 m->m_pkthdr.len += ETHER_HDR_LEN ;
865 M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
867 printf("M_PREPEND failed\n");
870 bcopy(&save_eh, mtod(m, struct ether_header *), ETHER_HDR_LEN);
872 if (! IF_HANDOFF(&last->if_snd, m, last)) {
874 BDG_MUTE(last); /* should I also mute ? */
877 BDG_STAT(last, BDG_OUT);
885 * If the interface is used for bridging, not muted, not full,
886 * up and running, is not the source interface, and belongs to
887 * the same cluster as the 'real_dst', then send here.
889 if ( BDG_USED(ifp) && !BDG_MUTED(ifp) && !_IF_QFULL(&ifp->if_snd) &&
890 (ifp->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING) &&
891 ifp != src && BDG_SAMECLUSTER(ifp, real_dst) )
893 ifp = TAILQ_NEXT(ifp, if_link) ;
897 DEB(bdg_fw_ticks += (u_long)(rdtsc() - ticks) ; bdg_fw_count++ ;
898 if (bdg_fw_count != 0) bdg_fw_avg = bdg_fw_ticks/bdg_fw_count; )
903 * initialization code, both for static and dynamic loading.
906 bridge_modevent(module_t mod, int type, void *unused)
922 #if !defined(KLD_MODULE)
923 printf("bridge statically compiled, cannot unload\n");
928 bridge_in_ptr = NULL;
929 bdg_forward_ptr = NULL;
930 bdgtakeifaces_ptr = NULL;
931 untimeout(bdg_timeout, NULL, bdg_timeout_h);
932 free(bdg_table, M_IFADDR);
934 free(ifp2sc, M_IFADDR);
946 static moduledata_t bridge_mod = {
952 DECLARE_MODULE(bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
953 MODULE_VERSION(bridge, 1);