]> git.ipfire.org Git - people/ms/rstp.git/blobdiff - bridge_track.c
Merge remote-tracking branch 'upstream/master'
[people/ms/rstp.git] / bridge_track.c
index f5efa3ff69c81b12c3b2f9edbfc5bdb14fe91648..10e13f75ea4a46d9bcfdd6e489db43174b6e928b 100644 (file)
@@ -249,12 +249,15 @@ static int stp_enabled(struct ifdata *br)
        return enabled == 2;    /* ie user mode STP */
 }
 
-void set_br_up(struct ifdata *br, int up)
+static void set_br_up(struct ifdata *br, int up)
 {
        int stp_up = stp_enabled(br);
-       INFO("%s was %s stp was %s", br->name, br->up ? "up" : "down", br->stp_up ? "up" : "down");
+       INFO("%s was %s stp was %s", br->name,
+            up ? "up" : "down", 
+            br->stp_up ? "up" : "down");
        INFO("Set bridge %s %s stp %s" , br->name,
-            up ? "up" : "down", stp_up ? "up" : "down");
+            up ? "up" : "down", 
+            stp_up ? "up" : "down");
 
        int changed = 0;
 
@@ -280,7 +283,7 @@ void set_br_up(struct ifdata *br, int up)
                                         (br->up && br->stp_up)?1:0);
 }
 
-void set_if_up(struct ifdata *ifc, int up)
+static void set_if_up(struct ifdata *ifc, int up)
 {
        INFO("Port %s : %s", ifc->name, (up ? "up" : "down"));
        int speed = -1;
@@ -332,14 +335,14 @@ void set_if_up(struct ifdata *ifc, int up)
 
 /*------------------------------------------------------------*/
 
-int bridge_notify(int br_index, int if_index, int newlink, int up)
+int bridge_notify(int br_index, int if_index, int newlink, 
+                 unsigned flags)
 {
-       if (up)
-               up = 1;
-       LOG("br_index %d, if_index %d, newlink %d, up %d",
-               br_index, if_index, newlink, up);
-
        struct ifdata *br = NULL;
+
+       LOG("br_index %d, if_index %d, up %d running %d",
+           br_index, if_index, (flags & IFF_UP), flags & IFF_RUNNING);
+
        if (br_index >= 0) {
                br = find_if(br_index);
                if (br && !br->is_bridge) {
@@ -395,7 +398,10 @@ int bridge_notify(int br_index, int if_index, int newlink, int up)
                        delete_if(ifc);
                        return 0;
                }
-               set_if_up(ifc, up);     /* And speed and duplex */
+               int up = (flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING);
+
+               if (ifc->up != up)
+                       set_if_up(ifc, up);     /* And speed and duplex */
        } else {                /* No br_index */
                if (!newlink) {
                        /* DELLINK not from bridge means interface unregistered. */
@@ -417,11 +423,24 @@ int bridge_notify(int br_index, int if_index, int newlink, int up)
                                        }
                                }
                        }
+                       if (ifc && !ifc->is_bridge &&
+                           !is_bridge_slave(ifc->master->name, ifc->name)) {
+                               /* Interface might have left bridge and we might have missed deletion */
+                               delete_if(ifc);
+                               return 0;
+                       }
+
                        if (ifc) {
-                               if (ifc->is_bridge)
-                                       set_br_up(ifc, up);
-                               else
-                                       set_if_up(ifc, up);
+                               if (ifc->is_bridge) {
+                                       int up = (flags & IFF_UP) != 0;
+                                       if (ifc->up != up)
+                                               set_br_up(ifc, up);
+                               } else {
+                                       int up = (flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING);
+
+                                       if (ifc->up != up)
+                                               set_if_up(ifc, up);
+                               }
                        }
                }
        }