lxc_config_define(net_veth_ipv4_route);
lxc_config_define(net_veth_ipv6_route);
lxc_config_define(net_veth_vlan_id);
+lxc_config_define(net_veth_vlan_tagged_id);
lxc_config_define(net_vlan_id);
lxc_config_define(no_new_privs);
lxc_config_define(personality);
{ "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.veth.vlan.id", set_config_net_veth_vlan_id, get_config_net_veth_vlan_id, clr_config_net_veth_vlan_id, },
+ { "lxc.net.veth.vlan.tagged.id", set_config_net_veth_vlan_tagged_id, get_config_net_veth_vlan_tagged_id, clr_config_net_veth_vlan_tagged_id, },
{ "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, },
netdev->type = LXC_NET_VETH;
lxc_list_init(&netdev->priv.veth_attr.ipv4_routes);
lxc_list_init(&netdev->priv.veth_attr.ipv6_routes);
+ lxc_list_init(&netdev->priv.veth_attr.vlan_tagged_ids);
if (!lxc_veth_flag_to_mode(netdev->priv.veth_attr.mode))
lxc_veth_mode_to_flag(&netdev->priv.veth_attr.mode, "bridge");
} else if (strcmp(value, "macvlan") == 0) {
return 0;
}
+static int set_config_net_veth_vlan_tagged_id(const char *key, const char *value,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ __do_free struct lxc_list *list = NULL;
+ int ret;
+ unsigned short vlan_id;
+ struct lxc_netdev *netdev = data;
+
+ if (!netdev)
+ return ret_errno(EINVAL);
+
+ if (lxc_config_value_empty(value))
+ return clr_config_net_veth_vlan_tagged_id(key, lxc_conf, data);
+
+ ret = get_u16(&vlan_id, value, 0);
+ if (ret < 0)
+ ret_errno(EINVAL);
+
+ if (vlan_id > BRIDGE_VLAN_ID_MAX)
+ ret_errno(EINVAL);
+
+ list = malloc(sizeof(*list));
+ if (!list)
+ return ret_errno(ENOMEM);
+
+ lxc_list_init(list);
+ list->elem = UINT_TO_PTR(vlan_id);
+
+ lxc_list_add_tail(&netdev->priv.veth_attr.vlan_tagged_ids, move_ptr(list));
+
+ return 0;
+}
+
static int set_config_net_macvlan_mode(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
return 0;
}
+static int clr_config_net_veth_vlan_tagged_id(const char *key,
+ struct lxc_conf *lxc_conf, void *data)
+{
+ struct lxc_netdev *netdev = data;
+ struct lxc_list *cur, *next;
+
+ if (!netdev)
+ return ret_errno(EINVAL);
+
+ lxc_list_for_each_safe(cur, &netdev->priv.veth_attr.vlan_tagged_ids, next) {
+ lxc_list_del(cur);
+ free(cur);
+ }
+
+ return 0;
+}
+
+
static int clr_config_net_script_up(const char *key, struct lxc_conf *lxc_conf,
void *data)
{
return fulllen;
}
+static int get_config_net_veth_vlan_tagged_id(const char *key, char *retv, int inlen,
+ struct lxc_conf *c, void *data)
+{
+ int len;
+ size_t listlen;
+ struct lxc_list *it;
+ int fulllen = 0;
+ struct lxc_netdev *netdev = data;
+
+ if (!netdev)
+ ret_errno(EINVAL);
+
+ if (netdev->type != LXC_NET_VETH)
+ return 0;
+
+ if (!retv)
+ inlen = 0;
+ else
+ memset(retv, 0, inlen);
+
+ listlen = lxc_list_len(&netdev->priv.veth_attr.vlan_tagged_ids);
+
+ lxc_list_for_each(it, &netdev->priv.veth_attr.vlan_tagged_ids) {
+ unsigned short i = PTR_TO_USHORT(it->elem);
+ strprint(retv, inlen, "%u%s", i,
+ (listlen-- > 1) ? "\n" : "");
+ }
+
+ return fulllen;
+}
+
static int get_config_net_script_up(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{