- Proper handle flags passed to bridge_rtflush() and bridge_rtdelete(),
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 26 Nov 2008 12:49:43 +0000 (12:49 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 26 Nov 2008 12:49:43 +0000 (12:49 +0000)
  instead of handle it as a boolean.
- Add IFBF_FLUSHSYNC flag so bridge_rtflush() and bridge_rtdelete() could
  perform async operation (used by STP code).

sys/net/bridge/bridgestp.c
sys/net/bridge/if_bridge.c
sys/net/bridge/if_bridgevar.h

index 37ad451..00da529 100644 (file)
@@ -31,7 +31,7 @@
  * $OpenBSD: bridgestp.c,v 1.5 2001/03/22 03:48:29 jason Exp $
  * $NetBSD: bridgestp.c,v 1.5 2003/11/28 08:56:48 keihan Exp $
  * $FreeBSD: src/sys/net/bridgestp.c,v 1.7 2005/10/11 02:58:32 thompsa Exp $
- * $DragonFly: src/sys/net/bridge/bridgestp.c,v 1.9 2008/11/22 04:30:28 sephe Exp $
+ * $DragonFly: src/sys/net/bridge/bridgestp.c,v 1.10 2008/11/26 12:49:43 sephe Exp $
  */
 
 /*
@@ -554,8 +554,6 @@ bstp_make_forwarding(struct bridge_softc *sc, struct bridge_iflist *bif)
 static void
 bstp_make_blocking(struct bridge_softc *sc, struct bridge_iflist *bif)
 {
-       struct ifnet *ifp, *bifp = sc->sc_ifp;
-
        if ((bif->bif_state != BSTP_IFSTATE_DISABLED) &&
            (bif->bif_state != BSTP_IFSTATE_BLOCKING)) {
                if ((bif->bif_state == BSTP_IFSTATE_FORWARDING) ||
@@ -565,12 +563,7 @@ bstp_make_blocking(struct bridge_softc *sc, struct bridge_iflist *bif)
                        }
                }
                bstp_set_port_state(bif, BSTP_IFSTATE_BLOCKING);
-
-               ifp = bif->bif_ifp;
-               lwkt_serialize_exit(bifp->if_serializer);
-               bridge_rtdelete(sc, ifp, IFBF_FLUSHDYN);
-               lwkt_serialize_enter(bifp->if_serializer);
-
+               bridge_rtdelete(sc, bif->bif_ifp, IFBF_FLUSHDYN);
                bstp_timer_stop(&bif->bif_forward_delay_timer);
        }
 }
@@ -964,7 +957,6 @@ bstp_enable_port(struct bridge_softc *sc, struct bridge_iflist *bif)
 static void
 bstp_disable_port(struct bridge_softc *sc, struct bridge_iflist *bif)
 {
-       struct ifnet *ifp, *bifp = sc->sc_ifp;
        int root;
 
        root = bstp_root_bridge(sc);
@@ -976,11 +968,7 @@ bstp_disable_port(struct bridge_softc *sc, struct bridge_iflist *bif)
        bstp_timer_stop(&bif->bif_forward_delay_timer);
        bstp_configuration_update(sc);
        bstp_port_state_selection(sc);
-
-       ifp = bif->bif_ifp;
-       lwkt_serialize_exit(bifp->if_serializer);
-       bridge_rtdelete(sc, ifp, IFBF_FLUSHDYN);
-       lwkt_serialize_enter(bifp->if_serializer);
+       bridge_rtdelete(sc, bif->bif_ifp, IFBF_FLUSHDYN);
 
        if (bstp_root_bridge(sc) && (root == 0)) {
                sc->sc_max_age = sc->sc_bridge_max_age;
index 1928424..46dc088 100644 (file)
@@ -66,7 +66,7 @@
  * $OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp $
  * $NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc Exp $
  * $FreeBSD: src/sys/net/if_bridge.c,v 1.26 2005/10/13 23:05:55 thompsa Exp $
- * $DragonFly: src/sys/net/bridge/if_bridge.c,v 1.59 2008/11/23 02:58:26 sephe Exp $
+ * $DragonFly: src/sys/net/bridge/if_bridge.c,v 1.60 2008/11/26 12:49:43 sephe Exp $
  */
 
 /*
@@ -384,6 +384,7 @@ static int  bridge_rtupdate(struct bridge_softc *, const uint8_t *,
                    struct ifnet *, uint8_t);
 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
 static void    bridge_rtreap(struct bridge_softc *);
+static void    bridge_rtreap_async(struct bridge_softc *);
 static void    bridge_rttrim(struct bridge_softc *);
 static int     bridge_rtage_finddead(struct bridge_softc *);
 static void    bridge_rtage(struct bridge_softc *);
@@ -1038,7 +1039,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
 
        /* See the comment in bridge_ioctl_stop() */
        bridge_rtmsg_sync(sc);
-       bridge_rtdelete(sc, ifs, IFBF_FLUSHALL);
+       bridge_rtdelete(sc, ifs, IFBF_FLUSHALL | IFBF_FLUSHSYNC);
 
        lwkt_serialize_enter(bifp->if_serializer);
 
@@ -1119,7 +1120,7 @@ bridge_ioctl_stop(struct bridge_softc *sc, void *arg __unused)
         * during above netmsg_service_sync() are flushed.
         */
        bridge_rtmsg_sync(sc);
-       bridge_rtflush(sc, IFBF_FLUSHDYN);
+       bridge_rtflush(sc, IFBF_FLUSHDYN | IFBF_FLUSHSYNC);
 
        lwkt_serialize_enter(ifp->if_serializer);
        return 0;
@@ -1512,7 +1513,7 @@ bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
        struct ifnet *ifp = sc->sc_ifp;
 
        lwkt_serialize_exit(ifp->if_serializer);
-       bridge_rtflush(sc, req->ifbr_ifsflags);
+       bridge_rtflush(sc, req->ifbr_ifsflags | IFBF_FLUSHSYNC);
        lwkt_serialize_enter(ifp->if_serializer);
 
        return (0);
@@ -2724,6 +2725,19 @@ bridge_rtreap(struct bridge_softc *sc)
        ifnet_domsg(&nmsg.nm_lmsg, 0);
 }
 
+static void
+bridge_rtreap_async(struct bridge_softc *sc)
+{
+       struct netmsg *nmsg;
+
+       nmsg = kmalloc(sizeof(*nmsg), M_LWKTMSG, M_WAITOK);
+
+       netmsg_init(nmsg, &netisr_afree_rport, 0, bridge_rtreap_handler);
+       nmsg->nm_lmsg.u.ms_resultp = sc;
+
+       ifnet_sendmsg(&nmsg->nm_lmsg, 0);
+}
+
 /*
  * bridge_rttrim:
  *
@@ -2871,25 +2885,27 @@ bridge_rtage(struct bridge_softc *sc)
  *     Remove all dynamic addresses from the bridge.
  */
 static void
-bridge_rtflush(struct bridge_softc *sc, int full)
+bridge_rtflush(struct bridge_softc *sc, int bf)
 {
        struct bridge_rtnode *brt;
        int reap;
 
-       ASSERT_NOT_SERIALIZED(sc->sc_ifp->if_serializer);
-
        reap = 0;
        LIST_FOREACH(brt, &sc->sc_rtlists[mycpuid], brt_list) {
                struct bridge_rtinfo *bri = brt->brt_info;
 
-               if (full ||
+               if ((bf & IFBF_FLUSHALL) ||
                    (bri->bri_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
                        bri->bri_dead = 1;
                        reap = 1;
                }
        }
-       if (reap)
-               bridge_rtreap(sc);
+       if (reap) {
+               if (bf & IFBF_FLUSHSYNC)
+                       bridge_rtreap(sc);
+               else
+                       bridge_rtreap_async(sc);
+       }
 }
 
 /*
@@ -2919,26 +2935,28 @@ bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
  *     Delete routes to a speicifc member interface.
  */
 void
-bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full)
+bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int bf)
 {
        struct bridge_rtnode *brt;
        int reap;
 
-       ASSERT_NOT_SERIALIZED(sc->sc_ifp->if_serializer);
-
        reap = 0;
        LIST_FOREACH(brt, &sc->sc_rtlists[mycpuid], brt_list) {
                struct bridge_rtinfo *bri = brt->brt_info;
 
                if (bri->bri_ifp == ifp &&
-                   (full ||
+                   ((bf & IFBF_FLUSHALL) ||
                     (bri->bri_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)) {
                        bri->bri_dead = 1;
                        reap = 1;
                }
        }
-       if (reap)
-               bridge_rtreap(sc);
+       if (reap) {
+               if (bf & IFBF_FLUSHSYNC)
+                       bridge_rtreap(sc);
+               else
+                       bridge_rtreap_async(sc);
+       }
 }
 
 /*
index 7e8eb57..333a1a0 100644 (file)
@@ -66,7 +66,7 @@
  * $OpenBSD: if_bridge.h,v 1.14 2001/03/22 03:48:29 jason Exp $
  * $NetBSD: if_bridgevar.h,v 1.4 2003/07/08 07:13:50 itojun Exp $
  * $FreeBSD: src/sys/net/if_bridgevar.h,v 1.4 2005/07/06 01:24:45 thompsa Exp $
- * $DragonFly: src/sys/net/bridge/if_bridgevar.h,v 1.9 2008/11/22 05:57:31 sephe Exp $
+ * $DragonFly: src/sys/net/bridge/if_bridgevar.h,v 1.10 2008/11/26 12:49:43 sephe Exp $
  */
 
 #ifndef _NET_IF_BRIDGEVAR_H
@@ -133,6 +133,7 @@ struct ifbreq {
 /* BRDGFLUSH */
 #define        IFBF_FLUSHDYN           0x00    /* flush learned addresses only */
 #define        IFBF_FLUSHALL           0x01    /* flush all addresses */
+#define IFBF_FLUSHSYNC         0x02    /* synchronized flush */
 
 /* STP port states */
 #define        BSTP_IFSTATE_DISABLED   0