Module Name:    src
Committed By:   riastradh
Date:           Thu Mar  3 05:53:14 UTC 2022

Modified Files:
        src/sys/dev/usb: if_aue.c if_cue.c if_kue.c if_mue.c if_smsc.c
            if_udav.c

Log Message:
usbnet drivers: Stop abusing ifp->if_flags & IFF_ALLMULTI.

This legacy flag is a figment of userland's imagination.  The actual
kernel state is ec->ec_flags & ETHER_F_ALLMULTI, protected by the
ETHER_LOCK, so that multicast filter updates -- which run without
IFNET_LOCK -- need not attempt to write racily to ifp->if_flags.


To generate a diff of this commit:
cvs rdiff -u -r1.179 -r1.180 src/sys/dev/usb/if_aue.c
cvs rdiff -u -r1.99 -r1.100 src/sys/dev/usb/if_cue.c
cvs rdiff -u -r1.112 -r1.113 src/sys/dev/usb/if_kue.c
cvs rdiff -u -r1.72 -r1.73 src/sys/dev/usb/if_mue.c
cvs rdiff -u -r1.81 -r1.82 src/sys/dev/usb/if_smsc.c
cvs rdiff -u -r1.86 -r1.87 src/sys/dev/usb/if_udav.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/if_aue.c
diff -u src/sys/dev/usb/if_aue.c:1.179 src/sys/dev/usb/if_aue.c:1.180
--- src/sys/dev/usb/if_aue.c:1.179	Thu Mar  3 05:53:04 2022
+++ src/sys/dev/usb/if_aue.c	Thu Mar  3 05:53:14 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_aue.c,v 1.179 2022/03/03 05:53:04 riastradh Exp $	*/
+/*	$NetBSD: if_aue.c,v 1.180 2022/03/03 05:53:14 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.179 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.180 2022/03/03 05:53:14 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -627,21 +627,20 @@ aue_uno_mcast(struct ifnet *ifp)
 	usbnet_isowned_core(un);
 
 	if (ifp->if_flags & IFF_PROMISC) {
+		ETHER_LOCK(ec);
 allmulti:
-		ifp->if_flags |= IFF_ALLMULTI;
+		ec->ec_flags |= ETHER_F_ALLMULTI;
+		ETHER_UNLOCK(ec);
 		AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
 		return;
 	}
 
-	AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
-
 	/* now program new ones */
 	ETHER_LOCK(ec);
 	ETHER_FIRST_MULTI(step, ec, enm);
 	while (enm != NULL) {
 		if (memcmp(enm->enm_addrlo,
 		    enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
-			ETHER_UNLOCK(ec);
 			goto allmulti;
 		}
 
@@ -649,13 +648,14 @@ allmulti:
 		hashtbl[h >> 3] |= 1 << (h & 0x7);
 		ETHER_NEXT_MULTI(step, enm);
 	}
+	ec->ec_flags &= ~ETHER_F_ALLMULTI;
 	ETHER_UNLOCK(ec);
 
+	AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
+
 	/* write the hashtable */
 	for (i = 0; i < 8; i++)
 		aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]);
-
-	ifp->if_flags &= ~IFF_ALLMULTI;
 }
 
 static void

Index: src/sys/dev/usb/if_cue.c
diff -u src/sys/dev/usb/if_cue.c:1.99 src/sys/dev/usb/if_cue.c:1.100
--- src/sys/dev/usb/if_cue.c:1.99	Thu Mar  3 05:53:04 2022
+++ src/sys/dev/usb/if_cue.c	Thu Mar  3 05:53:14 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_cue.c,v 1.99 2022/03/03 05:53:04 riastradh Exp $	*/
+/*	$NetBSD: if_cue.c,v 1.100 2022/03/03 05:53:14 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.99 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.100 2022/03/03 05:53:14 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -370,8 +370,10 @@ cue_uno_mcast(struct ifnet *ifp)
 	    device_xname(un->un_dev), ifp->if_flags));
 
 	if (ifp->if_flags & IFF_PROMISC) {
+		ETHER_LOCK(ec);
 allmulti:
-		ifp->if_flags |= IFF_ALLMULTI;
+		ec->ec_flags |= ETHER_F_ALLMULTI;
+		ETHER_UNLOCK(ec);
 		for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
 			sc->cue_mctab[i] = 0xFF;
 		cue_mem(un, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
@@ -389,7 +391,6 @@ allmulti:
 	while (enm != NULL) {
 		if (memcmp(enm->enm_addrlo,
 		    enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
-			ETHER_UNLOCK(ec);
 			goto allmulti;
 		}
 
@@ -397,10 +398,9 @@ allmulti:
 		sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
 		ETHER_NEXT_MULTI(step, enm);
 	}
+	ec->ec_flags &= ~ETHER_F_ALLMULTI;
 	ETHER_UNLOCK(ec);
 
-	ifp->if_flags &= ~IFF_ALLMULTI;
-
 	/*
 	 * Also include the broadcast address in the filter
 	 * so we can receive broadcast frames.

Index: src/sys/dev/usb/if_kue.c
diff -u src/sys/dev/usb/if_kue.c:1.112 src/sys/dev/usb/if_kue.c:1.113
--- src/sys/dev/usb/if_kue.c:1.112	Thu Mar  3 05:53:04 2022
+++ src/sys/dev/usb/if_kue.c	Thu Mar  3 05:53:14 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_kue.c,v 1.112 2022/03/03 05:53:04 riastradh Exp $	*/
+/*	$NetBSD: if_kue.c,v 1.113 2022/03/03 05:53:14 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.112 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.113 2022/03/03 05:53:14 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -336,8 +336,10 @@ kue_uno_mcast(struct ifnet *ifp)
 		sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
 
 	if (ifp->if_flags & IFF_PROMISC) {
+		ETHER_LOCK(ec);
 allmulti:
-		ifp->if_flags |= IFF_ALLMULTI;
+		ec->ec_flags |= ETHER_F_ALLMULTI;
+		ETHER_UNLOCK(ec);
 		sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC;
 		sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
 		kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
@@ -353,7 +355,6 @@ allmulti:
 		if (i == KUE_MCFILTCNT(sc) ||
 		    memcmp(enm->enm_addrlo, enm->enm_addrhi,
 		    ETHER_ADDR_LEN) != 0) {
-			ETHER_UNLOCK(ec);
 			goto allmulti;
 		}
 
@@ -361,10 +362,9 @@ allmulti:
 		ETHER_NEXT_MULTI(step, enm);
 		i++;
 	}
+	ec->ec_flags &= ~ETHER_F_ALLMULTI;
 	ETHER_UNLOCK(ec);
 
-	ifp->if_flags &= ~IFF_ALLMULTI;
-
 	sc->kue_rxfilt |= KUE_RXFILT_MULTICAST;
 	kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
 	    i, sc->kue_mcfilters, i * ETHER_ADDR_LEN);

Index: src/sys/dev/usb/if_mue.c
diff -u src/sys/dev/usb/if_mue.c:1.72 src/sys/dev/usb/if_mue.c:1.73
--- src/sys/dev/usb/if_mue.c:1.72	Thu Mar  3 05:53:04 2022
+++ src/sys/dev/usb/if_mue.c	Thu Mar  3 05:53:14 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_mue.c,v 1.72 2022/03/03 05:53:04 riastradh Exp $	*/
+/*	$NetBSD: if_mue.c,v 1.73 2022/03/03 05:53:14 riastradh Exp $	*/
 /*	$OpenBSD: if_mue.c,v 1.3 2018/08/04 16:42:46 jsg Exp $	*/
 
 /*
@@ -20,7 +20,7 @@
 /* Driver for Microchip LAN7500/LAN7800 chipsets. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.72 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.73 2022/03/03 05:53:14 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -1023,10 +1023,11 @@ mue_uno_mcast(struct ifnet *ifp)
 	/* Always accept broadcast frames. */
 	rxfilt |= MUE_RFE_CTL_BROADCAST;
 
+	ETHER_LOCK(ec);
 	if (ifp->if_flags & IFF_PROMISC) {
 		rxfilt |= MUE_RFE_CTL_UNICAST;
 allmulti:	rxfilt |= MUE_RFE_CTL_MULTICAST;
-		ifp->if_flags |= IFF_ALLMULTI;
+		ec->ec_flags |= ETHER_F_ALLMULTI;
 		if (ifp->if_flags & IFF_PROMISC)
 			DPRINTF(un, "promisc\n");
 		else
@@ -1036,7 +1037,6 @@ allmulti:	rxfilt |= MUE_RFE_CTL_MULTICAS
 		pfiltbl[0][0] = MUE_ENADDR_HI(enaddr) | MUE_ADDR_FILTX_VALID;
 		pfiltbl[0][1] = MUE_ENADDR_LO(enaddr);
 		i = 1;
-		ETHER_LOCK(ec);
 		ETHER_FIRST_MULTI(step, ec, enm);
 		while (enm != NULL) {
 			if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
@@ -1044,7 +1044,6 @@ allmulti:	rxfilt |= MUE_RFE_CTL_MULTICAS
 				memset(pfiltbl, 0, sizeof(pfiltbl));
 				memset(hashtbl, 0, sizeof(hashtbl));
 				rxfilt &= ~MUE_RFE_CTL_MULTICAST_HASH;
-				ETHER_UNLOCK(ec);
 				goto allmulti;
 			}
 			if (i < MUE_NUM_ADDR_FILTX) {
@@ -1062,14 +1061,14 @@ allmulti:	rxfilt |= MUE_RFE_CTL_MULTICAS
 			i++;
 			ETHER_NEXT_MULTI(step, enm);
 		}
-		ETHER_UNLOCK(ec);
+		ec->ec_flags &= ~ETHER_F_ALLMULTI;
 		rxfilt |= MUE_RFE_CTL_PERFECT;
-		ifp->if_flags &= ~IFF_ALLMULTI;
 		if (rxfilt & MUE_RFE_CTL_MULTICAST_HASH)
 			DPRINTF(un, "perfect filter and hash tables\n");
 		else
 			DPRINTF(un, "perfect filter\n");
 	}
+	ETHER_UNLOCK(ec);
 
 	for (i = 0; i < MUE_NUM_ADDR_FILTX; i++) {
 		hireg = (un->un_flags & LAN7500) ?

Index: src/sys/dev/usb/if_smsc.c
diff -u src/sys/dev/usb/if_smsc.c:1.81 src/sys/dev/usb/if_smsc.c:1.82
--- src/sys/dev/usb/if_smsc.c:1.81	Thu Mar  3 05:53:04 2022
+++ src/sys/dev/usb/if_smsc.c	Thu Mar  3 05:53:14 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_smsc.c,v 1.81 2022/03/03 05:53:04 riastradh Exp $	*/
+/*	$NetBSD: if_smsc.c,v 1.82 2022/03/03 05:53:14 riastradh Exp $	*/
 
 /*	$OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.81 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.82 2022/03/03 05:53:14 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -427,8 +427,11 @@ smsc_uno_mcast(struct ifnet *ifp)
 	if (usbnet_isdying(un))
 		return;
 
-	if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+	if (ifp->if_flags & IFF_PROMISC) {
+		ETHER_LOCK(ec);
 allmulti:
+		ec->ec_flags |= ETHER_F_ALLMULTI;
+		ETHER_UNLOCK(ec);
 		DPRINTF("receive all multicast enabled", 0, 0, 0, 0);
 		sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS;
 		sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT;
@@ -443,7 +446,6 @@ allmulti:
 	ETHER_FIRST_MULTI(step, ec, enm);
 	while (enm != NULL) {
 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
-			ETHER_UNLOCK(ec);
 			goto allmulti;
 		}
 
@@ -451,6 +453,7 @@ allmulti:
 		hashtbl[hash >> 5] |= 1 << (hash & 0x1F);
 		ETHER_NEXT_MULTI(step, enm);
 	}
+	ec->ec_flags &= ~ETHER_F_ALLMULTI;
 	ETHER_UNLOCK(ec);
 
 	/* Debug */
@@ -463,7 +466,6 @@ allmulti:
 	/* Write the hash table and mac control registers */
 
 	//XXX should we be doing this?
-	ifp->if_flags &= ~IFF_ALLMULTI;
 	smsc_writereg(un, SMSC_HASHH, hashtbl[1]);
 	smsc_writereg(un, SMSC_HASHL, hashtbl[0]);
 	smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);

Index: src/sys/dev/usb/if_udav.c
diff -u src/sys/dev/usb/if_udav.c:1.86 src/sys/dev/usb/if_udav.c:1.87
--- src/sys/dev/usb/if_udav.c:1.86	Thu Mar  3 05:53:04 2022
+++ src/sys/dev/usb/if_udav.c	Thu Mar  3 05:53:14 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_udav.c,v 1.86 2022/03/03 05:53:04 riastradh Exp $	*/
+/*	$NetBSD: if_udav.c,v 1.87 2022/03/03 05:53:14 riastradh Exp $	*/
 /*	$nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $	*/
 
 /*
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.86 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.87 2022/03/03 05:53:14 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -598,11 +598,16 @@ udav_uno_mcast(struct ifnet *ifp)
 	}
 
 	if (ifp->if_flags & IFF_PROMISC) {
+		ETHER_LOCK(ec);
+		ec->ec_flags |= ETHER_F_ALLMULTI;
+		ETHER_UNLOCK(ec);
 		UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
 		return;
-	} else if (ifp->if_flags & IFF_ALLMULTI) {
+	} else if (ifp->if_flags & IFF_ALLMULTI) { /* XXX ??? Can't happen? */
+		ETHER_LOCK(ec);
 allmulti:
-		ifp->if_flags |= IFF_ALLMULTI;
+		ec->ec_flags |= ETHER_F_ALLMULTI;
+		ETHER_UNLOCK(ec);
 		UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL);
 		UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_PRMSC);
 		return;
@@ -619,7 +624,6 @@ allmulti:
 	while (enm != NULL) {
 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
 		    ETHER_ADDR_LEN) != 0) {
-			ETHER_UNLOCK(ec);
 			goto allmulti;
 		}
 
@@ -627,10 +631,10 @@ allmulti:
 		hashes[h>>3] |= 1 << (h & 0x7);
 		ETHER_NEXT_MULTI(step, enm);
 	}
+	ec->ec_flags &= ~ETHER_F_ALLMULTI;
 	ETHER_UNLOCK(ec);
 
 	/* disable all multicast */
-	ifp->if_flags &= ~IFF_ALLMULTI;
 	UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL);
 
 	/* write hash value to the register */

Reply via email to