Subject: multicast address filtering bug in 1.2 dev/pci/if_de.c
To: None <netbsd-bugs@NetBSD.ORG>
From: David Rosenthal <dshr@vitria.COM>
List: netbsd-bugs
Date: 12/05/1996 14:28:10
The dev/pci/if_de.c driver that came with 1.2 doesn't work in a multicast
router because the multicast address filtering stuff doesn't recognize
that it may be asked to filter a range of multicast addresses as well
as a set of individual addresses (the code looks only at enm_addrlo not
at enm_addrhi as well).

Here's a hack to make it work.  I know nothing about the DEC chip,  so
cannot tell if there is a less tacky solution.  This hack has been tested
using a P5-100 system with an ASUS motherboard and an E-Net EN-9400P3 Rev D2
card which is recognized as 

	de0 at pci0 dev 10 function 0: DC21041 [10Mb/s] pass 1.1
	de0: Ethernet address 00:40:c7:95:01:5f
	de0: interrupting at irq 12

and it seems to work well enough that mrouted now gets packets to and
from machines on the net connected to de0,  which it didn't before.

	David.

*** /usr/src/sys/dev/pci/if_de.c.orig	Thu Dec  5 18:50:37 1996
--- /usr/src/sys/dev/pci/if_de.c	Thu Dec  5 18:55:01 1996
***************
*** 1874,1879 ****
--- 1874,1905 ----
      sc->tulip_flags |= TULIP_WANTSETUP;
      sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
      sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
+ #ifndef notdef
+     i = 0;
+     /* Do we have a range of addresses? */
+     ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm);
+     for (; enm != NULL; i++) {
+ 	if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
+ 		    sizeof (enm->enm_addrlo)) != 0) {
+ 	    /*
+ 	     * This is a range of addresses - for now the only use of
+ 	     * a range is for multicast routing,  which needs everything
+ 	     */
+ 	    i++;
+ 	    break;
+ 	}
+ 	ETHER_NEXT_MULTI(step, enm);
+     }
+     if (!(sc->tulip_if.if_flags & IFF_ALLMULTI) && i) {
+ 	/*  We have a range of addresses so we need ALLMULTI mode */
+ 	/*  XXX - how do we know when to clear the ALLMULTI flag? */
+ 	sc->tulip_if.if_flags |= IFF_ALLMULTI;
+     }
+     if (sc->tulip_if.if_flags & IFF_ALLMULTI) {
+ 	/*  Put the chip into ALLMULTI mode */
+ 	sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI;
+     }
+ #endif
      if (sc->tulip_ac.ac_multicnt > 14) {
  	unsigned hash;
  	/*