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