]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
confile_legacy: fix legacy network parser 2116/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 29 Jan 2018 21:01:20 +0000 (22:01 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 30 Jan 2018 00:00:21 +0000 (01:00 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/confile_legacy.c

index e09ddba8fb305e72b5ef845a97f7e6dd701349a9..df419e640beb37aaf1435a6bf785c26c5bfb50c3 100644 (file)
@@ -154,6 +154,53 @@ int set_config_network_legacy(const char *key, const char *value,
        return lxc_clear_config_network(lxc_conf);
 }
 
+/*
+ * If you have p="lxc.network.0.link", pass it p+12
+ * to get back '0' (the index of the nic).
+ */
+static int get_network_netdev_idx(const char *key)
+{
+       int ret, idx;
+
+       if (*key < '0' || *key > '9')
+               return EINVAL;
+
+       ret = sscanf(key, "%d", &idx);
+       if (ret != 1)
+               return EINVAL;
+
+       /* Since we've implemented the new network parser legacy networks are
+        * recorded using a negative index starting from -1. To preserve the old
+        * behavior we need this function to return the appropriate negative
+        * index.
+        */
+       return -(++idx);
+}
+
+/*
+ * If you have p="lxc.network.0", pass this p+12 and it will return
+ * the netdev of the first configured nic.
+ */
+static struct lxc_netdev *get_netdev_from_key(const char *key,
+                                             struct lxc_list *network)
+{
+       int idx;
+       struct lxc_list *it;
+       struct lxc_netdev *netdev = NULL;
+
+       idx = get_network_netdev_idx(key);
+       if (idx == EINVAL)
+               return NULL;
+
+       lxc_list_for_each(it, network) {
+               netdev = it->elem;
+               if (idx == netdev->idx)
+                       return netdev;
+       }
+
+       return NULL;
+}
+
 int set_config_network_legacy_type(const char *key, const char *value,
                                   struct lxc_conf *lxc_conf, void *data)
 {
@@ -164,6 +211,12 @@ int set_config_network_legacy_type(const char *key, const char *value,
        if (lxc_config_value_empty(value))
                return lxc_clear_config_network(lxc_conf);
 
+       netdev = get_netdev_from_key(key + 12, network);
+       if (netdev) {
+               ERROR("Network already exists");
+               return -EEXIST;
+       }
+
        netdev = malloc(sizeof(*netdev));
        if (!netdev) {
                SYSERROR("failed to allocate memory");
@@ -187,7 +240,7 @@ int set_config_network_legacy_type(const char *key, const char *value,
        /* We maintain a negative count for legacy networks. */
        netdev->idx = -1;
        if (!lxc_list_empty(network)) {
-               prevnetdev = lxc_list_last_elem(network);
+               prevnetdev = lxc_list_first_elem(network);
                netdev->idx = prevnetdev->idx;
                if (netdev->idx == INT_MIN) {
                        ERROR("number of requested networks would underflow "
@@ -199,7 +252,7 @@ int set_config_network_legacy_type(const char *key, const char *value,
                netdev->idx--;
        }
 
-       lxc_list_add_tail(network, list);
+       lxc_list_add(network, list);
 
        if (!strcmp(value, "veth"))
                netdev->type = LXC_NET_VETH;
@@ -221,53 +274,6 @@ int set_config_network_legacy_type(const char *key, const char *value,
        return 0;
 }
 
-/*
- * If you have p="lxc.network.0.link", pass it p+12
- * to get back '0' (the index of the nic).
- */
-static int get_network_netdev_idx(const char *key)
-{
-       int ret, idx;
-
-       if (*key < '0' || *key > '9')
-               return EINVAL;
-
-       ret = sscanf(key, "%d", &idx);
-       if (ret != 1)
-               return EINVAL;
-
-       /* Since we've implemented the new network parser legacy networks are
-        * recorded using a negative index starting from -1. To preserve the old
-        * behavior we need this function to return the appropriate negative
-        * index.
-        */
-       return -(++idx);
-}
-
-/*
- * If you have p="lxc.network.0", pass this p+12 and it will return
- * the netdev of the first configured nic.
- */
-static struct lxc_netdev *get_netdev_from_key(const char *key,
-                                             struct lxc_list *network)
-{
-       int idx;
-       struct lxc_list *it;
-       struct lxc_netdev *netdev = NULL;
-
-       idx = get_network_netdev_idx(key);
-       if (idx == EINVAL)
-               return NULL;
-
-       lxc_list_for_each(it, network) {
-               netdev = it->elem;
-               if (idx == netdev->idx)
-                       return netdev;
-       }
-
-       return NULL;
-}
-
 int lxc_list_nicconfigs_legacy(struct lxc_conf *c, const char *key, char *retv,
                               int inlen)
 {
@@ -328,7 +334,7 @@ static struct lxc_netdev *network_netdev(const char *key, const char *value,
        }
 
        if (get_network_netdev_idx(key + 12) == EINVAL)
-               netdev = lxc_list_last_elem(network);
+               netdev = lxc_list_first_elem(network);
        else
                netdev = get_netdev_from_key(key + 12, network);
 
@@ -958,7 +964,7 @@ static int lxc_clear_nic(struct lxc_conf *c, const char *key)
        }
 
        if ((idx = get_network_netdev_idx(key)) == EINVAL)
-               netdev = lxc_list_last_elem(&c->network);
+               netdev = lxc_list_first_elem(&c->network);
        else {
                lxc_list_for_each(it, &c->network) {
                        netdev = it->elem;