From 70a82405f4fe81c73ba05d682f858fcca0658e06 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Mon, 29 Jan 2018 22:01:20 +0100 Subject: [PATCH] confile_legacy: fix legacy network parser Signed-off-by: Christian Brauner --- src/lxc/confile_legacy.c | 108 +++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 51 deletions(-) diff --git a/src/lxc/confile_legacy.c b/src/lxc/confile_legacy.c index e09ddba8f..df419e640 100644 --- a/src/lxc/confile_legacy.c +++ b/src/lxc/confile_legacy.c @@ -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; -- 2.47.2