confile_legacy: fix legacy network parser

parent b28e2826
...@@ -154,6 +154,53 @@ int set_config_network_legacy(const char *key, const char *value, ...@@ -154,6 +154,53 @@ int set_config_network_legacy(const char *key, const char *value,
return lxc_clear_config_network(lxc_conf); 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, int set_config_network_legacy_type(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
...@@ -164,6 +211,12 @@ int set_config_network_legacy_type(const char *key, const char *value, ...@@ -164,6 +211,12 @@ int set_config_network_legacy_type(const char *key, const char *value,
if (lxc_config_value_empty(value)) if (lxc_config_value_empty(value))
return lxc_clear_config_network(lxc_conf); 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)); netdev = malloc(sizeof(*netdev));
if (!netdev) { if (!netdev) {
SYSERROR("failed to allocate memory"); SYSERROR("failed to allocate memory");
...@@ -187,7 +240,7 @@ int set_config_network_legacy_type(const char *key, const char *value, ...@@ -187,7 +240,7 @@ int set_config_network_legacy_type(const char *key, const char *value,
/* We maintain a negative count for legacy networks. */ /* We maintain a negative count for legacy networks. */
netdev->idx = -1; netdev->idx = -1;
if (!lxc_list_empty(network)) { if (!lxc_list_empty(network)) {
prevnetdev = lxc_list_last_elem(network); prevnetdev = lxc_list_first_elem(network);
netdev->idx = prevnetdev->idx; netdev->idx = prevnetdev->idx;
if (netdev->idx == INT_MIN) { if (netdev->idx == INT_MIN) {
ERROR("number of requested networks would underflow " ERROR("number of requested networks would underflow "
...@@ -199,7 +252,7 @@ int set_config_network_legacy_type(const char *key, const char *value, ...@@ -199,7 +252,7 @@ int set_config_network_legacy_type(const char *key, const char *value,
netdev->idx--; netdev->idx--;
} }
lxc_list_add_tail(network, list); lxc_list_add(network, list);
if (!strcmp(value, "veth")) if (!strcmp(value, "veth"))
netdev->type = LXC_NET_VETH; netdev->type = LXC_NET_VETH;
...@@ -221,53 +274,6 @@ int set_config_network_legacy_type(const char *key, const char *value, ...@@ -221,53 +274,6 @@ int set_config_network_legacy_type(const char *key, const char *value,
return 0; 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 lxc_list_nicconfigs_legacy(struct lxc_conf *c, const char *key, char *retv,
int inlen) int inlen)
{ {
...@@ -328,7 +334,7 @@ static struct lxc_netdev *network_netdev(const char *key, const char *value, ...@@ -328,7 +334,7 @@ static struct lxc_netdev *network_netdev(const char *key, const char *value,
} }
if (get_network_netdev_idx(key + 12) == EINVAL) if (get_network_netdev_idx(key + 12) == EINVAL)
netdev = lxc_list_last_elem(network); netdev = lxc_list_first_elem(network);
else else
netdev = get_netdev_from_key(key + 12, network); netdev = get_netdev_from_key(key + 12, network);
...@@ -958,7 +964,7 @@ static int lxc_clear_nic(struct lxc_conf *c, const char *key) ...@@ -958,7 +964,7 @@ static int lxc_clear_nic(struct lxc_conf *c, const char *key)
} }
if ((idx = get_network_netdev_idx(key)) == EINVAL) if ((idx = get_network_netdev_idx(key)) == EINVAL)
netdev = lxc_list_last_elem(&c->network); netdev = lxc_list_first_elem(&c->network);
else { else {
lxc_list_for_each(it, &c->network) { lxc_list_for_each(it, &c->network) {
netdev = it->elem; netdev = it->elem;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment