diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index ae9cced1c..14a572352 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -32,3 +32,9 @@ until a reboot succeeded. It takes a timeout argument. When set to `> 0`
This adds support for injecting and removing mounts into/from a running
containers. Two new API functions `mount()` and `umount()` are added. They
mirror the current mount and umount API of the kernel.
+
+## network\_veth\_routes
+
+This introduces the `lxc.net.[i].veth.ipv4.route` and `lxc.net.[i].veth.ipv6.route` properties
+on `veth` type network interfaces. This allows adding static routes on host to the container's
+network interface.
diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index 4ed65f63a..3b3dd6dde 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -375,7 +375,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
The only allowed values are 0 and 1. Set this to 1 to destroy a
- container on shutdown.
+ container on shutdown.
@@ -459,6 +459,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
the option (except for
unprivileged containers where this option is ignored for security
reasons).
+
+ Static routes can be added on the host pointing to the container using the
+ and
+ options.
+ Several lines specify several routes.
+ The route is in format x.y.z.t/m, eg. 192.168.1.0/24.
@@ -855,7 +861,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
When manually specifying a size for the log file the value should
be a power of 2 when converted to bytes. Valid size prefixes are
'KB', 'MB', 'GB'. (Note that all conversions are based on multiples
- of 1024. That means 'KB' == 'KiB', 'MB' == 'MiB', 'GB' == 'GiB'.
+ of 1024. That means 'KB' == 'KiB', 'MB' == 'MiB', 'GB' == 'GiB'.
Additionally, the case of the suffix is ignored, i.e. 'kB', 'KB' and
'Kb' are treated equally.)
@@ -1629,7 +1635,7 @@ dev/null proc/kcore none bind,relative 0 0
- To inherit the namespace from another container set the
+ To inherit the namespace from another container set the
to the name of
the container, e.g. .
@@ -1708,7 +1714,7 @@ dev/null proc/kcore none bind,relative 0 0
- Specify the kernel parameters to be set. The parameters available
+ Specify the kernel parameters to be set. The parameters available
are those listed under /proc/sys/.
Note that not all sysctls are namespaced. Changing Non-namespaced
sysctls will cause the system-wide setting to be modified.
@@ -1716,7 +1722,7 @@ dev/null proc/kcore none bind,relative 0 0
sysctl
8
.
- If used with no value, lxc will clear the parameters specified up
+ If used with no value, lxc will clear the parameters specified up
to this point.
diff --git a/src/lxc/api_extensions.h b/src/lxc/api_extensions.h
index e87c8e924..529f19863 100644
--- a/src/lxc/api_extensions.h
+++ b/src/lxc/api_extensions.h
@@ -44,6 +44,7 @@ static char *api_extensions[] = {
"mount_injection_file",
"seccomp_allow_nesting",
"seccomp_notify",
+ "network_veth_routes",
};
static size_t nr_api_extensions = sizeof(api_extensions) / sizeof(*api_extensions);
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index da5e45ce3..efcb705aa 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -137,6 +137,8 @@ lxc_config_define(net_script_down);
lxc_config_define(net_script_up);
lxc_config_define(net_type);
lxc_config_define(net_veth_pair);
+lxc_config_define(net_veth_ipv4_route);
+lxc_config_define(net_veth_ipv6_route);
lxc_config_define(net_vlan_id);
lxc_config_define(no_new_privs);
lxc_config_define(personality);
@@ -226,6 +228,8 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.net.type", set_config_net_type, get_config_net_type, clr_config_net_type, },
{ "lxc.net.vlan.id", set_config_net_vlan_id, get_config_net_vlan_id, clr_config_net_vlan_id, },
{ "lxc.net.veth.pair", set_config_net_veth_pair, get_config_net_veth_pair, clr_config_net_veth_pair, },
+ { "lxc.net.veth.ipv4.route", set_config_net_veth_ipv4_route, get_config_net_veth_ipv4_route, clr_config_net_veth_ipv4_route, },
+ { "lxc.net.veth.ipv6.route", set_config_net_veth_ipv6_route, get_config_net_veth_ipv6_route, clr_config_net_veth_ipv6_route, },
{ "lxc.net.", set_config_net_nic, get_config_net_nic, clr_config_net_nic, },
{ "lxc.net", set_config_net, get_config_net, clr_config_net, },
{ "lxc.no_new_privs", set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, },
@@ -289,6 +293,8 @@ static int set_config_net_type(const char *key, const char *value,
if (!strcmp(value, "veth")) {
netdev->type = LXC_NET_VETH;
+ lxc_list_init(&netdev->priv.veth_attr.ipv4_routes);
+ lxc_list_init(&netdev->priv.veth_attr.ipv6_routes);
} else if (!strcmp(value, "macvlan")) {
netdev->type = LXC_NET_MACVLAN;
lxc_macvlan_mode_to_flag(&netdev->priv.macvlan_attr.mode,
@@ -629,6 +635,69 @@ static int set_config_net_ipv4_gateway(const char *key, const char *value,
return 0;
}
+static int set_config_net_veth_ipv4_route(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ __do_free char *valdup = NULL;
+ __do_free struct lxc_inetdev *inetdev = NULL;
+ __do_free struct lxc_list *list = NULL;
+ int ret;
+ char *netmask, *slash;
+ struct lxc_netdev *netdev = data;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_net_veth_ipv4_route(key, lxc_conf, data);
+
+ if (!netdev)
+ return minus_one_set_errno(EINVAL);
+
+ if (netdev->type != LXC_NET_VETH) {
+ SYSERROR("Invalid ipv4 route \"%s\", can only be used with veth network", value);
+ return minus_one_set_errno(EINVAL);
+ }
+
+ inetdev = malloc(sizeof(*inetdev));
+ if (!inetdev)
+ return -1;
+ memset(inetdev, 0, sizeof(*inetdev));
+
+ list = malloc(sizeof(*list));
+ if (!list)
+ return -1;
+
+ lxc_list_init(list);
+ list->elem = inetdev;
+
+ valdup = strdup(value);
+ if (!valdup)
+ return -1;
+
+ slash = strchr(valdup, '/');
+ if (!slash)
+ return minus_one_set_errno(EINVAL);
+
+ *slash = '\0';
+ slash++;
+ if (*slash == '\0')
+ return minus_one_set_errno(EINVAL);
+
+ netmask = slash;
+
+ ret = lxc_safe_uint(netmask, &inetdev->prefix);
+ if (ret < 0 || inetdev->prefix > 32)
+ return minus_one_set_errno(EINVAL);
+
+ ret = inet_pton(AF_INET, valdup, &inetdev->addr);
+ if (!ret || ret < 0)
+ return minus_one_set_errno(EINVAL);
+
+ lxc_list_add_tail(&netdev->priv.veth_attr.ipv4_routes, list);
+ move_ptr(inetdev);
+ move_ptr(list);
+
+ return 0;
+}
+
static int set_config_net_ipv6_address(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
@@ -733,6 +802,69 @@ static int set_config_net_ipv6_gateway(const char *key, const char *value,
return 0;
}
+static int set_config_net_veth_ipv6_route(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ __do_free char *valdup;
+ __do_free struct lxc_inet6dev *inet6dev;
+ __do_free struct lxc_list *list;
+ int ret;
+ char *netmask, *slash;
+ struct lxc_netdev *netdev = data;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_net_veth_ipv6_route(key, lxc_conf, data);
+
+ if (!netdev)
+ return minus_one_set_errno(EINVAL);
+
+ if (netdev->type != LXC_NET_VETH) {
+ SYSERROR("Invalid ipv6 route \"%s\", can only be used with veth network", value);
+ return minus_one_set_errno(EINVAL);
+ }
+
+ inet6dev = malloc(sizeof(*inet6dev));
+ if (!inet6dev)
+ return -1;
+ memset(inet6dev, 0, sizeof(*inet6dev));
+
+ list = malloc(sizeof(*list));
+ if (!list)
+ return -1;
+
+ lxc_list_init(list);
+ list->elem = inet6dev;
+
+ valdup = strdup(value);
+ if (!valdup)
+ return -1;
+
+ slash = strchr(valdup, '/');
+ if (!slash)
+ return minus_one_set_errno(EINVAL);
+
+ *slash = '\0';
+ slash++;
+ if (*slash == '\0')
+ return minus_one_set_errno(EINVAL);
+
+ netmask = slash;
+
+ ret = lxc_safe_uint(netmask, &inet6dev->prefix);
+ if (ret < 0 || inet6dev->prefix > 128)
+ return minus_one_set_errno(EINVAL);
+
+ ret = inet_pton(AF_INET6, valdup, &inet6dev->addr);
+ if (!ret || ret < 0)
+ return minus_one_set_errno(EINVAL);
+
+ lxc_list_add_tail(&netdev->priv.veth_attr.ipv6_routes, list);
+ move_ptr(inet6dev);
+ move_ptr(list);
+
+ return 0;
+}
+
static int set_config_net_script_up(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
@@ -4898,6 +5030,24 @@ static int clr_config_net_ipv4_address(const char *key,
return 0;
}
+static int clr_config_net_veth_ipv4_route(const char *key,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_netdev *netdev = data;
+ struct lxc_list *cur, *next;
+
+ if (!netdev)
+ return -1;
+
+ lxc_list_for_each_safe(cur, &netdev->priv.veth_attr.ipv4_routes, next) {
+ lxc_list_del(cur);
+ free(cur->elem);
+ free(cur);
+ }
+
+ return 0;
+}
+
static int clr_config_net_ipv6_gateway(const char *key,
struct lxc_conf *lxc_conf, void *data)
{
@@ -4930,6 +5080,24 @@ static int clr_config_net_ipv6_address(const char *key,
return 0;
}
+static int clr_config_net_veth_ipv6_route(const char *key,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_netdev *netdev = data;
+ struct lxc_list *cur, *next;
+
+ if (!netdev)
+ return -1;
+
+ lxc_list_for_each_safe(cur, &netdev->priv.veth_attr.ipv6_routes, next) {
+ lxc_list_del(cur);
+ free(cur->elem);
+ free(cur);
+ }
+
+ return 0;
+}
+
static int get_config_net_nic(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
@@ -5274,6 +5442,39 @@ static int get_config_net_ipv4_address(const char *key, char *retv, int inlen,
return fulllen;
}
+static int get_config_net_veth_ipv4_route(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len;
+ size_t listlen;
+ char buf[INET_ADDRSTRLEN];
+ struct lxc_list *it;
+ int fulllen = 0;
+ struct lxc_netdev *netdev = data;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ if (!netdev)
+ return minus_one_set_errno(EINVAL);
+
+ if (netdev->type != LXC_NET_VETH)
+ return 0;
+
+ listlen = lxc_list_len(&netdev->priv.veth_attr.ipv4_routes);
+
+ lxc_list_for_each(it, &netdev->priv.veth_attr.ipv4_routes) {
+ struct lxc_inetdev *i = it->elem;
+ inet_ntop(AF_INET, &i->addr, buf, sizeof(buf));
+ strprint(retv, inlen, "%s/%u%s", buf, i->prefix,
+ (listlen-- > 1) ? "\n" : "");
+ }
+
+ return fulllen;
+}
+
static int get_config_net_ipv6_gateway(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
@@ -5330,6 +5531,39 @@ static int get_config_net_ipv6_address(const char *key, char *retv, int inlen,
return fulllen;
}
+static int get_config_net_veth_ipv6_route(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len;
+ size_t listlen;
+ char buf[INET6_ADDRSTRLEN];
+ struct lxc_list *it;
+ int fulllen = 0;
+ struct lxc_netdev *netdev = data;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ if (!netdev)
+ return minus_one_set_errno(EINVAL);
+
+ if (netdev->type != LXC_NET_VETH)
+ return 0;
+
+ listlen = lxc_list_len(&netdev->priv.veth_attr.ipv6_routes);
+
+ lxc_list_for_each(it, &netdev->priv.veth_attr.ipv6_routes) {
+ struct lxc_inet6dev *i = it->elem;
+ inet_ntop(AF_INET6, &i->addr, buf, sizeof(buf));
+ strprint(retv, inlen, "%s/%u%s", buf, i->prefix,
+ (listlen-- > 1) ? "\n" : "");
+ }
+
+ return fulllen;
+}
+
int lxc_list_config_items(char *retv, int inlen)
{
size_t i;
@@ -5463,6 +5697,8 @@ int lxc_list_net(struct lxc_conf *c, const char *key, char *retv, int inlen)
switch (netdev->type) {
case LXC_NET_VETH:
strprint(retv, inlen, "veth.pair\n");
+ strprint(retv, inlen, "veth.ipv4.route\n");
+ strprint(retv, inlen, "veth.ipv6.route\n");
break;
case LXC_NET_MACVLAN:
strprint(retv, inlen, "macvlan.mode\n");
diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c
index 50777c448..cfc23f312 100644
--- a/src/lxc/confile_utils.c
+++ b/src/lxc/confile_utils.c
@@ -317,7 +317,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE("type: none");
break;
default:
- ERROR("invalid network type %d", netdev->type);
+ ERROR("Invalid network type %d", netdev->type);
return;
}
@@ -374,6 +374,28 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
sizeof(bufinet6));
TRACE("ipv6 addr: %s", bufinet6);
}
+
+ if (netdev->type == LXC_NET_VETH) {
+ lxc_list_for_each_safe(cur, &netdev->priv.veth_attr.ipv4_routes, next) {
+ inet4dev = cur->elem;
+ if (!inet_ntop(AF_INET, &inet4dev->addr, bufinet4, sizeof(bufinet4))) {
+ ERROR("Invalid ipv4 veth route");
+ return;
+ }
+
+ TRACE("ipv4 veth route: %s/%u", bufinet4, inet4dev->prefix);
+ }
+
+ lxc_list_for_each_safe(cur, &netdev->priv.veth_attr.ipv6_routes, next) {
+ inet6dev = cur->elem;
+ if (!inet_ntop(AF_INET6, &inet6dev->addr, bufinet6, sizeof(bufinet6))) {
+ ERROR("Invalid ipv6 veth route");
+ return;
+ }
+
+ TRACE("ipv6 veth route: %s/%u", bufinet6, inet6dev->prefix);
+ }
+ }
}
}
}
@@ -401,6 +423,20 @@ static void lxc_free_netdev(struct lxc_netdev *netdev)
free(cur);
}
+ if (netdev->type == LXC_NET_VETH) {
+ lxc_list_for_each_safe(cur, &netdev->priv.veth_attr.ipv4_routes, next) {
+ lxc_list_del(cur);
+ free(cur->elem);
+ free(cur);
+ }
+
+ lxc_list_for_each_safe(cur, &netdev->priv.veth_attr.ipv6_routes, next) {
+ lxc_list_del(cur);
+ free(cur->elem);
+ free(cur);
+ }
+ }
+
free(netdev);
}
diff --git a/src/lxc/network.c b/src/lxc/network.c
index b49aae68c..a31544083 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -69,6 +69,44 @@ lxc_log_define(network, lxc);
typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *);
+static int lxc_setup_ipv4_routes(struct lxc_list *ip, int ifindex)
+{
+ struct lxc_list *iterator;
+ int err;
+
+ lxc_list_for_each(iterator, ip) {
+ struct lxc_inetdev *inetdev = iterator->elem;
+
+ err = lxc_ipv4_dest_add(ifindex, &inetdev->addr, inetdev->prefix);
+ if (err) {
+ SYSERROR("Failed to setup ipv4 route for network device "
+ "with ifindex %d", ifindex);
+ return minus_one_set_errno(-err);
+ }
+ }
+
+ return 0;
+}
+
+static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
+{
+ struct lxc_list *iterator;
+ int err;
+
+ lxc_list_for_each(iterator, ip) {
+ struct lxc_inet6dev *inet6dev = iterator->elem;
+
+ err = lxc_ipv6_dest_add(ifindex, &inet6dev->addr, inet6dev->prefix);
+ if (err) {
+ SYSERROR("Failed to setup ipv6 route for network device "
+ "with ifindex %d", ifindex);
+ return minus_one_set_errno(-err);
+ }
+ }
+
+ return 0;
+}
+
static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
int bridge_index, err;
@@ -183,6 +221,18 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
goto out_delete;
}
+ /* setup ipv4 routes on the host interface */
+ if (lxc_setup_ipv4_routes(&netdev->priv.veth_attr.ipv4_routes, netdev->priv.veth_attr.ifindex)) {
+ ERROR("Failed to setup ipv4 routes for network device \"%s\"", veth1);
+ goto out_delete;
+ }
+
+ /* setup ipv6 routes on the host interface */
+ if (lxc_setup_ipv6_routes(&netdev->priv.veth_attr.ipv6_routes, netdev->priv.veth_attr.ifindex)) {
+ ERROR("Failed to setup ipv6 routes for network device \"%s\"", veth1);
+ goto out_delete;
+ }
+
if (netdev->upscript) {
char *argv[] = {
"veth",
@@ -1780,7 +1830,7 @@ int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw)
return ip_gateway_add(AF_INET6, ifindex, gw);
}
-static int ip_route_dest_add(int family, int ifindex, void *dest)
+static int ip_route_dest_add(int family, int ifindex, void *dest, unsigned int netmask)
{
int addrlen, err;
struct nl_handler nlh;
@@ -1815,7 +1865,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
rt->rtm_scope = RT_SCOPE_LINK;
rt->rtm_protocol = RTPROT_BOOT;
rt->rtm_type = RTN_UNICAST;
- rt->rtm_dst_len = addrlen * 8;
+ rt->rtm_dst_len = netmask;
err = -EINVAL;
if (nla_put_buffer(nlmsg, RTA_DST, dest, addrlen))
@@ -1830,14 +1880,14 @@ out:
return err;
}
-int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest)
+int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest, unsigned int netmask)
{
- return ip_route_dest_add(AF_INET, ifindex, dest);
+ return ip_route_dest_add(AF_INET, ifindex, dest, netmask);
}
-int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
+int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest, unsigned int netmask)
{
- return ip_route_dest_add(AF_INET6, ifindex, dest);
+ return ip_route_dest_add(AF_INET6, ifindex, dest, netmask);
}
bool is_ovs_bridge(const char *bridge)
@@ -2807,7 +2857,7 @@ static int setup_ipv4_addr(struct lxc_list *ip, int ifindex)
if (err) {
errno = -err;
SYSERROR("Failed to setup ipv4 address for network device "
- "with eifindex %d", ifindex);
+ "with ifindex %d", ifindex);
return -1;
}
}
@@ -2829,7 +2879,7 @@ static int setup_ipv6_addr(struct lxc_list *ip, int ifindex)
if (err) {
errno = -err;
SYSERROR("Failed to setup ipv6 address for network device "
- "with eifindex %d", ifindex);
+ "with ifindex %d", ifindex);
return -1;
}
}
@@ -2988,7 +3038,7 @@ static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev *netdev)
err = lxc_ipv4_gateway_add(netdev->ifindex, netdev->ipv4_gateway);
if (err) {
- err = lxc_ipv4_dest_add(netdev->ifindex, netdev->ipv4_gateway);
+ err = lxc_ipv4_dest_add(netdev->ifindex, netdev->ipv4_gateway, 32);
if (err) {
errno = -err;
SYSERROR("Failed to add ipv4 dest for network device \"%s\"",
@@ -3027,7 +3077,7 @@ static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev *netdev)
err = lxc_ipv6_gateway_add(netdev->ifindex, netdev->ipv6_gateway);
if (err) {
- err = lxc_ipv6_dest_add(netdev->ifindex, netdev->ipv6_gateway);
+ err = lxc_ipv6_dest_add(netdev->ifindex, netdev->ipv6_gateway, 128);
if (err) {
errno = -err;
SYSERROR("Failed to add ipv6 dest for network device \"%s\"",
diff --git a/src/lxc/network.h b/src/lxc/network.h
index ef1b41b89..1084cae2d 100644
--- a/src/lxc/network.h
+++ b/src/lxc/network.h
@@ -95,6 +95,8 @@ struct ifla_veth {
char pair[IFNAMSIZ];
char veth1[IFNAMSIZ];
int ifindex;
+ struct lxc_list ipv4_routes;
+ struct lxc_list ipv6_routes;
};
struct ifla_vlan {
@@ -221,8 +223,8 @@ extern int lxc_ipv4_addr_get(int ifindex, struct in_addr **res);
extern int lxc_ipv6_addr_get(int ifindex, struct in6_addr **res);
/* Set a destination route to an interface. */
-extern int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest);
-extern int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest);
+extern int lxc_ipv4_dest_add(int ifindex, struct in_addr *dest, unsigned int netmask);
+extern int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest, unsigned int netmask);
/* Set default route. */
extern int lxc_ipv4_gateway_add(int ifindex, struct in_addr *gw);
diff --git a/src/tests/parse_config_file.c b/src/tests/parse_config_file.c
index b8b71c8e1..63692264d 100644
--- a/src/tests/parse_config_file.c
+++ b/src/tests/parse_config_file.c
@@ -134,6 +134,16 @@ static int set_and_clear_complete_netdev(struct lxc_container *c)
return -1;
}
+ if (!c->set_config_item(c, "lxc.net.1.veth.ipv4.route", "192.0.2.1/32")) {
+ lxc_error("%s\n", "lxc.net.1.veth.ipv4.route");
+ return -1;
+ }
+
+ if (!c->set_config_item(c, "lxc.net.1.veth.ipv6.route", "2001:db8::1/128")) {
+ lxc_error("%s\n", "lxc.net.1.veth.ipv6.route");
+ return -1;
+ }
+
if (!c->set_config_item(c, "lxc.net.1.hwaddr",
"52:54:00:80:7a:5d")) {
lxc_error("%s\n", "lxc.net.1.hwaddr");
@@ -695,6 +705,16 @@ int main(int argc, char *argv[])
goto non_test_error;
}
+ if (set_get_compare_clear_save_load_network(c, "lxc.net.0.veth.ipv4.route", "192.0.2.1/32", tmpf, true, "veth")) {
+ lxc_error("%s\n", "lxc.net.0.veth.ipv4.route");
+ return -1;
+ }
+
+ if (set_get_compare_clear_save_load_network(c, "lxc.net.0.veth.ipv6.route", "2001:db8::1/128", tmpf, true, "veth")) {
+ lxc_error("%s\n", "lxc.net.0.veth.ipv6.route");
+ return -1;
+ }
+
if (set_get_compare_clear_save_load(c, "lxc.net.0.script.up", "/some/up/path", tmpf, true)) {
lxc_error("%s\n", "lxc.net.0.script.up");
goto non_test_error;