Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 May 2009 19:46:43 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r191729 - head/sys/net
Message-ID:  <200905011946.n41Jkhpu051686@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: thompsa
Date: Fri May  1 19:46:42 2009
New Revision: 191729
URL: http://svn.freebsd.org/changeset/base/191729

Log:
  Reorder the bridge add and delete routines to avoid calling ifpromisc() with
  the bridge lock held.

Modified:
  head/sys/net/if_bridge.c

Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c	Fri May  1 19:05:07 2009	(r191728)
+++ head/sys/net/if_bridge.c	Fri May  1 19:46:42 2009	(r191729)
@@ -893,29 +893,6 @@ bridge_delete_member(struct bridge_softc
 
 	BRIDGE_LOCK_ASSERT(sc);
 
-	if (!gone) {
-		switch (ifs->if_type) {
-		case IFT_ETHER:
-		case IFT_L2VLAN:
-			/*
-			 * Take the interface out of promiscuous mode.
-			 */
-			(void) ifpromisc(ifs, 0);
-			break;
-
-		case IFT_GIF:
-			break;
-
-		default:
-#ifdef DIAGNOSTIC
-			panic("bridge_delete_member: impossible");
-#endif
-			break;
-		}
-		/* reneable any interface capabilities */
-		bridge_set_ifcap(sc, bif, bif->bif_savedcaps);
-	}
-
 	if (bif->bif_flags & IFBIF_STP)
 		bstp_disable(&bif->bif_stp);
 
@@ -948,6 +925,28 @@ bridge_delete_member(struct bridge_softc
 	    ("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt));
 
 	BRIDGE_UNLOCK(sc);
+	if (!gone) {
+		switch (ifs->if_type) {
+		case IFT_ETHER:
+		case IFT_L2VLAN:
+			/*
+			 * Take the interface out of promiscuous mode.
+			 */
+			(void) ifpromisc(ifs, 0);
+			break;
+
+		case IFT_GIF:
+			break;
+
+		default:
+#ifdef DIAGNOSTIC
+			panic("bridge_delete_member: impossible");
+#endif
+			break;
+		}
+		/* reneable any interface capabilities */
+		bridge_set_ifcap(sc, bif, bif->bif_savedcaps);
+	}
 	bstp_destroy(&bif->bif_stp);	/* prepare to free */
 	BRIDGE_LOCK(sc);
 	free(bif, M_DEVBUF);
@@ -1017,17 +1016,9 @@ bridge_ioctl_add(struct bridge_softc *sc
 	switch (ifs->if_type) {
 	case IFT_ETHER:
 	case IFT_L2VLAN:
-		/*
-		 * Place the interface into promiscuous mode.
-		 */
-		error = ifpromisc(ifs, 1);
-		if (error)
-			goto out;
-		break;
-
 	case IFT_GIF:
+		/* permitted interface types */
 		break;
-
 	default:
 		error = EINVAL;
 		goto out;
@@ -1055,6 +1046,20 @@ bridge_ioctl_add(struct bridge_softc *sc
 
 	/* Set interface capabilities to the intersection set of all members */
 	bridge_mutecaps(sc);
+
+	switch (ifs->if_type) {
+	case IFT_ETHER:
+	case IFT_L2VLAN:
+		/*
+		 * Place the interface into promiscuous mode.
+		 */
+		BRIDGE_UNLOCK(sc);
+		error = ifpromisc(ifs, 1);
+		BRIDGE_LOCK(sc);
+		break;
+	}
+	if (error)
+		bridge_delete_member(sc, bif, 0);
 out:
 	if (error) {
 		if (bif != NULL)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905011946.n41Jkhpu051686>