]> git.ipfire.org Git - people/ms/mstpd.git/commitdiff
{add|del}bridge commands on server side (mstpd)
authordv1tas <dv1tas@fbe50366-0c72-4402-a84b-5d246361dba7>
Sat, 17 Dec 2011 19:51:57 +0000 (19:51 +0000)
committerdv1tas <dv1tas@fbe50366-0c72-4402-a84b-5d246361dba7>
Sat, 17 Dec 2011 19:51:57 +0000 (19:51 +0000)
git-svn-id: svn://svn.code.sf.net/p/mstpd/code/trunk@25 fbe50366-0c72-4402-a84b-5d246361dba7

bridge_ctl.h
bridge_track.c

index 79dfe02c28ed58577981279014cfb4845d729bf7..5eaabfd9d7bb5b9cc984e233f9693db189cb5903 100644 (file)
@@ -37,7 +37,7 @@ typedef struct
     __u8 macaddr[ETH_ALEN];
     char name[IFNAMSIZ];
 
-    bool up, stp_up;
+    bool up;
 } sysdep_br_data_t;
 
 typedef struct
index caed2234212a63dbeb166f49fe9621bc7ce24f46..f5d3b3ac809411ceb2e3ce652eda8c78c74c5840 100644 (file)
@@ -175,26 +175,10 @@ static bool check_mac_address(char *name, __u8 *addr)
     }
 }
 
-static bool stp_enabled(bridge_t * br)
+static void set_br_up(bridge_t * br, bool up)
 {
-    char path[40 + IFNAMSIZ];
-    sprintf(path, "/sys/class/net/%s/bridge/stp_state", br->sysdeps.name);
-    FILE *f = fopen(path, "r");
-    int enabled = 0;
-    if(!f || (1 != fscanf(f, "%d", &enabled)))
-        ERROR("Can't read from %s", path);
-    fclose(f);
-    INFO("STP on %s state %d", br->sysdeps.name, enabled);
-
-    return enabled == 2; /* ie user mode STP */
-}
-
-static void set_br_up(bridge_t * br, bool up, bool stp_up)
-{
-    INFO("%s was %s stp was %s", br->sysdeps.name,
-         br->sysdeps.up ? "up" : "down", br->sysdeps.stp_up ? "up" : "down");
-    INFO("Set bridge %s %s stp %s" , br->sysdeps.name,
-         up ? "up" : "down", stp_up ? "up" : "down");
+    INFO("%s was %s", br->sysdeps.name, br->sysdeps.up ? "up" : "down");
+    INFO("Set bridge %s %s", br->sysdeps.name, up ? "up" : "down");
 
     bool changed = false;
 
@@ -204,12 +188,6 @@ static void set_br_up(bridge_t * br, bool up, bool stp_up)
         changed = true;
     }
 
-    if(br->sysdeps.stp_up != stp_up)
-    {
-        br->sysdeps.stp_up = stp_up;
-        changed = true;
-    }
-
     if(check_mac_address(br->sysdeps.name, br->sysdeps.macaddr))
     {
         /* MAC address changed */
@@ -218,7 +196,7 @@ static void set_br_up(bridge_t * br, bool up, bool stp_up)
     }
 
     if(changed)
-        MSTP_IN_set_bridge_enable(br, br->sysdeps.up && br->sysdeps.stp_up);
+        MSTP_IN_set_bridge_enable(br, br->sysdeps.up);
 }
 
 static void set_if_up(port_t * ifc, bool up)
@@ -291,15 +269,10 @@ int bridge_notify(int br_index, int if_index, bool newlink, unsigned flags)
     if((br_index >= 0) && (br_index != if_index))
     {
         if(!(br = find_br(br_index)))
-            br = create_br(br_index);
-        if(!br)
-        {
-            ERROR("Couldn't create data for bridge interface %d", br_index);
-            return -1;
-        }
+            return -2; /* bridge not in list */
         int br_flags = get_flags(br->sysdeps.name);
         if(br_flags >= 0)
-            set_br_up(br, !!(br_flags & IFF_UP), stp_enabled(br));
+            set_br_up(br, !!(br_flags & IFF_UP));
     }
 
     if(br)
@@ -358,15 +331,8 @@ int bridge_notify(int br_index, int if_index, bool newlink, unsigned flags)
             if(br_index == if_index)
             {
                 if(!(br = find_br(br_index)))
-                {
-                    if(!(br = create_br(br_index)))
-                    {
-                        ERROR("Couldn't create data for bridge interface %d",
-                              br_index);
-                        return -1;
-                    }
-                }
-                set_br_up(br, up, stp_enabled(br));
+                    return -2; /* bridge not in list */
+                set_br_up(br, up);
             }
         }
     }
@@ -412,8 +378,6 @@ void bridge_bpdu_rcv(int if_index, const unsigned char *data, int len)
     /* sanity checks */
     TST(br == ifc->bridge,);
     TST(ifc->sysdeps.up,);
-    if(!br->sysdeps.stp_up)
-        return;
 
     /* Validate Ethernet and LLC header,
      * maybe we can skip this check thanks to Berkeley filter in packet socket?
@@ -842,10 +806,83 @@ int CTL_set_fids2mstids(int br_index, __u16 *fids2mstids)
 
 int CTL_add_bridges(int *br_array, int* *ifaces_lists)
 {
+    int i, j, ifcount, brcount = br_array[0];
+    bridge_t *br, *other_br;
+    port_t *ifc, *nxt;
+    int br_flags, if_flags;
+    int *if_array;
+    bool found;
+
+    for(i = 1; i <= brcount; ++i)
+    {
+        if(NULL == (br = find_br(br_array[i])))
+        {
+            if(NULL == (br = create_br(br_array[i])))
+            {
+                ERROR("Couldn't create data for bridge interface %d",
+                      br_array[i]);
+                return -1;
+            }
+            if(0 <= (br_flags = get_flags(br->sysdeps.name)))
+                set_br_up(br, !!(br_flags & IFF_UP));
+        }
+        if_array = ifaces_lists[i - 1];
+        ifcount = if_array[0];
+        /* delete all interfaces which are not in list */
+        list_for_each_entry_safe(ifc, nxt, &br->ports, br_list)
+        {
+            found = false;
+            for(j = 1; j <= ifcount; ++j)
+            {
+                if(ifc->sysdeps.if_index == if_array[j])
+                {
+                    found = true;
+                    break;
+                }
+            }
+            if(!found)
+                delete_if(ifc);
+        }
+        /* add all new interfaces from the list */
+        for(j = 1; j <= ifcount; ++j)
+        {
+            if(NULL != find_if(br, if_array[j]))
+                continue;
+            /* Check if this interface is slave of another bridge */
+            list_for_each_entry(other_br, &bridges, list)
+            {
+                if(other_br != br)
+                    if(delete_if_byindex(other_br, if_array[j]))
+                    {
+                        INFO("Device %d has come to bridge %s. "
+                             "Missed notify for deletion from bridge %s",
+                             if_array[j], br->sysdeps.name,
+                             other_br->sysdeps.name);
+                        break;
+                    }
+            }
+            if(NULL == (ifc = create_if(br, if_array[j])))
+            {
+                INFO("Couldn't create data for interface %d (master %s)",
+                     if_array[j], br->sysdeps.name);
+                continue;
+            }
+            if(0 <= (if_flags = get_flags(ifc->sysdeps.name)))
+                set_if_up(ifc, (IFF_UP | IFF_RUNNING) ==
+                               (if_flags & (IFF_UP | IFF_RUNNING))
+                         );
+        }
+    }
+
     return 0;
 }
 
 int CTL_del_bridges(int *br_array)
 {
+    int i, brcount = br_array[0];
+
+    for(i = 1; i <= brcount; ++i)
+        delete_br_byindex(br_array[i]);
+
     return 0;
 }