[lxc-devel] [lxc/master] network parser fixes
brauner on Github
lxc-bot at linuxcontainers.org
Sun Jul 30 19:47:02 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 581 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170730/4bcd9671/attachment.bin>
-------------- next part --------------
From 31ee747baa110d3cea080005f773c786edacb3b1 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sun, 30 Jul 2017 21:42:40 +0200
Subject: [PATCH 1/2] confile: use deindexed network keys
When we are passed a network key like "lxc.net.[i].ipv4.address" we need to
make sure that we pass the deindexed key "lxc.net.ipv4.address" to the
{get,clr,set} methods otherwise we'll end up in an endless loop.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/confile.c | 161 ++++++++++++++++++++++++++++++++++--------------------
1 file changed, 102 insertions(+), 59 deletions(-)
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 55917e8c4..858341952 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -3680,72 +3680,88 @@ static int get_config_includefiles(const char *key, char *retv, int inlen,
return -ENOSYS;
}
-static struct lxc_config_t *
-get_network_config_ops(const char *key, struct lxc_conf *lxc_conf, ssize_t *idx)
+static struct lxc_config_t *get_network_config_ops(const char *key,
+ struct lxc_conf *lxc_conf,
+ ssize_t *idx,
+ char **deindexed_key)
{
+ int ret;
+ unsigned int tmpidx;
+ size_t numstrlen;
char *copy, *idx_start, *idx_end;
struct lxc_config_t *config = NULL;
/* check that this is a sensible network key */
- if (strncmp("lxc.net.", key, 8))
+ if (strncmp("lxc.net.", key, 8)) {
+ ERROR("Invalid network configuration key \"%s\"", key);
return NULL;
+ }
copy = strdup(key);
- if (!copy)
+ if (!copy) {
+ ERROR("Failed to duplicate string \"%s\"", key);
return NULL;
+ }
/* lxc.net.<n> */
- if (isdigit(*(key + 8))) {
- int ret;
- unsigned int tmpidx;
- size_t numstrlen;
-
- /* beginning of index string */
- idx_start = (copy + 7);
- *idx_start = '\0';
-
- /* end of index string */
- idx_end = strchr((copy + 8), '.');
- if (!idx_end)
- goto on_error;
- *idx_end = '\0';
-
- /* parse current index */
- ret = lxc_safe_uint((idx_start + 1), &tmpidx);
- if (ret < 0) {
- *idx = ret;
- goto on_error;
- }
-
- /* This, of course is utterly nonsensical on so many levels, but
- * better safe than sorry.
- * (Checking for INT_MAX here is intentional.)
- */
- if (tmpidx == INT_MAX) {
- SYSERROR(
- "number of configured networks would overflow the "
- "counter... what are you doing?");
- goto on_error;
- }
- *idx = tmpidx;
+ if (!isdigit(*(key + 8))) {
+ ERROR("Failed to detect digit in string \"%s\"", key + 8);
+ goto on_error;
+ }
- numstrlen = strlen((idx_start + 1));
+ /* beginning of index string */
+ idx_start = (copy + 7);
+ *idx_start = '\0';
- /* repair configuration key */
- *idx_start = '.';
- *idx_end = '.';
+ /* end of index string */
+ idx_end = strchr((copy + 8), '.');
+ if (!idx_end) {
+ ERROR("Failed to detect \".\" in string \"%s\"", (copy + 8));
+ goto on_error;
+ }
+ *idx_end = '\0';
+
+ /* parse current index */
+ ret = lxc_safe_uint((idx_start + 1), &tmpidx);
+ if (ret < 0) {
+ ERROR("Failed to parse usigned integer from string \"%s\": %s",
+ idx_start + 1, strerror(-ret));
+ *idx = ret;
+ goto on_error;
+ }
- memmove(copy + 8, idx_end + 1, strlen(idx_end + 1));
- copy[strlen(key) - numstrlen + 1] = '\0';
+ /* This, of course is utterly nonsensical on so many levels, but
+ * better safe than sorry.
+ * (Checking for INT_MAX here is intentional.)
+ */
+ if (tmpidx == INT_MAX) {
+ SYSERROR("number of configured networks would overflow the "
+ "counter... what are you doing?");
+ goto on_error;
}
+ *idx = tmpidx;
+
+ numstrlen = strlen((idx_start + 1));
+
+ /* repair configuration key */
+ *idx_start = '.';
+ *idx_end = '.';
+
+ memmove(copy + 8, idx_end + 1, strlen(idx_end + 1));
+ copy[strlen(key) - numstrlen + 1] = '\0';
config = lxc_getconfig(copy);
- if (!config)
+ if (!config) {
ERROR("unknown network configuration key %s", key);
+ goto on_error;
+ }
+
+ *deindexed_key = copy;
+ return config;
on_error:
free(copy);
- return config;
+ return NULL;
}
/*
@@ -3756,22 +3772,33 @@ get_network_config_ops(const char *key, struct lxc_conf *lxc_conf, ssize_t *idx)
static int set_config_net_nic(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
+ int ret;
+ const char *idxstring;
struct lxc_config_t *config;
struct lxc_netdev *netdev;
ssize_t idx = -1;
+ char *deindexed_key = NULL;
+
+ idxstring = key + 8;
+ if (!isdigit(*idxstring))
+ return -1;
if (lxc_config_value_empty(value))
return clr_config_net_nic(key, lxc_conf, data);
- config = get_network_config_ops(key, lxc_conf, &idx);
+ config = get_network_config_ops(key, lxc_conf, &idx, &deindexed_key);
if (!config || idx < 0)
return -1;
netdev = lxc_get_netdev_by_idx(lxc_conf, (unsigned int)idx, true);
- if (!netdev)
+ if (!netdev) {
+ free(deindexed_key);
return -1;
+ }
- return config->set(key, value, lxc_conf, netdev);
+ ret = config->set(deindexed_key, value, lxc_conf, netdev);
+ free(deindexed_key);
+ return ret;
}
/*
@@ -3782,18 +3809,19 @@ static int set_config_net_nic(const char *key, const char *value,
static int clr_config_net_nic(const char *key, struct lxc_conf *lxc_conf,
void *data)
{
+ int ret;
const char *idxstring;
struct lxc_config_t *config;
struct lxc_netdev *netdev;
- ssize_t idx;
+ ssize_t idx = -1;
+ char *deindexed_key = NULL;
- /* If we get passed "lxc.net.<n>" we clear the whole network. */
- if (strncmp("lxc.net.", key, 8))
+ idxstring = key + 8;
+ if (!isdigit(*idxstring))
return -1;
- idxstring = key + 8;
/* The left conjunct is pretty self-explanatory. The right conjunct
- * checks whether the two pointers are equal. If they are we now that
+ * checks whether the two pointers are equal. If they are we know that
* this is not a key that is namespaced any further and so we are
* supposed to clear the whole network.
*/
@@ -3808,15 +3836,19 @@ static int clr_config_net_nic(const char *key, struct lxc_conf *lxc_conf,
return 0;
}
- config = get_network_config_ops(key, lxc_conf, &idx);
+ config = get_network_config_ops(key, lxc_conf, &idx, &deindexed_key);
if (!config || idx < 0)
return -1;
netdev = lxc_get_netdev_by_idx(lxc_conf, (unsigned int)idx, false);
- if (!netdev)
+ if (!netdev) {
+ free(deindexed_key);
return -1;
+ }
- return config->clr(key, lxc_conf, netdev);
+ ret = config->clr(deindexed_key, lxc_conf, netdev);
+ free(deindexed_key);
+ return ret;
}
static int clr_config_net_type(const char *key, struct lxc_conf *lxc_conf,
@@ -4099,19 +4131,30 @@ static int clr_config_net_ipv6_address(const char *key,
static int get_config_net_nic(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
+ int ret;
+ const char *idxstring;
struct lxc_config_t *config;
struct lxc_netdev *netdev;
ssize_t idx = -1;
+ char *deindexed_key = NULL;
- config = get_network_config_ops(key, c, &idx);
+ idxstring = key + 8;
+ if (!isdigit(*idxstring))
+ return -1;
+
+ config = get_network_config_ops(key, c, &idx, &deindexed_key);
if (!config || idx < 0)
return -1;
netdev = lxc_get_netdev_by_idx(c, (unsigned int)idx, false);
- if (!netdev)
+ if (!netdev) {
+ free(deindexed_key);
return -1;
+ }
- return config->get(key, retv, inlen, c, netdev);
+ ret = config->get(deindexed_key, retv, inlen, c, netdev);
+ free(deindexed_key);
+ return ret;
}
static int get_config_net_type(const char *key, char *retv, int inlen,
From 4222a9f44b57af51d140350160877a807eea96a6 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sun, 30 Jul 2017 21:45:36 +0200
Subject: [PATCH 2/2] lxccontainer: clear whole indexed networks
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/lxccontainer.c | 46 ++++++++++++++++++++++++++++++++++------------
1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index fa04becb6..eba65a44a 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -50,6 +50,7 @@
#include "commands_utils.h"
#include "confile.h"
#include "confile_legacy.h"
+#include "confile_utils.h"
#include "console.h"
#include "criu.h"
#include "log.h"
@@ -1839,18 +1840,30 @@ static bool lxcapi_createl(struct lxc_container *c, const char *t,
static void do_clear_unexp_config_line(struct lxc_conf *conf, const char *key)
{
- if (strcmp(key, "lxc.cgroup") == 0)
- clear_unexp_config_line(conf, key, true);
- else if (strcmp(key, "lxc.network") == 0)
- clear_unexp_config_line(conf, key, true);
- else if (strcmp(key, "lxc.net") == 0)
- clear_unexp_config_line(conf, key, true);
- else if (strcmp(key, "lxc.hook") == 0)
- clear_unexp_config_line(conf, key, true);
- else
- clear_unexp_config_line(conf, key, false);
- if (!do_append_unexp_config_line(conf, key, ""))
- WARN("Error clearing configuration for %s", key);
+ if (!strcmp(key, "lxc.cgroup"))
+ return clear_unexp_config_line(conf, key, true);
+
+ if (!strcmp(key, "lxc.network"))
+ return clear_unexp_config_line(conf, key, true);
+
+ if (!strcmp(key, "lxc.net"))
+ return clear_unexp_config_line(conf, key, true);
+
+ /* Clear a network with a specific index. */
+ if (!strncmp(key, "lxc.net.", 8)) {
+ int ret;
+ const char *idx;
+
+ idx = key + 8;
+ ret = lxc_safe_uint(idx, &(unsigned int){0});
+ if (!ret)
+ return clear_unexp_config_line(conf, key, true);
+ }
+
+ if (!strcmp(key, "lxc.hook"))
+ return clear_unexp_config_line(conf, key, true);
+
+ return clear_unexp_config_line(conf, key, false);
}
static bool do_lxcapi_clear_config_item(struct lxc_container *c,
@@ -2656,13 +2669,22 @@ static bool set_config_item_locked(struct lxc_container *c, const char *key, con
if (!c->lxc_conf)
c->lxc_conf = lxc_conf_init();
+
if (!c->lxc_conf)
return false;
+
config = lxc_getconfig(key);
if (!config)
return false;
+
if (config->set(key, v, c->lxc_conf, NULL) != 0)
return false;
+
+ if (lxc_config_value_empty(v)) {
+ do_clear_unexp_config_line(c->lxc_conf, key);
+ return true;
+ }
+
return do_append_unexp_config_line(c->lxc_conf, key, v);
}
More information about the lxc-devel
mailing list