kernel - Major bridging functionality added (bug fixes 2)
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 5 Mar 2011 22:27:13 +0000 (14:27 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 5 Mar 2011 22:27:13 +0000 (14:27 -0800)
* Recalculate the port configuration after enabling a member interface,
  fixing an issue where openvpn brings up a TAP interface after
  authenticating the link but whos weights then go unrecognized by the
  bridge.

  The port configuration was already being recalculated after a member
  interface becomes disabled.

* Reinitialize the bridge when the link0, link1, and/or link2 interface
  flag changes state, so the sysop doesn't have to bring the interface
  down and up manually to recognize the new settings.

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

index 1af681a..8fd7ec7 100644 (file)
@@ -1242,6 +1242,7 @@ bstp_enable_port(struct bridge_softc *sc, struct bridge_iflist *bif)
        bstp_initialize_port(sc, bif);
        if (sc->sc_ifp->if_flags & IFF_LINK1)
                bstp_timer_start(&bif->bif_link1_timer, 0);
+       bstp_configuration_update(sc);
        bstp_port_state_selection(sc);
 }
 
index d9cd8d9..98714a2 100644 (file)
@@ -444,6 +444,7 @@ static int  bridge_ioctl_daddr(struct bridge_softc *, void *);
 static int     bridge_ioctl_flush(struct bridge_softc *, void *);
 static int     bridge_ioctl_gpri(struct bridge_softc *, void *);
 static int     bridge_ioctl_spri(struct bridge_softc *, void *);
+static int     bridge_ioctl_reinit(struct bridge_softc *, void *);
 static int     bridge_ioctl_ght(struct bridge_softc *, void *);
 static int     bridge_ioctl_sht(struct bridge_softc *, void *);
 static int     bridge_ioctl_gfd(struct bridge_softc *, void *);
@@ -875,6 +876,19 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
                         */
                        ifp->if_init(sc);
                }
+
+               /*
+                * If running and link flag state change we have to
+                * reinitialize as well.
+                */
+               if ((ifp->if_flags & IFF_RUNNING) &&
+                   (ifp->if_flags & (IFF_LINK0|IFF_LINK1|IFF_LINK2)) !=
+                   sc->sc_copy_flags) {
+                       sc->sc_copy_flags = ifp->if_flags &
+                                       (IFF_LINK0|IFF_LINK1|IFF_LINK2);
+                       bridge_control(sc, 0, bridge_ioctl_reinit, NULL);
+               }
+
                break;
 
        case SIOCSIFMTU:
@@ -1582,6 +1596,14 @@ bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
 }
 
 static int
+bridge_ioctl_reinit(struct bridge_softc *sc, void *arg __unused)
+{
+       if (sc->sc_ifp->if_flags & IFF_RUNNING)
+               bstp_initialization(sc);
+       return (0);
+}
+
+static int
 bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
 {
        struct ifbrparam *param = arg;
index 5d9dd92..fef5194 100644 (file)
@@ -374,6 +374,7 @@ struct bridge_softc {
        struct bridge_iflist_head sc_spanlist;  /* span ports list */
        int                     sc_span;        /* has span ports */
        struct bridge_timer     sc_link_timer;
+       int                     sc_copy_flags;  /* copy if_flags */
 };
 #define sc_if                   sc_arp.ac_if