From 519df1c1ac3a4fdd2fec94c91ec8c5c9cc6cd923 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 15 Jun 2017 22:05:53 +0200 Subject: [PATCH] network: clear whole networks When users specify lxc.network. we remove the whole network from the networks list. Signed-off-by: Christian Brauner --- src/lxc/confile.c | 27 ++++++++++++++++++++++--- src/lxc/confile_utils.c | 44 +++++++++++++++++++++++++++++++++++++++++ src/lxc/confile_utils.h | 1 + 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 04cc5a5f0..caa1374bd 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -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." 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) diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c index 895f9cd25..b67fe578d 100644 --- a/src/lxc/confile_utils.c +++ b/src/lxc/confile_utils.c @@ -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; +} diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h index 01cd0510b..c33ba0473 100644 --- a/src/lxc/confile_utils.h +++ b/src/lxc/confile_utils.h @@ -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 */