doc/examples/Makefile
doc/examples/lxc-macvlan.conf
+ doc/examples/lxc-vlan.conf
doc/examples/lxc-no-netns.conf
doc/examples/lxc-empty-netns.conf
doc/examples/lxc-phys.conf
pkgexamples_DATA = \
lxc-macvlan.conf \
+ lxc-vlan.conf \
lxc-no-netns.conf \
lxc-empty-netns.conf \
lxc-phys.conf \
noinst_DATA = \
lxc-macvlan.conf.in \
+ lxc-vlan.conf.in \
lxc-empty-netns.conf.in \
lxc-no-netns.conf.in \
lxc-phys.conf.in \
--- /dev/null
+# 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
static int instanciate_veth(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_empty(struct lxc_netdev *);
static instanciate_cb netdev_conf[MAXCONFTYPE + 1] = {
[VETH] = instanciate_veth,
[MACVLAN] = instanciate_macvlan,
+ [VLAN] = instanciate_vlan,
[PHYS] = instanciate_phys,
[EMPTY] = instanciate_empty,
};
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)
{
netdev->ifindex = if_nametoindex(netdev->link);
VETH,
MACVLAN,
PHYS,
+ VLAN,
MAXCONFTYPE,
};
struct lxc_route6 {
struct in6_addr addr;
};
+
+struct ifla_vlan {
+ uint flags;
+ uint fmask;
+ ushort vid;
+ ushort pad;
+};
+
/*
* Defines a structure to configure a network device
* @link : lxc.network.link, name of bridge or host iface to attach if any
char *pair;
char *hwaddr;
char *mtu;
+ struct ifla_vlan vlan_attr;
struct lxc_list ipv4;
struct lxc_list ipv6;
};
#include <net/if.h>
#include "parse.h"
+#include "utils.h"
#include <lxc/log.h>
#include <lxc/conf.h>
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_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_ipv4(const char *, char *, struct lxc_conf *);
static int config_network_ipv6(const char *, char *, struct lxc_conf *);
{ "lxc.network.pair", config_network_pair },
{ "lxc.network.hwaddr", config_network_hwaddr },
{ "lxc.network.mtu", config_network_mtu },
+ { "lxc.network.vlanid", config_network_vlanid },
{ "lxc.network.ipv4", config_network_ipv4 },
{ "lxc.network.ipv6", config_network_ipv6 },
};
netdev->type = VETH;
else if (!strcmp(value, "macvlan"))
netdev->type = MACVLAN;
+ else if (!strcmp(value, "vlan"))
+ netdev->type = VLAN;
else if (!strcmp(value, "phys"))
netdev->type = PHYS;
else if (!strcmp(value, "empty"))
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,
struct lxc_conf *lxc_conf)
{
echo "--- Misc ---"
echo -n "Veth pair device: " && is_enabled CONFIG_VETH
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
# define IFLA_INFO_KIND 1
#endif
+#ifndef IFLA_VLAN_ID
+# define IFLA_VLAN_ID 1
+#endif
+
#ifndef IFLA_INFO_DATA
# define IFLA_INFO_DATA 2
#endif
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)
{
struct nl_handler nlh;
*/
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
*/