]> git.proxmox.com Git - mirror_lxc.git/commitdiff
confile: Adds validation for lxc.net.veth.vlan.tagged.id
authorThomas Parrott <thomas.parrott@canonical.com>
Wed, 3 Jun 2020 16:44:13 +0000 (17:44 +0100)
committerThomas Parrott <thomas.parrott@canonical.com>
Tue, 9 Jun 2020 08:40:06 +0000 (09:40 +0100)
Signed-off-by: Thomas Parrott <thomas.parrott@canonical.com>
src/lxc/confile.c

index b8ae9a48b8676033f6584f3fcdd756377064b125..3ee2e8847a3eda9713ea167a1573a2554174e365 100644 (file)
@@ -128,6 +128,7 @@ lxc_config_define(net_veth_pair);
 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);
@@ -242,6 +243,7 @@ static struct lxc_config_t config_jump_table[] = {
        { "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,              },
@@ -309,6 +311,7 @@ static int set_config_net_type(const char *key, const char *value,
                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) {
@@ -520,6 +523,39 @@ static int set_config_net_veth_vlan_id(const char *key, const char *value,
        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)
 {
@@ -5348,6 +5384,24 @@ static int clr_config_net_veth_vlan_id(const char *key, struct lxc_conf *lxc_con
        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)
 {
@@ -5842,6 +5896,37 @@ static int get_config_net_veth_vlan_id(const char *key, char *retv, int inlen,
        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)
 {