timeout_barrier() in bridge_stop()

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

timeout_barrier() in bridge_stop()

Martin Pieuchot
If timeout_del(9) didn't remove the timeout we need to ensure we're not
leaving a reference to the `sc' in the wild.

We do not want to execute the timeout when the interface isn't running,
so add the proper check and correct the flag set/unset ordering.

ok?

diff --git sys/net/bridgectl.c sys/net/bridgectl.c
index 8fdbee5a50d..68114066f7c 100644
--- sys/net/bridgectl.c
+++ sys/net/bridgectl.c
@@ -328,9 +328,13 @@ void
 bridge_rtage(void *vsc)
 {
  struct bridge_softc *sc = vsc;
+ struct ifnet *ifp = &sc->sc_if;
  struct bridge_rtnode *n, *p;
  int i;
 
+ if (!ISSET(ifp->if_flags, IFF_RUNNING))
+ return;
+
  mtx_enter(&sc->sc_mtx);
  for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
  n = LIST_FIRST(&sc->sc_rts[i]);
diff --git sys/net/if_bridge.c sys/net/if_bridge.c
index 457206b11d4..7930bbc25ad 100644
--- sys/net/if_bridge.c
+++ sys/net/if_bridge.c
@@ -690,14 +690,15 @@ bridge_init(struct bridge_softc *sc)
 {
  struct ifnet *ifp = &sc->sc_if;
 
- if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING)
+ if (ISSET(ifp->if_flags, IFF_RUNNING))
  return;
 
- ifp->if_flags |= IFF_RUNNING;
  bstp_initialization(sc->sc_stp);
 
  if (sc->sc_brttimeout != 0)
  timeout_add_sec(&sc->sc_brtimeout, sc->sc_brttimeout);
+
+ SET(ifp->if_flags, IFF_RUNNING);
 }
 
 /*
@@ -708,17 +709,15 @@ bridge_stop(struct bridge_softc *sc)
 {
  struct ifnet *ifp = &sc->sc_if;
 
- /*
- * If we're not running, there's nothing to do.
- */
- if ((ifp->if_flags & IFF_RUNNING) == 0)
+ if (!ISSET(ifp->if_flags, IFF_RUNNING))
  return;
 
- timeout_del(&sc->sc_brtimeout);
+ CLR(ifp->if_flags, IFF_RUNNING);
 
- bridge_rtflush(sc, IFBF_FLUSHDYN);
+ if (!timeout_del(&sc->sc_brtimeout))
+ timeout_barrier(&sc->sc_brtimeout);
 
- ifp->if_flags &= ~IFF_RUNNING;
+ bridge_rtflush(sc, IFBF_FLUSHDYN);
 }
 
 /*