svn commit: r191729 - head/sys/net
Andrew Thompson
thompsa at FreeBSD.org
Fri May 1 19:46:43 UTC 2009
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)
More information about the svn-src-all
mailing list