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

bridge_track.c
ctl_functions.h
ctl_main.c
ctl_socket_server.c

index c2a11e0cbe4fa3dda79cb55c10c3b9ceb6866475..caed2234212a63dbeb166f49fe9621bc7ce24f46 100644 (file)
@@ -839,3 +839,13 @@ int CTL_set_fids2mstids(int br_index, __u16 *fids2mstids)
     CTL_CHECK_BRIDGE;
     return MSTP_IN_set_all_fids2mstids(br, fids2mstids) ? 0 : -1;
 }
+
+int CTL_add_bridges(int *br_array, int* *ifaces_lists)
+{
+    return 0;
+}
+
+int CTL_del_bridges(int *br_array)
+{
+    return 0;
+}
index 5b09a209e44dc032864b77624c3aee4f0c803add..a86e3e1d88a3e3b77d7d635085cf55c307cc500f 100644 (file)
@@ -448,6 +448,16 @@ struct set_fids2mstids_OUT
 #define set_fids2mstids_CALL (in->br_index, in->fids2mstids)
 CTL_DECLARE(set_fids2mstids);
 
+/* add bridges */
+#define CMD_CODE_add_bridges    122
+#define add_bridges_ARGS (int *br_array, int* *ifaces_lists)
+CTL_DECLARE(add_bridges);
+
+/* delete bridges */
+#define CMD_CODE_del_bridges    123
+#define del_bridges_ARGS (int *br_array)
+CTL_DECLARE(del_bridges);
+
 /* General case part in ctl command server switch */
 #define SERVER_MESSAGE_CASE(name)                            \
     case CMD_CODE_ ## name : do                              \
index 4411bbb4080a06f1ed21a0a3370f5cb46d70aaf4..0a34c86b2d744d30e0acdbac80c26337eb2ca299 100644 (file)
@@ -636,6 +636,18 @@ static int not_dot_dotdot(const struct dirent *entry)
     return !('.' == n[0] && (0 == n[1] || ('.' == n[1] && 0 == n[2])));
 }
 
+static int get_port_list(const char *br_ifname, struct dirent ***namelist)
+{
+    int res;
+    char buf[SYSFS_PATH_MAX];
+
+    snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", br_ifname);
+    if(0 > (res = scandir(buf, namelist, not_dot_dotdot, sorting_func)))
+        fprintf(stderr, "Error getting list of all ports of bridge %s\n",
+                br_ifname);
+    return res;
+}
+
 static int cmd_showport(int argc, char *const *argv)
 {
     int r = 0;
@@ -666,15 +678,8 @@ static int cmd_showport(int argc, char *const *argv)
     }
     else
     {
-        char buf[SYSFS_PATH_MAX];
-        snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", argv[1]);
-        count = scandir(buf, &namelist, not_dot_dotdot, sorting_func);
-        if(0 > count)
-        {
-            fprintf(stderr, "Error getting list of all ports of bridge %s\n",
-                    argv[1]);
-            return -1;
-        }
+        if(0 > (count = get_port_list(argv[1], &namelist)))
+            return count;
     }
 
     for(i = 0; i < count; ++i)
@@ -740,6 +745,91 @@ static int cmd_showtreeport(int argc, char *const *argv)
     return 0;
 }
 
+static int cmd_addbridge(int argc, char *const *argv)
+{
+    int i, j, res, ifcount, brcount = argc - 1;
+    int *br_array;
+    int* *ifaces_lists;
+
+    if(NULL == (br_array = malloc((brcount + 1) * sizeof(int))))
+    {
+out_of_memory_exit:
+        fprintf(stderr, "out of memory, brcount = %d\n", brcount);
+        return -1;
+    }
+    if(NULL == (ifaces_lists = malloc(brcount * sizeof(int*))))
+    {
+        free(br_array);
+        goto out_of_memory_exit;
+    }
+
+    br_array[0] = brcount;
+    for(i = 1; i <= brcount; ++i)
+    {
+        struct dirent **namelist;
+
+        br_array[i] = get_index(argv[i], "bridge");
+
+        if(0 > (ifcount = get_port_list(argv[i], &namelist)))
+        {
+ifaces_error_exit:
+            for(i -= 2; i >= 0; --i)
+                free(ifaces_lists[i]);
+            free(ifaces_lists);
+            free(br_array);
+            return ifcount;
+        }
+
+        if(NULL == (ifaces_lists[i - 1] = malloc((ifcount + 1) * sizeof(int))))
+        {
+            fprintf(stderr, "out of memory, bridge %s, ifcount = %d\n",
+                    argv[i], ifcount);
+            for(j = 0; j < ifcount; ++j)
+                free(namelist[j]);
+            free(namelist);
+            ifcount = -1;
+            goto ifaces_error_exit;
+        }
+
+        ifaces_lists[i - 1][0] = ifcount;
+        for(j = 1; j <= ifcount; ++j)
+        {
+            ifaces_lists[i - 1][j] = get_index(namelist[j - 1]->d_name, "port");
+            free(namelist[j - 1]);
+        }
+        free(namelist);
+    }
+
+    res = CTL_add_bridges(br_array, ifaces_lists);
+
+    for(i = 0; i < brcount; ++i)
+        free(ifaces_lists[i]);
+    free(ifaces_lists);
+    free(br_array);
+    return res;
+}
+
+static int cmd_delbridge(int argc, char *const *argv)
+{
+    int i, res, brcount = argc - 1;
+    int *br_array;
+
+    if(NULL == (br_array = malloc((brcount + 1) * sizeof(int))))
+    {
+        fprintf(stderr, "out of memory, brcount = %d\n", brcount);
+        return -1;
+    }
+
+    br_array[0] = brcount;
+    for(i = 1; i <= brcount; ++i)
+        br_array[i] = get_index(argv[i], "bridge");
+
+    res = CTL_del_bridges(br_array);
+
+    free(br_array);
+    return res;
+}
+
 static unsigned int getuint(const char *s)
 {
     char *end;
@@ -1203,6 +1293,12 @@ struct command
 
 static const struct command commands[] =
 {
+    /* Add/delete bridges */
+    {1, 32, "addbridge", cmd_addbridge,
+     "<bridge> [<bridge> ...]", "Add bridges to the mstpd's list"},
+    {1, 32, "delbridge", cmd_delbridge,
+     "<bridge> [<bridge> ...]", "Remove bridges from the mstpd's list"},
+
     /* Show global bridge */
     {0, 32, "showbridge", cmd_showbridge,
      "[<bridge> ... [param]]", "Show bridge state for the CIST"},
@@ -1395,6 +1491,60 @@ CLIENT_SIDE_FUNCTION(set_fid2mstid)
 CLIENT_SIDE_FUNCTION(set_vids2fids)
 CLIENT_SIDE_FUNCTION(set_fids2mstids)
 
+CTL_DECLARE(add_bridges)
+{
+    int res = 0;
+    LogString log = { .buf = "" };
+    int i, chunk_count, brcount, serialized_data_count;
+    int *serialized_data, *ptr;
+
+    chunk_count = serialized_data_count = (brcount = br_array[0]) + 1;
+    for(i = 0; i < brcount; ++i)
+        serialized_data_count += ifaces_lists[i][0] + 1;
+    if(NULL == (serialized_data = malloc(serialized_data_count * sizeof(int))))
+    {
+        LOG("out of memory, serialized_data_count = %d",
+            serialized_data_count);
+        return -1;
+    }
+    memcpy(serialized_data, br_array, chunk_count * sizeof(int));
+    ptr = serialized_data + chunk_count;
+    for(i = 0; i < brcount; ++i)
+    {
+        chunk_count = ifaces_lists[i][0] + 1;
+        memcpy(ptr, ifaces_lists[i], chunk_count * sizeof(int));
+        ptr += chunk_count;
+    }
+
+    int r = send_ctl_message(CMD_CODE_add_bridges, serialized_data,
+                             serialized_data_count * sizeof(int),
+                             NULL, 0, &log, &res);
+    free(serialized_data);
+    if(r || res)
+        LOG("Got return code %d, %d\n%s", r, res, log.buf);
+    if(r)
+        return r;
+    if(res)
+        return res;
+    return 0;
+}
+
+CTL_DECLARE(del_bridges)
+{
+    int res = 0;
+    LogString log = { .buf = "" };
+    int r = send_ctl_message(CMD_CODE_del_bridges,
+                             br_array, (br_array[0] + 1) * sizeof(int),
+                             NULL, 0, &log, &res);
+    if(r || res)
+        LOG("Got return code %d, %d\n%s", r, res, log.buf);
+    if(r)
+        return r;
+    if(res)
+        return res;
+    return 0;
+}
+
 /*********************** Logging *********************/
 
 void Dprintf(int level, const char *fmt, ...)
index 105ccbb6b13f2d181e079d4b561365dd4e9c6045..46919a8af9629c72d7e1b57618b738c199cc18a8 100644 (file)
@@ -83,6 +83,91 @@ static int handle_message(int cmd, void *inbuf, int lin,
         SERVER_MESSAGE_CASE(set_vids2fids);
         SERVER_MESSAGE_CASE(set_fids2mstids);
 
+        case CMD_CODE_add_bridges:
+        {
+            if(0 != lout)
+            {
+                LOG("Bad sizes: lout %d != 0", lout);
+                return -1;
+            }
+            if(sizeof(int) > lin)
+            {
+                LOG("Bad sizes: lin == 0");
+                return -1;
+            }
+            int *br_array = inbuf;
+            int i, serialized_data_count, chunk_count, brcount = br_array[0];
+            int *ptr = br_array + (serialized_data_count = (brcount + 1));
+            if(lin < ((serialized_data_count + 1) * sizeof(int)))
+            {
+bad_lin1:       LOG("Bad sizes: lin %d < %d", lin,
+                    (serialized_data_count + 1) * sizeof(int));
+                return -1;
+            }
+            for(i = 0; i < brcount; ++i)
+            {
+                serialized_data_count += (chunk_count = *ptr + 1);
+                if(i < (brcount - 1))
+                {
+                    if(lin < ((serialized_data_count + 1) * sizeof(int)))
+                        goto bad_lin1;
+                    ptr += chunk_count;
+                }
+                else
+                {
+                    if(lin != (serialized_data_count * sizeof(int)))
+                    {
+                        LOG("Bad sizes: lin %d != %d", lin,
+                            serialized_data_count * sizeof(int));
+                        return -1;
+                    }
+                }
+            }
+            int* *ifaces_lists = malloc(brcount * sizeof(int*));
+            if(NULL == ifaces_lists)
+            {
+                LOG("out of memory, brcount = %d\n", brcount);
+                return -1;
+            }
+            ptr = br_array + (brcount + 1);
+            for(i = 0; i < brcount; ++i)
+            {
+                ifaces_lists[i] = ptr;
+                ptr += ifaces_lists[i][0] + 1;
+            }
+            int r = CTL_add_bridges(br_array, ifaces_lists);
+            free(ifaces_lists);
+            if(r)
+                return r;
+            return r;
+        }
+
+        case CMD_CODE_del_bridges:
+        {
+            if(0 != lout)
+            {
+                LOG("Bad sizes: lout %d != 0", lout);
+                return -1;
+            }
+            if(sizeof(int) > lin)
+            {
+                LOG("Bad sizes: lin == 0");
+                return -1;
+            }
+            int *br_array = inbuf;
+            int brcount = br_array[0];
+            if(((brcount + 1) * sizeof(int)) != lin)
+            {
+                LOG("Bad sizes: lin %d != %d", lin,
+                    (brcount + 1) * sizeof(int));
+                return -1;
+            }
+            int r = CTL_del_bridges(br_array);
+            if(r)
+                return r;
+            return r;
+        }
+
         default:
             ERROR("CTL: Unknown command %d", cmd);
             return -1;