Subject: Re: SMC91C92 (if_sm.c/smc91cxx.c) gets unicast packet twice on BPF
To: Charlie Root <root@ihack.net>
From: None <itojun@iijlab.net>
List: tech-net
Date: 01/17/2000 15:41:40
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <13841.948091289.1@coconut.itojun.org>
Content-Transfer-Encoding: 7bit

>Also, since we're setting IFF_SIMPLEX, we should not receive this
>packet again, since the network stack already looped it back
>internally if necessary.  Doing so causes a duplicate packet to reach
>the upper-level protocols, which is canonically wrong.  It is already
>the case that smc91cxx_read() drops multicast and broadcast packets
>from our address in promiscuous mode; it needs to be adjusted to also
>do so for unicast packets (i.e. by just removing the test on the
>destination address).  In addition, this block should be moved *after*
>the call to bpf_mtap().

	thanks for comment, does this look correct?

itojun

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <13841.948091289.2@coconut.itojun.org>
Content-Transfer-Encoding: 7bit

Index: smc91cxx.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/smc91cxx.c,v
retrieving revision 1.20
diff -c -r1.20 smc91cxx.c
*** smc91cxx.c	1999/09/28 17:55:33	1.20
--- smc91cxx.c	2000/01/17 06:41:18
***************
*** 928,958 ****
  
  	ifp->if_ipackets++;
  
  	if ((ifp->if_flags & IFF_PROMISC) != 0) {
  		/*
- 		 * Make sure to behave as IFF_SIMPLEX in all cases.
  		 * Drop multicast/broadcast packet looped back from myself.
- 		 *
- 		 * This is to cope with SMC91C92 (Megahertz XJ10BT), which
- 		 * loops back multicast packet to itself on promiscuous mode.
- 		 * (should be ensured by chipset configuration)
  		 */
  		if ((eh->ether_dhost[0] & 1) == 1 &&	/* mcast || bcast */
  		    ether_cmp(eh->ether_shost, LLADDR(ifp->if_sadl)) == 0) {
  			m_freem(m);
  			goto out;
  		}
- 	}
- 
- #if NBPFILTER > 0
- 	/*
- 	 * Hand the packet off to bpf listeners.
- 	 */
- 	if (ifp->if_bpf)
- 		bpf_mtap(ifp->if_bpf, m);
- #endif
  
- 	if ((ifp->if_flags & IFF_PROMISC) != 0) {
  		/*
  		 * If this is unicast and not for me, drop it.
  		 */
--- 928,949 ----
  
  	ifp->if_ipackets++;
  
+ 	/*
+ 	 * Make sure to behave as IFF_SIMPLEX in all cases.
+ 	 * This is to cope with SMC91C92 (Megahertz XJ10BT), which
+ 	 * loops back packets to itself on promiscuous mode.
+ 	 * (should be ensured by chipset configuration)
+ 	 */
  	if ((ifp->if_flags & IFF_PROMISC) != 0) {
  		/*
  		 * Drop multicast/broadcast packet looped back from myself.
  		 */
  		if ((eh->ether_dhost[0] & 1) == 1 &&	/* mcast || bcast */
  		    ether_cmp(eh->ether_shost, LLADDR(ifp->if_sadl)) == 0) {
  			m_freem(m);
  			goto out;
  		}
  
  		/*
  		 * If this is unicast and not for me, drop it.
  		 */
***************
*** 962,967 ****
--- 953,966 ----
  			goto out;
  		}
  	}
+ 
+ #if NBPFILTER > 0
+ 	/*
+ 	 * Hand the packet off to bpf listeners.
+ 	 */
+ 	if (ifp->if_bpf)
+ 		bpf_mtap(ifp->if_bpf, m);
+ #endif
  
  	m->m_pkthdr.len = m->m_len = packetlen;
  	(*ifp->if_input)(ifp, m);

------- =_aaaaaaaaaa0--