Dependency between interfaces
Andrew Thompson
thompsa at freebsd.org
Sat Oct 22 12:45:26 PDT 2005
On Sat, Oct 22, 2005 at 01:37:35PM +0000, Wojciech A. Koszek wrote:
> On Fri, Oct 21, 2005 at 09:23:27AM +1300, Andrew Thompson wrote:
> > On Thu, Oct 20, 2005 at 08:20:34PM +0000, Wojciech A. Koszek wrote:
> > > Hello,
> > >
>
> [..]
> >
> > Is it still a problem or did you test on a pre r1.26 kernel?
> >
>
> Results from -CURRENT: I got panic if sk/rl modules are loaded, interfaces
> added to bridge0 and these drivers kldunload(8)ed:
>
> http://freebsd.czest.pl/dunstan/FreeBSD/bridge_rl.trace
> http://freebsd.czest.pl/dunstan/FreeBSD/bridge_sk.trace
>
Can you please try this patch.
cheers,
Andrew
-------------- next part --------------
Index: if_bridge.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_bridge.c,v
retrieving revision 1.29
diff -u -p -r1.29 if_bridge.c
--- if_bridge.c 14 Oct 2005 20:57:02 -0000 1.29
+++ if_bridge.c 22 Oct 2005 19:41:18 -0000
@@ -219,7 +219,7 @@ static struct bridge_iflist *bridge_look
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_so
* 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
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);
}
More information about the freebsd-net
mailing list