From 8d1005c8c4ad00270e75828d2a593f37ddba2d96 Mon Sep 17 00:00:00 2001 From: David Greenman Date: Thu, 3 Oct 1996 10:47:03 +0000 Subject: [PATCH] Added multicast support (BPF cookie bug was already fixed). Submitted by: Steven McCanne --- sys/pci/if_vx.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- sys/pci/if_vxreg.h | 1 + 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/sys/pci/if_vx.c b/sys/pci/if_vx.c index 36b6ed67ed57..2400a8d741e5 100644 --- a/sys/pci/if_vx.c +++ b/sys/pci/if_vx.c @@ -52,6 +52,15 @@ * babkin@hq.icb.chel.su */ +/* + * Sep 29, 1996 + * Multicast support and bpf bug fixes. + * + * Steven McCanne + * http://www.cs.berkeley.edu/~mccanne/ + * mccanne@cs.berkeley.edu + */ + #include "vx.h" #if NVX > 0 @@ -253,7 +262,7 @@ vx_pci_attach( ifp->if_unit = unit; ifp->if_name = "vx"; ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX /*| IFF_NOTRAILERS*/; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_output = ether_output; ifp->if_start = vxstart; ifp->if_ioctl = vxioctl; @@ -355,9 +364,13 @@ vxinit(unit) if(ifp->if_flags & IFF_PROMISC) outw(BASE + VX_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | FIL_GROUP | FIL_BRDCST | FIL_ALL); + else if((ifp->if_flags & IFF_ALLMULTI) != 0 || + sc->arpcom.ac_multiaddrs != 0) + outw(BASE + VX_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | + FIL_GROUP | FIL_BRDCST | FIL_ALL); else outw(BASE + VX_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL | - FIL_GROUP | FIL_BRDCST); + FIL_BRDCST); /* * S.B. @@ -879,10 +892,9 @@ all_pkt: */ eh = mtod(top, struct ether_header *); if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && + /* non-multicast (also non-broadcast) */ (eh->ether_dhost[0] & 1) == 0 && bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, - sizeof(eh->ether_dhost)) != 0 && - bcmp(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost)) != 0) { if (sc->top) { m_freem(sc->top); @@ -1013,7 +1025,33 @@ vxioctl(ifp, cmd, data) vxinit(ifp->if_unit); } + if ( (ifp->if_flags & IFF_ALLMULTI) && !vx_ftst(F_ALLMULTI) ) { + vx_fset(F_ALLMULTI); + vxinit(ifp->if_unit); + } + else if( !(ifp->if_flags & IFF_ALLMULTI) && vx_ftst(F_ALLMULTI) ) { + vx_frst(F_ALLMULTI); + vxinit(ifp->if_unit); + } + break; + + case SIOCADDMULTI: + case SIOCDELMULTI: + /* + * Update multicast listeners + */ + error = (cmd == SIOCADDMULTI ? + ether_addmulti(ifr, &sc->arpcom) : + ether_delmulti(ifr, &sc->arpcom)); + + if(error == ENETRESET) { + /* reset multicast filtering */ + vxinit(ifp->if_unit); + error = 0; + } + break; + #ifdef notdef case SIOCGHWADDR: bcopy((caddr_t) sc->sc_addr, (caddr_t) & ifr->ifr_data, diff --git a/sys/pci/if_vxreg.h b/sys/pci/if_vxreg.h index b57b1ad4f5f6..bc7b88ccc6df 100644 --- a/sys/pci/if_vxreg.h +++ b/sys/pci/if_vxreg.h @@ -69,6 +69,7 @@ struct vx_softc { #define F_WAIT_TRAIL 0x2 #define F_RX_TRAILER 0x4 #define F_PROMISC 0x8 +#define F_ALLMULTI 0x10 #define F_ACCESS_32_BITS 0x100