From 1bbde12e5741b260b16639711033d2da738e0706 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 2 Dec 2022 16:36:57 +0100 Subject: [PATCH] libnm,nmcli: add vlan.protocol property Introduce a "vlan.protocol" property that specifies the protocol of a VLAN, which controls the tag (EtherType) used for encapsulation. Regular VLANs use 802.1Q (tag 0x8100). To implement VLAN stacking it's sometimes useful to have 802.1ad VLANs with tag 0x88A8. The property is a string instead of e.g. an enum because this allows maximum flexibility in the future. For example, it becomes possible to specify an arbitrary number in case if the kernel ever allows it. --- src/libnm-client-impl/libnm.ver | 1 + ...gen-metadata-nm-settings-libnm-core.xml.in | 4 ++ src/libnm-core-impl/nm-setting-vlan.c | 47 +++++++++++++++++++ src/libnm-core-public/nm-setting-vlan.h | 3 ++ src/libnmc-setting/nm-meta-setting-desc.c | 6 +++ src/libnmc-setting/settings-docs.h.in | 1 + .../gen-metadata-nm-settings-nmcli.xml.in | 2 + 7 files changed, 64 insertions(+) diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index 66538c5e29..7f531b6de2 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -1904,5 +1904,6 @@ global: nm_setting_ovs_port_get_trunk; nm_setting_ovs_port_remove_trunk; nm_setting_ovs_port_remove_trunk_by_value; + nm_setting_vlan_get_protocol; nm_utils_ensure_gtypes; } libnm_1_40_0; diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index 781f7610ec..6e4347b915 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -2256,6 +2256,10 @@ dbus-type="s" gprop-type="gchararray" /> + parent; } +/** + * nm_setting_vlan_get_protocol: + * @setting: the #NMSettingVlan + * + * Since: 1.42 + * + * Returns: the #NMSettingVlan:protocol property of the setting + **/ +const char * +nm_setting_vlan_get_protocol(NMSettingVlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VLAN(setting), NULL); + + return NM_SETTING_VLAN_GET_PRIVATE(setting)->protocol; +} + /** * nm_setting_vlan_get_id: * @setting: the #NMSettingVlan @@ -662,6 +680,16 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (!NM_IN_STRSET(priv->protocol, NULL, "802.1Q", "802.1ad")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid VLAN protocol %s: must be '802.1Q' or '802.1ad'"), + priv->protocol); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PROTOCOL); + return FALSE; + } + if (connection && !s_wired) { /* technically, a VLAN setting does not require an ethernet setting. However, * the ifcfg-rh reader always adds a ethernet setting when reading a vlan setting. @@ -915,6 +943,25 @@ nm_setting_vlan_class_init(NMSettingVlanClass *klass) .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_gprop, .from_dbus_is_full = TRUE)); + /** + * NMSettingVlan:protocol: + * + * Specifies the VLAN protocol to use for encapsulation. + * + * Supported values are: '802.1Q', '802.1ad'. If not specified the default + * value is '802.1Q'. + * + * Since: 1.42 + **/ + _nm_setting_property_define_direct_string(properties_override, + obj_properties, + NM_SETTING_VLAN_PROTOCOL, + PROP_PROTOCOL, + NM_SETTING_PARAM_INFERRABLE, + NMSettingVlanPrivate, + protocol, + .direct_string_is_refstr = TRUE); + /** * NMSettingVlan:ingress-priority-map: * diff --git a/src/libnm-core-public/nm-setting-vlan.h b/src/libnm-core-public/nm-setting-vlan.h index a99d725613..7fa79e357d 100644 --- a/src/libnm-core-public/nm-setting-vlan.h +++ b/src/libnm-core-public/nm-setting-vlan.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS #define NM_SETTING_VLAN_PARENT "parent" #define NM_SETTING_VLAN_ID "id" #define NM_SETTING_VLAN_FLAGS "flags" +#define NM_SETTING_VLAN_PROTOCOL "protocol" #define NM_SETTING_VLAN_INGRESS_PRIORITY_MAP "ingress-priority-map" #define NM_SETTING_VLAN_EGRESS_PRIORITY_MAP "egress-priority-map" @@ -84,6 +85,8 @@ NMSetting *nm_setting_vlan_new(void); const char *nm_setting_vlan_get_parent(NMSettingVlan *setting); guint32 nm_setting_vlan_get_id(NMSettingVlan *setting); guint32 nm_setting_vlan_get_flags(NMSettingVlan *setting); +NM_AVAILABLE_IN_1_42 +const char *nm_setting_vlan_get_protocol(NMSettingVlan *setting); gint32 nm_setting_vlan_get_num_priorities(NMSettingVlan *setting, NMVlanPriorityMap map); diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index c485095a5d..d5a92d9821 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -7530,6 +7530,12 @@ static const NMMetaPropertyInfo *const property_infos_VLAN[] = { .set_fcn = _set_fcn_gobject_flags, ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_PROTOCOL, + .property_type = &_pt_gobject_string, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = NM_MAKE_STRV ("802.1Q", "802.1ad"), + ), + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, .is_cli_option = TRUE, .property_alias = "ingress", diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in index 86759ced7a..6905a1793d 100644 --- a/src/libnmc-setting/settings-docs.h.in +++ b/src/libnmc-setting/settings-docs.h.in @@ -334,6 +334,7 @@ #define DESCRIBE_DOC_NM_SETTING_VLAN_ID N_("The VLAN identifier that the interface created by this connection should be assigned. The valid range is from 0 to 4094, without the reserved id 4095.") #define DESCRIBE_DOC_NM_SETTING_VLAN_INGRESS_PRIORITY_MAP N_("For incoming packets, a list of mappings from 802.1p priorities to Linux SKB priorities. The mapping is given in the format \"from:to\" where both \"from\" and \"to\" are unsigned integers, ie \"7:3\".") #define DESCRIBE_DOC_NM_SETTING_VLAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this VLAN interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.") +#define DESCRIBE_DOC_NM_SETTING_VLAN_PROTOCOL N_("Specifies the VLAN protocol to use for encapsulation. Supported values are: '802.1Q', '802.1ad'. If not specified the default value is '802.1Q'.") #define DESCRIBE_DOC_NM_SETTING_VPN_DATA N_("Dictionary of key/value pairs of VPN plugin specific data. Both keys and values must be strings.") #define DESCRIBE_DOC_NM_SETTING_VPN_PERSISTENT N_("If the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected.") #define DESCRIBE_DOC_NM_SETTING_VPN_SECRETS N_("Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys. Both keys and values must be strings.") diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in index 6dcd98a662..8b1ee61ebf 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in @@ -1045,6 +1045,8 @@ +