[lxc-devel] [lxc/master] network: Adds IPVLAN support
tomponline on Github
lxc-bot at linuxcontainers.org
Fri Apr 26 10:28:12 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 570 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190426/d4d8b0b5/attachment-0001.bin>
-------------- next part --------------
From 9f658c8d7069999f50c75507b34fcf7aaee5daa2 Mon Sep 17 00:00:00 2001
From: tomponline <thomas.parrott at canonical.com>
Date: Fri, 26 Apr 2019 11:26:45 +0100
Subject: [PATCH] network: Adds IPVLAN support
Example usage:
lxc.net[i].type=ipvlan
lxc.net[i].ipvlan.mode=[l3|l3s|l2] (defaults to l3)
lxc.net[i].ipvlan.flags=[bridge|private|vepa] (defaults to bridge)
lxc.net[i].link=eth0
lxc.net[i].flags=up
Signed-off-by: tomponline <thomas.parrott at canonical.com>
---
src/lxc/confile.c | 146 ++++++++++++++++++++++++++++++++++++++++
src/lxc/confile_utils.c | 88 ++++++++++++++++++++++++
src/lxc/confile_utils.h | 4 ++
src/lxc/macro.h | 24 +++++++
src/lxc/network.c | 15 +++++
src/lxc/network.h | 7 ++
6 files changed, 284 insertions(+)
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index da5e45ce3c..40eb9fcbf9 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -130,6 +130,8 @@ lxc_config_define(net_ipv6_address);
lxc_config_define(net_ipv6_gateway);
lxc_config_define(net_link);
lxc_config_define(net_macvlan_mode);
+lxc_config_define(net_ipvlan_mode);
+lxc_config_define(net_ipvlan_flags);
lxc_config_define(net_mtu);
lxc_config_define(net_name);
lxc_config_define(net_nic);
@@ -219,6 +221,8 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.net.ipv6.gateway", set_config_net_ipv6_gateway, get_config_net_ipv6_gateway, clr_config_net_ipv6_gateway, },
{ "lxc.net.link", set_config_net_link, get_config_net_link, clr_config_net_link, },
{ "lxc.net.macvlan.mode", set_config_net_macvlan_mode, get_config_net_macvlan_mode, clr_config_net_macvlan_mode, },
+ { "lxc.net.ipvlan.mode", set_config_net_ipvlan_mode, get_config_net_ipvlan_mode, clr_config_net_ipvlan_mode, },
+ { "lxc.net.ipvlan.flags", set_config_net_ipvlan_flags, get_config_net_ipvlan_flags, clr_config_net_ipvlan_flags, },
{ "lxc.net.mtu", set_config_net_mtu, get_config_net_mtu, clr_config_net_mtu, },
{ "lxc.net.name", set_config_net_name, get_config_net_name, clr_config_net_name, },
{ "lxc.net.script.down", set_config_net_script_down, get_config_net_script_down, clr_config_net_script_down, },
@@ -432,6 +436,34 @@ static int set_config_net_macvlan_mode(const char *key, const char *value,
return lxc_macvlan_mode_to_flag(&netdev->priv.macvlan_attr.mode, value);
}
+static int set_config_net_ipvlan_mode(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_netdev *netdev = data;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_net_ipvlan_mode(key, lxc_conf, data);
+
+ if (!netdev)
+ return -1;
+
+ return lxc_ipvlan_mode_to_flag(&netdev->priv.ipvlan_attr.mode, value);
+}
+
+static int set_config_net_ipvlan_flags(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_netdev *netdev = data;
+
+ if (lxc_config_value_empty(value))
+ return clr_config_net_ipvlan_flags(key, lxc_conf, data);
+
+ if (!netdev)
+ return -1;
+
+ return lxc_ipvlan_flags_to_flag(&netdev->priv.ipvlan_attr.mode, value);
+}
+
static int set_config_net_hwaddr(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
@@ -4784,6 +4816,38 @@ static int clr_config_net_macvlan_mode(const char *key,
return 0;
}
+static int clr_config_net_ipvlan_mode(const char *key,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_netdev *netdev = data;
+
+ if (!netdev)
+ return -1;
+
+ if (netdev->type != LXC_NET_IPVLAN)
+ return 0;
+
+ netdev->priv.ipvlan_attr.mode = -1;
+
+ return 0;
+}
+
+static int clr_config_net_ipvlan_flags(const char *key,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_netdev *netdev = data;
+
+ if (!netdev)
+ return -1;
+
+ if (netdev->type != LXC_NET_IPVLAN)
+ return 0;
+
+ netdev->priv.ipvlan_attr.flags = -1;
+
+ return 0;
+}
+
static int clr_config_net_veth_pair(const char *key, struct lxc_conf *lxc_conf,
void *data)
{
@@ -5085,6 +5149,84 @@ static int get_config_net_macvlan_mode(const char *key, char *retv, int inlen,
return fulllen;
}
+static int get_config_net_ipvlan_mode(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len;
+ int fulllen = 0;
+ const char *mode;
+ struct lxc_netdev *netdev = data;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ if (!netdev)
+ return -1;
+
+ if (netdev->type != LXC_NET_IPVLAN)
+ return 0;
+
+ switch (netdev->priv.ipvlan_attr.mode) {
+ case IPVLAN_MODE_L3:
+ mode = "l3";
+ break;
+ case IPVLAN_MODE_L3S:
+ mode = "ls3";
+ break;
+ case IPVLAN_MODE_L2:
+ mode = "l2";
+ break;
+ default:
+ mode = "(invalid)";
+ break;
+ }
+
+ strprint(retv, inlen, "%s", mode);
+
+ return fulllen;
+}
+
+static int get_config_net_ipvlan_flags(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len;
+ int fulllen = 0;
+ const char *mode;
+ struct lxc_netdev *netdev = data;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ if (!netdev)
+ return -1;
+
+ if (netdev->type != LXC_NET_IPVLAN)
+ return 0;
+
+ switch (netdev->priv.ipvlan_attr.mode) {
+ case IPVLAN_FLAGS_BRIDGE:
+ mode = "bridge";
+ break;
+ case IPVLAN_FLAGS_PRIVATE:
+ mode = "private";
+ break;
+ case IPVLAN_FLAGS_VEPA:
+ mode = "vepa";
+ break;
+ default:
+ mode = "(invalid)";
+ break;
+ }
+
+ strprint(retv, inlen, "%s", mode);
+
+ return fulllen;
+}
+
static int get_config_net_veth_pair(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
@@ -5467,6 +5609,10 @@ int lxc_list_net(struct lxc_conf *c, const char *key, char *retv, int inlen)
case LXC_NET_MACVLAN:
strprint(retv, inlen, "macvlan.mode\n");
break;
+ case LXC_NET_IPVLAN:
+ strprint(retv, inlen, "ipvlan.mode\n");
+ strprint(retv, inlen, "ipvlan.flags\n");
+ break;
case LXC_NET_VLAN:
strprint(retv, inlen, "vlan.id\n");
break;
diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c
index 50777c4481..7ca7c11ee6 100644
--- a/src/lxc/confile_utils.c
+++ b/src/lxc/confile_utils.c
@@ -299,6 +299,18 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
mode ? mode : "(invalid mode)");
}
break;
+ case LXC_NET_IPVLAN:
+ TRACE("type: ipvlan");
+
+ if (netdev->priv.ipvlan_attr.mode > 0) {
+ char *mode;
+
+ mode = lxc_ipvlan_flag_to_mode(
+ netdev->priv.ipvlan_attr.mode);
+ TRACE("ipvlan mode: %s",
+ mode ? mode : "(invalid mode)");
+ }
+ break;
case LXC_NET_VLAN:
TRACE("type: vlan");
TRACE("vlan id: %d", netdev->priv.vlan_attr.vid);
@@ -483,6 +495,82 @@ char *lxc_macvlan_flag_to_mode(int mode)
return NULL;
}
+static struct lxc_ipvlan_mode {
+ char *name;
+ int mode;
+} ipvlan_mode[] = {
+ { "l3", IPVLAN_MODE_L3 },
+ { "l3s", IPVLAN_MODE_L3S },
+ { "l3", IPVLAN_MODE_L2 },
+};
+
+int lxc_ipvlan_mode_to_flag(int *mode, const char *value)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof(ipvlan_mode) / sizeof(ipvlan_mode[0]); i++) {
+ if (strcmp(ipvlan_mode[i].name, value))
+ continue;
+
+ *mode = ipvlan_mode[i].mode;
+ return 0;
+ }
+
+ return -1;
+}
+
+char *lxc_ipvlan_flag_to_mode(int mode)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof(ipvlan_mode) / sizeof(ipvlan_mode[0]); i++) {
+ if (ipvlan_mode[i].mode == mode)
+ continue;
+
+ return ipvlan_mode[i].name;
+ }
+
+ return NULL;
+}
+
+static struct lxc_ipvlan_flags {
+ char *name;
+ int mode;
+} ipvlan_flags[] = {
+ { "bridge", IPVLAN_FLAGS_BRIDGE },
+ { "private", IPVLAN_FLAGS_PRIVATE },
+ { "vepa", IPVLAN_FLAGS_VEPA },
+};
+
+int lxc_ipvlan_flags_to_flag(int *mode, const char *value)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof(ipvlan_flags) / sizeof(ipvlan_flags[0]); i++) {
+ if (strcmp(ipvlan_flags[i].name, value))
+ continue;
+
+ *mode = ipvlan_flags[i].mode;
+ return 0;
+ }
+
+ return -1;
+}
+
+char *lxc_ipvlan_flag_to_flags(int mode)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof(ipvlan_flags) / sizeof(ipvlan_flags[0]); i++) {
+ if (ipvlan_flags[i].mode == mode)
+ continue;
+
+ return ipvlan_flags[i].name;
+ }
+
+ return NULL;
+}
+
int set_config_string_item(char **conf_item, const char *value)
{
char *new_value;
diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h
index 5a3bcc914c..c91f47398b 100644
--- a/src/lxc/confile_utils.h
+++ b/src/lxc/confile_utils.h
@@ -58,6 +58,10 @@ extern bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx);
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 lxc_ipvlan_mode_to_flag(int *mode, const char *value);
+extern char *lxc_ipvlan_flag_to_mode(int mode);
+extern int lxc_ipvlan_flags_to_flag(int *mode, const char *value);
+extern char *lxc_ipvlan_flag_to_flags(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,
diff --git a/src/lxc/macro.h b/src/lxc/macro.h
index 7df3b56f03..c392dfac01 100644
--- a/src/lxc/macro.h
+++ b/src/lxc/macro.h
@@ -333,6 +333,30 @@ extern int __build_bug_on_failed;
#define MACVLAN_MODE_PASSTHRU 8
#endif
+#ifndef IPVLAN_MODE_L3
+#define IPVLAN_MODE_L3 1
+#endif
+
+#ifndef IPVLAN_MODE_L3S
+#define IPVLAN_MODE_L3S 2
+#endif
+
+#ifndef IPVLAN_MODE_L2
+#define IPVLAN_MODE_L2 4
+#endif
+
+#ifndef IPVLAN_FLAGS_BRIDGE
+#define IPVLAN_FLAGS_BRIDGE 1
+#endif
+
+#ifndef IPVLAN_FLAGS_PRIVATE
+#define IPVLAN_FLAGS_PRIVATE 2
+#endif
+
+#ifndef IPVLAN_FLAGS_VEPA
+#define IPVLAN_FLAGS_VEPA 3
+#endif
+
/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */
enum {
__LXC_NETNSA_NONE,
diff --git a/src/lxc/network.c b/src/lxc/network.c
index d1b4d43ada..2ac72b5391 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -266,6 +266,11 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
return -1;
}
+static int instantiate_ipvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
+{
+ return 0;
+}
+
static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
char peer[IFNAMSIZ];
@@ -320,6 +325,8 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
return 0;
}
+
+
static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
int ret;
@@ -392,6 +399,7 @@ static int instantiate_none(struct lxc_handler *handler, struct lxc_netdev *netd
static instantiate_cb netdev_conf[LXC_NET_MAXCONFTYPE + 1] = {
[LXC_NET_VETH] = instantiate_veth,
[LXC_NET_MACVLAN] = instantiate_macvlan,
+ [LXC_NET_IPVLAN] = instantiate_ipvlan,
[LXC_NET_VLAN] = instantiate_vlan,
[LXC_NET_PHYS] = instantiate_phys,
[LXC_NET_EMPTY] = instantiate_empty,
@@ -445,6 +453,11 @@ static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netd
return 0;
}
+static int shutdown_ipvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
+{
+ return 0;
+}
+
static int shutdown_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
return 0;
@@ -497,6 +510,7 @@ static int shutdown_none(struct lxc_handler *handler, struct lxc_netdev *netdev)
static instantiate_cb netdev_deconf[LXC_NET_MAXCONFTYPE + 1] = {
[LXC_NET_VETH] = shutdown_veth,
[LXC_NET_MACVLAN] = shutdown_macvlan,
+ [LXC_NET_IPVLAN] = shutdown_ipvlan,
[LXC_NET_VLAN] = shutdown_vlan,
[LXC_NET_PHYS] = shutdown_phys,
[LXC_NET_EMPTY] = shutdown_empty,
@@ -1932,6 +1946,7 @@ static const char *const lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = {
[LXC_NET_EMPTY] = "empty",
[LXC_NET_VETH] = "veth",
[LXC_NET_MACVLAN] = "macvlan",
+ [LXC_NET_IPVLAN] = "ipvlan",
[LXC_NET_PHYS] = "phys",
[LXC_NET_VLAN] = "vlan",
[LXC_NET_NONE] = "none",
diff --git a/src/lxc/network.h b/src/lxc/network.h
index ef1b41b897..aaa663dbbd 100644
--- a/src/lxc/network.h
+++ b/src/lxc/network.h
@@ -40,6 +40,7 @@ enum {
LXC_NET_EMPTY,
LXC_NET_VETH,
LXC_NET_MACVLAN,
+ LXC_NET_IPVLAN,
LXC_NET_PHYS,
LXC_NET_VLAN,
LXC_NET_NONE,
@@ -108,6 +109,11 @@ struct ifla_macvlan {
int mode; /* private, vepa, bridge, passthru */
};
+struct ifla_ipvlan {
+ int mode; /* l3, l3s, l2 */
+ int flags; /* bridge, private, vepa */
+};
+
/* Contains information about the physical network device as seen from the host.
* @ifindex : The ifindex of the physical network device in the host's network
* namespace.
@@ -118,6 +124,7 @@ struct ifla_phys {
union netdev_p {
struct ifla_macvlan macvlan_attr;
+ struct ifla_ipvlan ipvlan_attr;
struct ifla_phys phys_attr;
struct ifla_veth veth_attr;
struct ifla_vlan vlan_attr;
More information about the lxc-devel
mailing list