Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Aug 1998 08:50:01 -0700 (PDT)
From:      Greg Troxel <gdt@ir.bbn.com>
To:        freebsd-bugs@FreeBSD.ORG
Subject:   Re: kern/7144: WaveLAN interface moves packets to uper layer while dst addr does not belong to that interface (even while not in allmulti/promisc mode)
Message-ID:  <199808191550.IAA28309@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/7144; it has been noted by GNATS.

From: Greg Troxel <gdt@ir.bbn.com>
To: freebsd-gnats-submit@freebsd.org, max@cca.usart.ru
Cc: Jim Binkley <jrb@cs.pdx.edu>, Mike Smith <mike@smith.net.au>
Subject: Re: kern/7144: WaveLAN interface moves packets to uper layer while dst addr does not belong to that interface (even while not in allmulti/promisc mode)
Date: Wed, 19 Aug 1998 11:40:20 -0400

 I had just about the same problem, with 915 MHz ISA wavelans cards and
 no wavepoints.  Running mrouted, which set IFF_ALLMULTI caused unicast
 packets with a mac address not matching the local machine to be
 forwarded.  My fix is different, and I believe makes bpf work
 correctly.
 
 The check for dropping unicast packets not sent to our ethernet
 address is after the bpf tap, but not conditioned on it.  All packets
 received should get handed to bpf, and unicast packets not to us (mac)
 should get dropped whether or not there is a bpf listener.  I believe
 that the common optimization that the interface is in hw promisc mode
 iff there is a bpf listener is in general wrong, but more frequently
 so on wavelans.
 
 I think Max's fix makes bpf listeners not see unicast packets sent to
 others, but I'm not sure.
 
 One can argue that checking on MOD_ENAL is wrong, but the code only
 drops packets that shouldn't be received.  The correctness condition
 is that it be run whenever unicast packets without our mac address can
 be received.
 
 Index: if_wl.c
 ===================================================================
 RCS file: /OBS-CVS/FreeBSD/src/sys/i386/isa/if_wl.c,v
 retrieving revision 1.1
 retrieving revision 1.3
 diff -u -r1.1 -r1.3
 @@ -1080,25 +1089,6 @@
  
      m->m_pkthdr.len = clen;
  
 -#ifdef NOTYET
 -    /* due to fact that controller does not support
 -     * all multicast mode, we must filter out unicast packets
 -     * that are not for us. 
 -     *
 -     * if we are in all multicast mode and not promiscuous mode
 -     * and packet is unicast and not for us, 
 -     * 		toss the packet 
 -     *
 -     * TBD: also discard packets where NWID does not match.
 -     */
 -    if ( (sc->mode & MOD_ENAL) && ((sc->mode & MOD_PROM) != 0) &&
 -        ((eh.ether_dhost[0] & 1) == 0) /* !mcast and !bcast */ &&
 -        (bcmp(eh.ether_dhost, sc->wl_ac.ac_enaddr,
 -    	 sizeof(eh.ether_dhost)) != 0) ) {
 -        m_freem(m);
 -        return 1;
 -    }
 -#endif
  #if NBPFILTER > 0
      /*
       * Check if there's a BPF listener on this interface. If so, hand off
 @@ -1116,24 +1106,35 @@
  
  	bpf_mtap(ifp, &m0);
  	
 -	/*
 -	 * point of this code is that even though we are in promiscuous
 -	 * mode, and due to fact that bpf got packet already, we
 -	 * do toss unicast packet not to us so that stacks upstairs
 -	 * do not need to weed it out
 -	 *
 -	 * logic: if promiscuous mode AND not multicast/bcast AND
 -	 *	not to us, throw away
 -	 */
 -	if ((sc->wl_ac.ac_if.if_flags & IFF_PROMISC) &&
 -	    (eh.ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
 -	    bcmp(eh.ether_dhost, sc->wl_ac.ac_enaddr,
 -		 sizeof(eh.ether_dhost)) != 0 ) {
 -	    m_freem(m);
 -	    return 1;
 -	}
      }
  #endif
 +    /*
 +     * If hw is in promiscuous mode (note that I said hardware, not if
 +     * IFF_PROMISC is set in ifnet flags), then if this is a unicast
 +     * packet and the MAC dst is not us, drop it.  This check was formerly
 +     * inside the bpf if, above, but IFF_MULTI causes hw promisc without
 +     * a bpf listener, so this is wrong.
 +     *		Greg Troxel <gdt@ir.bbn.com>, 1998-08-07
 +     */
 +    /*
 +     * TBD: also discard packets where NWID does not match.
 +     * However, there does not appear to be a way to read the nwid
 +     * for a received packet.  -gdt 1998-08-07
 +     */
 +    if (
 +#ifdef WL_USE_IFNET_PROMISC_CHECK /* not defined */
 +	(sc->wl_ac.ac_if.if_flags & (IFF_PROMISC|IFF_ALLMULTI))
 +#else
 +	/* hw is in promisc mode if this is true */
 +	(sc->mode & (MOD_PROM | MOD_ENAL))
 +#endif
 +	&&
 +	(eh.ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
 +	bcmp(eh.ether_dhost, sc->wl_ac.ac_enaddr,
 +	     sizeof(eh.ether_dhost)) != 0 ) {
 +      m_freem(m);
 +      return 1;
 +    }
  
  #ifdef WLDEBUG
      if (sc->wl_if.if_flags & IFF_DEBUG)

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199808191550.IAA28309>