Commit 26c39028 by Jamal Hadi Salim Committed by Daniel Lezcano

Add VLAN support in config

This adds ability to migrate vlan interfaces into namespaces by specifying them in a config Signed-off-by: 's avatarJamal Hadi Salim <hadi@cyberus.ca> Acked-by: 's avatarDaniel Lezcano <daniel.lezcano@free.fr> Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 9ddaf3bf
...@@ -102,6 +102,7 @@ AC_CONFIG_FILES([ ...@@ -102,6 +102,7 @@ AC_CONFIG_FILES([
doc/examples/Makefile doc/examples/Makefile
doc/examples/lxc-macvlan.conf doc/examples/lxc-macvlan.conf
doc/examples/lxc-vlan.conf
doc/examples/lxc-no-netns.conf doc/examples/lxc-no-netns.conf
doc/examples/lxc-empty-netns.conf doc/examples/lxc-empty-netns.conf
doc/examples/lxc-phys.conf doc/examples/lxc-phys.conf
......
...@@ -5,6 +5,7 @@ pkgexamplesdir=$(docdir)/examples ...@@ -5,6 +5,7 @@ pkgexamplesdir=$(docdir)/examples
pkgexamples_DATA = \ pkgexamples_DATA = \
lxc-macvlan.conf \ lxc-macvlan.conf \
lxc-vlan.conf \
lxc-no-netns.conf \ lxc-no-netns.conf \
lxc-empty-netns.conf \ lxc-empty-netns.conf \
lxc-phys.conf \ lxc-phys.conf \
...@@ -14,6 +15,7 @@ endif ...@@ -14,6 +15,7 @@ endif
noinst_DATA = \ noinst_DATA = \
lxc-macvlan.conf.in \ lxc-macvlan.conf.in \
lxc-vlan.conf.in \
lxc-empty-netns.conf.in \ lxc-empty-netns.conf.in \
lxc-no-netns.conf.in \ lxc-no-netns.conf.in \
lxc-phys.conf.in \ lxc-phys.conf.in \
......
# Container with network virtualized using the vlan device driver
lxc.utsname = alpha
lxc.network.type = vlan
lxc.network.vlan.id = 1234
lxc.network.flags = up
lxc.network.link = eth0
lxc.network.hwaddr = 4a:49:43:49:79:bd
lxc.network.ipv4 = 1.2.3.4/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596
...@@ -75,12 +75,14 @@ struct mount_opt { ...@@ -75,12 +75,14 @@ struct mount_opt {
static int instanciate_veth(struct lxc_netdev *); static int instanciate_veth(struct lxc_netdev *);
static int instanciate_macvlan(struct lxc_netdev *); static int instanciate_macvlan(struct lxc_netdev *);
static int instanciate_vlan(struct lxc_netdev *);
static int instanciate_phys(struct lxc_netdev *); static int instanciate_phys(struct lxc_netdev *);
static int instanciate_empty(struct lxc_netdev *); static int instanciate_empty(struct lxc_netdev *);
static instanciate_cb netdev_conf[MAXCONFTYPE + 1] = { static instanciate_cb netdev_conf[MAXCONFTYPE + 1] = {
[VETH] = instanciate_veth, [VETH] = instanciate_veth,
[MACVLAN] = instanciate_macvlan, [MACVLAN] = instanciate_macvlan,
[VLAN] = instanciate_vlan,
[PHYS] = instanciate_phys, [PHYS] = instanciate_phys,
[EMPTY] = instanciate_empty, [EMPTY] = instanciate_empty,
}; };
...@@ -927,6 +929,35 @@ static int instanciate_macvlan(struct lxc_netdev *netdev) ...@@ -927,6 +929,35 @@ static int instanciate_macvlan(struct lxc_netdev *netdev)
return 0; return 0;
} }
/* XXX: merge with instanciate_macvlan */
static int instanciate_vlan(struct lxc_netdev *netdev)
{
char peer[IFNAMSIZ];
if (!netdev->link) {
ERROR("no link specified for vlan netdev");
return -1;
}
snprintf(peer, sizeof(peer), "vlan%d",netdev->vlan_attr.vid);
if (lxc_vlan_create(netdev->link, peer, netdev->vlan_attr.vid)) {
ERROR("failed to create vlan interface '%s' on '%s'",
peer, netdev->link);
return -1;
}
netdev->ifindex = if_nametoindex(peer);
if (!netdev->ifindex) {
ERROR("failed to retrieve the ifindex for %s", peer);
lxc_device_delete(peer);
return -1;
}
DEBUG("instanciated vlan '%s', ifindex is '%d'", "vlan1000", netdev->ifindex);
return 0;
}
static int instanciate_phys(struct lxc_netdev *netdev) static int instanciate_phys(struct lxc_netdev *netdev)
{ {
netdev->ifindex = if_nametoindex(netdev->link); netdev->ifindex = if_nametoindex(netdev->link);
......
...@@ -33,6 +33,7 @@ enum { ...@@ -33,6 +33,7 @@ enum {
VETH, VETH,
MACVLAN, MACVLAN,
PHYS, PHYS,
VLAN,
MAXCONFTYPE, MAXCONFTYPE,
}; };
...@@ -69,6 +70,14 @@ struct lxc_inet6dev { ...@@ -69,6 +70,14 @@ struct lxc_inet6dev {
struct lxc_route6 { struct lxc_route6 {
struct in6_addr addr; struct in6_addr addr;
}; };
struct ifla_vlan {
uint flags;
uint fmask;
ushort vid;
ushort pad;
};
/* /*
* Defines a structure to configure a network device * Defines a structure to configure a network device
* @link : lxc.network.link, name of bridge or host iface to attach if any * @link : lxc.network.link, name of bridge or host iface to attach if any
...@@ -87,6 +96,7 @@ struct lxc_netdev { ...@@ -87,6 +96,7 @@ struct lxc_netdev {
char *pair; char *pair;
char *hwaddr; char *hwaddr;
char *mtu; char *mtu;
struct ifla_vlan vlan_attr;
struct lxc_list ipv4; struct lxc_list ipv4;
struct lxc_list ipv6; struct lxc_list ipv6;
}; };
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <net/if.h> #include <net/if.h>
#include "parse.h" #include "parse.h"
#include "utils.h"
#include <lxc/log.h> #include <lxc/log.h>
#include <lxc/conf.h> #include <lxc/conf.h>
...@@ -51,6 +52,7 @@ static int config_network_link(const char *, char *, struct lxc_conf *); ...@@ -51,6 +52,7 @@ static int config_network_link(const char *, char *, struct lxc_conf *);
static int config_network_name(const char *, char *, struct lxc_conf *); static int config_network_name(const char *, char *, struct lxc_conf *);
static int config_network_pair(const char *, char *, struct lxc_conf *); static int config_network_pair(const char *, char *, struct lxc_conf *);
static int config_network_hwaddr(const char *, char *, struct lxc_conf *); static int config_network_hwaddr(const char *, char *, struct lxc_conf *);
static int config_network_vlanid(const char *, char *, struct lxc_conf *);
static int config_network_mtu(const char *, char *, struct lxc_conf *); static int config_network_mtu(const char *, char *, struct lxc_conf *);
static int config_network_ipv4(const char *, char *, struct lxc_conf *); static int config_network_ipv4(const char *, char *, struct lxc_conf *);
static int config_network_ipv6(const char *, char *, struct lxc_conf *); static int config_network_ipv6(const char *, char *, struct lxc_conf *);
...@@ -77,6 +79,7 @@ static struct config config[] = { ...@@ -77,6 +79,7 @@ static struct config config[] = {
{ "lxc.network.pair", config_network_pair }, { "lxc.network.pair", config_network_pair },
{ "lxc.network.hwaddr", config_network_hwaddr }, { "lxc.network.hwaddr", config_network_hwaddr },
{ "lxc.network.mtu", config_network_mtu }, { "lxc.network.mtu", config_network_mtu },
{ "lxc.network.vlanid", config_network_vlanid },
{ "lxc.network.ipv4", config_network_ipv4 }, { "lxc.network.ipv4", config_network_ipv4 },
{ "lxc.network.ipv6", config_network_ipv6 }, { "lxc.network.ipv6", config_network_ipv6 },
}; };
...@@ -125,6 +128,8 @@ static int config_network_type(const char *key, char *value, struct lxc_conf *lx ...@@ -125,6 +128,8 @@ static int config_network_type(const char *key, char *value, struct lxc_conf *lx
netdev->type = VETH; netdev->type = VETH;
else if (!strcmp(value, "macvlan")) else if (!strcmp(value, "macvlan"))
netdev->type = MACVLAN; netdev->type = MACVLAN;
else if (!strcmp(value, "vlan"))
netdev->type = VLAN;
else if (!strcmp(value, "phys")) else if (!strcmp(value, "phys"))
netdev->type = PHYS; netdev->type = PHYS;
else if (!strcmp(value, "empty")) else if (!strcmp(value, "empty"))
...@@ -253,6 +258,21 @@ static int config_network_hwaddr(const char *key, char *value, ...@@ -253,6 +258,21 @@ static int config_network_hwaddr(const char *key, char *value,
return 0; return 0;
} }
static int config_network_vlanid(const char *key, char *value,
struct lxc_conf *lxc_conf)
{
struct lxc_netdev *netdev;
netdev = network_netdev(key, value, &lxc_conf->network);
if (!netdev)
return -1;
if (get_u16(&netdev->vlan_attr.vid, value, 0))
return -1;
return 0;
}
static int config_network_mtu(const char *key, char *value, static int config_network_mtu(const char *key, char *value,
struct lxc_conf *lxc_conf) struct lxc_conf *lxc_conf)
{ {
......
...@@ -65,4 +65,5 @@ echo ...@@ -65,4 +65,5 @@ echo
echo "--- Misc ---" echo "--- Misc ---"
echo -n "Veth pair device: " && is_enabled CONFIG_VETH echo -n "Veth pair device: " && is_enabled CONFIG_VETH
echo -n "Macvlan: " && is_enabled CONFIG_MACVLAN echo -n "Macvlan: " && is_enabled CONFIG_MACVLAN
echo -n "Vlan: " && is_enabled CONFIG_VLAN_8021Q
echo -n "File capabilities: " && is_enabled CONFIG_SECURITY_FILE_CAPABILITIES echo -n "File capabilities: " && is_enabled CONFIG_SECURITY_FILE_CAPABILITIES
...@@ -63,6 +63,10 @@ ...@@ -63,6 +63,10 @@
# define IFLA_INFO_KIND 1 # define IFLA_INFO_KIND 1
#endif #endif
#ifndef IFLA_VLAN_ID
# define IFLA_VLAN_ID 1
#endif
#ifndef IFLA_INFO_DATA #ifndef IFLA_INFO_DATA
# define IFLA_INFO_DATA 2 # define IFLA_INFO_DATA 2
#endif #endif
...@@ -392,6 +396,80 @@ out: ...@@ -392,6 +396,80 @@ out:
return err; return err;
} }
/* XXX: merge with lxc_macvlan_create */
int lxc_vlan_create(const char *master, const char *name, ushort vlanid)
{
struct nl_handler nlh;
struct nlmsg *nlmsg = NULL, *answer = NULL;
struct link_req *link_req;
struct rtattr *nest, *nest2;
int lindex, len, err = -1;
if (netlink_open(&nlh, NETLINK_ROUTE))
return -1;
len = strlen(master);
if (len == 1 || len > IFNAMSIZ)
goto err3;
len = strlen(name);
if (len == 1 || len > IFNAMSIZ)
goto err3;
nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!nlmsg)
goto err3;
answer = nlmsg_alloc(NLMSG_GOOD_SIZE);
if (!answer)
goto err2;
lindex = if_nametoindex(master);
if (!lindex)
goto err1;
link_req = (struct link_req *)nlmsg;
link_req->ifinfomsg.ifi_family = AF_UNSPEC;
nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
nlmsg->nlmsghdr.nlmsg_flags =
NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK;
nest = nla_begin_nested(nlmsg, IFLA_LINKINFO);
if (!nest)
goto err1;
if (nla_put_string(nlmsg, IFLA_INFO_KIND, "vlan"))
goto err1;
nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA);
if (!nest2)
goto err1;
if (nla_put_u16(nlmsg, IFLA_VLAN_ID, vlanid))
goto err1;
nla_end_nested(nlmsg, nest2);
nla_end_nested(nlmsg, nest);
if (nla_put_u32(nlmsg, IFLA_LINK, lindex))
goto err1;
if (nla_put_string(nlmsg, IFLA_IFNAME, name))
goto err1;
if (netlink_transaction(&nlh, nlmsg, answer))
goto err1;
err = 0;
err1:
nlmsg_free(answer);
err2:
nlmsg_free(nlmsg);
err3:
netlink_close(&nlh);
return err;
}
int lxc_macvlan_create(const char *master, const char *name) int lxc_macvlan_create(const char *master, const char *name)
{ {
struct nl_handler nlh; struct nl_handler nlh;
......
...@@ -69,6 +69,11 @@ extern int lxc_veth_create(const char *name1, const char *name2); ...@@ -69,6 +69,11 @@ extern int lxc_veth_create(const char *name1, const char *name2);
extern int lxc_macvlan_create(const char *master, const char *name); extern int lxc_macvlan_create(const char *master, const char *name);
/* /*
* Create a vlan network device
*/
extern int lxc_vlan_create(const char *master, const char *name, ushort vid);
/*
* Activate forwarding * Activate forwarding
*/ */
extern int lxc_ip_forward_on(const char *name, int family); extern int lxc_ip_forward_on(const char *name, int family);
......
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