network: clear whole networks

When users specify

lxc.network.<n>

we remove the whole network from the networks list.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2017-06-15 22:05:53 +02:00
parent ff6da29581
commit 519df1c1ac
No known key found for this signature in database
GPG Key ID: 7B3C391EFEA93624
3 changed files with 69 additions and 3 deletions

View 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 /* This, of course is utterly nonsensical on so many levels, but
* better * better safe than sorry.
* safe than sorry.
*/ */
if (tmpidx == UINT_MAX) { if (tmpidx == UINT_MAX) {
SYSERROR( 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, static int clr_config_network_nic(const char *key, struct lxc_conf *lxc_conf,
void *data) void *data)
{ {
const char *idxstring;
struct lxc_config_t *config; struct lxc_config_t *config;
struct lxc_netdev *netdev; 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); config = get_network_config_ops(key, lxc_conf, &idx);
if (!config || idx < 0) if (!config || idx < 0)

View File

@ -293,3 +293,47 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE("downscript: %s", netdev->downscript); 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;
}

View 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, extern struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf,
unsigned int idx); unsigned int idx);
extern void lxc_log_configured_netdevs(const struct lxc_conf *conf); 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 */ #endif /* __LXC_CONFILE_UTILS_H */