network: new network parser part II

Serge and I discussed the new network parser we've merge a couple of days ago. He pointed out that a bunch of use-cases we're currently supporting in the old network parser would be broken by the new parser. As we've pointed out many times before, we're strongly commited to backwards compatibility and not breaking existing use-cases. That's why we decided to take a new approach. Instead of trying to mangle the old parser and new parser to come up with something that allows a smooth transition we will simply deprecate the old configuration keys with LXC 3.0. In the meantime we will support the full-blown old legacy parser and the new network parser. Specifically, this means that we're deprecating: lxc.network.* in favor of lxc.net.* With LXC 2.1. defining networks using lxc.network.* keys will cause a deprecation warning to be shown/logged. We strongly suggest that users upgrade their existing configuration files to switch to the new network configuration parser. Starting with LXC 3.0 we will remove all lxc.network.* keys and will only support lxc.net.* style network configurations. Note that the new network configuration parser will only accept index based configuration keys, i.e. we are only support lxc.net.[i].* keys without an index such as lxc.net.type are not supported anymore. The advantages of this approach are vast. Not just internally, but also user-facing since it is much clearer what configuration key belongs to what network. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 842404a7
......@@ -21,6 +21,7 @@ noinst_HEADERS = \
caps.h \
conf.h \
confile.h \
confile_network_legacy.h \
confile_utils.h \
console.h \
error.h \
......@@ -103,6 +104,7 @@ liblxc_la_SOURCES = \
namespace.h namespace.c \
conf.c conf.h \
confile.c confile.h \
confile_network_legacy.c confile_network_legacy.h \
confile_utils.c confile_utils.h \
list.h \
state.c state.h \
......
......@@ -2533,6 +2533,13 @@ static int lxc_setup_networks_in_child_namespaces(const struct lxc_conf *conf,
lxc_list_for_each(iterator, network) {
netdev = iterator->elem;
/* REMOVE in LXC 3.0 */
if (netdev->idx < 0) {
ERROR("WARNING: using \"lxc.network.*\" keys to define "
"networks is DEPRECATED, please switch to using "
"\"lxc.net.[i].* keys\"");
}
if (lxc_setup_netdev_in_child_namespaces(netdev)) {
ERROR("failed to setup netdev");
return -1;
......
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <daniel.lezcano at free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __LXC_CONFILE_NETWORK_LEGACY_H
#define __LXC_CONFILE_NETWORK_LEGACY_H
#include <stdio.h>
#include <lxc/attach_options.h>
#include <stdbool.h>
struct lxc_conf;
struct lxc_list;
extern int set_config_network_legacy_type(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_flags(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_link(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_name(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_veth_pair(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_macvlan_mode(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_hwaddr(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_vlan_id(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_mtu(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_ipv4(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_ipv4_gateway(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_script_up(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_script_down(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_ipv6(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_ipv6_gateway(const char *, const char *,
struct lxc_conf *, void *);
extern int set_config_network_legacy_nic(const char *, const char *,
struct lxc_conf *, void *);
extern int get_config_network_legacy_item(const char *, char *, int,
struct lxc_conf *, void *);
extern int clr_config_network_legacy_item(const char *, struct lxc_conf *,
void *);
extern int set_config_network_legacy(const char *, const char *,
struct lxc_conf *, void *);
extern int get_config_network_legacy(const char *, char *, int,
struct lxc_conf *, void *);
extern int clr_config_network_legacy(const char *, struct lxc_conf *, void *);
extern int lxc_list_nicconfigs_legacy(struct lxc_conf *c, const char *key,
char *retv, int inlen);
extern int lxc_listconfigs(char *retv, int inlen);
extern bool network_new_hwaddrs(struct lxc_conf *conf);
#endif
......@@ -19,6 +19,7 @@
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -30,6 +31,7 @@
#include "error.h"
#include "log.h"
#include "list.h"
#include "parse.h"
#include "utils.h"
lxc_log_define(lxc_confile_utils, lxc);
......@@ -444,3 +446,139 @@ char *lxc_macvlan_flag_to_mode(int mode)
return NULL;
}
int set_config_string_item(char **conf_item, const char *value)
{
char *new_value;
if (lxc_config_value_empty(value)) {
free(*conf_item);
*conf_item = NULL;
return 0;
}
new_value = strdup(value);
if (!new_value) {
SYSERROR("failed to duplicate string \"%s\"", value);
return -1;
}
free(*conf_item);
*conf_item = new_value;
return 0;
}
int set_config_string_item_max(char **conf_item, const char *value, size_t max)
{
if (strlen(value) >= max) {
ERROR("%s is too long (>= %lu)", value, (unsigned long)max);
return -1;
}
return set_config_string_item(conf_item, value);
}
int set_config_path_item(char **conf_item, const char *value)
{
return set_config_string_item_max(conf_item, value, PATH_MAX);
}
int config_ip_prefix(struct in_addr *addr)
{
if (IN_CLASSA(addr->s_addr))
return 32 - IN_CLASSA_NSHIFT;
if (IN_CLASSB(addr->s_addr))
return 32 - IN_CLASSB_NSHIFT;
if (IN_CLASSC(addr->s_addr))
return 32 - IN_CLASSC_NSHIFT;
return 0;
}
int network_ifname(char **valuep, const char *value)
{
return set_config_string_item_max(valuep, value, IFNAMSIZ);
}
int rand_complete_hwaddr(char *hwaddr)
{
const char hex[] = "0123456789abcdef";
char *curs = hwaddr;
#ifndef HAVE_RAND_R
randseed(true);
#else
unsigned int seed;
seed = randseed(false);
#endif
while (*curs != '\0' && *curs != '\n') {
if (*curs == 'x' || *curs == 'X') {
if (curs - hwaddr == 1) {
/* ensure address is unicast */
#ifdef HAVE_RAND_R
*curs = hex[rand_r(&seed) & 0x0E];
} else {
*curs = hex[rand_r(&seed) & 0x0F];
#else
*curs = hex[rand() & 0x0E];
} else {
*curs = hex[rand() & 0x0F];
#endif
}
}
curs++;
}
return 0;
}
/*
* If we find a lxc.network.hwaddr in the original config file, we expand it in
* the unexpanded_config, so that after a save_config we store the hwaddr for
* re-use.
* This is only called when reading the config file, not when executing a
* lxc.include.
* 'x' and 'X' are substituted in-place.
*/
void update_hwaddr(const char *line)
{
char *p;
line += lxc_char_left_gc(line, strlen(line));
if (line[0] == '#')
return;
if ((strncmp(line, "lxc.network.hwaddr", 18) != 0) &&
(strncmp(line, "lxc.net.hwaddr", 14) != 0))
return;
/* Let config_net_hwaddr raise the error. */
p = strchr(line, '=');
if (!p)
return;
p++;
while (isblank(*p))
p++;
if (!*p)
return;
rand_complete_hwaddr(p);
}
bool new_hwaddr(char *hwaddr)
{
int ret;
(void)randseed(true);
ret = snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand() % 255,
rand() % 255, rand() % 255);
if (ret < 0 || ret >= 18) {
SYSERROR("Failed to call snprintf().");
return false;
}
return true;
}
......@@ -23,6 +23,7 @@
#include <stdbool.h>
#include "conf.h"
#include "confile_utils.h"
#ifndef MACVLAN_MODE_PRIVATE
#define MACVLAN_MODE_PRIVATE 1
......@@ -40,6 +41,23 @@
#define MACVLAN_MODE_PASSTHRU 8
#endif
#define strprint(str, inlen, ...) \
do { \
len = snprintf(str, inlen, ##__VA_ARGS__); \
if (len < 0) { \
SYSERROR("failed to create string"); \
return -1; \
}; \
fulllen += len; \
if (inlen > 0) { \
if (str) \
str += len; \
inlen -= len; \
if (inlen < 0) \
inlen = 0; \
} \
} while (0);
extern int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
unsigned long *hostid, unsigned long *range);
......@@ -54,4 +72,14 @@ extern void lxc_free_networks(struct lxc_list *networks);
extern int lxc_macvlan_mode_to_flag(int *mode, const char *value);
extern char *lxc_macvlan_flag_to_mode(int mode);
extern int set_config_string_item(char **conf_item, const char *value);
extern int set_config_string_item_max(char **conf_item, const char *value,
size_t max);
extern int set_config_path_item(char **conf_item, const char *value);
extern int config_ip_prefix(struct in_addr *addr);
extern int network_ifname(char **valuep, const char *value);
extern int rand_complete_hwaddr(char *hwaddr);
extern void update_hwaddr(const char *line);
extern bool new_hwaddr(char *hwaddr);
#endif /* __LXC_CONFILE_UTILS_H */
......@@ -47,6 +47,7 @@
#include "config.h"
#include "commands.h"
#include "confile.h"
#include "confile_network_legacy.h"
#include "console.h"
#include "criu.h"
#include "log.h"
......@@ -1697,6 +1698,8 @@ static void do_clear_unexp_config_line(struct lxc_conf *conf, const char *key)
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
......@@ -2075,8 +2078,10 @@ static int do_lxcapi_get_keys(struct lxc_container *c, const char *key, char *re
if (container_mem_lock(c))
return -1;
int ret = -1;
if (strncmp(key, "lxc.network.", 12) == 0)
if (strncmp(key, "lxc.net.", 8) == 0)
ret = lxc_list_nicconfigs(c->lxc_conf, key, retv, inlen);
else if (strncmp(key, "lxc.network.", 12) == 0)
ret = lxc_list_nicconfigs_legacy(c->lxc_conf, key, retv, inlen);
container_mem_unlock(c);
return ret;
}
......
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