diff options
| author | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
| commit | e74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch) | |
| tree | 3469f17ea9af91f7ff169b890633bda68b0cf76e /libnm-core/nm-setting-ovs-external-ids.c | |
| parent | bfe522304da217296e2a61040f58e35ec5d6f3f2 (diff) | |
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'libnm-core/nm-setting-ovs-external-ids.c')
| -rw-r--r-- | libnm-core/nm-setting-ovs-external-ids.c | 551 |
1 files changed, 0 insertions, 551 deletions
diff --git a/libnm-core/nm-setting-ovs-external-ids.c b/libnm-core/nm-setting-ovs-external-ids.c deleted file mode 100644 index 16becb72..00000000 --- a/libnm-core/nm-setting-ovs-external-ids.c +++ /dev/null @@ -1,551 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2017 - 2020 Red Hat, Inc. - */ - -#include "libnm-core/nm-default-libnm-core.h" - -#include "nm-setting-ovs-external-ids.h" - -#include "nm-setting-private.h" -#include "nm-utils-private.h" -#include "nm-connection-private.h" - -#define MAX_NUM_KEYS 256 - -/*****************************************************************************/ - -/** - * SECTION:nm-setting-ovs-external-ids - * @short_description: External-IDs for OVS database - * - * The #NMSettingOvsExternalIDs object is a #NMSetting subclass that allow to - * configure external ids for OVS. - **/ - -/*****************************************************************************/ - -NM_GOBJECT_PROPERTIES_DEFINE(NMSettingOvsExternalIDs, PROP_DATA, ); - -typedef struct { - GHashTable * data; - const char **data_keys; -} NMSettingOvsExternalIDsPrivate; - -/** - * NMSettingOvsExternalIDs: - * - * OVS External IDs Settings - */ -struct _NMSettingOvsExternalIDs { - NMSetting parent; - NMSettingOvsExternalIDsPrivate _priv; -}; - -struct _NMSettingOvsExternalIDsClass { - NMSettingClass parent; -}; - -G_DEFINE_TYPE(NMSettingOvsExternalIDs, nm_setting_ovs_external_ids, NM_TYPE_SETTING) - -#define NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMSettingOvsExternalIDs, NM_IS_SETTING_OVS_EXTERNAL_IDS) - -/*****************************************************************************/ - -static gboolean -_exid_key_char_is_regular(char ch) -{ - /* allow words of printable characters, plus some - * special characters, for example to support base64 encoding. */ - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') - || NM_IN_SET(ch, '-', '_', '+', '/', '=', '.'); -} - -/** - * nm_setting_ovs_external_ids_check_key: - * @key: (allow-none): the key to check - * @error: a #GError, %NULL to ignore. - * - * Checks whether @key is a valid key for OVS' external-ids. - * This means, the key cannot be %NULL, not too large and valid ASCII. - * Also, only digits and numbers are allowed with a few special - * characters. They key must also not start with "NM.". - * - * Since: 1.30 - * - * Returns: %TRUE if @key is a valid user data key. - */ -gboolean -nm_setting_ovs_external_ids_check_key(const char *key, GError **error) -{ - gsize len; - - g_return_val_if_fail(!error || !*error, FALSE); - - if (!key || !key[0]) { - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("missing key")); - return FALSE; - } - len = strlen(key); - if (len > 255u) { - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("key is too long")); - return FALSE; - } - if (!g_utf8_validate(key, len, NULL)) { - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("key must be UTF8")); - return FALSE; - } - if (!NM_STRCHAR_ALL(key, ch, _exid_key_char_is_regular(ch))) { - /* Probably OVS is more forgiving about what makes a valid key for - * an external-id. However, we are strict (at least, for now). */ - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("key contains invalid characters")); - return FALSE; - } - - if (NM_STR_HAS_PREFIX(key, NM_OVS_EXTERNAL_ID_NM_PREFIX)) { - /* these keys are reserved. */ - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("key cannot start with \"NM.\"")); - return FALSE; - } - - return TRUE; -} - -/** - * nm_setting_ovs_external_ids_check_val: - * @val: (allow-none): the value to check - * @error: a #GError, %NULL to ignore. - * - * Checks whether @val is a valid user data value. This means, - * value is not %NULL, not too large and valid UTF-8. - * - * Since: 1.30 - * - * Returns: %TRUE if @val is a valid user data value. - */ -gboolean -nm_setting_ovs_external_ids_check_val(const char *val, GError **error) -{ - gsize len; - - g_return_val_if_fail(!error || !*error, FALSE); - - if (!val) { - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("value is missing")); - return FALSE; - } - - len = strlen(val); - if (len > (8u * 1024u)) { - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("value is too large")); - return FALSE; - } - - if (!g_utf8_validate(val, len, NULL)) { - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("value is not valid UTF8")); - return FALSE; - } - - return TRUE; -} - -/*****************************************************************************/ - -static GHashTable * -_create_data_hash(void) -{ - return g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); -} - -GHashTable * -_nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *self) -{ - return NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self)->data; -} - -/** - * nm_setting_ovs_external_ids_get_data_keys: - * @setting: the #NMSettingOvsExternalIDs - * @out_len: (out): the length of the returned array - * - * Returns: (array length=out_len) (transfer none): a - * %NULL-terminated array containing each key from the table. - **/ -const char *const * -nm_setting_ovs_external_ids_get_data_keys(NMSettingOvsExternalIDs *setting, guint *out_len) -{ - NMSettingOvsExternalIDs * self = setting; - NMSettingOvsExternalIDsPrivate *priv; - - g_return_val_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self), NULL); - - priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); - - if (priv->data_keys) { - NM_SET_OUT(out_len, g_hash_table_size(priv->data)); - return priv->data_keys; - } - - priv->data_keys = nm_utils_strdict_get_keys(priv->data, TRUE, out_len); - - /* don't return %NULL, but hijack the @data_keys fields as a pseudo - * empty strv array. */ - return priv->data_keys ?: ((const char **) &priv->data_keys); -} - -/*****************************************************************************/ - -/** - * nm_setting_ovs_external_ids_get_data: - * @setting: the #NMSettingOvsExternalIDs instance - * @key: the external-id to lookup - * - * Since: 1.30 - * - * Returns: (transfer none): the value associated with @key or %NULL if no such - * value exists. - */ -const char * -nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *setting, const char *key) -{ - NMSettingOvsExternalIDs * self = setting; - NMSettingOvsExternalIDsPrivate *priv; - - g_return_val_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self), NULL); - g_return_val_if_fail(key, NULL); - - priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); - - if (!priv->data) - return NULL; - - return g_hash_table_lookup(priv->data, key); -} - -/** - * nm_setting_ovs_external_ids_set_data: - * @setting: the #NMSettingOvsExternalIDs instance - * @key: the key to set - * @val: (allow-none): the value to set or %NULL to clear a key. - * - * Since: 1.30 - */ -void -nm_setting_ovs_external_ids_set_data(NMSettingOvsExternalIDs *setting, - const char * key, - const char * val) -{ - NMSettingOvsExternalIDs * self = setting; - NMSettingOvsExternalIDsPrivate *priv; - - g_return_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self)); - - priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); - - if (!val) { - if (priv->data && g_hash_table_remove(priv->data, key)) - goto out_changed; - return; - } - - if (priv->data) { - const char *val2; - - if (g_hash_table_lookup_extended(priv->data, key, NULL, (gpointer *) &val2)) { - if (nm_streq(val, val2)) - return; - } - } else - priv->data = _create_data_hash(); - - g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val)); - -out_changed: - nm_clear_g_free(&priv->data_keys); - _notify(self, PROP_DATA); -} - -/*****************************************************************************/ - -static gboolean -verify(NMSetting *setting, NMConnection *connection, GError **error) -{ - NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(setting); - NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); - - if (priv->data) { - gs_free_error GError *local = NULL; - GHashTableIter iter; - const char * key; - const char * val; - - g_hash_table_iter_init(&iter, priv->data); - while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { - if (!nm_setting_ovs_external_ids_check_key(key, &local)) { - g_set_error(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - _("invalid key \"%s\": %s"), - key, - local->message); - } else if (!nm_setting_ovs_external_ids_check_val(val, &local)) { - g_set_error(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - _("invalid value for \"%s\": %s"), - key, - local->message); - } else - continue; - g_prefix_error(error, - "%s.%s: ", - NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, - NM_SETTING_OVS_EXTERNAL_IDS_DATA); - return FALSE; - } - } - - if (priv->data && g_hash_table_size(priv->data) > MAX_NUM_KEYS) { - g_set_error(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("maximum number of user data entries reached (%u instead of %u)"), - g_hash_table_size(priv->data), - (unsigned) MAX_NUM_KEYS); - g_prefix_error(error, - "%s.%s: ", - NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, - NM_SETTING_OVS_EXTERNAL_IDS_DATA); - return FALSE; - } - - if (connection) { - NMSettingConnection *s_con; - const char * type; - const char * slave_type; - - type = nm_connection_get_connection_type(connection); - if (!type) { - NMSetting *s_base; - - s_base = _nm_connection_find_base_type_setting(connection); - if (s_base) - type = nm_setting_get_name(s_base); - } - if (NM_IN_STRSET(type, - NM_SETTING_OVS_BRIDGE_SETTING_NAME, - NM_SETTING_OVS_PORT_SETTING_NAME, - NM_SETTING_OVS_INTERFACE_SETTING_NAME)) - goto connection_type_is_good; - - if ((s_con = nm_connection_get_setting_connection(connection)) - && _nm_connection_detect_slave_type_full(s_con, - connection, - &slave_type, - NULL, - NULL, - NULL, - NULL) - && nm_streq0(slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) - goto connection_type_is_good; - - g_set_error_literal(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("OVS external IDs can only be added to a profile of type OVS " - "bridge/port/interface or to OVS system interface")); - return FALSE; - } -connection_type_is_good: - - return TRUE; -} - -static NMTernary -compare_property(const NMSettInfoSetting *sett_info, - guint property_idx, - NMConnection * con_a, - NMSetting * set_a, - NMConnection * con_b, - NMSetting * set_b, - NMSettingCompareFlags flags) -{ - NMSettingOvsExternalIDsPrivate *priv; - NMSettingOvsExternalIDsPrivate *pri2; - - if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_OVS_EXTERNAL_IDS_DATA)) { - if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE)) - return NM_TERNARY_DEFAULT; - - if (!set_b) - return TRUE; - - priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_a)); - pri2 = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_b)); - return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal); - } - - return NM_SETTING_CLASS(nm_setting_ovs_external_ids_parent_class) - ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); -} - -/*****************************************************************************/ - -static void -get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object); - NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); - GHashTableIter iter; - GHashTable * data; - const char * key; - const char * val; - - switch (prop_id) { - case PROP_DATA: - data = _create_data_hash(); - if (priv->data) { - g_hash_table_iter_init(&iter, priv->data); - while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) - g_hash_table_insert(data, g_strdup(key), g_strdup(val)); - } - g_value_take_boxed(value, data); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object); - NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); - - switch (prop_id) { - case PROP_DATA: - { - gs_unref_hashtable GHashTable *old = NULL; - GHashTableIter iter; - GHashTable * data; - const char * key; - const char * val; - - nm_clear_g_free(&priv->data_keys); - - old = g_steal_pointer(&priv->data); - - data = g_value_get_boxed(value); - if (nm_g_hash_table_size(data) <= 0) - return; - - priv->data = _create_data_hash(); - g_hash_table_iter_init(&iter, data); - while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) - g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val)); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -/*****************************************************************************/ - -static void -nm_setting_ovs_external_ids_init(NMSettingOvsExternalIDs *self) -{} - -/** - * nm_setting_ovs_external_ids_new: - * - * Creates a new #NMSettingOvsExternalIDs object with default values. - * - * Returns: (transfer full) (type NMSettingOvsExternalIDs): the new empty - * #NMSettingOvsExternalIDs object - * - * Since: 1.30 - */ -NMSetting * -nm_setting_ovs_external_ids_new(void) -{ - return g_object_new(NM_TYPE_SETTING_OVS_EXTERNAL_IDS, NULL); -} - -static void -finalize(GObject *object) -{ - NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object); - NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self); - - g_free(priv->data_keys); - if (priv->data) - g_hash_table_unref(priv->data); - - G_OBJECT_CLASS(nm_setting_ovs_external_ids_parent_class)->finalize(object); -} - -static void -nm_setting_ovs_external_ids_class_init(NMSettingOvsExternalIDsClass *klass) -{ - GObjectClass * object_class = G_OBJECT_CLASS(klass); - NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray * properties_override = _nm_sett_info_property_override_create_array(); - - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->finalize = finalize; - - setting_class->compare_property = compare_property; - setting_class->verify = verify; - - /** - * NMSettingOvsExternalIDs:data: (type GHashTable(utf8,utf8)) - * - * A dictionary of key/value pairs with exernal-ids for OVS. - * - * Since: 1.30 - **/ - obj_properties[PROP_DATA] = g_param_spec_boxed(NM_SETTING_OVS_EXTERNAL_IDS_DATA, - "", - "", - G_TYPE_HASH_TABLE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - _nm_properties_override_gobj(properties_override, - obj_properties[PROP_DATA], - &nm_sett_info_propert_type_strdict); - - g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - _nm_setting_class_commit_full(setting_class, - NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS, - NULL, - properties_override); -} |