diff options
author | Luigi Rizzo <luigi@FreeBSD.org> | 1999-03-17 16:44:53 +0000 |
---|---|---|
committer | Luigi Rizzo <luigi@FreeBSD.org> | 1999-03-17 16:44:53 +0000 |
commit | ab090e5b4e4edd2a9d68b95fe2f0184099cdfddc (patch) | |
tree | f509c447987bf41216b92edaa005600e6705fdd5 | |
parent | dfce77f3a9a6be9b2a1c770057641617dc38ed1b (diff) | |
download | src-ab090e5b4e4edd2a9d68b95fe2f0184099cdfddc.tar.gz src-ab090e5b4e4edd2a9d68b95fe2f0184099cdfddc.zip |
MF22... add bridging support to the device drivers. Without this
bridging cannot work on -current/releng3!
Notes
Notes:
svn path=/head/; revision=44829
-rw-r--r-- | sys/dev/de/if_de.c | 23 | ||||
-rw-r--r-- | sys/dev/ed/if_ed.c | 73 | ||||
-rw-r--r-- | sys/dev/fxp/if_fxp.c | 61 | ||||
-rw-r--r-- | sys/dev/lnc/if_lnc.c | 33 | ||||
-rw-r--r-- | sys/i386/isa/if_ed.c | 73 | ||||
-rw-r--r-- | sys/i386/isa/if_lnc.c | 33 | ||||
-rw-r--r-- | sys/pci/if_de.c | 23 | ||||
-rw-r--r-- | sys/pci/if_fxp.c | 61 |
8 files changed, 306 insertions, 74 deletions
diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c index facad1116f11..d9c52f706856 100644 --- a/sys/dev/de/if_de.c +++ b/sys/dev/de/if_de.c @@ -1,5 +1,5 @@ /* $NetBSD: if_de.c,v 1.82 1999/02/28 17:08:51 explorer Exp $ */ -/* $Id: if_de.c,v 1.100 1999/03/13 09:21:27 peter Exp $ */ +/* $Id: if_de.c,v 1.101 1999/03/14 08:32:52 peter Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -124,6 +124,10 @@ #include <pci/dc21040reg.h> #define DEVAR_INCLUDE "pci/if_devar.h" #endif +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/bridge.h> +#endif #endif /* __FreeBSD__ */ #if defined(__bsdi__) @@ -3544,6 +3548,23 @@ tulip_rx_intr( } #endif sc->tulip_flags |= TULIP_RXACT; + +#ifdef BRIDGE /* see code in if_ed.c */ + ms->m_pkthdr.rcvif = ifp; /* XXX */ + ms->m_pkthdr.len = total_len; /* XXX */ + if (do_bridge) { + struct ifnet *bdg_ifp ; + bdg_ifp = bridge_in(ms); + if (bdg_ifp == BDG_DROP) + goto next ; /* and drop */ + if (bdg_ifp != BDG_LOCAL) + bdg_forward(&ms, bdg_ifp); + if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_BCAST && + bdg_ifp != BDG_MCAST) + goto next ; /* and drop */ + /* all others accepted locally */ + } else +#endif if ((sc->tulip_flags & (TULIP_PROMISC|TULIP_HASHONLY)) && (eh.ether_dhost[0] & 1) == 0 && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr)) diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index e7bab24448a9..1408b2b47327 100644 --- a/sys/dev/ed/if_ed.c +++ b/sys/dev/ed/if_ed.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_ed.c,v 1.148 1999/01/19 00:21:38 peter Exp $ + * $Id: if_ed.c,v 1.149 1999/01/28 01:59:53 dillon Exp $ */ /* @@ -68,6 +68,10 @@ #if NBPFILTER > 0 #include <net/bpf.h> #endif +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/bridge.h> +#endif #include <machine/clock.h> #include <machine/md_var.h> @@ -2253,6 +2257,13 @@ ed_rint(sc) len += ((packet_hdr.next_packet - sc->rec_page_start) + (sc->rec_page_stop - sc->next_packet)) * ED_PAGE_SIZE; } + /* + * because buffers are aligned on 256-byte boundary, + * the length computed above is off by 256 in almost + * all cases. Fix it... + */ + if (len & 0xff) + len -= 256 ; if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring))) sc->mibdata.dot3StatsFrameTooLongs++; @@ -2731,6 +2742,42 @@ ed_get_packet(sc, buf, len, multicast) m->m_data += 2; eh = mtod(m, struct ether_header *); +#ifdef BRIDGE + /* + * Get link layer header, invoke brige_in, then + * depending on the outcome of the test fetch the rest of the + * packet and either pass up or call bdg_forward. + */ + if (do_bridge) { + struct ifnet *ifp ; + int need_more = 1 ; /* in case not bpf */ + +#if NBPFILTER > 0 + if (sc->arpcom.ac_if.if_bpf) { + need_more = 0 ; + ed_ring_copy(sc, buf, (char *)eh, len); + bpf_mtap(&sc->arpcom.ac_if, m); + } else +#endif + ed_ring_copy(sc, buf, (char *)eh, 14); + ifp = bridge_in(m); + if (ifp == BDG_DROP) { + m_freem(m); + return ; + } + /* else fetch rest of pkt and continue */ + if (need_more && len > 14) + ed_ring_copy(sc, buf+14, (char *)(eh+1), len - 14); + if (ifp != BDG_LOCAL ) + bdg_forward(&m, ifp); /* not local, need forwarding */ + if (ifp == BDG_LOCAL || ifp == BDG_BCAST || ifp == BDG_MCAST) + goto getit ; + /* not local and not multicast, just drop it */ + if (m) + m_freem(m); + return ; + } +#endif /* * Get packet, including link layer address, from interface. */ @@ -2742,23 +2789,21 @@ ed_get_packet(sc, buf, len, multicast) * Check if there's a BPF listener on this interface. If so, hand off * the raw packet to bpf. */ - if (sc->arpcom.ac_if.if_bpf) { + if (sc->arpcom.ac_if.if_bpf) bpf_mtap(&sc->arpcom.ac_if, m); - - /* - * Note that the interface cannot be in promiscuous mode if - * there are no BPF listeners. And if we are in promiscuous - * mode, we have to check if this packet is really ours. - */ - if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && - bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, +#endif + /* + * If we are in promiscuous mode, we have to check whether + * this packet is really for us. + */ + if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && + bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, sizeof(eh->ether_dhost)) != 0 && multicast == 0) { - m_freem(m); - return; - } + m_freem(m); + return; } -#endif +getit: /* * Remove link layer address. */ diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 79032ac4ca40..65689290d277 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxp.c,v 1.63 1999/02/11 21:47:09 julian Exp $ + * $Id: if_fxp.c,v 1.64 1999/02/12 17:56:23 julian Exp $ */ /* @@ -103,6 +103,12 @@ #endif /* __NetBSD__ */ +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/if_types.h> +#include <net/bridge.h> +#endif + /* * NOTE! On the Alpha, we have an alignment constraint. The * card DMAs the packet immediately following the RFA. However, @@ -1010,31 +1016,50 @@ rcvloop: } m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = - total_len - - sizeof(struct ether_header); + total_len ; eh = mtod(m, struct ether_header *); #if NBPFILTER > 0 - if (ifp->if_bpf) { + if (ifp->if_bpf) bpf_tap(FXP_BPFTAP_ARG(ifp), mtod(m, caddr_t), total_len); - /* - * Only pass this packet up - * if it is for us. - */ - if ((ifp->if_flags & - IFF_PROMISC) && - (rfa->rfa_status & - FXP_RFA_STATUS_IAMATCH) && - (eh->ether_dhost[0] & 1) - == 0) { - m_freem(m); - goto rcvloop; - } - } #endif /* NBPFILTER > 0 */ +#ifdef BRIDGE + if (do_bridge) { + struct ifnet *bdg_ifp ; + bdg_ifp = bridge_in(m); + if (bdg_ifp == BDG_DROP) + goto dropit ; + if (bdg_ifp != BDG_LOCAL) + bdg_forward(&m, bdg_ifp); + if (bdg_ifp != BDG_LOCAL && + bdg_ifp != BDG_BCAST && + bdg_ifp != BDG_MCAST) + goto dropit ; + goto getit ; + } +#endif + /* + * Only pass this packet up + * if it is for us. + */ + if ((ifp->if_flags & + IFF_PROMISC) && + (rfa->rfa_status & + FXP_RFA_STATUS_IAMATCH) && + (eh->ether_dhost[0] & 1) + == 0) { +dropit: + if (m) + m_freem(m); + goto rcvloop; + } +getit: m->m_data += sizeof(struct ether_header); + m->m_len -= + sizeof(struct ether_header); + m->m_pkthdr.len = m->m_len ; ether_input(ifp, eh, m); } goto rcvloop; diff --git a/sys/dev/lnc/if_lnc.c b/sys/dev/lnc/if_lnc.c index 2efa620e0e0a..2c49cac17bc4 100644 --- a/sys/dev/lnc/if_lnc.c +++ b/sys/dev/lnc/if_lnc.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_lnc.c,v 1.52 1999/01/31 00:39:20 paul Exp $ + * $Id: if_lnc.c,v 1.53 1999/01/31 00:44:37 paul Exp $ */ /* @@ -92,6 +92,11 @@ #include <net/bpf.h> #endif +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/bridge.h> +#endif + #ifdef PC98 #include <machine/clock.h> #endif @@ -597,7 +602,7 @@ lnc_rint(struct lnc_softc *sc) * ethernet and packet headers */ head->m_pkthdr.rcvif = &sc->arpcom.ac_if; - head->m_pkthdr.len = pkt_len - sizeof *eh; + head->m_pkthdr.len = pkt_len ; /* * BPF expects the ether header to be in the first @@ -611,7 +616,26 @@ lnc_rint(struct lnc_softc *sc) #if NBPFILTER > 0 if (sc->arpcom.ac_if.if_bpf) bpf_mtap(&sc->arpcom.ac_if, head); - +#endif +#ifdef BRIDGE + if (do_bridge) { + struct ifnet *bdg_ifp ; + + bdg_ifp = bridge_in(head); + if (bdg_ifp == BDG_DROP) + m_freem(head); + else { + if (bdg_ifp != BDG_LOCAL) + bdg_forward(&head, bdg_ifp); + if ( bdg_ifp == BDG_LOCAL || + bdg_ifp == BDG_BCAST || + bdg_ifp == BDG_MCAST ) + goto getit; + else if (head) + m_freem(head); + } + } else +#endif /* Check this packet is really for us */ if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && @@ -620,11 +644,12 @@ lnc_rint(struct lnc_softc *sc) sizeof(eh->ether_dhost)))) m_freem(head); else -#endif { +getit: /* Skip over the ether header */ head->m_data += sizeof *eh; head->m_len -= sizeof *eh; + head->m_pkthdr.len -= sizeof *eh; ether_input(&sc->arpcom.ac_if, eh, head); } diff --git a/sys/i386/isa/if_ed.c b/sys/i386/isa/if_ed.c index e7bab24448a9..1408b2b47327 100644 --- a/sys/i386/isa/if_ed.c +++ b/sys/i386/isa/if_ed.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_ed.c,v 1.148 1999/01/19 00:21:38 peter Exp $ + * $Id: if_ed.c,v 1.149 1999/01/28 01:59:53 dillon Exp $ */ /* @@ -68,6 +68,10 @@ #if NBPFILTER > 0 #include <net/bpf.h> #endif +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/bridge.h> +#endif #include <machine/clock.h> #include <machine/md_var.h> @@ -2253,6 +2257,13 @@ ed_rint(sc) len += ((packet_hdr.next_packet - sc->rec_page_start) + (sc->rec_page_stop - sc->next_packet)) * ED_PAGE_SIZE; } + /* + * because buffers are aligned on 256-byte boundary, + * the length computed above is off by 256 in almost + * all cases. Fix it... + */ + if (len & 0xff) + len -= 256 ; if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring))) sc->mibdata.dot3StatsFrameTooLongs++; @@ -2731,6 +2742,42 @@ ed_get_packet(sc, buf, len, multicast) m->m_data += 2; eh = mtod(m, struct ether_header *); +#ifdef BRIDGE + /* + * Get link layer header, invoke brige_in, then + * depending on the outcome of the test fetch the rest of the + * packet and either pass up or call bdg_forward. + */ + if (do_bridge) { + struct ifnet *ifp ; + int need_more = 1 ; /* in case not bpf */ + +#if NBPFILTER > 0 + if (sc->arpcom.ac_if.if_bpf) { + need_more = 0 ; + ed_ring_copy(sc, buf, (char *)eh, len); + bpf_mtap(&sc->arpcom.ac_if, m); + } else +#endif + ed_ring_copy(sc, buf, (char *)eh, 14); + ifp = bridge_in(m); + if (ifp == BDG_DROP) { + m_freem(m); + return ; + } + /* else fetch rest of pkt and continue */ + if (need_more && len > 14) + ed_ring_copy(sc, buf+14, (char *)(eh+1), len - 14); + if (ifp != BDG_LOCAL ) + bdg_forward(&m, ifp); /* not local, need forwarding */ + if (ifp == BDG_LOCAL || ifp == BDG_BCAST || ifp == BDG_MCAST) + goto getit ; + /* not local and not multicast, just drop it */ + if (m) + m_freem(m); + return ; + } +#endif /* * Get packet, including link layer address, from interface. */ @@ -2742,23 +2789,21 @@ ed_get_packet(sc, buf, len, multicast) * Check if there's a BPF listener on this interface. If so, hand off * the raw packet to bpf. */ - if (sc->arpcom.ac_if.if_bpf) { + if (sc->arpcom.ac_if.if_bpf) bpf_mtap(&sc->arpcom.ac_if, m); - - /* - * Note that the interface cannot be in promiscuous mode if - * there are no BPF listeners. And if we are in promiscuous - * mode, we have to check if this packet is really ours. - */ - if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && - bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, +#endif + /* + * If we are in promiscuous mode, we have to check whether + * this packet is really for us. + */ + if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && + bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, sizeof(eh->ether_dhost)) != 0 && multicast == 0) { - m_freem(m); - return; - } + m_freem(m); + return; } -#endif +getit: /* * Remove link layer address. */ diff --git a/sys/i386/isa/if_lnc.c b/sys/i386/isa/if_lnc.c index 2efa620e0e0a..2c49cac17bc4 100644 --- a/sys/i386/isa/if_lnc.c +++ b/sys/i386/isa/if_lnc.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_lnc.c,v 1.52 1999/01/31 00:39:20 paul Exp $ + * $Id: if_lnc.c,v 1.53 1999/01/31 00:44:37 paul Exp $ */ /* @@ -92,6 +92,11 @@ #include <net/bpf.h> #endif +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/bridge.h> +#endif + #ifdef PC98 #include <machine/clock.h> #endif @@ -597,7 +602,7 @@ lnc_rint(struct lnc_softc *sc) * ethernet and packet headers */ head->m_pkthdr.rcvif = &sc->arpcom.ac_if; - head->m_pkthdr.len = pkt_len - sizeof *eh; + head->m_pkthdr.len = pkt_len ; /* * BPF expects the ether header to be in the first @@ -611,7 +616,26 @@ lnc_rint(struct lnc_softc *sc) #if NBPFILTER > 0 if (sc->arpcom.ac_if.if_bpf) bpf_mtap(&sc->arpcom.ac_if, head); - +#endif +#ifdef BRIDGE + if (do_bridge) { + struct ifnet *bdg_ifp ; + + bdg_ifp = bridge_in(head); + if (bdg_ifp == BDG_DROP) + m_freem(head); + else { + if (bdg_ifp != BDG_LOCAL) + bdg_forward(&head, bdg_ifp); + if ( bdg_ifp == BDG_LOCAL || + bdg_ifp == BDG_BCAST || + bdg_ifp == BDG_MCAST ) + goto getit; + else if (head) + m_freem(head); + } + } else +#endif /* Check this packet is really for us */ if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && @@ -620,11 +644,12 @@ lnc_rint(struct lnc_softc *sc) sizeof(eh->ether_dhost)))) m_freem(head); else -#endif { +getit: /* Skip over the ether header */ head->m_data += sizeof *eh; head->m_len -= sizeof *eh; + head->m_pkthdr.len -= sizeof *eh; ether_input(&sc->arpcom.ac_if, eh, head); } diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index facad1116f11..d9c52f706856 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -1,5 +1,5 @@ /* $NetBSD: if_de.c,v 1.82 1999/02/28 17:08:51 explorer Exp $ */ -/* $Id: if_de.c,v 1.100 1999/03/13 09:21:27 peter Exp $ */ +/* $Id: if_de.c,v 1.101 1999/03/14 08:32:52 peter Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -124,6 +124,10 @@ #include <pci/dc21040reg.h> #define DEVAR_INCLUDE "pci/if_devar.h" #endif +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/bridge.h> +#endif #endif /* __FreeBSD__ */ #if defined(__bsdi__) @@ -3544,6 +3548,23 @@ tulip_rx_intr( } #endif sc->tulip_flags |= TULIP_RXACT; + +#ifdef BRIDGE /* see code in if_ed.c */ + ms->m_pkthdr.rcvif = ifp; /* XXX */ + ms->m_pkthdr.len = total_len; /* XXX */ + if (do_bridge) { + struct ifnet *bdg_ifp ; + bdg_ifp = bridge_in(ms); + if (bdg_ifp == BDG_DROP) + goto next ; /* and drop */ + if (bdg_ifp != BDG_LOCAL) + bdg_forward(&ms, bdg_ifp); + if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_BCAST && + bdg_ifp != BDG_MCAST) + goto next ; /* and drop */ + /* all others accepted locally */ + } else +#endif if ((sc->tulip_flags & (TULIP_PROMISC|TULIP_HASHONLY)) && (eh.ether_dhost[0] & 1) == 0 && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr)) diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c index 79032ac4ca40..65689290d277 100644 --- a/sys/pci/if_fxp.c +++ b/sys/pci/if_fxp.c @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_fxp.c,v 1.63 1999/02/11 21:47:09 julian Exp $ + * $Id: if_fxp.c,v 1.64 1999/02/12 17:56:23 julian Exp $ */ /* @@ -103,6 +103,12 @@ #endif /* __NetBSD__ */ +#include "opt_bdg.h" +#ifdef BRIDGE +#include <net/if_types.h> +#include <net/bridge.h> +#endif + /* * NOTE! On the Alpha, we have an alignment constraint. The * card DMAs the packet immediately following the RFA. However, @@ -1010,31 +1016,50 @@ rcvloop: } m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = - total_len - - sizeof(struct ether_header); + total_len ; eh = mtod(m, struct ether_header *); #if NBPFILTER > 0 - if (ifp->if_bpf) { + if (ifp->if_bpf) bpf_tap(FXP_BPFTAP_ARG(ifp), mtod(m, caddr_t), total_len); - /* - * Only pass this packet up - * if it is for us. - */ - if ((ifp->if_flags & - IFF_PROMISC) && - (rfa->rfa_status & - FXP_RFA_STATUS_IAMATCH) && - (eh->ether_dhost[0] & 1) - == 0) { - m_freem(m); - goto rcvloop; - } - } #endif /* NBPFILTER > 0 */ +#ifdef BRIDGE + if (do_bridge) { + struct ifnet *bdg_ifp ; + bdg_ifp = bridge_in(m); + if (bdg_ifp == BDG_DROP) + goto dropit ; + if (bdg_ifp != BDG_LOCAL) + bdg_forward(&m, bdg_ifp); + if (bdg_ifp != BDG_LOCAL && + bdg_ifp != BDG_BCAST && + bdg_ifp != BDG_MCAST) + goto dropit ; + goto getit ; + } +#endif + /* + * Only pass this packet up + * if it is for us. + */ + if ((ifp->if_flags & + IFF_PROMISC) && + (rfa->rfa_status & + FXP_RFA_STATUS_IAMATCH) && + (eh->ether_dhost[0] & 1) + == 0) { +dropit: + if (m) + m_freem(m); + goto rcvloop; + } +getit: m->m_data += sizeof(struct ether_header); + m->m_len -= + sizeof(struct ether_header); + m->m_pkthdr.len = m->m_len ; ether_input(ifp, eh, m); } goto rcvloop; |