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:
Andrew Thompson 2005-10-23 22:30:07 +00:00
parent b77b750ee9
commit 1a2661371b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151594

View File

@ -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);
}