Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 09 Jun 2012 16:27:56 +0200
From:      Gustau Perez Querol <gperez@entel.upc.edu>
To:        <net@freebsd.org>
Subject:   Panic with if_bridge when removing components
Message-ID:  <c3457a59051eba45d2204aa1fb7388db@webmail.entel.upc.edu>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
   Hi,

   I'm seeing panics when removing an interface of a bridge. The system 
runs HEAD/AMD64 r236733. I see no changes to if_bridge.c in the last two 
days, so I would say the problem's still there. I also checked stable 
and the problem should be there too.

   The problem is that I have a bridge composed of two ethernet 
interfaces, an ath interface and a tap. As soon as I remove any of them 
the system panics. Because the system runs openvpn with the tap 
connected to the bridge, when the system starts to reboot, the openvpn 
daemon removes the tap and thus causing also the panic.

   The panic comes because at sys/net/if_bridge.c:943 the struct 
*ifnet->if_bridge of the interface removed is set to NULL too early. 
Because of this, at sys/net/if_bridge.c:996 we call 
if_bridge.c:bridge_linkstate where the struct *ifnet->if_bridge is 
needed. This causes the panic.

   I can pastebin the core file if needed.

   I'm attaching a simple patch that solves it. The struct 
*ifnet->if_bridge could be set to null only if the interface removed is 
gone, but I think it won't hurt to set it to null in any case.

   Regards,

   Gustau

[-- Attachment #2 --]
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 271ef30..6c112de 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -940,7 +940,6 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
 	if (bif->bif_flags & IFBIF_STP)
 		bstp_disable(&bif->bif_stp);
 
-	ifs->if_bridge = NULL;
 	BRIDGE_XLOCK(sc);
 	LIST_REMOVE(bif, bif_next);
 	BRIDGE_XDROP(sc);
@@ -994,6 +993,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
 	}
 	bstp_destroy(&bif->bif_stp);	/* prepare to free */
 	bridge_linkstate(ifs);
+	ifs->if_bridge = NULL;
 	BRIDGE_LOCK(sc);
 	free(bif, M_DEVBUF);
 }

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