mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-03 23:28:58 +00:00
If we have been called from ether_ifdetach() then do not try and clear the
promisc flag from the member interface, this is a no-op anyway since the interface is disappearing. The driver may have already released its resources such as miibus and this is likely to panic the kernel. Submitted and tested by: Wojciech A. Koszek MFC after: 2 weeks
This commit is contained in:
parent
b77b750ee9
commit
1a2661371b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151594
|
@ -219,7 +219,7 @@ static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
|
|||
static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
|
||||
struct ifnet *ifp);
|
||||
static void bridge_delete_member(struct bridge_softc *,
|
||||
struct bridge_iflist *);
|
||||
struct bridge_iflist *, int);
|
||||
|
||||
static int bridge_ioctl_add(struct bridge_softc *, void *);
|
||||
static int bridge_ioctl_del(struct bridge_softc *, void *);
|
||||
|
@ -506,7 +506,7 @@ bridge_clone_destroy(struct ifnet *ifp)
|
|||
ifp->if_flags &= ~IFF_UP;
|
||||
|
||||
while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
|
||||
bridge_delete_member(sc, bif);
|
||||
bridge_delete_member(sc, bif, 0);
|
||||
|
||||
BRIDGE_UNLOCK(sc);
|
||||
|
||||
|
@ -690,26 +690,29 @@ bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
|
|||
* Delete the specified member interface.
|
||||
*/
|
||||
static void
|
||||
bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
|
||||
bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
|
||||
int gone)
|
||||
{
|
||||
struct ifnet *ifs = bif->bif_ifp;
|
||||
|
||||
BRIDGE_LOCK_ASSERT(sc);
|
||||
|
||||
switch (ifs->if_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_L2VLAN:
|
||||
/*
|
||||
* Take the interface out of promiscuous mode.
|
||||
*/
|
||||
(void) ifpromisc(ifs, 0);
|
||||
break;
|
||||
if (!gone) {
|
||||
switch (ifs->if_type) {
|
||||
case IFT_ETHER:
|
||||
case IFT_L2VLAN:
|
||||
/*
|
||||
* Take the interface out of promiscuous mode.
|
||||
*/
|
||||
(void) ifpromisc(ifs, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
#ifdef DIAGNOSTIC
|
||||
panic("bridge_delete_member: impossible");
|
||||
panic("bridge_delete_member: impossible");
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ifs->if_bridge = NULL;
|
||||
|
@ -811,7 +814,7 @@ bridge_ioctl_del(struct bridge_softc *sc, void *arg)
|
|||
if (bif == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
bridge_delete_member(sc, bif);
|
||||
bridge_delete_member(sc, bif, 0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -1207,14 +1210,16 @@ static void
|
|||
bridge_ifdetach(struct ifnet *ifp)
|
||||
{
|
||||
struct bridge_softc *sc = ifp->if_bridge;
|
||||
struct ifbreq breq;
|
||||
struct bridge_iflist *bif;
|
||||
|
||||
BRIDGE_LOCK(sc);
|
||||
|
||||
memset(&breq, 0, sizeof(breq));
|
||||
snprintf(breq.ifbr_ifsname, sizeof(breq.ifbr_ifsname), ifp->if_xname);
|
||||
bif = bridge_lookup_member_if(sc, ifp);
|
||||
if (bif == NULL)
|
||||
return;
|
||||
|
||||
bridge_delete_member(sc, bif, 1);
|
||||
|
||||
(void) bridge_ioctl_del(sc, &breq);
|
||||
BRIDGE_UNLOCK(sc);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue