From c2dbbbb6122e1ed1814dc076e4300d30ad3759e7 Mon Sep 17 00:00:00 2001 From: 0x0916 Date: Thu, 29 Jun 2017 11:48:35 +0800 Subject: [PATCH] confile_legacy: fix lxc_clear_nic error `lxc_clear_nic` can not clear the nic, because it will not found the right `netdev`. testcase from get_item.c ``` 313 if (!c->set_config_item(c, "lxc.network.hwaddr", "00:16:3e:xx:xx:xx")) { 314 fprintf(stderr, "%d: failed to set network.hwaddr\n", __LINE__); 315 goto out; 316 } 317 if (!c->set_config_item(c, "lxc.network.ipv4", "10.2.3.4")) { 318 fprintf(stderr, "%d: failed to set ipv4\n", __LINE__); 319 goto out; 320 } 321 322 ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); 323 if (ret <= 0) { 324 fprintf(stderr, "%d: lxc.network.0.ipv4 returned %d\n", __LINE__, ret); 325 goto out; 326 } 327 if (!c->clear_config_item(c, "lxc.network.0.ipv4")) { 328 fprintf(stderr, "%d: failed clearing all ipv4 entries\n", __LINE__); 329 goto out; 330 } 331 ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); 332 if (ret != 0) { 333 fprintf(stderr, "%d: after clearing ipv4 entries get_item(lxc.network.0.ipv4 returned %d\n", __LINE__, ret); 334 goto out; 335 } ``` line `327` will failed to clear nic, and line `333` give the error. Signed-off-by: 0x0916 --- src/lxc/confile_legacy.c | 47 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/lxc/confile_legacy.c b/src/lxc/confile_legacy.c index bb5c63c52..ba8bfe6ce 100644 --- a/src/lxc/confile_legacy.c +++ b/src/lxc/confile_legacy.c @@ -945,34 +945,33 @@ int get_config_network_legacy_item(const char *key, char *retv, int inlen, static int lxc_clear_nic(struct lxc_conf *c, const char *key) { char *p1; - int ret, idx, i; - struct lxc_list *it; - struct lxc_netdev *netdev; + int idx; + struct lxc_list *it = NULL; + struct lxc_netdev *netdev = NULL; + + if (lxc_list_empty(&c->network)) { + ERROR("network is not created for %s", key); + return -1; + } + + if ((idx = get_network_netdev_idx(key)) == EINVAL) + netdev = lxc_list_last_elem(&c->network); + else { + lxc_list_for_each(it, &c->network) { + netdev = it->elem; + if (idx == netdev->idx) + break; + netdev = NULL; + } + } + if (!netdev) + return -1; p1 = strchr(key, '.'); if (!p1 || *(p1+1) == '\0') p1 = NULL; - ret = sscanf(key, "%d", &idx); - if (ret != 1) return -1; - if (idx < 0) - return -1; - - i = 0; - lxc_list_for_each(it, &c->network) { - if (i == idx) - break; - i++; - } - if (i < idx) // we don't have that many nics defined - return -1; - - if (!it || !it->elem) - return -1; - - netdev = it->elem; - - if (!p1) { + if (!p1 && it) { lxc_remove_nic(it); } else if (strcmp(p1, ".ipv4") == 0) { struct lxc_list *it2,*next; @@ -989,7 +988,7 @@ static int lxc_clear_nic(struct lxc_conf *c, const char *key) free(it2); } } - else return -1; + else return -1; return 0; }