summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-05-14 09:16:32 +0200
committerThomas Haller <thaller@redhat.com>2020-05-22 15:58:08 +0200
commit9655dff5cb60a0b920a3e9faed64913a10f5be65 (patch)
tree743de9cdf940e0f8e0e651aadf4d6f23e257694f
parent618ae93b94d23b8ce6fe5e96b23e992aa15b8945 (diff)
downloadNetworkManager-9655dff5cb60a0b920a3e9faed64913a10f5be65.tar.gz
libnm: add API for setting gendata options to NMSetting (nm_setting_option_get())
NMSettingEthtool is implemented using "gendata", meaning a hash of GVariant. This is different from most other settings that have properties implemented as GObject properties. There are two reasons for this approach: - The setting is transferred via D-Bus as "a{sv}" dictionary. By unpacking the dictionary into GObject properties, the setting cannot handle unknown properties. To be forward compatible (and due to sloppy programming), unknown dictionary keys are silently ignored when parsing a NMSetting. That is error prone and also prevents settings to be treated loss-less. Instead, we should at first accept all values from the dictionary. Only in a second step, nm_connection_verify() rejects invalid settings with an error reason. This way, the user can create a NMSetting, but in a separate step handle if the setting doesn't verify. "gendata" solves this by tracking the full GVariant dictionary. This is still not entirely lossless, because multiple keys are combined. This is for example interesting if an libnm client fetches a connection from a newer NetworkManager version. Now the user can modify the properties that she knows about, while leaving all unknown properties (from newer versions) in place. - the approach aims to reduce the necessary boiler plate to create GObject properties. Adding a new property should require less new code. This approach was always be intended to be suitable for all settings, not only NMSettingEthtool. We should not once again try to add API like nm_setting_ethtool_set_feature(), nm_setting_ethtool_set_coalesce(), etc. Note that the option name already fully encodes whether it is a feature, a coalesce option, or whatever. We should not have "nm_setting_set_$SUB_GROUP (setting, $ONE_NAME_FROM_GROUP)" API, but simply "nm_setting_option_set (setting, $OPTION)" accessors. Also, when parsing a NMSettingEthtool from a GVariant, then a feature option can be any kind of variant. Only nm_setting_verify() rejects variants of the wrong type. As such, nm_setting_option_set*() also doesn't validate whether the variant type matches the option. Of course, if you set a value of wrong type, verify() will reject the setting. Add new general purpose API for this and expose it for NMSetting.
-rw-r--r--libnm-core/nm-core-internal.h3
-rw-r--r--libnm-core/nm-setting-ethtool.c2
-rw-r--r--libnm-core/nm-setting.c40
-rw-r--r--libnm-core/nm-setting.h7
-rw-r--r--libnm/libnm.ver1
5 files changed, 35 insertions, 18 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 4493a47d85..252c61d64e 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -322,9 +322,6 @@ guint _nm_setting_option_get_all (NMSetting *setting,
const char *const**out_names,
GVariant *const**out_values);
-GVariant *_nm_setting_option_get (NMSetting *setting,
- const char *name);
-
const char *const*_nm_setting_option_get_all_names (NMSetting *setting,
guint *out_len);
diff --git a/libnm-core/nm-setting-ethtool.c b/libnm-core/nm-setting-ethtool.c
index 664b7d4d63..de7bded5f2 100644
--- a/libnm-core/nm-setting-ethtool.c
+++ b/libnm-core/nm-setting-ethtool.c
@@ -145,7 +145,7 @@ nm_setting_ethtool_get_feature (NMSettingEthtool *setting,
g_return_val_if_fail (NM_IS_SETTING_ETHTOOL (setting), NM_TERNARY_DEFAULT);
g_return_val_if_fail (optname && nm_ethtool_optname_is_feature (optname), NM_TERNARY_DEFAULT);
- v = _nm_setting_option_get (NM_SETTING (setting), optname);
+ v = nm_setting_option_get (NM_SETTING (setting), optname);
if ( v
&& g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) {
return g_variant_get_boolean (v)
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index c7cab45d29..efd81c7b8a 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -2433,19 +2433,6 @@ out:
_nm_setting_emit_property_changed (setting);
}
-GVariant *
-_nm_setting_option_get (NMSetting *setting,
- const char *name)
-{
- GenData *gendata;
-
- g_return_val_if_fail (NM_IS_SETTING (setting), NULL);
- g_return_val_if_fail (name, NULL);
-
- gendata = _gendata_hash (setting, FALSE);
- return gendata ? g_hash_table_lookup (gendata->hash, name) : NULL;
-}
-
guint
_nm_setting_option_get_all (NMSetting *setting,
const char *const**out_names,
@@ -2534,7 +2521,7 @@ _nm_setting_option_get_uint32 (NMSetting *setting,
nm_assert (NM_IS_SETTING (setting));
nm_assert (nm_str_not_empty (optname));
- v = _nm_setting_option_get (setting, optname);
+ v = nm_setting_option_get (setting, optname);
if ( v
&& g_variant_is_of_type (v, G_VARIANT_TYPE_UINT32)) {
NM_SET_OUT (out_value, g_variant_get_uint32 (v));
@@ -2601,6 +2588,31 @@ _nm_setting_option_clear_all (NMSetting *setting,
/*****************************************************************************/
+/**
+ * nm_setting_option_get:
+ * @setting: the #NMSetting
+ * @opt_name: the option name to request.
+ *
+ * Returns: (transfer none): the #GVariant or %NULL if the option
+ * is not set.
+ *
+ * Since: 1.26.
+ */
+GVariant *
+nm_setting_option_get (NMSetting *setting,
+ const char *opt_name)
+{
+ GenData *gendata;
+
+ g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
+ g_return_val_if_fail (opt_name, FALSE);
+
+ gendata = _gendata_hash (setting, FALSE);
+ return gendata ? g_hash_table_lookup (gendata->hash, opt_name) : NULL;
+}
+
+/*****************************************************************************/
+
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h
index 26c1b1ee8d..a0bb51bbf0 100644
--- a/libnm-core/nm-setting.h
+++ b/libnm-core/nm-setting.h
@@ -333,6 +333,13 @@ gboolean nm_setting_set_secret_flags (NMSetting *setting,
/*****************************************************************************/
+NM_AVAILABLE_IN_1_26
+GVariant *nm_setting_option_get (NMSetting *setting,
+ const char *opt_name);
+
+
+/*****************************************************************************/
+
const GVariantType *nm_setting_get_dbus_property_type (NMSetting *setting,
const char *property_name);
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index effa41d162..97cdc06a83 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1732,4 +1732,5 @@ global:
nm_setting_match_remove_driver_by_value;
nm_setting_match_remove_kernel_command_line;
nm_setting_match_remove_kernel_command_line_by_value;
+ nm_setting_option_get;
} libnm_1_24_0;