From owner-freebsd-bugs Thu Oct 3 02:11:37 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id CAA16827 for bugs-outgoing; Thu, 3 Oct 1996 02:11:37 -0700 (PDT) Received: from durant.cs.berkeley.edu (durant.CS.Berkeley.EDU [128.32.33.199]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id CAA16820 for ; Thu, 3 Oct 1996 02:11:34 -0700 (PDT) Received: from localhost (mccanne@localhost) by durant.cs.berkeley.edu (950413.SGI.8.6.12/950213.SGI.AUTOCF) via SMTP id CAA13487 for ; Thu, 3 Oct 1996 02:11:35 -0700 Message-Id: <199610030911.CAA13487@durant.cs.berkeley.edu> To: bugs@freebsd.org Subject: bpf and multicast don't work in pci/if_vx.c From: mccanne@eecs.berkeley.edu (Steven McCanne) Date: Thu, 03 Oct 1996 02:11:34 -0700 Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Attached is a patch to the vx driver that fixes a bug related to bpf and adds multicast support. (w/o this patch bpf_mtap is never called because the pointer address passed to bpfattach is not the same as the pointer tested in the recv/xmit path). Steve *** pci/if_vx.c 1996/09/29 21:03:24 1.1 --- pci/if_vx.c 1996/10/03 07:51:32 *************** *** 52,57 **** --- 52,66 ---- * 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 *************** *** 254,260 **** ifp->if_unit = unit; ifp->if_name = "vx"; ifp->if_mtu = ETHERMTU; ! ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX /*| IFF_NOTRAILERS*/; ifp->if_output = ether_output; ifp->if_start = vxstart; ifp->if_ioctl = vxioctl; --- 263,269 ---- ifp->if_unit = unit; ifp->if_name = "vx"; ifp->if_mtu = ETHERMTU; ! ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_output = ether_output; ifp->if_start = vxstart; ifp->if_ioctl = vxioctl; *************** *** 356,364 **** if(ifp->if_flags & IFF_PROMISC) 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); /* * S.B. --- 365,377 ---- 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_BRDCST); /* * S.B. *************** *** 552,558 **** outb(BASE + VX_W1_TX_PIO_WR_1, 0); /* Padding */ #if NBPFILTER > 0 ! if (sc->arpcom.ac_if.if_bpf) { bpf_mtap(sc->bpf, top); } #endif --- 565,571 ---- outb(BASE + VX_W1_TX_PIO_WR_1, 0); /* Padding */ #if NBPFILTER > 0 ! if (sc->bpf) { bpf_mtap(sc->bpf, top); } #endif *************** *** 870,876 **** top->m_pkthdr.len = sc->cur_len; #if NBPFILTER > 0 ! if (sc->arpcom.ac_if.if_bpf) { bpf_mtap(sc->bpf, top); /* --- 883,889 ---- top->m_pkthdr.len = sc->cur_len; #if NBPFILTER > 0 ! if (sc->bpf) { bpf_mtap(sc->bpf, top); /* *************** *** 880,889 **** */ eh = mtod(top, struct ether_header *); if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) && (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); --- 893,901 ---- */ 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) { if (sc->top) { m_freem(sc->top); *************** *** 1014,1020 **** --- 1026,1058 ---- 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, *** pci/if_vxreg.h 1996/09/29 21:12:27 1.1 --- pci/if_vxreg.h 1996/09/29 21:24:17 *************** *** 70,75 **** --- 70,76 ---- #define F_WAIT_TRAIL 0x2 #define F_RX_TRAILER 0x4 #define F_PROMISC 0x8 + #define F_ALLMULTI 0x10 #define F_ACCESS_32_BITS 0x100