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 */