]> git.proxmox.com Git - mirror_lxc.git/commitdiff
network: clear whole networks
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 15 Jun 2017 20:05:53 +0000 (22:05 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 18 Jun 2017 09:55:32 +0000 (11:55 +0200)
When users specify

lxc.network.<n>

we remove the whole network from the networks list.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/confile.c
src/lxc/confile_utils.c
src/lxc/confile_utils.h

index 04cc5a5f0af0d6543583749a57e524a6fed24b65..caa1374bdd279db16ed67be2cd0ac74b578461d4 100644 (file)
@@ -4294,8 +4294,7 @@ get_network_config_ops(const char *key, struct lxc_conf *lxc_conf, ssize_t *idx)
                }
 
                /* This, of course is utterly nonsensical on so many levels, but
-               * better
-               * safe than sorry.
+                * better safe than sorry.
                 */
                if (tmpidx == UINT_MAX) {
                        SYSERROR(
@@ -4355,9 +4354,31 @@ static int set_config_network_nic(const char *key, const char *value,
 static int clr_config_network_nic(const char *key, struct lxc_conf *lxc_conf,
                                  void *data)
 {
+       const char *idxstring;
        struct lxc_config_t *config;
        struct lxc_netdev *netdev;
-       ssize_t idx = -1;
+       ssize_t idx;
+
+       /* If we get passed "lxc.network.<n>" we clear the whole network. */
+       if (strncmp("lxc.network.", key, 12))
+               return -1;
+
+       idxstring = key + 12;
+       /* The left conjunct is pretty self-explanatory. The right conjunct
+        * checks whether the two pointers are equal. If they are we now that
+        * this is not a key that is namespaced any further and so we are
+        * supposed to clear the whole network.
+        */
+       if (isdigit(*idxstring) && (strrchr(key, '.') == (idxstring - 1))) {
+               unsigned int rmnetdevidx;
+
+               if (lxc_safe_uint(idxstring, &rmnetdevidx) < 0)
+                       return -1;
+
+               /* Remove network from network list. */
+               lxc_remove_nic_by_idx(lxc_conf, rmnetdevidx);
+               return 0;
+       }
 
        config = get_network_config_ops(key, lxc_conf, &idx);
        if (!config || idx < 0)
index 895f9cd25bf9279acc016337059500067b5f2bea..b67fe578d1a70898c510a067b4a8209aa179d19a 100644 (file)
@@ -293,3 +293,47 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
                        TRACE("downscript: %s", netdev->downscript);
        }
 }
+
+bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx)
+{
+       struct lxc_list *cur, *it, *next;
+       struct lxc_netdev *netdev;
+       bool found = false;
+
+       lxc_list_for_each_safe(cur, &conf->network, next) {
+               netdev = cur->elem;
+               if (netdev->idx != idx)
+                       continue;
+
+               lxc_list_del(cur);
+               found = true;
+               break;
+       }
+
+       if (!found)
+               return false;
+
+       free(netdev->link);
+       free(netdev->name);
+       if (netdev->type == LXC_NET_VETH)
+               free(netdev->priv.veth_attr.pair);
+       free(netdev->upscript);
+       free(netdev->hwaddr);
+       free(netdev->mtu);
+       free(netdev->ipv4_gateway);
+       free(netdev->ipv6_gateway);
+       lxc_list_for_each_safe(it, &netdev->ipv4, next) {
+               lxc_list_del(it);
+               free(it->elem);
+               free(it);
+       }
+       lxc_list_for_each_safe(it, &netdev->ipv6, next) {
+               lxc_list_del(it);
+               free(it->elem);
+               free(it);
+       }
+       free(netdev);
+       free(cur);
+
+       return true;
+}
index 01cd0510b4bd666d2153d4bc0b20c4ceba97f7df..c33ba047374f9ae1633a6b8b8c16c74263cb3118 100644 (file)
@@ -33,5 +33,6 @@ extern struct lxc_netdev *lxc_find_netdev_by_idx(struct lxc_conf *conf,
 extern struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf,
                                                unsigned int idx);
 extern void lxc_log_configured_netdevs(const struct lxc_conf *conf);
+extern bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx);
 
 #endif /* __LXC_CONFILE_UTILS_H */