Merge pull request #1632 from brauner/2017-06-19/new_network_parser_part_deux

network: new network parser part II
This commit is contained in:
Serge Hallyn 2017-06-21 10:30:58 -05:00 committed by GitHub
commit 72cc48f990
10 changed files with 1854 additions and 1118 deletions

View File

@ -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 \

View File

@ -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;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
/*
* 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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -298,7 +298,7 @@ int main(int argc, char *argv[])
}
printf("%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2);
if (!c->set_config_item(c, "lxc.network.0.ipv4", "10.2.3.4")) {
if (!c->set_config_item(c, "lxc.network.ipv4", "10.2.3.4")) {
fprintf(stderr, "%d: failed to set ipv4\n", __LINE__);
goto out;
}
@ -318,7 +318,7 @@ int main(int argc, char *argv[])
goto out;
}
if (!c->set_config_item(c, "lxc.network.0.ipv4.gateway", "10.2.3.254")) {
if (!c->set_config_item(c, "lxc.network.ipv4.gateway", "10.2.3.254")) {
fprintf(stderr, "%d: failed to set ipv4.gateway\n", __LINE__);
goto out;
}

View File

@ -90,61 +90,61 @@ static int set_get_compare_clear_save_load(struct lxc_container *c,
static int set_and_clear_complete_netdev(struct lxc_container *c)
{
if (!c->set_config_item(c, "lxc.network.1.type", "veth")) {
lxc_error("%s\n", "lxc.network.1.type");
if (!c->set_config_item(c, "lxc.net.1.type", "veth")) {
lxc_error("%s\n", "lxc.net.1.type");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.ipv4", "10.0.2.3/24")) {
lxc_error("%s\n", "lxc.network.1.ipv4");
if (!c->set_config_item(c, "lxc.net.1.ipv4", "10.0.2.3/24")) {
lxc_error("%s\n", "lxc.net.1.ipv4");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.ipv4_gateway", "10.0.2.2")) {
lxc_error("%s\n", "lxc.network.1.ipv4");
if (!c->set_config_item(c, "lxc.net.1.ipv4_gateway", "10.0.2.2")) {
lxc_error("%s\n", "lxc.net.1.ipv4");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.ipv6",
if (!c->set_config_item(c, "lxc.net.1.ipv6",
"2003:db8:1:0:214:1234:fe0b:3596/64")) {
lxc_error("%s\n", "lxc.network.1.ipv6");
lxc_error("%s\n", "lxc.net.1.ipv6");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.ipv6_gateway",
if (!c->set_config_item(c, "lxc.net.1.ipv6_gateway",
"2003:db8:1:0::1")) {
lxc_error("%s\n", "lxc.network.1.ipv6");
lxc_error("%s\n", "lxc.net.1.ipv6");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.flags", "up")) {
lxc_error("%s\n", "lxc.network.1.flags");
if (!c->set_config_item(c, "lxc.net.1.flags", "up")) {
lxc_error("%s\n", "lxc.net.1.flags");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.link", "br0")) {
lxc_error("%s\n", "lxc.network.1.link");
if (!c->set_config_item(c, "lxc.net.1.link", "br0")) {
lxc_error("%s\n", "lxc.net.1.link");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.veth.pair", "bla")) {
lxc_error("%s\n", "lxc.network.1.veth.pair");
if (!c->set_config_item(c, "lxc.net.1.veth.pair", "bla")) {
lxc_error("%s\n", "lxc.net.1.veth.pair");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.hwaddr",
if (!c->set_config_item(c, "lxc.net.1.hwaddr",
"52:54:00:80:7a:5d")) {
lxc_error("%s\n", "lxc.network.1.hwaddr");
lxc_error("%s\n", "lxc.net.1.hwaddr");
return -1;
}
if (!c->set_config_item(c, "lxc.network.1.mtu", "2000")) {
lxc_error("%s\n", "lxc.network.1.mtu");
if (!c->set_config_item(c, "lxc.net.1.mtu", "2000")) {
lxc_error("%s\n", "lxc.net.1.mtu");
return -1;
}
if (!c->clear_config_item(c, "lxc.network.1")) {
lxc_error("%s", "failed to clear \"lxc.network.1\"\n");
if (!c->clear_config_item(c, "lxc.net.1")) {
lxc_error("%s", "failed to clear \"lxc.net.1\"\n");
return -1;
}
@ -212,8 +212,8 @@ static int set_get_compare_clear_save_load_network(
char retval[4096] = {0};
int ret;
if (!c->set_config_item(c, "lxc.network.0.type", network_type)) {
lxc_error("%s\n", "lxc.network.0.type");
if (!c->set_config_item(c, "lxc.net.0.type", network_type)) {
lxc_error("%s\n", "lxc.net.0.type");
return -1;
}
@ -260,8 +260,8 @@ static int set_get_compare_clear_save_load_network(
return -1;
}
if (!c->clear_config_item(c, "lxc.network.0.type")) {
lxc_error("%s\n", "lxc.network.0.type");
if (!c->clear_config_item(c, "lxc.net.0.type")) {
lxc_error("%s\n", "lxc.net.0.type");
return -1;
}
@ -714,140 +714,140 @@ int main(int argc, char *argv[])
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.type", "veth",
if (set_get_compare_clear_save_load(c, "lxc.net.0.type", "veth",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.type");
lxc_error("%s\n", "lxc.net.0.type");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.2.type", "none",
if (set_get_compare_clear_save_load(c, "lxc.net.2.type", "none",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.2.type");
lxc_error("%s\n", "lxc.net.2.type");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.3.type", "empty",
if (set_get_compare_clear_save_load(c, "lxc.net.3.type", "empty",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.3.type");
lxc_error("%s\n", "lxc.net.3.type");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.4.type", "vlan",
if (set_get_compare_clear_save_load(c, "lxc.net.4.type", "vlan",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.4.type");
lxc_error("%s\n", "lxc.net.4.type");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.type", "macvlan",
if (set_get_compare_clear_save_load(c, "lxc.net.0.type", "macvlan",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.type");
lxc_error("%s\n", "lxc.net.0.type");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.1000.type", "phys",
if (set_get_compare_clear_save_load(c, "lxc.net.1000.type", "phys",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.1000.type");
lxc_error("%s\n", "lxc.net.1000.type");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.flags", "up",
if (set_get_compare_clear_save_load(c, "lxc.net.0.flags", "up",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.flags");
lxc_error("%s\n", "lxc.net.0.flags");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.name", "eth0",
if (set_get_compare_clear_save_load(c, "lxc.net.0.name", "eth0",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.name");
lxc_error("%s\n", "lxc.net.0.name");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.link", "bla",
if (set_get_compare_clear_save_load(c, "lxc.net.0.link", "bla",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.link");
lxc_error("%s\n", "lxc.net.0.link");
goto non_test_error;
}
if (set_get_compare_clear_save_load_network(
c, "lxc.network.0.macvlan.mode", "private", tmpf, true,
c, "lxc.net.0.macvlan.mode", "private", tmpf, true,
"macvlan")) {
lxc_error("%s\n", "lxc.network.0.macvlan.mode");
lxc_error("%s\n", "lxc.net.0.macvlan.mode");
goto non_test_error;
}
if (set_get_compare_clear_save_load_network(
c, "lxc.network.0.macvlan.mode", "vepa", tmpf, true,
c, "lxc.net.0.macvlan.mode", "vepa", tmpf, true,
"macvlan")) {
lxc_error("%s\n", "lxc.network.0.macvlan.mode");
lxc_error("%s\n", "lxc.net.0.macvlan.mode");
goto non_test_error;
}
if (set_get_compare_clear_save_load_network(
c, "lxc.network.0.macvlan.mode", "bridge", tmpf, true,
c, "lxc.net.0.macvlan.mode", "bridge", tmpf, true,
"macvlan")) {
lxc_error("%s\n", "lxc.network.0.macvlan.mode");
lxc_error("%s\n", "lxc.net.0.macvlan.mode");
goto non_test_error;
}
if (set_get_compare_clear_save_load_network(
c, "lxc.network.0.veth.pair", "clusterfuck", tmpf, true,
c, "lxc.net.0.veth.pair", "clusterfuck", tmpf, true,
"veth")) {
lxc_error("%s\n", "lxc.network.0.veth.pair");
lxc_error("%s\n", "lxc.net.0.veth.pair");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.script.up",
if (set_get_compare_clear_save_load(c, "lxc.net.0.script.up",
"/some/up/path", tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.script.up");
lxc_error("%s\n", "lxc.net.0.script.up");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.script.down",
if (set_get_compare_clear_save_load(c, "lxc.net.0.script.down",
"/some/down/path", tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.script.down");
lxc_error("%s\n", "lxc.net.0.script.down");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.hwaddr",
if (set_get_compare_clear_save_load(c, "lxc.net.0.hwaddr",
"52:54:00:80:7a:5d", tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.hwaddr");
lxc_error("%s\n", "lxc.net.0.hwaddr");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.mtu", "2000",
if (set_get_compare_clear_save_load(c, "lxc.net.0.mtu", "2000",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.mtu");
lxc_error("%s\n", "lxc.net.0.mtu");
goto non_test_error;
}
if (set_get_compare_clear_save_load_network(c, "lxc.network.0.vlan.id",
if (set_get_compare_clear_save_load_network(c, "lxc.net.0.vlan.id",
"2", tmpf, true, "vlan")) {
lxc_error("%s\n", "lxc.network.0.vlan.id");
lxc_error("%s\n", "lxc.net.0.vlan.id");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.ipv4.gateway",
if (set_get_compare_clear_save_load(c, "lxc.net.0.ipv4.gateway",
"10.0.2.2", tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.ipv4.gateway");
lxc_error("%s\n", "lxc.net.0.ipv4.gateway");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.ipv6.gateway",
if (set_get_compare_clear_save_load(c, "lxc.net.0.ipv6.gateway",
"2003:db8:1::1", tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.ipv6.gateway");
lxc_error("%s\n", "lxc.net.0.ipv6.gateway");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.network.0.ipv4",
if (set_get_compare_clear_save_load(c, "lxc.net.0.ipv4",
"10.0.2.3/24", tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.ipv4");
lxc_error("%s\n", "lxc.net.0.ipv4");
goto non_test_error;
}
if (set_get_compare_clear_save_load(
c, "lxc.network.0.ipv6", "2003:db8:1:0:214:1234:fe0b:3596/64",
c, "lxc.net.0.ipv6", "2003:db8:1:0:214:1234:fe0b:3596/64",
tmpf, true)) {
lxc_error("%s\n", "lxc.network.0.ipv6");
lxc_error("%s\n", "lxc.net.0.ipv6");
goto non_test_error;
}