summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-03-25 10:15:08 +0100
committerThomas Haller <thaller@redhat.com>2019-03-25 10:15:08 +0100
commitf224d6a8537dd58fafc8b7ba977ec7fffe8c31e9 (patch)
treeaf24ac8141818d4adcb27e67a437e8f26ca2d685
parentc7864fc1b226de0e2699fd1b33b6dd8e6cb3b343 (diff)
parent8b0461380febd98cb6b8b867104653325bcddac4 (diff)
downloadNetworkManager-f224d6a8537dd58fafc8b7ba977ec7fffe8c31e9.tar.gz
nmcli: merge branch 'th/nmcli-list-options'
https://github.com/NetworkManager/NetworkManager/pull/317
-rw-r--r--Makefile.am4
-rw-r--r--clients/cli/connections.c148
-rw-r--r--clients/cli/settings.c260
-rw-r--r--clients/cli/settings.h13
-rw-r--r--clients/common/meson.build2
-rw-r--r--clients/common/nm-client-utils.c4
-rw-r--r--clients/common/nm-client-utils.h8
-rw-r--r--clients/common/nm-meta-setting-desc.c3819
-rw-r--r--clients/common/nm-meta-setting-desc.h77
-rw-r--r--libnm-core/meson.build1
-rw-r--r--libnm-core/nm-core-internal.h24
-rw-r--r--libnm-core/nm-setting-connection.c7
-rw-r--r--libnm-core/nm-setting-team.c2
-rw-r--r--libnm-core/nm-setting-vlan.c122
-rw-r--r--libnm-core/nm-setting-vpn.c14
-rw-r--r--libnm-core/nm-setting-wired.c16
-rw-r--r--libnm-core/nm-utils.c3
-rw-r--r--libnm-core/tests/test-general.c127
-rw-r--r--libnm/nm-secret-agent-old.c3
-rw-r--r--shared/meson.build2
-rw-r--r--shared/nm-libnm-core-utils.c76
-rw-r--r--shared/nm-libnm-core-utils.h90
-rw-r--r--shared/nm-meta-setting.c8
-rw-r--r--shared/nm-meta-setting.h12
-rw-r--r--shared/nm-utils/nm-macros-internal.h3
-rw-r--r--shared/nm-utils/nm-shared-utils.c66
-rw-r--r--shared/nm-utils/nm-shared-utils.h16
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c6
28 files changed, 2248 insertions, 2685 deletions
diff --git a/Makefile.am b/Makefile.am
index 21c43884b7..a8353656da 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -669,6 +669,7 @@ libnm_core_lib_h_pub_mkenums = \
libnm-core/nm-core-enum-types.h
libnm_core_lib_h_priv = \
shared/nm-ethtool-utils.h \
+ shared/nm-libnm-core-utils.h \
shared/nm-meta-setting.h \
libnm-core/nm-crypto.h \
libnm-core/nm-crypto-impl.h \
@@ -731,6 +732,7 @@ libnm_core_lib_c_settings_real = \
libnm_core_lib_c_real = \
$(libnm_core_lib_c_settings_real) \
shared/nm-ethtool-utils.c \
+ shared/nm-libnm-core-utils.c \
shared/nm-meta-setting.c \
libnm-core/nm-crypto.c \
libnm-core/nm-connection.c \
@@ -3914,6 +3916,8 @@ clients_common_libnmc_la_SOURCES = \
\
shared/nm-ethtool-utils.c \
shared/nm-ethtool-utils.h \
+ shared/nm-libnm-core-utils.c \
+ shared/nm-libnm-core-utils.h \
\
clients/common/nm-meta-setting-desc.c \
clients/common/nm-meta-setting-desc.h \
diff --git a/clients/cli/connections.c b/clients/cli/connections.c
index 6db44f8760..c8a6b37bfa 100644
--- a/clients/cli/connections.c
+++ b/clients/cli/connections.c
@@ -3959,11 +3959,12 @@ set_property (NMClient *client,
char modifier,
GError **error)
{
- gs_free char *property_name = NULL, *value_free = NULL;
+ gs_free char *property_name = NULL;
+ gs_free_error GError *local = NULL;
NMSetting *setting;
- GError *local = NULL;
- g_assert (setting_name && setting_name[0]);
+ nm_assert (setting_name && setting_name[0]);
+ nm_assert (NM_IN_SET (modifier, '\0', '+', '-'));
setting = nm_connection_get_setting_by_name (connection, setting_name);
if (!setting) {
@@ -3977,48 +3978,26 @@ set_property (NMClient *client,
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: invalid property '%s': %s."),
property, local->message);
- g_clear_error (&local);
return FALSE;
}
- if (modifier != '-') {
- /* Set/add value */
- if (modifier != '+') {
- /* We allow the existing property value to be passed as parameter,
- * so make a copy if we are going to free it.
- */
- value = value_free = g_strdup (value);
- nmc_setting_reset_property (setting, property_name, NULL);
- }
- if (!nmc_setting_set_property (client, setting, property_name, value, &local)) {
- g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
- _("Error: failed to modify %s.%s: %s."),
- setting_name, property, local->message);
- g_clear_error (&local);
- return FALSE;
- }
- } else {
- /* Remove value
- * - either empty: remove whole value
- * - or specified by index <0-n>: remove item at the index
- * - or option name: remove item with the option name
- */
- if (value) {
- unsigned long idx;
-
- if (nmc_string_to_uint (value, TRUE, 0, G_MAXUINT32, &idx))
- nmc_setting_remove_property_option (setting, property_name, NULL, idx, &local);
- else
- nmc_setting_remove_property_option (setting, property_name, value, 0, &local);
- if (local) {
- g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
- _("Error: failed to remove a value from %s.%s: %s."),
- setting_name, property, local->message);
- g_clear_error (&local);
- return FALSE;
- }
- } else
- nmc_setting_reset_property (setting, property_name, NULL);
+ if (!nmc_setting_set_property (client,
+ setting,
+ property_name,
+ ( (modifier == '-' && !value)
+ ? '\0'
+ : modifier),
+ value,
+ &local)) {
+ g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
+ _("Error: failed to %s %s.%s: %s."),
+ ( modifier != '-'
+ ? "modify"
+ : "remove a value from"),
+ setting_name,
+ property,
+ local->message);
+ return FALSE;
}
/* Don't ask for this property in interactive mode. */
@@ -6904,7 +6883,6 @@ property_edit_submenu (NmCli *nmc,
gs_free char *cmd_property_user = NULL;
gs_free char *cmd_property_arg = NULL;
gs_free char *prop_val_user = NULL;
- nm_auto_unset_gvalue GValue prop_g_value = G_VALUE_INIT;
gboolean removed;
gboolean dirty;
@@ -6954,24 +6932,17 @@ property_edit_submenu (NmCli *nmc,
} else
prop_val_user = g_strdup (cmd_property_arg);
- /* nmc_setting_set_property() only adds new value, thus we have to
- * remove the original value and save it for error cases.
- */
- if (cmdsub == NMC_EDITOR_SUB_CMD_SET) {
- nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value);
- nmc_property_set_default_value (curr_setting, prop_name);
- }
-
- set_result = nmc_setting_set_property (nmc->client, curr_setting, prop_name, prop_val_user, &tmp_err);
+ set_result = nmc_setting_set_property (nmc->client,
+ curr_setting,
+ prop_name,
+ (cmdsub == NMC_EDITOR_SUB_CMD_SET)
+ ? '\0'
+ : '+',
+ prop_val_user,
+ &tmp_err);
if (!set_result) {
g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message);
g_clear_error (&tmp_err);
- if (cmdsub == NMC_EDITOR_SUB_CMD_SET) {
- /* Block change signals and restore original value */
- g_signal_handlers_block_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
- nmc_property_set_gvalue (curr_setting, prop_name, &prop_g_value);
- g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
- }
}
break;
@@ -6982,41 +6953,23 @@ property_edit_submenu (NmCli *nmc,
_("Edit '%s' value: "),
prop_name);
- nmc_property_get_gvalue (curr_setting, prop_name, &prop_g_value);
- nmc_property_set_default_value (curr_setting, prop_name);
-
- if (!nmc_setting_set_property (nmc->client, curr_setting, prop_name, prop_val_user, &tmp_err)) {
+ if (!nmc_setting_set_property (nmc->client, curr_setting, prop_name, '\0', prop_val_user, &tmp_err)) {
g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message);
g_clear_error (&tmp_err);
- g_signal_handlers_block_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
- nmc_property_set_gvalue (curr_setting, prop_name, &prop_g_value);
- g_signal_handlers_unblock_matched (curr_setting, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL);
}
break;
case NMC_EDITOR_SUB_CMD_REMOVE:
- if (cmd_property_arg) {
- unsigned long val_int = G_MAXUINT32;
- gs_free char *option = NULL;
-
- if (!nmc_string_to_uint (cmd_property_arg, TRUE, 0, G_MAXUINT32, &val_int)) {
- option = g_strdup (cmd_property_arg);
- g_strstrip (option);
- }
-
- if (!nmc_setting_remove_property_option (curr_setting, prop_name,
- option,
- (guint32) val_int,
- &tmp_err)) {
- g_print (_("Error: %s\n"), tmp_err->message);
- g_clear_error (&tmp_err);
- }
- } else {
- if (!nmc_setting_reset_property (curr_setting, prop_name, &tmp_err)) {
- g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name,
- tmp_err->message);
- g_clear_error (&tmp_err);
- }
+ if (!nmc_setting_set_property (nmc->client,
+ curr_setting,
+ prop_name,
+ ( cmd_property_arg
+ ? '-'
+ : '\0'),
+ cmd_property_arg,
+ &tmp_err)) {
+ g_print (_("Error: %s\n"), tmp_err->message);
+ g_clear_error (&tmp_err);
}
break;
@@ -7367,8 +7320,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
_("Enter '%s' value: "),
prop_name);
- /* Set property value */
- if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, prop_val_user, &tmp_err)) {
+ if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, '+', prop_val_user, &tmp_err)) {
g_print (_("Error: failed to set '%s' property: %s\n"), prop_name, tmp_err->message);
g_clear_error (&tmp_err);
}
@@ -7428,8 +7380,13 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
prop_name);
}
- /* Set property value */
- if (!nmc_setting_set_property (nmc->client, ss, prop_name, cmd_arg_v, &tmp_err)) {
+ /* setting a value in edit mode "appends". That seems unexpected behavior. */
+ if (!nmc_setting_set_property (nmc->client,
+ ss,
+ prop_name,
+ cmd_arg_v ? '+' : '\0',
+ cmd_arg_v,
+ &tmp_err)) {
g_print (_("Error: failed to set '%s' property: %s\n"),
prop_name, tmp_err->message);
g_clear_error (&tmp_err);
@@ -7526,8 +7483,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
if (!prop_name)
break;
- /* Delete property value */
- if (!nmc_setting_reset_property (menu_ctx.curr_setting, prop_name, &tmp_err)) {
+ if (!nmc_setting_set_property (nmc->client, menu_ctx.curr_setting, prop_name, '\0', NULL, &tmp_err)) {
g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name,
tmp_err->message);
g_clear_error (&tmp_err);
@@ -7577,8 +7533,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
prop_name = is_property_valid (ss, cmd_arg_p, &tmp_err);
if (prop_name) {
- /* Delete property value */
- if (!nmc_setting_reset_property (ss, prop_name, &tmp_err)) {
+ if (!nmc_setting_set_property (nmc->client, ss, prop_name, '\0', NULL, &tmp_err)) {
g_print (_("Error: failed to remove value of '%s': %s\n"), prop_name,
tmp_err->message);
g_clear_error (&tmp_err);
@@ -8148,6 +8103,9 @@ editor_init_existing_connection (NMConnection *connection)
NMSettingWireless *s_wireless;
NMSettingConnection *s_con;
+ /* FIXME: this approach of connecting handlers to do something is fundamentally
+ * flawed. See the comment in nmc_setting_ip6_connect_handlers(). */
+
s_ip4 = nm_connection_get_setting_ip4_config (connection);
s_ip6 = nm_connection_get_setting_ip6_config (connection);
s_proxy = nm_connection_get_setting_proxy (connection);
diff --git a/clients/cli/settings.c b/clients/cli/settings.c
index a04c8eb604..aa0a7ff23c 100644
--- a/clients/cli/settings.c
+++ b/clients/cli/settings.c
@@ -89,7 +89,7 @@ ipv4_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat
static void
ipv4_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
{
- static GValue value = G_VALUE_INIT;
+ static GPtrArray *old_value = NULL;
static gboolean answered = FALSE;
static gboolean answer = FALSE;
@@ -103,17 +103,17 @@ ipv4_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
answer = get_answer ("ipv4.addresses", NULL);
}
if (answer) {
- if (G_IS_VALUE (&value))
- g_value_unset (&value);
- nmc_property_get_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
+ nm_clear_pointer (&old_value, g_ptr_array_unref);
+ g_object_get (object, NM_SETTING_IP_CONFIG_ADDRESSES, &old_value, NULL);
g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, NULL, NULL);
}
}
} else {
answered = FALSE;
- if (G_IS_VALUE (&value)) {
- nmc_property_set_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
- g_value_unset (&value);
+ if (old_value) {
+ gs_unref_ptrarray GPtrArray *v = g_steal_pointer (&old_value);
+
+ g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, v, NULL);
}
}
@@ -142,6 +142,25 @@ ipv6_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat
}
} else {
answered = FALSE;
+ /* FIXME: editor_init_existing_connection() and registering handlers is not the
+ * right approach.
+ *
+ * This only happens to work because in nmcli's edit mode
+ * tends to append addresses -- instead of setting them.
+ * If we would change that (to behavior I'd expect), we'd get:
+ *
+ * nmcli> set ipv6.addresses fc01::1:5/68
+ * Do you also want to set 'ipv6.method' to 'manual'? [yes]: y
+ * nmcli> set ipv6.addresses fc01::1:6/68
+ * Do you also want to set 'ipv6.method' to 'manual'? [yes]:
+ *
+ * That's because nmc_setting_set_property() calls set_fcn(). With modifier '\0'
+ * (set), it would first clear all addresses before adding the address. Thereby
+ * emitting multiple property changed signals.
+ *
+ * That can be avoided by freezing/thawing the signals, but this solution
+ * here is ugly in general.
+ */
if (!g_strcmp0 (nm_setting_ip_config_get_method (NM_SETTING_IP_CONFIG (object)), NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
g_object_set (object, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
}
@@ -152,7 +171,7 @@ ipv6_addresses_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_dat
static void
ipv6_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
{
- static GValue value = G_VALUE_INIT;
+ static GPtrArray *old_value = NULL;
static gboolean answered = FALSE;
static gboolean answer = FALSE;
@@ -166,17 +185,17 @@ ipv6_method_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
answer = get_answer ("ipv6.addresses", NULL);
}
if (answer) {
- if (G_IS_VALUE (&value))
- g_value_unset (&value);
- nmc_property_get_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
+ nm_clear_pointer (&old_value, g_ptr_array_unref);
+ g_object_get (object, NM_SETTING_IP_CONFIG_ADDRESSES, &old_value, NULL);
g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, NULL, NULL);
}
}
} else {
answered = FALSE;
- if (G_IS_VALUE (&value)) {
- nmc_property_set_gvalue (NM_SETTING (object), NM_SETTING_IP_CONFIG_ADDRESSES, &value);
- g_value_unset (&value);
+ if (old_value) {
+ gs_unref_ptrarray GPtrArray *v = g_steal_pointer (&old_value);
+
+ g_object_set (object, NM_SETTING_IP_CONFIG_ADDRESSES, v, NULL);
}
}
@@ -509,152 +528,68 @@ nmc_setting_get_property_parsable (NMSetting *setting, const char *prop, GError
return get_property_val (setting, prop, NM_META_ACCESSOR_GET_TYPE_PARSABLE, TRUE, error);
}
-static gboolean
-_set_fcn_call (const NMMetaPropertyInfo *property_info,
- NMSetting *setting,
- const char *value,
- GError **error)
-{
- return property_info->property_type->set_fcn (property_info,
- nmc_meta_environment,
- nmc_meta_environment_arg,
- setting,
- value,
- error);
-}
-
-/*
- * Generic function for setting property value.
- *
- * Sets property=value in setting by calling specialized functions.
- * If value is NULL then default property value is set.
- *
- * Returns: TRUE on success; FALSE on failure and sets error
- */
gboolean
-nmc_setting_set_property (NMClient *client, NMSetting *setting, const char *prop, const char *value, GError **error)
+nmc_setting_set_property (NMClient *client,
+ NMSetting *setting,
+ const char *prop,
+ char modifier,
+ const char *value,
+ GError **error)
{
const NMMetaPropertyInfo *property_info;
+ gs_free char *value_to_free = NULL;
+ gboolean success;
g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) {
-
- if (!value) {
- /* No value argument sets default value */
- nmc_property_set_default_value (setting, prop);
- return TRUE;
- }
-
- if (property_info->property_type->set_fcn) {
- switch (property_info->setting_info->general->meta_type) {
- case NM_META_SETTING_TYPE_CONNECTION:
- if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) {
- gs_free char *value_coerced = NULL;
-
- if (!_set_fcn_precheck_connection_secondaries (client, value, &value_coerced, error))
- return FALSE;
-
- return _set_fcn_call (property_info,
- setting,
- value_coerced ?: value,
- error);
- }
- break;
- default:
- break;
- }
- return _set_fcn_call (property_info,
- setting,
- value,
- error);
- }
- }
-
- g_set_error_literal (error, 1, 0, _("the property can't be changed"));
- return FALSE;
-}
-
-void
-nmc_property_set_default_value (NMSetting *setting, const char *prop)
-{
- GValue value = G_VALUE_INIT;
- GParamSpec *param_spec;
-
- param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop);
- if (param_spec) {
- g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (param_spec));
- g_param_value_set_default (param_spec, &value);
- g_object_set_property (G_OBJECT (setting), prop, &value);
+ g_return_val_if_fail (NM_IN_SET (modifier, '\0', '-', '+'), FALSE);
+ g_return_val_if_fail (value || modifier == '\0', FALSE);
+
+ if (!(property_info = nm_meta_property_info_find_by_setting (setting, prop)))
+ goto out_fail_read_only;
+ if (!property_info->property_type->set_fcn)
+ goto out_fail_read_only;
+
+ if ( modifier == '-'
+ && !property_info->property_type->set_supports_remove) {
+ /* The property is a plain property. It does not support '-'.
+ *
+ * Maybe we should fail, but just return silently. */
+ return TRUE;
}
-}
-
-/*
- * Generic function for resetting (single value) properties.
- *
- * The function resets the property value to the default one. It respects
- * nmcli restrictions for changing properties. So if 'set_func' is NULL,
- * resetting the value is denied.
- *
- * Returns: TRUE on success; FALSE on failure and sets error
- */
-gboolean
-nmc_setting_reset_property (NMSetting *setting, const char *prop, GError **error)
-{
- const NMMetaPropertyInfo *property_info;
- g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) {
- if (property_info->property_type->set_fcn) {
- nmc_property_set_default_value (setting, prop);
- return TRUE;
+ if (value) {
+ switch (property_info->setting_info->general->meta_type) {
+ case NM_META_SETTING_TYPE_CONNECTION:
+ if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) {
+ if (!_set_fcn_precheck_connection_secondaries (client, value, &value_to_free, error))
+ return FALSE;
+ if (value_to_free)
+ value = value_to_free;
+ }
+ break;
+ default:
+ break;
}
}
- g_set_error_literal (error, 1, 0, _("the property can't be changed"));
+ g_object_freeze_notify (G_OBJECT (setting));
+ success = property_info->property_type->set_fcn (property_info,
+ nmc_meta_environment,
+ nmc_meta_environment_arg,
+ setting,
+ modifier,
+ value,
+ error);
+ g_object_thaw_notify (G_OBJECT (setting));
+ return success;
+
+out_fail_read_only:
+ nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, _("the property can't be changed"));
return FALSE;
}
/*
- * Generic function for removing items for collection-type properties.
- *
- * If 'option' is not NULL, it tries to remove it, otherwise 'idx' is used.
- * For single-value properties (not having specialized remove function) this
- * function does nothing and just returns TRUE.
- *
- * Returns: TRUE on success; FALSE on failure and sets error
- */
-gboolean
-nmc_setting_remove_property_option (NMSetting *setting,
- const char *prop,
- const char *option,
- guint32 idx,
- GError **error)
-{
- const NMMetaPropertyInfo *property_info;
-
- g_return_val_if_fail (NM_IS_SETTING (setting), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- if ((property_info = nm_meta_property_info_find_by_setting (setting, prop))) {
- if (property_info->property_type->remove_fcn) {
- return property_info->property_type->remove_fcn (property_info,
- nmc_meta_environment,
- nmc_meta_environment_arg,
- setting,
- option,
- idx,
- error);
- }
- }
-
- return TRUE;
-}
-
-/*
* Get valid property names for a setting.
*
* Returns: string array with the properties or NULL on failure.
@@ -749,41 +684,6 @@ nmc_setting_get_property_desc (NMSetting *setting, const char *prop)
nmcli_desc ?: "");
}
-/*
- * Gets setting:prop property value and returns it in 'value'.
- * Caller is responsible for freeing the GValue resources using g_value_unset()
- */
-gboolean
-nmc_property_get_gvalue (NMSetting *setting, const char *prop, GValue *value)
-{
- GParamSpec *param_spec;
-
- param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop);
- if (param_spec) {
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (param_spec));
- g_object_get_property (G_OBJECT (setting), prop, value);
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * Sets setting:prop property value from 'value'.
- */
-gboolean
-nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value)
-{
- GParamSpec *param_spec;
-
- param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), prop);
- if (param_spec && G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (param_spec)) {
- g_object_set_property (G_OBJECT (setting), prop, value);
- return TRUE;
- }
- return FALSE;
-}
-
/*****************************************************************************/
gboolean
diff --git a/clients/cli/settings.h b/clients/cli/settings.h
index 4e7e38df85..1ff936859c 100644
--- a/clients/cli/settings.h
+++ b/clients/cli/settings.h
@@ -45,20 +45,9 @@ char *nmc_setting_get_property_parsable (NMSetting *setting,
gboolean nmc_setting_set_property (NMClient *client,
NMSetting *setting,
const char *prop,
+ char modifier,
const char *val,
GError **error);
-gboolean nmc_setting_reset_property (NMSetting *setting,
- const char *prop,
- GError **error);
-gboolean nmc_setting_remove_property_option (NMSetting *setting,
- const char *prop,
- const char *option,
- guint32 idx,
- GError **error);
-void nmc_property_set_default_value (NMSetting *setting, const char *prop);
-
-gboolean nmc_property_get_gvalue (NMSetting *setting, const char *prop, GValue *value);
-gboolean nmc_property_set_gvalue (NMSetting *setting, const char *prop, GValue *value);
gboolean setting_details (const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop);
diff --git a/clients/common/meson.build b/clients/common/meson.build
index b4b6bcacd3..c137d4463e 100644
--- a/clients/common/meson.build
+++ b/clients/common/meson.build
@@ -55,7 +55,7 @@ libnmc = static_library(
sources: files(
'nm-meta-setting-access.c',
'nm-meta-setting-desc.c',
- ) + shared_nm_meta_setting_c + shared_nm_ethtool_utils_c + [settings_docs_source],
+ ) + shared_nm_meta_setting_c + shared_nm_ethtool_utils_c + shared_nm_libnm_core_utils_c + [settings_docs_source],
dependencies: deps,
c_args: cflags,
link_with: libnmc_base,
diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c
index 1241131a11..0a155dae40 100644
--- a/clients/common/nm-client-utils.c
+++ b/clients/common/nm-client-utils.c
@@ -82,6 +82,10 @@ nmc_string_to_uint_base (const char *str,
char *end;
unsigned long int tmp;
+ if (!str || !str[0])
+ return FALSE;
+
+ /* FIXME: don't use this function, replace by _nm_utils_ascii_str_to_int64() */
errno = 0;
tmp = strtoul (str, &end, base);
if (errno || *end != '\0' || (range_check && (tmp < min || tmp > max))) {
diff --git a/clients/common/nm-client-utils.h b/clients/common/nm-client-utils.h
index a5bc05fab0..fd726ee93c 100644
--- a/clients/common/nm-client-utils.h
+++ b/clients/common/nm-client-utils.h
@@ -23,13 +23,7 @@
#include "nm-meta-setting.h"
#include "nm-active-connection.h"
#include "nm-device.h"
-
-
-#define nm_auto_unref_ip_address nm_auto (_nm_ip_address_unref)
-NM_AUTO_DEFINE_FCN0 (NMIPAddress *, _nm_ip_address_unref, nm_ip_address_unref)
-
-#define nm_auto_unref_wgpeer nm_auto (_nm_auto_unref_wgpeer)
-NM_AUTO_DEFINE_FCN0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref)
+#include "nm-libnm-core-utils.h"
const NMObject **nmc_objects_sort_by_path (const NMObject *const*objs, gssize len);
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c
index 6e35228ad6..0529420118 100644
--- a/clients/common/nm-meta-setting-desc.c
+++ b/clients/common/nm-meta-setting-desc.c
@@ -26,6 +26,8 @@
#include "nm-common-macros.h"
#include "nm-utils/nm-enum-utils.h"
+#include "nm-utils/nm-secret-utils.h"
+#include "nm-libnm-core-utils.h"
#include "nm-vpn-helpers.h"
#include "nm-client-utils.h"
@@ -74,6 +76,168 @@ _gtype_property_get_gtype (GType gtype, const char *property_name)
/*****************************************************************************/
+static int
+_int64_cmp_desc (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ NM_CMP_DIRECT (*((const gint64 *) b), *((const gint64 *) a));
+ return 0;
+}
+
+static gint64 *
+_value_str_as_index_list (const char *value, gsize *out_len)
+{
+ gs_free char *str_clone_free = NULL;
+ gboolean str_cloned = FALSE;
+ char *str;
+ gsize i, j;
+ gsize n_alloc;
+ gsize len;
+ gs_free gint64 *arr = NULL;
+
+ *out_len = 0;
+
+ if (!value)
+ return NULL;
+
+ str = (char *) value;
+ n_alloc = 0;
+ len = 0;
+ while (TRUE) {
+ gint64 i64;
+ const char *s;
+ gsize good;
+
+ good = strcspn (str, ","NM_ASCII_SPACES);
+ if (good == 0) {
+ if (str[0] == '\0')
+ break;
+ str++;
+ continue;
+ }
+ if (str[good] == '\0') {
+ s = str;
+ str += good;
+ } else {
+ if (!str_cloned) {
+ str_cloned = TRUE;
+ str = nm_strndup_a (200, str, strlen (str), &str_clone_free);
+ }
+ s = str;
+ str[good] = '\0';
+ str += good + 1;
+ }
+
+ i64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXINT64, -1);
+ if (i64 == -1)
+ return NULL;
+
+ if (len >= n_alloc) {
+ if (n_alloc > 0) {
+ n_alloc = n_alloc * 2;
+ arr = g_realloc (arr, n_alloc * sizeof (gint64));
+ } else {
+ n_alloc = 4;
+ arr = g_new (gint64, n_alloc);
+ }
+ }
+ arr[len++] = i64;
+ }
+
+ if (len > 1) {
+ /* sort the list of indexes descendingly, and drop duplicates. */
+ g_qsort_with_data (arr,
+ len,
+ sizeof (gint64),
+ _int64_cmp_desc,
+ NULL);
+ j = 1;
+ for (i = 1; i < len; i++) {
+ nm_assert (arr[i - 1] >= arr[i]);
+ if (arr[i - 1] > arr[i])
+ arr[j++] = arr[i];
+ }
+ len = j;
+ }
+
+ *out_len = len;
+ return g_steal_pointer (&arr);
+}
+
+#define MULTILIST_WITH_ESCAPE_CHARS NM_ASCII_SPACES","
+
+typedef enum {
+ VALUE_STRSPLIT_MODE_STRIPPED,
+ VALUE_STRSPLIT_MODE_OBJLIST,
+ VALUE_STRSPLIT_MODE_MULTILIST,
+ VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE,
+} ValueStrsplitMode;
+
+static const char *
+_value_strescape (const char *str, char **out_to_free)
+{
+ return _nm_utils_escape_plain (str, MULTILIST_WITH_ESCAPE_CHARS, out_to_free);
+}
+
+static const char **
+_value_strsplit (const char *value,
+ ValueStrsplitMode split_mode,
+ gsize *out_len)
+{
+ gs_free const char **strv = NULL;
+ gsize i;
+ gsize len;
+
+ /* FIXME: some modes should support backslash escaping.
+ * In particular, to distingish from _value_str_as_index_list(), which
+ * does not accept '\\'. */
+
+ /* note that all modes remove empty tokens (",", "a,,b", ",,"). */
+ switch (split_mode) {
+ case VALUE_STRSPLIT_MODE_STRIPPED:
+ strv = nm_utils_strsplit_set (value, NM_ASCII_SPACES",", FALSE);
+ break;
+ case VALUE_STRSPLIT_MODE_OBJLIST:
+ strv = nm_utils_strsplit_set (value, ",", FALSE);
+ break;
+ case VALUE_STRSPLIT_MODE_MULTILIST:
+ strv = nm_utils_strsplit_set (value, " \t,", FALSE);
+ break;
+ case VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE:
+ strv = nm_utils_strsplit_set (value, MULTILIST_WITH_ESCAPE_CHARS, TRUE);
+ break;
+ default:
+ nm_assert_not_reached ();
+ break;
+ }
+
+ NM_SET_OUT (out_len, 0);
+
+ if (!strv)
+ return NULL;
+
+ len = 0;
+ for (i = 0; strv[i]; i++) {
+ const char *s = strv[i];
+
+ s = nm_str_skip_leading_spaces (s);
+ if (s[0] == '\0')
+ continue;
+
+ if (split_mode == VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE)
+ _nm_utils_unescape_plain ((char *) s, MULTILIST_WITH_ESCAPE_CHARS, TRUE);
+ else
+ g_strchomp ((char *) s);
+
+ strv[len++] = s;
+ }
+ strv[len] = NULL;
+
+ NM_SET_OUT (out_len, len);
+ return g_steal_pointer (&strv);
+}
+
static NMIPAddress *
_parse_ip_address (int family, const char *address, GError **error)
{
@@ -123,19 +287,19 @@ _parse_ip_route (int family,
gint64 metric = -1;
guint i;
gs_free const char **routev = NULL;
- gs_free char *str_clean = NULL;
+ gs_free char *str_clean_free = NULL;
+ const char *str_clean;
gs_free char *dest_clone = NULL;
const char *dest;
const char *plen;
gs_unref_hashtable GHashTable *attrs = NULL;
- GHashTable *tmp_attrs;
#define ROUTE_SYNTAX _("The valid syntax is: 'ip[/prefix] [next-hop] [metric] [attribute=val]... [,ip[/prefix] ...]'")
nm_assert (NM_IN_SET (family, AF_INET, AF_INET6));
nm_assert (str);
nm_assert (!error || !*error);
- str_clean = g_strstrip (g_strdup (str));
+ str_clean = nm_strstrip_avoid_copy (str, &str_clean_free);
routev = nm_utils_strsplit_set (str_clean, " \t", FALSE);
if (!routev) {
g_set_error (error, 1, 0,
@@ -182,6 +346,7 @@ _parse_ip_route (int family,
GHashTableIter iter;
char *iter_key;
GVariant *iter_value;
+ gs_unref_hashtable GHashTable *tmp_attrs = NULL;
tmp_attrs = nm_utils_parse_variant_attributes (routev[i], ' ', '=', FALSE,
nm_ip_route_get_variant_attribute_spec(),
@@ -207,13 +372,11 @@ _parse_ip_route (int family,
if (!nm_ip_route_attribute_validate (iter_key, iter_value, family, NULL, error)) {
g_prefix_error (error, "%s: ", iter_key);
- g_hash_table_unref (tmp_attrs);
return NULL;
}
g_hash_table_insert (attrs, iter_key, iter_value);
g_hash_table_iter_steal (&iter);
}
- g_hash_table_unref (tmp_attrs);
} else {
g_set_error (error, 1, 0, "%s", ROUTE_SYNTAX);
return NULL;
@@ -298,7 +461,8 @@ _parse_team_link_watcher (const char *str,
GError **error)
{
gs_free const char **watcherv = NULL;
- gs_free char *str_clean = NULL;
+ gs_free char *str_clean_free = NULL;
+ const char *str_clean;
guint i;
gs_free const char *name = NULL;
int val1 = 0, val2 = 0, val3 = 3, val4 = -1;
@@ -309,7 +473,7 @@ _parse_team_link_watcher (const char *str,
nm_assert (str);
nm_assert (!error || !*error);
- str_clean = g_strstrip (g_strdup (str));
+ str_clean = nm_strstrip_avoid_copy (str, &str_clean_free);
watcherv = nm_utils_strsplit_set (str_clean, " \t", FALSE);
if (!watcherv) {
g_set_error (error, 1, 0, "'%s' is not valid", str);
@@ -398,62 +562,6 @@ _parse_team_link_watcher (const char *str,
#define MAX_8021P_PRIO 7 /* Max 802.1p priority */
/*
- * Parse VLAN priority mappings from the following format: 2:1,3:4,7:3
- * and verify if the priority numbers are valid
- *
- * Return: string array with split maps, or NULL on error
- * Caller is responsible for freeing the array.
- */
-static char **
-_parse_vlan_priority_maps (const char *priority_map,
- NMVlanPriorityMap map_type,
- GError **error)
-{
- char **mapping = NULL, **iter;
- unsigned long from, to, from_max, to_max;
-
- g_return_val_if_fail (priority_map != NULL, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- if (map_type == NM_VLAN_INGRESS_MAP) {
- from_max = MAX_8021P_PRIO;
- to_max = MAX_SKB_PRIO;
- } else {
- from_max = MAX_SKB_PRIO;
- to_max = MAX_8021P_PRIO;
- }
-
- mapping = g_strsplit (priority_map, ",", 0);
- for (iter = mapping; iter && *iter; iter++) {
- char *left, *right;
-
- left = g_strstrip (*iter);
- right = strchr (left, ':');
- if (!right) {
- g_set_error (error, 1, 0, _("invalid priority map '%s'"), *iter);
- g_strfreev (mapping);
- return NULL;
- }
- *right++ = '\0';
-
- if (!nmc_string_to_uint (left, TRUE, 0, from_max, &from)) {
- g_set_error (error, 1, 0, _("priority '%s' is not valid (<0-%ld>)"),
- left, from_max);
- g_strfreev (mapping);
- return NULL;
- }
- if (!nmc_string_to_uint (right, TRUE, 0, to_max, &to)) {
- g_set_error (error, 1, 0, _("priority '%s' is not valid (<0-%ld>)"),
- right, to_max);
- g_strfreev (mapping);
- return NULL;
- }
- *(right-1) = ':'; /* Put back ':' */
- }
- return mapping;
-}
-
-/*
* nmc_proxy_check_script:
* @script: file name with PAC script, or raw PAC Script data
* @out_script: raw PAC Script (with removed new-line characters)
@@ -646,10 +754,10 @@ _env_warn_fcn (const NMMetaEnvironment *environment,
const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, NMMetaAccessorGetType get_type, NMMetaAccessorGetFlags get_flags, NMMetaAccessorGetOutFlags *out_flags, gboolean *out_is_default, gpointer *out_to_free
#define ARGS_SET_FCN \
- const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error
+ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, char modifier, const char *value, GError **error
#define ARGS_REMOVE_FCN \
- const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, guint32 idx, GError **error
+ const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, GError **error
#define ARGS_COMPLETE_FCN \
const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free
@@ -660,6 +768,46 @@ _env_warn_fcn (const NMMetaEnvironment *environment,
#define ARGS_SETTING_INIT_FCN \
const NMMetaSettingInfoEditor *setting_info, NMSetting *setting, NMMetaAccessorSettingInitType init_type
+static gboolean
+_SET_FCN_DO_RESET_DEFAULT (const NMMetaPropertyInfo *property_info, char modifier, const char *value)
+{
+ nm_assert (property_info);
+ nm_assert (!property_info->property_type->set_supports_remove);
+ nm_assert (NM_IN_SET (modifier, '\0', '+'));
+ nm_assert (value || modifier == '\0');
+
+ return value == NULL;
+}
+
+static gboolean
+_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (const NMMetaPropertyInfo *property_info, char modifier, const char *value)
+{
+ nm_assert (property_info);
+ nm_assert (property_info->property_type->set_supports_remove);
+ nm_assert (NM_IN_SET (modifier, '\0', '+', '-'));
+ nm_assert (value || modifier == '\0');
+
+ return value == NULL;
+}
+
+static gboolean
+_SET_FCN_DO_SET_ALL (char modifier, const char *value)
+{
+ nm_assert (NM_IN_SET (modifier, '\0', '+', '-'));
+ nm_assert (value);
+
+ return modifier == '\0';
+}
+
+static gboolean
+_SET_FCN_DO_REMOVE (char modifier, const char *value)
+{
+ nm_assert (NM_IN_SET (modifier, '\0', '+', '-'));
+ nm_assert (value);
+
+ return modifier == '-';
+}
+
#define RETURN_UNSUPPORTED_GET_TYPE() \
G_STMT_START { \
if (!NM_IN_SET (get_type, \
@@ -677,7 +825,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment,
} G_STMT_END
static gboolean
-property_is_default (NMSetting *setting, const char *prop_name)
+_gobject_property_is_default (NMSetting *setting, const char *prop_name)
{
nm_auto_unset_gvalue GValue v = G_VALUE_INIT;
GParamSpec *pspec;
@@ -703,32 +851,30 @@ property_is_default (NMSetting *setting, const char *prop_name)
return g_param_value_defaults (pspec, &v);
}
-static gconstpointer
-_get_fcn_nmc_with_default (ARGS_GET_FCN)
+static gboolean
+_gobject_property_reset (NMSetting *setting,
+ const char *prop_name,
+ gboolean reset_default)
{
- const char *s;
- char *s_full;
- GValue val = G_VALUE_INIT;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
- NM_SET_OUT (out_is_default, property_is_default (setting, property_info->property_name));
+ nm_auto_unset_gvalue GValue v = G_VALUE_INIT;
+ GParamSpec *pspec;
- if (property_info->property_typ_data->subtype.get_with_default.fcn (setting)) {
- if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
- return _("(default)");
- return "";
- }
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)),
+ prop_name);
+ if (!G_IS_PARAM_SPEC (pspec))
+ g_return_val_if_reached (FALSE);
- g_value_init (&val, G_TYPE_STRING);
- g_object_get_property (G_OBJECT (setting), property_info->property_name, &val);
- s = g_value_get_string (&val);
- if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
- s_full = s ? g_strdup_printf ("\"%s\"", s) : g_strdup ("");
- else
- s_full = g_strdup (s && *s ? s : " ");
- g_value_unset (&val);
+ g_value_init (&v, pspec->value_type);
+ if (reset_default)
+ g_param_value_defaults (pspec, &v);
+ g_object_set_property (G_OBJECT (setting), prop_name, &v);
+ return TRUE;
+}
- RETURN_STR_TO_FREE (s_full);
+static gboolean
+_gobject_property_reset_default (NMSetting *setting, const char *prop_name)
+{
+ return _gobject_property_reset (setting, prop_name, TRUE);
}
static gconstpointer
@@ -738,13 +884,20 @@ _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info,
gboolean *out_is_default,
gpointer *out_to_free)
{
- char *s;
- const char *s_c;
+ const char *cstr;
GType gtype_prop;
nm_auto_unset_gvalue GValue val = G_VALUE_INIT;
RETURN_UNSUPPORTED_GET_TYPE ();
- NM_SET_OUT (out_is_default, property_is_default (setting, property_info->property_name));
+ NM_SET_OUT (out_is_default, _gobject_property_is_default (setting, property_info->property_name));
+
+ if ( property_info->property_typ_data
+ && property_info->property_typ_data->is_default_fcn
+ && property_info->property_typ_data->is_default_fcn (setting)) {
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
+ return _("(default)");
+ return "";
+ }
gtype_prop = _gobject_property_get_gtype (G_OBJECT (setting), property_info->property_name);
@@ -755,15 +908,35 @@ _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info,
g_object_get_property (G_OBJECT (setting), property_info->property_name, &val);
b = g_value_get_boolean (&val);
if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
- s_c = b ? _("yes") : _("no");
+ cstr = b ? _("yes") : _("no");
else
- s_c = b ? "yes" : "no";
- return s_c;
+ cstr = b ? "yes" : "no";
+ return cstr;
} else {
+ char *str;
+
+ /* Note that we register certain transform functions in nmc_value_transforms_register().
+ * This makes G_TYPE_STRV working.
+ *
+ * FIXME: that is particularly ugly because it's non-obvious which code relies
+ * on nmc_value_transforms_register(). Also, nmc_value_transforms_register() is
+ * in clients/cli, while we are here in clients/common. */
g_value_init (&val, G_TYPE_STRING);
g_object_get_property (G_OBJECT (setting), property_info->property_name, &val);
- s = g_value_dup_string (&val);
- RETURN_STR_TO_FREE (s);
+ cstr = g_value_get_string (&val);
+
+ if ( property_info->property_typ_data
+ && property_info->property_typ_data->is_default_fcn) {
+ if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) {
+ str = cstr
+ ? g_strdup_printf ("\"%s\"", cstr)
+ : g_strdup ("");
+ } else
+ str = g_strdup (cstr && cstr[0] ? cstr : " ");
+ } else
+ str = cstr ? g_strdup (cstr) : NULL;
+
+ RETURN_STR_TO_FREE (str);
}
}
@@ -842,10 +1015,9 @@ _get_fcn_gobject_int (ARGS_GET_FCN)
for (; value_infos->nick; value_infos++) {
if ( ( is_uint64 && value_infos->value.u64 == v.u64)
|| (!is_uint64 && value_infos->value.i64 == v.i64)) {
- char *old_str = return_str;
+ gs_free char *old_str = return_str;
return_str = g_strdup_printf ("%s (%s)", old_str, value_infos->nick);
- g_free (old_str);
break;
}
}
@@ -1033,6 +1205,9 @@ _set_fcn_gobject_string (ARGS_SET_FCN)
{
gs_free char *to_free = NULL;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
if (property_info->property_typ_data) {
if (property_info->property_typ_data->subtype.gobject_string.validate_fcn) {
value = property_info->property_typ_data->subtype.gobject_string.validate_fcn (value, &to_free, error);
@@ -1055,6 +1230,9 @@ _set_fcn_gobject_bool (ARGS_SET_FCN)
{
gboolean val_bool;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
if (!nmc_string_to_bool (value, &val_bool, error))
return FALSE;
@@ -1076,6 +1254,9 @@ _set_fcn_gobject_int (ARGS_SET_FCN)
guint base = 10;
const NMMetaUtilsIntValueInfo *value_infos;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), property_info->property_name);
if (!G_IS_PARAM_SPEC (pspec))
g_return_val_if_reached (FALSE);
@@ -1085,14 +1266,10 @@ _set_fcn_gobject_int (ARGS_SET_FCN)
if (property_info->property_typ_data) {
if ( value
&& (value_infos = property_info->property_typ_data->subtype.gobject_int.value_infos)) {
- gs_free char *vv_stripped = NULL;
- const char *vv = nm_str_skip_leading_spaces (value);
-
- if (vv[0] && g_ascii_isspace (vv[strlen (vv) - 1])) {
- vv_stripped = g_strstrip (g_strdup (vv));
- vv = vv_stripped;
- }
+ gs_free char *vv_free = NULL;
+ const char *vv;
+ vv = nm_strstrip_avoid_copy (value, &vv_free);
for (; value_infos->nick; value_infos++) {
if (nm_streq (value_infos->nick, vv)) {
v = value_infos->value;
@@ -1216,7 +1393,10 @@ _set_fcn_gobject_mtu (ARGS_SET_FCN)
const GParamSpec *pspec;
gint64 v;
- if (nm_streq0 (value, "auto"))
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
+ if (nm_streq (value, "auto"))
value = "0";
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)),
@@ -1254,6 +1434,9 @@ _set_fcn_gobject_mac (ARGS_SET_FCN)
NMMetaPropertyTypeMacMode mode;
gboolean valid;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
if (property_info->property_typ_data)
mode = property_info->property_typ_data->subtype.mac.mode;
else
@@ -1289,6 +1472,9 @@ _set_fcn_gobject_enum (ARGS_SET_FCN)
gboolean is_flags;
int v;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
if (property_info->property_typ_data) {
if (property_info->property_typ_data->subtype.gobject_enum.get_gtype) {
gtype = property_info->property_typ_data->subtype.gobject_enum.get_gtype ();
@@ -1619,166 +1805,202 @@ vpn_data_item (const char *key, const char *value, gpointer user_data)
g_string_append_printf (ret_str, "%s = %s", key, value);
}
-#define DEFINE_SETTER_STR_LIST_MULTI(def_func, s_macro, set_func) \
- static gboolean \
- def_func (NMSetting *setting, \
- const char *prop, \
- const char *value, \
- const char **valid_strv, \
- GError **error) \
- { \
- gs_free const char **strv = NULL; \
- gsize i; \
- const char *item; \
- nm_assert (!error || !*error); \
- strv = nm_utils_strsplit_set (value, " \t,", FALSE); \
- if (strv) { \
- for (i = 0; strv[i]; i++) { \
- if (!(item = nmc_string_is_valid (strv[i], valid_strv, error))) { \
- return FALSE; \
- } \
- set_func (s_macro (setting), item); \
- } \
- } \
- return TRUE; \
+static const char *
+_multilist_do_validate (const NMMetaPropertyInfo *property_info,
+ NMSetting *setting,
+ const char *item,
+ GError **error)
+{
+ if (property_info->property_typ_data->values_static) {
+ nm_assert (!property_info->property_typ_data->subtype.multilist.validate_fcn);
+ return nmc_string_is_valid (item,
+ (const char **) property_info->property_typ_data->values_static,
+ error);
+ }
+ if (property_info->property_typ_data->subtype.multilist.validate_fcn) {
+ return property_info->property_typ_data->subtype.multilist.validate_fcn (item,
+ error);
+ }
+ if (property_info->property_typ_data->subtype.multilist.validate2_fcn) {
+ return property_info->property_typ_data->subtype.multilist.validate2_fcn (setting,
+ item,
+ error);
}
-#define DEFINE_SETTER_OPTIONS(def_func, s_macro, s_type, add_func, valid_func1, valid_func2) \
- static gboolean \
- def_func (ARGS_SET_FCN) \
- { \
- gs_free const char **strv = NULL; \
- const char **iter; \
- const char **(*valid_func1_p) (s_type *) = valid_func1; \
- const char * (*valid_func2_p) (const char *, const char *, GError **) = valid_func2; \
- const char *opt_name, *opt_val; \
- \
- nm_assert (!error || !*error); \
- \
- strv = nm_utils_strsplit_set (value, ",", FALSE); \
- for (iter = strv; iter && *iter; iter++) { \
- gs_free char *left_clone = g_strstrip (g_strdup (*iter)); \
- char *left = left_clone; \
- char *right = strchr (left, '='); \
- if (!right) { \
- g_set_error (error, 1, 0, _("'%s' is not valid; use <option>=<value>"), *iter); \
- return FALSE; \
- } \
- *right++ = '\0'; \
- g_strchomp (left); \
- \
- if (valid_func1_p) { \
- const char **valid_options = valid_func1_p (s_macro (setting)); \
- if (!(opt_name = nmc_string_is_valid (left, valid_options, error))) { \
- return FALSE; \
- } \
- } else \
- opt_name = left;\
- \
- opt_val = g_strchug (right); \
- if (valid_func2_p) { \
- if (!(opt_val = valid_func2_p ((const char *) left, (const char *) opt_val, error))) { \
- return FALSE; \
- }\
- }\
- add_func (s_macro (setting), opt_name, opt_val); \
- } \
- return TRUE; \
+ return item;
+}
+
+static gboolean
+_set_fcn_multilist (ARGS_SET_FCN)
+{
+ gs_free const char **strv = NULL;
+ gsize i, j, nstrv;
+
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value)) {
+ if (property_info->property_typ_data->subtype.multilist.clear_all_fcn) {
+ property_info->property_typ_data->subtype.multilist.clear_all_fcn (setting);
+ return TRUE;
+ }
+ return _gobject_property_reset (setting, property_info->property_name, FALSE);
+ }
+
+ if ( _SET_FCN_DO_REMOVE (modifier, value)
+ && ( property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32
+ || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s
+ || property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u)) {
+ gs_free gint64 *indexes = NULL;
+
+ indexes = _value_str_as_index_list (value, &nstrv);
+ if (indexes) {
+ gint64 num;
+
+ if (property_info->property_typ_data->subtype.multilist.get_num_fcn_u32)
+ num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u32 (setting);
+ else
+ num = property_info->property_typ_data->subtype.multilist.get_num_fcn_u (setting);
+ for (i = 0; i < nstrv; i++) {
+ gint64 idx = indexes[i];
+
+ if (idx >= num)
+ continue;
+
+ if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32)
+ property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u32 (setting, idx);
+ else if (property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s)
+ property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_s (setting, idx);
+ else
+ property_info->property_typ_data->subtype.multilist.remove_by_idx_fcn_u (setting, idx);
+ }
+ return TRUE;
+ }
}
-#define DEFINE_REMOVER_INDEX_OR_VALUE(def_func, s_macro, num_func, rem_func_idx, rem_func_val) \
- static gboolean \
- def_func (ARGS_REMOVE_FCN) \
- { \
- guint32 num; \
- if (value) { \
- gboolean ret; \
- char *value_stripped = g_strstrip (g_strdup (value)); \
- ret = rem_func_val (s_macro (setting), value_stripped, error); \
- g_free (value_stripped); \
- return ret; \
- } \
- num = num_func (s_macro (setting)); \
- if (num == 0) { \
- g_set_error_literal (error, 1, 0, _("no item to remove")); \
- return FALSE; \
- } \
- if (idx >= num) { \
- g_set_error (error, 1, 0, _("index '%d' is not in range <0-%d>"), idx, num - 1); \
- return FALSE; \
- } \
- rem_func_idx (s_macro (setting), idx); \
- return TRUE; \
+ strv = _value_strsplit (value,
+ property_info->property_typ_data->subtype.multilist.with_escaped_spaces
+ ? VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE
+ : VALUE_STRSPLIT_MODE_MULTILIST,
+ &nstrv);
+
+ j = 0;
+ for (i = 0; i < nstrv; i++) {
+ const char *item = strv[i];
+
+ item = _multilist_do_validate (property_info,
+ setting,
+ item,
+ error);
+ if (!item)
+ return FALSE;
+ strv[j++] = item;
}
+ nstrv = j;
-#define DEFINE_REMOVER_OPTION(def_func, s_macro, rem_func) \
- static gboolean \
- def_func (ARGS_REMOVE_FCN) \
- { \
- gboolean success = FALSE; \
- if (value && *value) { \
- success = rem_func (s_macro (setting), value); \
- if (!success) \
- g_set_error (error, 1, 0, _("invalid option '%s'"), value); \
- } else \
- g_set_error_literal (error, 1, 0, _("missing option")); \
- return success; \
- }
-
-#define DEFINE_ALLOWED_VAL_FUNC(def_func, valid_values) \
- static const char *const* \
- def_func (NMSetting *setting, const char *prop) \
- { \
- return valid_values; \
+ if (_SET_FCN_DO_SET_ALL (modifier, value)) {
+ if (property_info->property_typ_data->subtype.multilist.clear_all_fcn)
+ property_info->property_typ_data->subtype.multilist.clear_all_fcn (setting);
+ else
+ _gobject_property_reset (setting, property_info->property_name, FALSE);
}
-#define DEFINE_SETTER_MAC_BLACKLIST(def_func, s_macro, add_func) \
- static gboolean \
- def_func (ARGS_SET_FCN) \
- { \
- guint8 buf[32]; \
- gs_free const char **strv = NULL; \
- const char *const*iter; \
- \
- nm_assert (!error || !*error); \
- \
- strv = nm_utils_strsplit_set (value, " \t,", FALSE); \
- for (iter = strv; strv && *iter; iter++) { \
- if (!nm_utils_hwaddr_aton (*iter, buf, ETH_ALEN)) { \
- g_set_error (error, 1, 0, _("'%s' is not a valid MAC"), *iter); \
- return FALSE; \
- } \
- } \
- \
- for (iter = strv; strv && *iter; iter++) \
- add_func (s_macro (setting), *iter); \
- \
- return TRUE; \
+ for (i = 0; i < nstrv; i++) {
+ if (_SET_FCN_DO_REMOVE (modifier, value)) {
+ property_info->property_typ_data->subtype.multilist.remove_by_value_fcn (setting,
+ strv[i]);
+ } else {
+ if (property_info->property_typ_data->subtype.multilist.add2_fcn)
+ property_info->property_typ_data->subtype.multilist.add2_fcn (setting, strv[i]);
+ else
+ property_info->property_typ_data->subtype.multilist.add_fcn (setting, strv[i]);
+ }
}
+ return TRUE;
+}
static gboolean
-verify_string_list (const char *const*strv,
- const char *prop,
- gboolean (*validate_func) (const char *),
- GError **error)
+_set_fcn_optionlist (ARGS_SET_FCN)
{
- const char *const*iter;
+ gs_free const char **strv = NULL;
+ gs_free const char **strv_val = NULL;
+ gsize i, nstrv;
nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
+ nstrv = 0;
+ strv = nm_utils_strsplit_set (value, ",", FALSE);
if (strv) {
- for (iter = strv; *iter; iter++) {
- if (**iter == '\0')
- continue;
- if (validate_func) {
- if (!validate_func (*iter)) {
- g_set_error (error, 1, 0, _("'%s' is not valid"),
- *iter);
+ strv_val = g_new (const char *, NM_PTRARRAY_LEN (strv));
+ for (i = 0; strv[i]; i++) {
+ const char *opt_name;
+ const char *opt_value;
+
+ opt_name = nm_str_skip_leading_spaces (strv[i]);
+
+ /* FIXME: support backslash escaping for the option list. */
+ opt_value = strchr (opt_name, '=');
+ if (opt_value) {
+ ((char *) opt_value)[0] = '\0';
+ opt_value++;
+ opt_value = nm_str_skip_leading_spaces (opt_value);
+ g_strchomp ((char *) opt_value);
+ }
+ g_strchomp ((char *) opt_name);
+
+ if ( property_info->property_type->values_fcn
+ || property_info->property_typ_data->values_static) {
+ gs_strfreev char **valid_options_to_free = NULL;
+ const char *const*valid_options;
+
+ if (property_info->property_type->values_fcn)
+ valid_options = property_info->property_type->values_fcn (property_info, &valid_options_to_free);
+ else
+ valid_options = property_info->property_typ_data->values_static;
+
+ opt_name = nmc_string_is_valid (opt_name, (const char **) valid_options, error);
+ if (!opt_name)
+ return FALSE;
+ }
+
+ if (opt_value) {
+ if (_SET_FCN_DO_REMOVE (modifier, value))
+ opt_value = NULL;
+ } else {
+ if (!_SET_FCN_DO_REMOVE (modifier, value)) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is not valid; use <option>=<value>"),
+ opt_name);
return FALSE;
}
}
+
+ if ( opt_value
+ && opt_value[0] == '\0'
+ && property_info->property_typ_data->subtype.optionlist.no_empty_value) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("cannot set empty \"%s\" option"),
+ opt_name);
+ return FALSE;
+ }
+
+ strv[nstrv] = opt_name;
+ strv_val[nstrv] = opt_value;
+ nstrv++;
}
}
+
+ if (_SET_FCN_DO_SET_ALL (modifier, value))
+ _gobject_property_reset (setting, property_info->property_name, FALSE);
+
+ for (i = 0; i < nstrv; i++) {
+ if (!property_info->property_typ_data->subtype.optionlist.set_fcn (setting,
+ strv[i],
+ strv_val[i],
+ error))
+ return FALSE;
+ }
+
return TRUE;
}
@@ -1811,11 +2033,13 @@ validate_flags (NMSetting *setting, const char* prop, guint val, GError **error)
if (g_param_value_validate (pspec, &value)) {
GParamSpecFlags *pspec_flags = (GParamSpecFlags *) pspec;
- char *flag_values = flag_values_to_string (pspec_flags->flags_class->values,
- pspec_flags->flags_class->n_values);
+ gs_free char *flag_values = NULL;
+
+ flag_values = flag_values_to_string (pspec_flags->flags_class->values,
+ pspec_flags->flags_class->n_values);
+
g_set_error (error, 1, 0, _("'%u' flags are not valid; use combination of %s"),
val, flag_values);
- g_free (flag_values);
success = FALSE;
}
g_value_unset (&value);
@@ -1823,30 +2047,12 @@ validate_flags (NMSetting *setting, const char* prop, guint val, GError **error)
}
static gboolean
-check_and_set_string (NMSetting *setting,
- const char *prop,
- const char *val,
- const char **valid_strv,
- GError **error)
-{
- const char *checked_val;
-
- nm_assert (!error || !*error);
-
- checked_val = nmc_string_is_valid (val, valid_strv, error);
- if (!checked_val)
- return FALSE;
-
- g_object_set (setting, prop, checked_val, NULL);
- return TRUE;
-}
-
-static gboolean
_set_fcn_gobject_flags (ARGS_SET_FCN)
{
unsigned long val_int;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
if (!nmc_string_to_uint (value, TRUE, 0, G_MAXUINT, &val_int)) {
g_set_error (error, 1, 0, _("'%s' is not a valid number (or out of range)"), value);
@@ -1864,9 +2070,10 @@ _set_fcn_gobject_flags (ARGS_SET_FCN)
static gboolean
_set_fcn_gobject_ssid (ARGS_SET_FCN)
{
- GBytes *ssid;
+ gs_unref_bytes GBytes *ssid = NULL;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
if (strlen (value) > 32) {
g_set_error (error, 1, 0, _("'%s' is not valid"), value);
@@ -1875,14 +2082,14 @@ _set_fcn_gobject_ssid (ARGS_SET_FCN)
ssid = g_bytes_new (value, strlen (value));
g_object_set (setting, property_info->property_name, ssid, NULL);
- g_bytes_unref (ssid);
return TRUE;
}
static gboolean
_set_fcn_gobject_ifname (ARGS_SET_FCN)
{
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
if (!nm_utils_is_valid_iface_name (value, error))
return FALSE;
@@ -1895,6 +2102,9 @@ _set_fcn_vpn_service_type (ARGS_SET_FCN)
{
gs_free char *service_name = NULL;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
service_name = nm_vpn_plugin_info_list_find_service_type (nm_vpn_get_plugin_infos (), value);
g_object_set (setting, property_info->property_name, service_name ?: value, NULL);
return TRUE;
@@ -1933,11 +2143,11 @@ _complete_fcn_vpn_service_type (ARGS_COMPLETE_FCN)
return (const char *const*) (*out_to_free = values);
}
-static gboolean
-nmc_util_is_domain (const char *domain)
+static const char *
+_multilist_validate_fcn_is_domain (const char *domain, GError **error)
{
//FIXME: implement
- return TRUE;
+ return domain;
}
static gboolean
@@ -1950,7 +2160,8 @@ _set_fcn_gobject_bytes (ARGS_SET_FCN)
gs_unref_bytes GBytes *bytes = NULL;
GByteArray *array;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
val_strip = nm_strstrip_avoid_copy (value, &val_strip_free);
@@ -1995,113 +2206,85 @@ done:
/*****************************************************************************/
static gconstpointer
-_get_fcn_802_1x_ca_cert (ARGS_GET_FCN)
+_get_fcn_cert_8021x (ARGS_GET_FCN)
{
NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting);
- char *ca_cert_str = NULL;
+ const NMSetting8021xSchemeVtable *vtable;
+ char *str = NULL;
RETURN_UNSUPPORTED_GET_TYPE ();
- switch (nm_setting_802_1x_get_ca_cert_scheme (s_8021X)) {
- case NM_SETTING_802_1X_CK_SCHEME_BLOB:
- ca_cert_str = bytes_to_string (nm_setting_802_1x_get_ca_cert_blob (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PATH:
- ca_cert_str = g_strdup (nm_setting_802_1x_get_ca_cert_path (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
- ca_cert_str = g_strdup (nm_setting_802_1x_get_ca_cert_uri (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
- break;
- }
-
- NM_SET_OUT (out_is_default, !ca_cert_str || !ca_cert_str[0]);
- RETURN_STR_TO_FREE (ca_cert_str);
-}
-
-static gconstpointer
-_get_fcn_802_1x_client_cert (ARGS_GET_FCN)
-{
- NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting);
- char *cert_str = NULL;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
+ vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x.scheme_type];
- switch (nm_setting_802_1x_get_client_cert_scheme (s_8021X)) {
+ switch (vtable->scheme_func (s_8021X)) {
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
- if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS))
- cert_str = bytes_to_string (nm_setting_802_1x_get_client_cert_blob (s_8021X));
- else
+ if ( vtable->is_secret
+ && !NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS))
return _get_text_hidden (get_type);
+ str = bytes_to_string (vtable->blob_func (s_8021X));
break;
case NM_SETTING_802_1X_CK_SCHEME_PATH:
- cert_str = g_strdup (nm_setting_802_1x_get_client_cert_path (s_8021X));
+ str = g_strdup (vtable->path_func (s_8021X));
break;
case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
- cert_str = g_strdup (nm_setting_802_1x_get_client_cert_uri (s_8021X));
+ str = g_strdup (vtable->uri_func (s_8021X));
break;
case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
break;
}
- NM_SET_OUT (out_is_default, !cert_str || !cert_str[0]);
- RETURN_STR_TO_FREE (cert_str);
+ NM_SET_OUT (out_is_default, !str || !str[0]);
+ RETURN_STR_TO_FREE (str);
}
-static gconstpointer
-_get_fcn_802_1x_phase2_ca_cert (ARGS_GET_FCN)
+static gboolean
+_set_fcn_cert_8021x (ARGS_SET_FCN)
{
- NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting);
- char *phase2_ca_cert_str = NULL;
+ gs_free char *value_to_free = NULL;
+ NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_PATH;
+ const NMSetting8021xSchemeVtable *vtable;
- RETURN_UNSUPPORTED_GET_TYPE ();
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
- switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (s_8021X)) {
- case NM_SETTING_802_1X_CK_SCHEME_BLOB:
- phase2_ca_cert_str = bytes_to_string (nm_setting_802_1x_get_phase2_ca_cert_blob (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PATH:
- phase2_ca_cert_str = g_strdup (nm_setting_802_1x_get_phase2_ca_cert_path (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
- phase2_ca_cert_str = g_strdup (nm_setting_802_1x_get_phase2_ca_cert_uri (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
- break;
- }
+ value = nm_strstrip_avoid_copy (value, &value_to_free);
- NM_SET_OUT (out_is_default, !phase2_ca_cert_str || !phase2_ca_cert_str[0]);
- RETURN_STR_TO_FREE (phase2_ca_cert_str);
-}
+ if (strncmp (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11, NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11)) == 0)
+ scheme = NM_SETTING_802_1X_CK_SCHEME_PKCS11;
+ else if (strncmp (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)) == 0)
+ value += NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH);
-static gconstpointer
-_get_fcn_802_1x_phase2_client_cert (ARGS_GET_FCN)
-{
- NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting);
- char *cert_str = NULL;
+ vtable = &nm_setting_8021x_scheme_vtable[property_info->property_typ_data->subtype.cert_8021x.scheme_type];
- RETURN_UNSUPPORTED_GET_TYPE ();
+ if (vtable->is_secret) {
+ gs_free char *path = NULL;
+ nm_auto_free_secret char *password_free = NULL;
+ char *password;
- switch (nm_setting_802_1x_get_phase2_client_cert_scheme (s_8021X)) {
- case NM_SETTING_802_1X_CK_SCHEME_BLOB:
- if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS))
- cert_str = bytes_to_string (nm_setting_802_1x_get_phase2_client_cert_blob (s_8021X));
- else
- return _get_text_hidden (get_type);
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PATH:
- cert_str = g_strdup (nm_setting_802_1x_get_phase2_client_cert_path (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
- cert_str = g_strdup (nm_setting_802_1x_get_phase2_client_cert_uri (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
- break;
- }
+ path = g_strdup (value);
+ password = path + strcspn (path, " \t");
+ if (password[0] != '\0') {
+ password[0] = '\0';
+ while (nm_utils_is_separator (password[0]))
+ password++;
+ } else {
+ password_free = g_strdup (vtable->passwd_func (NM_SETTING_802_1X (setting)));
+ password = password_free;
+ }
- NM_SET_OUT (out_is_default, !cert_str || !cert_str[0]);
- RETURN_STR_TO_FREE (cert_str);
+ return vtable->set_private_key_func (NM_SETTING_802_1X (setting),
+ path,
+ password,
+ scheme,
+ NULL,
+ error);
+ } else {
+ return vtable->set_cert_func (NM_SETTING_802_1X (setting),
+ value,
+ scheme,
+ NULL,
+ error);
+ }
}
static gconstpointer
@@ -2120,219 +2303,6 @@ _get_fcn_gobject_bytes (ARGS_GET_FCN)
}
static gconstpointer
-_get_fcn_802_1x_private_key (ARGS_GET_FCN)
-{
- NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting);
- char *key_str = NULL;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- switch (nm_setting_802_1x_get_private_key_scheme (s_8021X)) {
- case NM_SETTING_802_1X_CK_SCHEME_BLOB:
- if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS))
- key_str = bytes_to_string (nm_setting_802_1x_get_private_key_blob (s_8021X));
- else
- return _get_text_hidden (get_type);
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PATH:
- key_str = g_strdup (nm_setting_802_1x_get_private_key_path (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
- key_str = g_strdup (nm_setting_802_1x_get_private_key_uri (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
- break;
- }
-
- NM_SET_OUT (out_is_default, !key_str || !key_str[0]);
- RETURN_STR_TO_FREE (key_str);
-}
-
-static gconstpointer
-_get_fcn_802_1x_phase2_private_key (ARGS_GET_FCN)
-{
- NMSetting8021x *s_8021X = NM_SETTING_802_1X (setting);
- char *key_str = NULL;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- switch (nm_setting_802_1x_get_phase2_private_key_scheme (s_8021X)) {
- case NM_SETTING_802_1X_CK_SCHEME_BLOB:
- if (NM_FLAGS_HAS (get_flags, NM_META_ACCESSOR_GET_FLAGS_SHOW_SECRETS))
- key_str = bytes_to_string (nm_setting_802_1x_get_phase2_private_key_blob (s_8021X));
- else
- return _get_text_hidden (get_type);
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PATH:
- key_str = g_strdup (nm_setting_802_1x_get_phase2_private_key_path (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
- key_str = g_strdup (nm_setting_802_1x_get_phase2_private_key_uri (s_8021X));
- break;
- case NM_SETTING_802_1X_CK_SCHEME_UNKNOWN:
- break;
- }
-
- NM_SET_OUT (out_is_default, !key_str || !key_str[0]);
- RETURN_STR_TO_FREE (key_str);
-}
-
-#define DEFINE_SETTER_STR_LIST(def_func, set_func) \
- static gboolean \
- def_func (ARGS_SET_FCN) \
- { \
- const char **strv = NULL; \
- gsize i; \
- \
- nm_assert (error == NULL || *error == NULL); \
- \
- strv = nm_utils_strsplit_set (value, " \t,", FALSE); \
- if (strv) { \
- for (i = 0; strv[i]; i++) \
- set_func (NM_SETTING_802_1X (setting), strv[i]); \
- } \
- return TRUE; \
- }
-
-#define DEFINE_SETTER_CERT(def_func, set_func) \
- static gboolean \
- def_func (ARGS_SET_FCN) \
- { \
- char *val_strip = g_strstrip (g_strdup (value)); \
- char *p = val_strip; \
- NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_PATH; \
- gboolean success; \
- \
- if (strncmp (val_strip, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11, NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11)) == 0) \
- scheme = NM_SETTING_802_1X_CK_SCHEME_PKCS11; \
- else if (strncmp (val_strip, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)) == 0) \
- p += NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); \
- \
- success = set_func (NM_SETTING_802_1X (setting), p, scheme, NULL, error); \
- g_free (val_strip); \
- return success; \
- }
-
-#define DEFINE_SETTER_PRIV_KEY(def_func, pwd_func, set_func) \
- static gboolean \
- def_func (ARGS_SET_FCN) \
- { \
- gs_free char *path = NULL; \
- gs_free char *password_free = NULL; \
- char *password; \
- NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_PATH; \
- \
- value = nm_str_skip_leading_spaces (value); \
- \
- if (strncmp (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11, NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PKCS11)) == 0) \
- scheme = NM_SETTING_802_1X_CK_SCHEME_PKCS11; \
- else if (strncmp (value, NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH, NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH)) == 0) \
- value += NM_STRLEN (NM_SETTING_802_1X_CERT_SCHEME_PREFIX_PATH); \
- \
- path = g_strdup (value); \
- password = path + strcspn (path, " \t"); \
- if (password[0] != '\0') { \
- password[0] = '\0'; \
- while (nm_utils_is_separator (password[0])) \
- password++; \
- } else \
- password = password_free = g_strdup (pwd_func (NM_SETTING_802_1X (setting))); \
- return set_func (NM_SETTING_802_1X (setting), path, password, scheme, NULL, error); \
- }
-
-DEFINE_SETTER_STR_LIST_MULTI (check_and_add_eap_method,
- NM_SETTING_802_1X,
- nm_setting_802_1x_add_eap_method)
-
-static gboolean
-_set_fcn_802_1x_eap (ARGS_SET_FCN)
-{
- return check_and_add_eap_method (setting,
- property_info->property_name,
- value,
- (const char **) property_info->property_typ_data->values_static,
- error);
-}
-
-static gboolean
-_validate_and_remove_eap_method (NMSetting8021x *setting,
- const char *eap,
- GError **error)
-{
- gboolean ret;
-
- ret = nm_setting_802_1x_remove_eap_method_by_value (setting, eap);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain EAP method '%s'"), eap);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_802_1x_eap,
- NM_SETTING_802_1X,
- nm_setting_802_1x_get_num_eap_methods,
- nm_setting_802_1x_remove_eap_method,
- _validate_and_remove_eap_method)
-
-DEFINE_SETTER_CERT (_set_fcn_802_1x_ca_cert, nm_setting_802_1x_set_ca_cert)
-
-DEFINE_SETTER_STR_LIST (_set_fcn_802_1x_altsubject_matches, nm_setting_802_1x_add_altsubject_match)
-
-static gboolean
-_validate_and_remove_altsubject_match (NMSetting8021x *setting,
- const char *altsubject_match,
- GError **error)
-{
- gboolean ret;
-
- ret = nm_setting_802_1x_remove_altsubject_match_by_value (setting, altsubject_match);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain alternative subject match '%s'"),
- altsubject_match);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_802_1x_altsubject_matches,
- NM_SETTING_802_1X,
- nm_setting_802_1x_get_num_altsubject_matches,
- nm_setting_802_1x_remove_altsubject_match,
- _validate_and_remove_altsubject_match)
-
-DEFINE_SETTER_CERT (_set_fcn_802_1x_client_cert, nm_setting_802_1x_set_client_cert)
-
-DEFINE_SETTER_CERT (_set_fcn_802_1x_phase2_ca_cert, nm_setting_802_1x_set_phase2_ca_cert)
-
-DEFINE_SETTER_STR_LIST (_set_fcn_802_1x_phase2_altsubject_matches, nm_setting_802_1x_add_phase2_altsubject_match)
-
-static gboolean
-_validate_and_remove_phase2_altsubject_match (NMSetting8021x *setting,
- const char *phase2_altsubject_match,
- GError **error)
-{
- gboolean ret;
-
- ret = nm_setting_802_1x_remove_phase2_altsubject_match_by_value (setting, phase2_altsubject_match);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain \"phase2\" alternative subject match '%s'"),
- phase2_altsubject_match);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_802_1x_phase2_altsubject_matches,
- NM_SETTING_802_1X,
- nm_setting_802_1x_get_num_phase2_altsubject_matches,
- nm_setting_802_1x_remove_phase2_altsubject_match,
- _validate_and_remove_phase2_altsubject_match)
-
-DEFINE_SETTER_CERT (_set_fcn_802_1x_phase2_client_cert, nm_setting_802_1x_set_phase2_client_cert)
-
-DEFINE_SETTER_PRIV_KEY (_set_fcn_802_1x_private_key,
- nm_setting_802_1x_get_private_key_password,
- nm_setting_802_1x_set_private_key)
-
-DEFINE_SETTER_PRIV_KEY (_set_fcn_802_1x_phase2_private_key,
- nm_setting_802_1x_get_phase2_private_key_password,
- nm_setting_802_1x_set_phase2_private_key)
-
-static gconstpointer
_get_fcn_bond_options (ARGS_GET_FCN)
{
NMSettingBond *s_bond = NM_SETTING_BOND (setting);
@@ -2365,59 +2335,40 @@ _get_fcn_bond_options (ARGS_GET_FCN)
RETURN_STR_TO_FREE (g_string_free (bond_options_s, FALSE));
}
-/* example: miimon=100,mode=balance-rr, updelay=5 */
static gboolean
-_validate_and_remove_bond_option (NMSettingBond *setting, const char *option)
-{
- const char *opt;
- const char **valid_options;
-
- valid_options = nm_setting_bond_get_valid_options (setting);
- opt = nmc_string_is_valid (option, valid_options, NULL);
-
- if (opt)
- return nm_setting_bond_remove_option (setting, opt);
- else
- return FALSE;
-}
-
-static const char *
-_validate_bond_option_value (const char *option, const char *value, GError **error)
-{
- if (!g_strcmp0 (option, NM_SETTING_BOND_OPTION_MODE))
- return nmc_bond_validate_mode (value, error);
-
- return value;
-}
-
-static gboolean
-_bond_add_option (NMSettingBond *setting,
- const char *name,
- const char *value)
+_optionlist_set_fcn_bond_options (NMSetting *setting,
+ const char *name,
+ const char *value,
+ GError **error)
{
gs_free char *tmp_value = NULL;
char *p;
- if (nm_streq0 (name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
+ if (!value) {
+ nm_setting_bond_remove_option (NM_SETTING_BOND (setting), name);
+ return TRUE;
+ }
+
+ if (nm_streq (name, NM_SETTING_BOND_OPTION_MODE)) {
+ value = nmc_bond_validate_mode (value, error);
+ if (!value)
+ return FALSE;
+ } else if (nm_streq (name, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) {
value = tmp_value = g_strdup (value);
for (p = tmp_value; p && *p; p++)
if (*p == ' ')
*p = ',';
}
- return nm_setting_bond_add_option (setting, name, value);
+ if (!nm_setting_bond_add_option (NM_SETTING_BOND (setting), name, value)) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("failed to set bond option \"%s\""),
+ name);
+ return FALSE;
+ }
+ return TRUE;
}
-DEFINE_SETTER_OPTIONS (_set_fcn_bond_options,
- NM_SETTING_BOND,
- NMSettingBond,
- _bond_add_option,
- nm_setting_bond_get_valid_options,
- _validate_bond_option_value)
-DEFINE_REMOVER_OPTION (_remove_fcn_bond_options,
- NM_SETTING_BOND,
- _validate_and_remove_bond_option)
-
static const char *
_describe_fcn_bond_options (ARGS_DESCRIBE_FCN)
{
@@ -2456,25 +2407,27 @@ _get_fcn_connection_permissions (ARGS_GET_FCN)
GString *perm = NULL;
const char *perm_item;
const char *perm_type;
- int i;
+ guint i, n;
RETURN_UNSUPPORTED_GET_TYPE ();
- perm = g_string_new (NULL);
- for (i = 0; i < nm_setting_connection_get_num_permissions (s_con); i++) {
- if (nm_setting_connection_get_permission (s_con, i, &perm_type, &perm_item, NULL))
- g_string_append_printf (perm, "%s:%s,", perm_type, perm_item);
+ n = nm_setting_connection_get_num_permissions (s_con);
+ for (i = 0; i < n; i++) {
+ if (!nm_setting_connection_get_permission (s_con, i, &perm_type, &perm_item, NULL))
+ continue;
+
+ if (!perm)
+ perm = g_string_new (NULL);
+ else
+ g_string_append_c (perm, ',');
+ g_string_append_printf (perm, "%s:%s", perm_type, perm_item);
}
- NM_SET_OUT (out_is_default, perm->len == 0);
+ NM_SET_OUT (out_is_default, !perm);
- if (perm->len > 0) {
- g_string_truncate (perm, perm->len-1); /* remove trailing , */
+ if (perm)
RETURN_STR_TO_FREE (g_string_free (perm, FALSE));
- }
- /* No value from get_permission */
- g_string_free (perm, TRUE);
return NULL;
}
@@ -2495,6 +2448,11 @@ _set_fcn_connection_type (ARGS_SET_FCN)
return FALSE;
}
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) {
+ g_object_set (G_OBJECT (setting), property_info->property_name, NULL, NULL);
+ return TRUE;
+ }
+
uuid = nm_utils_uuid_generate ();
g_object_set (G_OBJECT (setting),
NM_SETTING_CONNECTION_UUID, uuid,
@@ -2541,75 +2499,61 @@ _complete_fcn_connection_type (ARGS_COMPLETE_FCN)
return (const char *const*) (*out_to_free = result);
}
-/* define from libnm-core/nm-setting-connection.c */
#define PERM_USER_PREFIX "user:"
-static gboolean
-permissions_valid (const char *perm)
+static const char *
+_sanitize_connection_permission_user (const char *perm)
{
- if (!perm || perm[0] == '\0')
- return FALSE;
+ if (NM_STR_HAS_PREFIX (perm, PERM_USER_PREFIX))
+ perm += NM_STRLEN (PERM_USER_PREFIX);
- if (strncmp (perm, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0) {
- if ( strlen (perm) <= strlen (PERM_USER_PREFIX)
- || strchr (perm + strlen (PERM_USER_PREFIX), ':'))
- return FALSE;
- } else {
- if (strchr (perm, ':'))
- return FALSE;
- }
+ if (perm[0] == '\0')
+ return NULL;
+ if (!g_utf8_validate (perm, -1, NULL))
+ return NULL;
- return TRUE;
+ return perm;
}
-static gboolean
-_set_fcn_connection_permissions (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- gsize i;
-
- nm_assert (!error || !*error);
-
- strv = nm_utils_strsplit_set (value, " \t,", FALSE);
- if (!verify_string_list (strv, property_info->property_name, permissions_valid, error))
- return FALSE;
-
- for (i = 0; strv && strv[i]; i++) {
- const char *user = strv[i];
-
- if (strncmp (user, PERM_USER_PREFIX, NM_STRLEN (PERM_USER_PREFIX)) == 0)
- user += NM_STRLEN (PERM_USER_PREFIX);
- nm_setting_connection_add_permission (NM_SETTING_CONNECTION (setting), "user", user, NULL);
+static const char *
+_multilist_validate2_fcn_connection_permissions (NMSetting *setting,
+ const char *item,
+ GError **error)
+{
+ if (!_sanitize_connection_permission_user (item)) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid permission \"%s\""),
+ item);
+ return NULL;
}
+ return item;
+}
+static gboolean
+_multilist_set_fcn_connection_permissions (NMSetting *setting,
+ const char *item)
+{
+ item = _sanitize_connection_permission_user (item);
+ nm_setting_connection_add_permission (NM_SETTING_CONNECTION (setting), "user", item, NULL);
return TRUE;
}
static gboolean
-_validate_and_remove_connection_permission (NMSettingConnection *setting,
- const char *perm,
- GError **error)
+_multilist_remove_by_value_fcn_connection_permissions (NMSetting *setting,
+ const char *item)
{
- gboolean ret;
+ const char *sanitized;
- ret = nm_setting_connection_remove_permission_by_value (setting, "user", perm, NULL);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain permission '%s'"), perm);
- return ret;
+ sanitized = _sanitize_connection_permission_user (item);
+ nm_setting_connection_remove_permission_by_value (NM_SETTING_CONNECTION (setting), "user", sanitized ?: item, NULL);
+ return TRUE;
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_connection_permissions,
- NM_SETTING_CONNECTION,
- nm_setting_connection_get_num_permissions,
- nm_setting_connection_remove_permission,
- _validate_and_remove_connection_permission)
static gboolean
_set_fcn_connection_master (ARGS_SET_FCN)
{
- nm_assert (!error || !*error);
-
- if (!value)
- ;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ value = NULL;
else if (!*value)
value = NULL;
else if ( !nm_utils_is_valid_iface_name (value, NULL)
@@ -2689,44 +2633,20 @@ _complete_fcn_connection_master (ARGS_COMPLETE_FCN)
return (const char *const*) (*out_to_free = result);
}
-static gboolean
-_set_fcn_connection_secondaries (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
-
- strv = nm_utils_strsplit_set (value, " \t,", FALSE);
- if (strv) {
- for (iter = strv; *iter; iter++)
- nm_setting_connection_add_secondary (NM_SETTING_CONNECTION (setting), *iter);
- }
- return TRUE;
-}
-
-static gboolean
-_validate_and_remove_connection_secondary (NMSettingConnection *setting,
- const char *secondary_uuid,
- GError **error)
+static const char *
+_multilist_validate2_fcn_uuid (NMSetting *setting,
+ const char *item,
+ GError **error)
{
- gboolean ret;
-
- if (!nm_utils_is_uuid (secondary_uuid)) {
- g_set_error (error, 1, 0,
- _("the value '%s' is not a valid UUID"), secondary_uuid);
- return FALSE;
+ if (!nm_utils_is_uuid (item)) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("the value '%s' is not a valid UUID"),
+ item);
+ return NULL;
}
- ret = nm_setting_connection_remove_secondary_by_value (setting, secondary_uuid);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain UUID '%s'"), secondary_uuid);
- return ret;
+ return item;
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_connection_secondaries,
- NM_SETTING_CONNECTION,
- nm_setting_connection_get_num_secondaries,
- nm_setting_connection_remove_secondary,
- _validate_and_remove_connection_secondary)
static gconstpointer
_get_fcn_connection_metered (ARGS_GET_FCN)
@@ -2761,6 +2681,9 @@ _set_fcn_connection_metered (ARGS_SET_FCN)
NMMetered metered;
NMTernary ts_val;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
if (!nmc_string_to_ternary (value, &ts_val, error))
return FALSE;
@@ -2810,87 +2733,54 @@ dcb_flags_to_string (NMSettingDcbFlags flags)
return g_string_free (flag_str, FALSE);
}
-#define DEFINE_DCB_FLAGS_GETTER(func_name, property_name) \
- static gconstpointer \
- func_name (ARGS_GET_FCN) \
- { \
- guint v; \
- GValue val = G_VALUE_INIT; \
- \
- RETURN_UNSUPPORTED_GET_TYPE (); \
- g_value_init (&val, G_TYPE_UINT); \
- g_object_get_property (G_OBJECT (setting), property_name, &val); \
- v = g_value_get_uint (&val); \
- g_value_unset (&val); \
- RETURN_STR_TO_FREE (dcb_flags_to_string (v)); \
- }
+static gconstpointer
+_get_fcn_dcb (ARGS_GET_FCN)
+{
+ NMSettingDcb *s_dcb = NM_SETTING_DCB (setting);
+ GString *str;
+ guint i;
-#define DEFINE_DCB_BOOL_GETTER(func_name, getter_func_name) \
- static gconstpointer \
- func_name (ARGS_GET_FCN) \
- { \
- NMSettingDcb *s_dcb = NM_SETTING_DCB (setting); \
- GString *str; \
- guint i; \
- \
- RETURN_UNSUPPORTED_GET_TYPE (); \
- \
- str = g_string_new (NULL); \
- for (i = 0; i < 8; i++) { \
- if (getter_func_name (s_dcb, i)) \
- g_string_append_c (str, '1'); \
- else \
- g_string_append_c (str, '0'); \
- if (i < 7) \
- g_string_append_c (str, ','); \
- } \
- \
- RETURN_STR_TO_FREE (g_string_free (str, FALSE)); \
- }
+ RETURN_UNSUPPORTED_GET_TYPE ();
-#define DEFINE_DCB_UINT_GETTER(func_name, getter_func_name) \
- static gconstpointer \
- func_name (ARGS_GET_FCN) \
- { \
- NMSettingDcb *s_dcb = NM_SETTING_DCB (setting); \
- GString *str; \
- guint i; \
- \
- RETURN_UNSUPPORTED_GET_TYPE (); \
- \
- str = g_string_new (NULL); \
- for (i = 0; i < 8; i++) { \
- g_string_append_printf (str, "%u", getter_func_name (s_dcb, i)); \
- if (i < 7) \
- g_string_append_c (str, ','); \
- } \
- \
- RETURN_STR_TO_FREE (g_string_free (str, FALSE)); \
- }
+ str = g_string_new (NULL);
+ for (i = 0; i < 8; i++) {
+ guint v;
-DEFINE_DCB_FLAGS_GETTER (_get_fcn_dcb_app_fcoe_flags, NM_SETTING_DCB_APP_FCOE_FLAGS)
-DEFINE_DCB_FLAGS_GETTER (_get_fcn_dcb_app_iscsi_flags, NM_SETTING_DCB_APP_ISCSI_FLAGS)
-DEFINE_DCB_FLAGS_GETTER (_get_fcn_dcb_app_fip_flags, NM_SETTING_DCB_APP_FIP_FLAGS)
+ v = property_info->property_typ_data->subtype.dcb.get_fcn (s_dcb, i);
-DEFINE_DCB_FLAGS_GETTER (_get_fcn_dcb_priority_flow_control_flags, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS)
-DEFINE_DCB_BOOL_GETTER (_get_fcn_dcb_priority_flow_control, nm_setting_dcb_get_priority_flow_control)
+ if (i > 0)
+ g_string_append_c (str, ',');
+ g_string_append_printf (str, "%u", v);
+ }
-DEFINE_DCB_FLAGS_GETTER (_get_fcn_dcb_priority_group_flags, NM_SETTING_DCB_PRIORITY_GROUP_FLAGS)
-DEFINE_DCB_UINT_GETTER (_get_fcn_dcb_priority_group_id, nm_setting_dcb_get_priority_group_id)
-DEFINE_DCB_UINT_GETTER (_get_fcn_dcb_priority_group_bandwidth, nm_setting_dcb_get_priority_group_bandwidth)
-DEFINE_DCB_UINT_GETTER (_get_fcn_dcb_priority_bandwidth, nm_setting_dcb_get_priority_bandwidth)
-DEFINE_DCB_BOOL_GETTER (_get_fcn_dcb_priority_strict, nm_setting_dcb_get_priority_strict_bandwidth)
-DEFINE_DCB_UINT_GETTER (_get_fcn_dcb_priority_traffic_class, nm_setting_dcb_get_priority_traffic_class)
+ RETURN_STR_TO_FREE (g_string_free (str, FALSE));
+}
#define DCB_ALL_FLAGS (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING)
+static gconstpointer
+_get_fcn_dcb_flags (ARGS_GET_FCN)
+{
+ nm_auto_unset_gvalue GValue val = G_VALUE_INIT;
+ guint v;
+
+ RETURN_UNSUPPORTED_GET_TYPE ();
+
+ g_value_init (&val, G_TYPE_UINT);
+ g_object_get_property (G_OBJECT (setting), property_info->property_name, &val);
+ v = g_value_get_uint (&val);
+
+ RETURN_STR_TO_FREE (dcb_flags_to_string (v));
+}
+
static gboolean
_set_fcn_dcb_flags (ARGS_SET_FCN)
{
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
long int t;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
/* Check for overall hex numeric value */
t = _nm_utils_ascii_str_to_int64 (value, 0, 0, DCB_ALL_FLAGS, -1);
@@ -2938,15 +2828,13 @@ static gboolean
dcb_parse_uint_array (const char *val,
guint max,
guint other,
- guint *out_array,
+ guint out_array[static 8],
GError **error)
{
gs_strfreev char **items = NULL;
char **iter;
gsize i;
- nm_assert (out_array);
-
items = g_strsplit_set (val, ",", -1);
if (g_strv_length (items) != 8) {
g_set_error_literal (error, 1, 0, _("must contain 8 comma-separated numbers"));
@@ -2995,117 +2883,89 @@ dcb_check_feature_enabled (const NMMetaEnvironment *environment, gpointer *envir
}
static gboolean
-_set_fcn_dcb_priority_flow_control (ARGS_SET_FCN)
+_set_fcn_dcb (ARGS_SET_FCN)
{
guint i = 0;
- guint nums[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ guint nums[8] = { 0, };
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
- if (!dcb_parse_uint_array (value, 1, 0, nums, error))
+ if (!dcb_parse_uint_array (value,
+ property_info->property_typ_data->subtype.dcb.max,
+ property_info->property_typ_data->subtype.dcb.other,
+ nums,
+ error))
return FALSE;
- for (i = 0; i < 8; i++)
- nm_setting_dcb_set_priority_flow_control (NM_SETTING_DCB (setting), i, !!nums[i]);
-
- dcb_check_feature_enabled (environment, environment_user_data, NM_SETTING_DCB (setting), NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS);
- return TRUE;
-}
-
-static gboolean
-_set_fcn_dcb_priority_group_id (ARGS_SET_FCN)
-{
- guint i = 0;
- guint nums[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- nm_assert (!error || !*error);
-
- if (!dcb_parse_uint_array (value, 7, 15, nums, error))
- return FALSE;
-
- for (i = 0; i < 8; i++)
- nm_setting_dcb_set_priority_group_id (NM_SETTING_DCB (setting), i, nums[i]);
-
- dcb_check_feature_enabled (environment, environment_user_data, NM_SETTING_DCB (setting), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS);
- return TRUE;
-}
+ if (property_info->property_typ_data->subtype.dcb.is_percent) {
+ guint sum = 0;
-static gboolean
-_set_fcn_dcb_priority_group_bandwidth (ARGS_SET_FCN)
-{
- guint i = 0, sum = 0;
- guint nums[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- nm_assert (!error || !*error);
-
- if (!dcb_parse_uint_array (value, 100, 0, nums, error))
- return FALSE;
-
- for (i = 0; i < 8; i++)
- sum += nums[i];
- if (sum != 100) {
- g_set_error_literal (error, 1, 0, _("bandwidth percentages must total 100%%"));
- return FALSE;
+ for (i = 0; i < 8; i++) {
+ sum += nums[i];
+ if (nums[i] > 100 || sum > 100)
+ break;
+ }
+ if (sum != 100) {
+ g_set_error_literal (error, 1, 0, _("bandwidth percentages must total 100%%"));
+ return FALSE;
+ }
}
for (i = 0; i < 8; i++)
- nm_setting_dcb_set_priority_group_bandwidth (NM_SETTING_DCB (setting), i, nums[i]);
+ property_info->property_typ_data->subtype.dcb.set_fcn (NM_SETTING_DCB (setting), i, nums[i]);
dcb_check_feature_enabled (environment, environment_user_data, NM_SETTING_DCB (setting), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS);
return TRUE;
}
-static gboolean
-_set_fcn_dcb_priority_bandwidth (ARGS_SET_FCN)
+static gconstpointer
+_get_fcn_dcb_bool (ARGS_GET_FCN)
{
- guint i = 0;
- guint nums[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- nm_assert (!error || !*error);
-
- if (!dcb_parse_uint_array (value, 100, 0, nums, error))
- return FALSE;
-
- for (i = 0; i < 8; i++)
- nm_setting_dcb_set_priority_bandwidth (NM_SETTING_DCB (setting), i, nums[i]);
-
- dcb_check_feature_enabled (environment, environment_user_data, NM_SETTING_DCB (setting), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS);
- return TRUE;
-}
+ NMSettingDcb *s_dcb = NM_SETTING_DCB (setting);
+ GString *str;
+ guint i;
-static gboolean
-_set_fcn_dcb_priority_strict (ARGS_SET_FCN)
-{
- guint i = 0;
- guint nums[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ RETURN_UNSUPPORTED_GET_TYPE ();
- nm_assert (!error || !*error);
+ str = g_string_new (NULL);
+ for (i = 0; i < 8; i++) {
+ gboolean v;
- if (!dcb_parse_uint_array (value, 1, 0, nums, error))
- return FALSE;
+ v = property_info->property_typ_data->subtype.dcb_bool.get_fcn (s_dcb, i);
- for (i = 0; i < 8; i++)
- nm_setting_dcb_set_priority_strict_bandwidth (NM_SETTING_DCB (setting), i, !!nums[i]);
+ if (i > 0)
+ g_string_append_c (str, ',');
+ g_string_append_c (str, v ? '1': '0');
+ }
- dcb_check_feature_enabled (environment, environment_user_data, NM_SETTING_DCB (setting), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS);
- return TRUE;
+ RETURN_STR_TO_FREE (g_string_free (str, FALSE));
}
static gboolean
-_set_fcn_dcb_priority_traffic_class (ARGS_SET_FCN)
+_set_fcn_dcb_bool (ARGS_SET_FCN)
{
guint i = 0;
- guint nums[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ guint nums[8] = { 0, };
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
- if (!dcb_parse_uint_array (value, 7, 0, nums, error))
+ if (!dcb_parse_uint_array (value, 1, 0, nums, error))
return FALSE;
- for (i = 0; i < 8; i++)
- nm_setting_dcb_set_priority_traffic_class (NM_SETTING_DCB (setting), i, nums[i]);
+ for (i = 0; i < 8; i++) {
+ property_info->property_typ_data->subtype.dcb_bool.set_fcn (NM_SETTING_DCB (setting),
+ i,
+ !!nums[i]);
+ }
- dcb_check_feature_enabled (environment, environment_user_data, NM_SETTING_DCB (setting), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS);
+ dcb_check_feature_enabled (environment,
+ environment_user_data,
+ NM_SETTING_DCB (setting),
+ ( property_info->property_typ_data->subtype.dcb_bool.with_flow_control_flags
+ ? NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS
+ : NM_SETTING_DCB_PRIORITY_GROUP_FLAGS));
return TRUE;
}
@@ -3114,9 +2974,10 @@ _set_fcn_gsm_sim_operator_id (ARGS_SET_FCN)
{
const char *p = value;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
- if (strlen (value) != 5 && strlen (value) != 6) {
+ if (!NM_IN_SET (strlen (value), 5, 6)) {
g_set_error_literal (error, 1, 0, _("SIM operator ID must be a 5 or 6 number MCCMNC code"));
return FALSE;
}
@@ -3137,16 +2998,16 @@ _set_fcn_gsm_sim_operator_id (ARGS_SET_FCN)
static gboolean
_set_fcn_infiniband_p_key (ARGS_SET_FCN)
{
- const gint64 INVALID = G_MININT64;
gint64 p_key;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
if (nm_streq (value, "default"))
p_key = -1;
else {
- p_key = _nm_utils_ascii_str_to_int64 (value, 0, -1, G_MAXUINT16, INVALID);
- if (p_key == INVALID) {
+ p_key = _nm_utils_ascii_str_to_int64 (value, 0, -1, G_MAXUINT16, -2);
+ if (p_key == -2) {
g_set_error (error, 1, 0, _("'%s' is not a valid IBoIP P_Key"), value);
return FALSE;
}
@@ -3177,525 +3038,302 @@ _get_fcn_infiniband_p_key (ARGS_GET_FCN)
}
static gconstpointer
-_get_fcn_ip_config_addresses (ARGS_GET_FCN)
+_get_fcn_objlist (ARGS_GET_FCN)
{
- NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
- GString *printable;
- guint num_addresses, i;
- NMIPAddress *addr;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- printable = g_string_new (NULL);
-
- num_addresses = NM_MIN ((guint) G_MAXINT, nm_setting_ip_config_get_num_addresses (s_ip));
- for (i = 0; i < num_addresses; i++) {
- addr = nm_setting_ip_config_get_address (s_ip, i);
-
- if (printable->len > 0)
- g_string_append (printable, ", ");
-
- g_string_append_printf (printable, "%s/%u",
- nm_ip_address_get_address (addr),
- nm_ip_address_get_prefix (addr));
- }
-
- NM_SET_OUT (out_is_default, num_addresses == 0);
- RETURN_STR_TO_FREE (g_string_free (printable, FALSE));
-}
-
-static gconstpointer
-_get_fcn_ip_config_routes (ARGS_GET_FCN)
-{
- NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
- GString *printable;
- guint num_routes, i;
- NMIPRoute *route;
+ GString *str = NULL;
+ guint num;
+ guint idx;
RETURN_UNSUPPORTED_GET_TYPE ();
- printable = g_string_new (NULL);
-
- num_routes = NM_MIN ((guint) G_MAXINT, nm_setting_ip_config_get_num_routes (s_ip));
- for (i = 0; i < num_routes; i++) {
- gs_free char *attr_str = NULL;
- gs_strfreev char **attr_names = NULL;
- gs_unref_hashtable GHashTable *hash = g_hash_table_new (nm_str_hash, g_str_equal);
- int j;
-
- route = nm_setting_ip_config_get_route (s_ip, i);
-
- attr_names = nm_ip_route_get_attribute_names (route);
- for (j = 0; attr_names && attr_names[j]; j++) {
- g_hash_table_insert (hash, attr_names[j],
- nm_ip_route_get_attribute (route, attr_names[j]));
+ num = property_info->property_typ_data->subtype.objlist.get_num_fcn (setting);
+
+ for (idx = 0; idx < num; idx++) {
+ if (!str)
+ str = g_string_new (NULL);
+ else if (str->len > 0) {
+ if ( get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY
+ && property_info->property_typ_data->subtype.objlist.delimit_pretty_with_semicolon)
+ g_string_append (str, "; ");
+ else
+ g_string_append (str, ", ");
}
- attr_str = nm_utils_format_variant_attributes (hash, ' ', '=');
-
- if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) {
- if (printable->len > 0)
- g_string_append (printable, ", ");
-
- g_string_append_printf (printable, "%s/%u",
- nm_ip_route_get_dest (route),
- nm_ip_route_get_prefix (route));
-
- if (nm_ip_route_get_next_hop (route))
- g_string_append_printf (printable, " %s", nm_ip_route_get_next_hop (route));
- if (nm_ip_route_get_metric (route) != -1)
- g_string_append_printf (printable, " %u", (guint32) nm_ip_route_get_metric (route));
- if (attr_str)
- g_string_append_printf (printable, " %s", attr_str);
- } else {
-
- if (printable->len > 0)
- g_string_append (printable, "; ");
-
- g_string_append (printable, "{ ");
-
- g_string_append_printf (printable, "ip = %s/%u",
- nm_ip_route_get_dest (route),
- nm_ip_route_get_prefix (route));
-
- if (nm_ip_route_get_next_hop (route)) {
- g_string_append_printf (printable, ", nh = %s",
- nm_ip_route_get_next_hop (route));
- }
-
- if (nm_ip_route_get_metric (route) != -1)
- g_string_append_printf (printable, ", mt = %u", (guint32) nm_ip_route_get_metric (route));
- if (attr_str)
- g_string_append_printf (printable, " %s", attr_str);
-
- g_string_append (printable, " }");
- }
+ property_info->property_typ_data->subtype.objlist.obj_to_str_fcn (get_type,
+ setting,
+ idx,
+ str);
}
- NM_SET_OUT (out_is_default, num_routes == 0);
- RETURN_STR_TO_FREE (g_string_free (printable, FALSE));
+ NM_SET_OUT (out_is_default, num == 0);
+ if (str)
+ RETURN_STR_TO_FREE (g_string_free (str, FALSE));
+ return NULL;
}
-static const char *ipv4_valid_methods[] = {
- NM_SETTING_IP4_CONFIG_METHOD_AUTO,
- NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
- NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
- NM_SETTING_IP4_CONFIG_METHOD_SHARED,
- NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
- NULL
-};
-
-static gboolean
-_set_fcn_ip4_config_method (ARGS_SET_FCN)
+static void
+_objlist_obj_to_str_fcn_ip_config_addresses (NMMetaAccessorGetType get_type,
+ NMSetting *setting,
+ guint idx,
+ GString *str)
{
- /* Silently accept "static" and convert to "manual" */
- if (value && strlen (value) > 1 && matches (value, "static"))
- value = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
+ NMIPAddress *obj;
- return check_and_set_string (setting, property_info->property_name, value, ipv4_valid_methods, error);
+ obj = nm_setting_ip_config_get_address (NM_SETTING_IP_CONFIG (setting),
+ idx);
+ g_string_append_printf (str,
+ "%s/%u",
+ nm_ip_address_get_address (obj),
+ nm_ip_address_get_prefix (obj));
}
-static gboolean
-_set_fcn_ip4_config_dns (ARGS_SET_FCN)
+static void
+_objlist_obj_to_str_fcn_ip_config_routes (NMMetaAccessorGetType get_type,
+ NMSetting *setting,
+ guint idx,
+ GString *str)
{
- const char **strv = NULL;
- const char *const*iter;
- in_addr_t ip4_addr;
-
- nm_assert (!error || !*error);
+ NMIPRoute *route;
+ gs_free char *attr_str = NULL;
+ gs_strfreev char **attr_names = NULL;
+ gs_unref_hashtable GHashTable *hash = g_hash_table_new (nm_str_hash, g_str_equal);
+ int j;
- strv = nm_utils_strsplit_set (value, " \t,", FALSE);
- for (iter = strv; iter && *iter; iter++) {
- gs_free char *addr = g_strstrip (g_strdup (*iter));
+ route = nm_setting_ip_config_get_route (NM_SETTING_IP_CONFIG (setting), idx);
- if (inet_pton (AF_INET, addr, &ip4_addr) < 1) {
- g_set_error (error, 1, 0, _("invalid IPv4 address '%s'"), addr);
- return FALSE;
- }
- nm_setting_ip_config_add_dns (NM_SETTING_IP_CONFIG (setting), addr);
+ attr_names = nm_ip_route_get_attribute_names (route);
+ for (j = 0; attr_names && attr_names[j]; j++) {
+ g_hash_table_insert (hash, attr_names[j],
+ nm_ip_route_get_attribute (route, attr_names[j]));
}
- return TRUE;
-}
-static gboolean
-_validate_and_remove_ipv4_dns (NMSettingIPConfig *setting,
- const char *dns,
- GError **error)
-{
- guint32 ip4_addr;
- gboolean ret;
+ attr_str = nm_utils_format_variant_attributes (hash, ' ', '=');
- if (inet_pton (AF_INET, dns, &ip4_addr) < 1) {
- g_set_error (error, 1, 0, _("invalid IPv4 address '%s'"), dns);
- return FALSE;
- }
+ if (get_type != NM_META_ACCESSOR_GET_TYPE_PRETTY) {
+ g_string_append_printf (str, "%s/%u",
+ nm_ip_route_get_dest (route),
+ nm_ip_route_get_prefix (route));
- ret = nm_setting_ip_config_remove_dns_by_value (setting, dns);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain DNS server '%s'"), dns);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv4_config_dns,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_dns,
- nm_setting_ip_config_remove_dns,
- _validate_and_remove_ipv4_dns)
+ if (nm_ip_route_get_next_hop (route))
+ g_string_append_printf (str, " %s", nm_ip_route_get_next_hop (route));
+ if (nm_ip_route_get_metric (route) != -1)
+ g_string_append_printf (str, " %u", (guint32) nm_ip_route_get_metric (route));
+ if (attr_str)
+ g_string_append_printf (str, " %s", attr_str);
+ } else {
+ g_string_append (str, "{ ");
-static gboolean
-_set_fcn_ip_config_dns_search (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- gsize i;
+ g_string_append_printf (str, "ip = %s/%u",
+ nm_ip_route_get_dest (route),
+ nm_ip_route_get_prefix (route));
- nm_assert (!error || !*error);
+ if (nm_ip_route_get_next_hop (route)) {
+ g_string_append_printf (str, ", nh = %s",
+ nm_ip_route_get_next_hop (route));
+ }
- strv = nm_utils_strsplit_set (value, " \t,", FALSE);
- if (!verify_string_list (strv, property_info->property_name, nmc_util_is_domain, error))
- return FALSE;
+ if (nm_ip_route_get_metric (route) != -1)
+ g_string_append_printf (str, ", mt = %u", (guint32) nm_ip_route_get_metric (route));
+ if (attr_str)
+ g_string_append_printf (str, " %s", attr_str);
- if (strv) {
- for (i = 0; strv[i]; i++)
- nm_setting_ip_config_add_dns_search (NM_SETTING_IP_CONFIG (setting), strv[i]);
+ g_string_append (str, " }");
}
- return TRUE;
-}
-
-static gboolean
-_validate_and_remove_ip_dns_search (NMSettingIPConfig *setting,
- const char *dns_search,
- GError **error)
-{
- gboolean ret;
-
- ret = nm_setting_ip_config_remove_dns_search_by_value (setting, dns_search);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain DNS search domain '%s'"),
- dns_search);
- return ret;
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ip_config_dns_search,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_dns_searches,
- nm_setting_ip_config_remove_dns_search,
- _validate_and_remove_ip_dns_search)
static gboolean
-_set_fcn_ip_config_dns_options (ARGS_SET_FCN)
+_set_fcn_ip_config_method (ARGS_SET_FCN)
{
- gs_free const char **strv = NULL;
- NMSettingIPConfig *s_ip;
- gsize i;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
- nm_assert (!error || !*error);
- s_ip = NM_SETTING_IP_CONFIG (setting);
-
- strv = nm_utils_strsplit_set (value, " \t,", FALSE);
- if (strv) {
- for (i = 0; strv[i]; i++) {
- nm_setting_ip_config_remove_dns_option_by_value (s_ip, strv[i]);
- nm_setting_ip_config_add_dns_option (s_ip, strv[i]);
- }
+ /* Silently accept "static" and convert to "manual" */
+ if ( strlen (value) > 1
+ && matches (value, "static")) {
+ if (nm_setting_ip_config_get_addr_family (NM_SETTING_IP_CONFIG (setting)) == AF_INET)
+ value = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
+ else
+ value = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
}
- return TRUE;
-}
-
-static gboolean
-_validate_and_remove_ip_dns_option (NMSettingIPConfig *setting,
- const char *dns_option,
- GError **error)
-{
- gboolean ret;
-
- ret = nm_setting_ip_config_remove_dns_option_by_value (setting, dns_option);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain DNS option '%s'"),
- dns_option);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ip_config_dns_options,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_dns_options,
- nm_setting_ip_config_remove_dns_option,
- _validate_and_remove_ip_dns_option)
-static gboolean
-_set_fcn_ip4_config_addresses (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMIPAddress *ip4addr;
+ value = nmc_string_is_valid (value,
+ (const char **) property_info->property_typ_data->values_static,
+ error);
+ if (!value)
+ return FALSE;
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; *iter; iter++) {
- ip4addr = _parse_ip_address (AF_INET, *iter, error);
- if (!ip4addr)
- return FALSE;
- nm_setting_ip_config_add_address (NM_SETTING_IP_CONFIG (setting), ip4addr);
- nm_ip_address_unref (ip4addr);
- }
+ g_object_set (setting, property_info->property_name, value, NULL);
return TRUE;
}
-static gboolean
-_validate_and_remove_ipv4_address (NMSettingIPConfig *setting,
- const char *address,
- GError **error)
+static const char *
+_multilist_validate2_fcn_ip_config_dns (NMSetting *setting,
+ const char *value,
+ GError **error)
{
- NMIPAddress *ip4addr;
- gboolean ret;
-
- ip4addr = _parse_ip_address (AF_INET, address, error);
- if (!ip4addr)
- return FALSE;
+ int addr_family = nm_setting_ip_config_get_addr_family (NM_SETTING_IP_CONFIG (setting));
- ret = nm_setting_ip_config_remove_address_by_value (setting, ip4addr);
- if (!ret) {
- g_set_error (error, 1, 0,
- _("the property doesn't contain IP address '%s'"), address);
+ if (!nm_utils_parse_inaddr (addr_family, value, NULL)) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("invalid IPv%c address '%s'"),
+ nm_utils_addr_family_to_char (addr_family),
+ value);
+ return NULL;
}
- nm_ip_address_unref (ip4addr);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv4_config_addresses,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_addresses,
- nm_setting_ip_config_remove_address,
- _validate_and_remove_ipv4_address)
-
-static gboolean
-_set_fcn_ip4_config_gateway (ARGS_SET_FCN)
-{
- gs_free char *addr = NULL;
-
- addr = g_strstrip (g_strdup (value));
- if (!nm_utils_ipaddr_valid (AF_INET, addr)) {
- g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT,
- _("invalid gateway address '%s'"), value);
- return FALSE;
- }
- g_object_set (setting, property_info->property_name, addr, NULL);
- return TRUE;
+ return value;
}
static gboolean
-_set_fcn_ip4_config_routes (ARGS_SET_FCN)
+_multilist_add_fcn_ip_config_dns_options (NMSetting *setting,
+ const char *item)
{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMIPRoute *ip4route;
+ NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; *iter; iter++) {
- ip4route = _parse_ip_route (AF_INET, *iter, error);
- if (!ip4route)
- return FALSE;
- nm_setting_ip_config_add_route (NM_SETTING_IP_CONFIG (setting), ip4route);
- nm_ip_route_unref (ip4route);
+ if (!nm_setting_ip_config_add_dns_option (s_ip, item)) {
+ /* maybe it failed, because the element already existed. *sigh*. */
+ nm_setting_ip_config_remove_dns_option_by_value (s_ip, item);
+ return nm_setting_ip_config_add_dns_option (s_ip, item);
}
return TRUE;
}
static gboolean
-_validate_and_remove_ipv4_route (NMSettingIPConfig *setting,
- const char *route,
- GError **error)
-{
- NMIPRoute *ip4route;
- gboolean ret;
-
- ip4route = _parse_ip_route (AF_INET, route, error);
- if (!ip4route)
- return FALSE;
-
- ret = nm_setting_ip_config_remove_route_by_value (setting, ip4route);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain route '%s'"), route);
- nm_ip_route_unref (ip4route);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv4_config_routes,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_routes,
- nm_setting_ip_config_remove_route,
- _validate_and_remove_ipv4_route)
-
-static const char *ipv6_valid_methods[] = {
- NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
- NM_SETTING_IP6_CONFIG_METHOD_AUTO,
- NM_SETTING_IP6_CONFIG_METHOD_DHCP,
- NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
- NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
- NM_SETTING_IP6_CONFIG_METHOD_SHARED,
- NULL
-};
-
-static gboolean
-_set_fcn_ip6_config_method (ARGS_SET_FCN)
-{
- /* Silently accept "static" and convert to "manual" */
- if (value && strlen (value) > 1 && matches (value, "static"))
- value = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
-
- return check_and_set_string (setting, property_info->property_name, value, ipv6_valid_methods, error);
-}
-
-static gboolean
-_set_fcn_ip6_config_dns (ARGS_SET_FCN)
+_set_fcn_objlist (ARGS_SET_FCN)
{
gs_free const char **strv = NULL;
- const char *const*iter;
- struct in6_addr ip6_addr;
-
- nm_assert (!error || !*error);
+ gsize i, nstrv;
- strv = nm_utils_strsplit_set (value, " \t,", FALSE);
- for (iter = strv; iter && *iter; iter++) {
- gs_free char *addr = g_strstrip (g_strdup (*iter));
-
- if (inet_pton (AF_INET6, addr, &ip6_addr) < 1) {
- g_set_error (error, 1, 0, _("invalid IPv6 address '%s'"), addr);
- return FALSE;
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value)) {
+ if (property_info->property_typ_data->subtype.objlist.clear_all_fcn) {
+ property_info->property_typ_data->subtype.objlist.clear_all_fcn (setting);
+ return TRUE;
}
- nm_setting_ip_config_add_dns (NM_SETTING_IP_CONFIG (setting), addr);
+ return _gobject_property_reset_default (setting, property_info->property_name);
}
- return TRUE;
-}
-static gboolean
-_validate_and_remove_ipv6_dns (NMSettingIPConfig *setting,
- const char *dns,
- GError **error)
-{
- struct in6_addr ip6_addr;
- gboolean ret;
+ if ( _SET_FCN_DO_REMOVE (modifier, value)
+ && ( property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u
+ || property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_s)) {
+ gs_free gint64 *indexes = NULL;
- if (inet_pton (AF_INET6, dns, &ip6_addr) < 1) {
- g_set_error (error, 1, 0, _("invalid IPv6 address '%s'"), dns);
- return FALSE;
- }
+ indexes = _value_str_as_index_list (value, &nstrv);
+ if (indexes) {
+ gint64 num;
- ret = nm_setting_ip_config_remove_dns_by_value (setting, dns);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain DNS server '%s'"), dns);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv6_config_dns,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_dns,
- nm_setting_ip_config_remove_dns,
- _validate_and_remove_ipv6_dns)
+ num = property_info->property_typ_data->subtype.objlist.get_num_fcn (setting);
+ for (i = 0; i < nstrv; i++) {
+ gint64 idx = indexes[i];
-static gboolean
-_dns_options_is_default (NMSettingIPConfig *setting)
-{
- return nm_setting_ip_config_has_dns_options (setting)
- && !nm_setting_ip_config_get_num_dns_options (setting);
-}
+ if (idx >= num)
+ continue;
+ if (property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u)
+ property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_u (setting, idx);
+ else
+ property_info->property_typ_data->subtype.objlist.remove_by_idx_fcn_s (setting, idx);
+ }
+ return TRUE;
+ }
+ }
-static gboolean
-_set_fcn_ip6_config_addresses (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMIPAddress *ip6addr;
+ strv = _value_strsplit (value,
+ VALUE_STRSPLIT_MODE_OBJLIST,
+ &nstrv);
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- ip6addr = _parse_ip_address (AF_INET6, *iter, error);
- if (!ip6addr)
+ if (_SET_FCN_DO_SET_ALL (modifier, value)) {
+ if (property_info->property_typ_data->subtype.objlist.clear_all_fcn)
+ property_info->property_typ_data->subtype.objlist.clear_all_fcn (setting);
+ else
+ _gobject_property_reset (setting, property_info->property_name, FALSE);
+ }
+
+ for (i = 0; i < nstrv; i++) {
+ /* FIXME: there is the problem here that set_fcn() might succed on the first item
+ * (modifying it), and fail to parse the second one.
+ *
+ * Optimally, we would first parse all input strings before starting the
+ * modify the setting. The setting should only be modified if (and only if)
+ * the entire operation succeeds to set all items.
+ *
+ * Currently, in interactive mode this leads to odd behavior.
+ *
+ * This does not only affect objlist.set_fcn() or _pt_objlist properties.
+ * E.g. we also call _gobject_property_reset() before validating the input. */
+ if (!property_info->property_typ_data->subtype.objlist.set_fcn (setting,
+ !_SET_FCN_DO_REMOVE (modifier, value),
+ strv[i],
+ error))
return FALSE;
- nm_setting_ip_config_add_address (NM_SETTING_IP_CONFIG (setting), ip6addr);
- nm_ip_address_unref (ip6addr);
}
return TRUE;
}
static gboolean
-_validate_and_remove_ipv6_address (NMSettingIPConfig *setting,
- const char *address,
- GError **error)
+_objlist_set_fcn_ip_config_addresses (NMSetting *setting,
+ gboolean do_add,
+ const char *value,
+ GError **error)
{
- NMIPAddress *ip6addr;
- gboolean ret;
+ int addr_family = nm_setting_ip_config_get_addr_family (NM_SETTING_IP_CONFIG (setting));
+ nm_auto_unref_ip_address NMIPAddress *addr = NULL;
- ip6addr = _parse_ip_address (AF_INET6, address, error);
- if (!ip6addr)
+ addr = _parse_ip_address (addr_family, value, error);
+ if (!addr)
return FALSE;
-
- ret = nm_setting_ip_config_remove_address_by_value (setting, ip6addr);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain IP address '%s'"), address);
- nm_ip_address_unref (ip6addr);
- return ret;
+ if (do_add)
+ nm_setting_ip_config_add_address (NM_SETTING_IP_CONFIG (setting), addr);
+ else
+ nm_setting_ip_config_remove_address_by_value (NM_SETTING_IP_CONFIG (setting), addr);
+ return TRUE;
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv6_config_addresses,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_addresses,
- nm_setting_ip_config_remove_address,
- _validate_and_remove_ipv6_address)
static gboolean
-_set_fcn_ip6_config_gateway (ARGS_SET_FCN)
+_set_fcn_ip_config_gateway (ARGS_SET_FCN)
{
- gs_free char *addr = NULL;
+ gs_free char *value_to_free = NULL;
+ int addr_family = nm_setting_ip_config_get_addr_family (NM_SETTING_IP_CONFIG (setting));
- addr = g_strstrip (g_strdup (value));
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
- if (!nm_utils_ipaddr_valid (AF_INET6, addr)) {
+ value = nm_strstrip_avoid_copy (value, &value_to_free);
+
+ if (!nm_utils_ipaddr_valid (addr_family, value)) {
g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT,
_("invalid gateway address '%s'"),
- addr);
+ value);
return FALSE;
}
- g_object_set (setting, property_info->property_name, addr, NULL);
+ g_object_set (setting, property_info->property_name, value, NULL);
return TRUE;
}
static gboolean
-_set_fcn_ip6_config_routes (ARGS_SET_FCN)
+_objlist_set_fcn_ip_config_routes (NMSetting *setting,
+ gboolean do_add,
+ const char *value,
+ GError **error)
{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMIPRoute *ip6route;
+ int addr_family = nm_setting_ip_config_get_addr_family (NM_SETTING_IP_CONFIG (setting));
+ nm_auto_unref_ip_route NMIPRoute *route = NULL;
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- ip6route = _parse_ip_route (AF_INET6, *iter, error);
- if (!ip6route)
- return FALSE;
- nm_setting_ip_config_add_route (NM_SETTING_IP_CONFIG (setting), ip6route);
- nm_ip_route_unref (ip6route);
- }
+ route = _parse_ip_route (addr_family, value, error);
+ if (!route)
+ return FALSE;
+ if (do_add)
+ nm_setting_ip_config_add_route (NM_SETTING_IP_CONFIG (setting), route);
+ else
+ nm_setting_ip_config_remove_route_by_value (NM_SETTING_IP_CONFIG (setting), route);
return TRUE;
}
static gboolean
-_validate_and_remove_ipv6_route (NMSettingIPConfig *setting,
- const char *route,
- GError **error)
+_is_default_func_ip_config_dns_options (NMSetting *setting)
{
- NMIPRoute *ip6route;
- gboolean ret;
-
- ip6route = _parse_ip_route (AF_INET6, route, error);
- if (!ip6route)
- return FALSE;
-
- ret = nm_setting_ip_config_remove_route_by_value (setting, ip6route);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain route '%s'"), route);
- nm_ip_route_unref (ip6route);
- return ret;
+ return nm_setting_ip_config_has_dns_options (NM_SETTING_IP_CONFIG (setting))
+ && !nm_setting_ip_config_get_num_dns_options (NM_SETTING_IP_CONFIG (setting));
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv6_config_routes,
- NM_SETTING_IP_CONFIG,
- nm_setting_ip_config_get_num_routes,
- nm_setting_ip_config_remove_route,
- _validate_and_remove_ipv6_route)
static gconstpointer
_get_fcn_match_interface_name (ARGS_GET_FCN)
@@ -3716,49 +3354,11 @@ _get_fcn_match_interface_name (ARGS_GET_FCN)
else
g_string_append_c (str, ' ');
name = nm_setting_match_get_interface_name (s_match, i);
- g_string_append (str, _nm_utils_escape_spaces (name, &to_free));
+ g_string_append (str, _value_strescape (name, &to_free));
}
RETURN_STR_TO_FREE (g_string_free (str, FALSE));
}
-static gboolean
-_set_fcn_match_interface_name (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- gsize i;
-
- nm_assert (!error || !*error);
-
- strv = nm_utils_strsplit_set (value, " \t", TRUE);
- if (strv) {
- for (i = 0; strv[i]; i++) {
- nm_setting_match_add_interface_name (NM_SETTING_MATCH (setting),
- _nm_utils_unescape_spaces ((char *) strv[i]));
- }
- }
- return TRUE;
-}
-
-static gboolean
-_validate_and_remove_match_interface_name (NMSettingMatch *setting,
- const char *interface_name,
- GError **error)
-{
- gboolean ret;
-
- ret = nm_setting_match_remove_interface_name_by_value (setting, interface_name);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain interface name '%s'"),
- interface_name);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_match_interface_name,
- NM_SETTING_MATCH,
- nm_setting_match_get_num_interface_names,
- nm_setting_match_remove_interface_name,
- _validate_and_remove_match_interface_name)
-
static gconstpointer
_get_fcn_olpc_mesh_ssid (ARGS_GET_FCN)
{
@@ -3783,7 +3383,8 @@ _set_fcn_olpc_mesh_channel (ARGS_SET_FCN)
{
unsigned long chan_int;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
if (!nmc_string_to_uint (value, TRUE, 1, 13, &chan_int)) {
g_set_error (error, 1, 0, _("'%s' is not a valid channel; use <1-13>"), value);
@@ -3803,241 +3404,123 @@ _validate_fcn_proxy_pac_script (const char *value, char **out_to_free, GError **
RETURN_STR_TO_FREE (script);
}
-static gconstpointer
-_get_fcn_sriov_vfs (ARGS_GET_FCN)
+static void
+_objlist_obj_to_str_fcn_sriov_vfs (NMMetaAccessorGetType get_type,
+ NMSetting *setting,
+ guint idx,
+ GString *str)
{
- NMSettingSriov *s_sriov = NM_SETTING_SRIOV (setting);
- GString *printable;
- guint num_vfs, i;
+ gs_free char *s = NULL;
NMSriovVF *vf;
- char *str;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- printable = g_string_new (NULL);
-
- num_vfs = nm_setting_sriov_get_num_vfs (s_sriov);
- for (i = 0; i < num_vfs; i++) {
- vf = nm_setting_sriov_get_vf (s_sriov, i);
-
- if (printable->len > 0)
- g_string_append (printable, ", ");
- str = nm_utils_sriov_vf_to_str (vf, FALSE, NULL);
- if (str) {
- g_string_append (printable, str);
- g_free (str);
- }
- }
-
- NM_SET_OUT (out_is_default, num_vfs == 0);
- RETURN_STR_TO_FREE (g_string_free (printable, FALSE));
+ vf = nm_setting_sriov_get_vf (NM_SETTING_SRIOV (setting), idx);
+ s = nm_utils_sriov_vf_to_str (vf, FALSE, NULL);
+ if (s)
+ g_string_append (str, s);
}
-static gconstpointer
-_get_fcn_tc_config_qdiscs (ARGS_GET_FCN)
+static void
+_objlist_obj_to_str_fcn_tc_config_qdiscs (NMMetaAccessorGetType get_type,
+ NMSetting *setting,
+ guint idx,
+ GString *str)
{
- NMSettingTCConfig *s_tc = NM_SETTING_TC_CONFIG (setting);
- GString *printable;
- guint num_qdiscs, i;
+ gs_free char *s = NULL;
NMTCQdisc *qdisc;
- char *str;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
- printable = g_string_new (NULL);
-
- num_qdiscs = nm_setting_tc_config_get_num_qdiscs (s_tc);
- for (i = 0; i < num_qdiscs; i++) {
- qdisc = nm_setting_tc_config_get_qdisc (s_tc, i);
-
- if (printable->len > 0)
- g_string_append (printable, ", ");
-
- str = nm_utils_tc_qdisc_to_str (qdisc, NULL);
- if (str) {
- g_string_append (printable, str);
- g_free (str);
- }
- }
-
- NM_SET_OUT (out_is_default, num_qdiscs == 0);
- RETURN_STR_TO_FREE (g_string_free (printable, FALSE));
+ qdisc = nm_setting_tc_config_get_qdisc (NM_SETTING_TC_CONFIG (setting), idx);
+ s = nm_utils_tc_qdisc_to_str (qdisc, NULL);
+ if (s)
+ g_string_append (str, s);
}
static gboolean
-_set_fcn_sriov_vfs (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMSriovVF *vf;
- GError *local = NULL;
-
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- vf = nm_utils_sriov_vf_from_str (*iter, &local);
- if (!vf) {
- g_set_error (error, 1, 0, "%s. %s", local->message,
- _("The valid syntax is: vf [attribute=value]... [,vf [attribute=value]...]"));
- return FALSE;
- }
- nm_setting_sriov_add_vf (NM_SETTING_SRIOV (setting), vf);
- nm_sriov_vf_unref (vf);
+_objlist_set_fcn_sriov_vfs (NMSetting *setting,
+ gboolean do_add,
+ const char *value,
+ GError **error)
+{
+ nm_auto_unref_sriov_vf NMSriovVF *vf = NULL;
+ gs_free_error GError *local = NULL;
+
+ vf = nm_utils_sriov_vf_from_str (value, &local);
+ if (!vf) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ "%s. %s",
+ local->message,
+ _("The valid syntax is: vf [attribute=value]... [,vf [attribute=value]...]"));
+ return FALSE;
}
+ if (do_add)
+ nm_setting_sriov_add_vf (NM_SETTING_SRIOV (setting), vf);
+ else
+ nm_setting_sriov_remove_vf_by_index (NM_SETTING_SRIOV (setting), nm_sriov_vf_get_index (vf));
return TRUE;
}
static gboolean
-_set_fcn_tc_config_qdiscs (ARGS_SET_FCN)
+_objlist_set_fcn_tc_config_qdiscs (NMSetting *setting,
+ gboolean do_add,
+ const char *value,
+ GError **error)
{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMTCQdisc *tc_qdisc;
- GError *local = NULL;
+ nm_auto_unref_tc_qdisc NMTCQdisc *tc_qdisc = NULL;
+ gs_free_error GError *local = NULL;
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- tc_qdisc = nm_utils_tc_qdisc_from_str (*iter, &local);
- if (!tc_qdisc) {
- g_set_error (error, 1, 0, "%s %s", local->message,
- _("The valid syntax is: '[root | parent <handle>] [handle <handle>] <qdisc>'"));
- return FALSE;
- }
- nm_setting_tc_config_add_qdisc (NM_SETTING_TC_CONFIG (setting), tc_qdisc);
- nm_tc_qdisc_unref (tc_qdisc);
+ tc_qdisc = nm_utils_tc_qdisc_from_str (value, &local);
+ if (!tc_qdisc) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ "%s %s",
+ local->message,
+ _("The valid syntax is: '[root | parent <handle>] [handle <handle>] <qdisc>'"));
+ return FALSE;
}
+ if (do_add)
+ nm_setting_tc_config_add_qdisc (NM_SETTING_TC_CONFIG (setting), tc_qdisc);
+ else
+ nm_setting_tc_config_remove_qdisc_by_value (NM_SETTING_TC_CONFIG (setting), tc_qdisc);
return TRUE;
}
-static gboolean
-_validate_and_remove_sriov_vf (NMSettingSriov *setting,
- const char *value,
- GError **error)
+static void
+_objlist_obj_to_str_fcn_tc_config_tfilters (NMMetaAccessorGetType get_type,
+ NMSetting *setting,
+ guint idx,
+ GString *str)
{
- NMSriovVF *vf;
- gboolean ret;
-
- vf = nm_utils_sriov_vf_from_str (value, error);
- if (!vf)
- return FALSE;
+ NMTCTfilter *tfilter;
+ gs_free char *s = NULL;
- ret = nm_setting_sriov_remove_vf_by_index (setting, nm_sriov_vf_get_index (vf));
- if (!ret) {
- g_set_error (error, 1, 0,
- _("the property doesn't contain vf with index %u"),
- nm_sriov_vf_get_index (vf));
- }
- nm_sriov_vf_unref (vf);
- return ret;
+ tfilter = nm_setting_tc_config_get_tfilter (NM_SETTING_TC_CONFIG (setting), idx);
+ s = nm_utils_tc_tfilter_to_str (tfilter, NULL);
+ if (s)
+ g_string_append (str, s);
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_sriov_vfs,
- NM_SETTING_SRIOV,
- nm_setting_sriov_get_num_vfs,
- nm_setting_sriov_remove_vf,
- _validate_and_remove_sriov_vf)
-
static gboolean
-_validate_and_remove_tc_qdisc (NMSettingTCConfig *setting,
- const char *value,
- GError **error)
+_objlist_set_fcn_tc_config_tfilters (NMSetting *setting,
+ gboolean do_add,
+ const char *value,
+ GError **error)
{
- NMTCQdisc *qdisc;
- gboolean ret;
+ gs_free_error GError *local = NULL;
+ nm_auto_unref_tc_tfilter NMTCTfilter *tc_tfilter = NULL;
- qdisc = nm_utils_tc_qdisc_from_str (value, error);
- if (!qdisc)
+ tc_tfilter = nm_utils_tc_tfilter_from_str (value, &local);
+ if (!tc_tfilter) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ "%s %s",
+ local->message,
+ _("The valid syntax is: '[root | parent <handle>] [handle <handle>] <tfilter>'"));
return FALSE;
-
- ret = nm_setting_tc_config_remove_qdisc_by_value (setting, qdisc);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain qdisc '%s'"), value);
- nm_tc_qdisc_unref (qdisc);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_tc_config_qdiscs,
- NM_SETTING_TC_CONFIG,
- nm_setting_tc_config_get_num_qdiscs,
- nm_setting_tc_config_remove_qdisc,
- _validate_and_remove_tc_qdisc)
-
-static gconstpointer
-_get_fcn_tc_config_tfilters (ARGS_GET_FCN)
-{
- NMSettingTCConfig *s_tc = NM_SETTING_TC_CONFIG (setting);
- GString *printable;
- guint num_tfilters, i;
- NMTCTfilter *tfilter;
- char *str;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- printable = g_string_new (NULL);
-
- num_tfilters = nm_setting_tc_config_get_num_tfilters (s_tc);
- for (i = 0; i < num_tfilters; i++) {
- tfilter = nm_setting_tc_config_get_tfilter (s_tc, i);
-
- if (printable->len > 0)
- g_string_append (printable, ", ");
-
- str = nm_utils_tc_tfilter_to_str (tfilter, NULL);
- if (str) {
- g_string_append (printable, str);
- g_free (str);
- }
}
-
- NM_SET_OUT (out_is_default, num_tfilters == 0);
- RETURN_STR_TO_FREE (g_string_free (printable, FALSE));
-}
-
-static gboolean
-_set_fcn_tc_config_tfilters (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMTCTfilter *tc_tfilter;
- GError *local = NULL;
-
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- tc_tfilter = nm_utils_tc_tfilter_from_str (*iter, &local);
- if (!tc_tfilter) {
- g_set_error (error, 1, 0, "%s %s", local->message,
- _("The valid syntax is: '[root | parent <handle>] [handle <handle>] <tfilter>'"));
- return FALSE;
- }
+ if (do_add)
nm_setting_tc_config_add_tfilter (NM_SETTING_TC_CONFIG (setting), tc_tfilter);
- nm_tc_tfilter_unref (tc_tfilter);
- }
+ else
+ nm_setting_tc_config_remove_tfilter_by_value (NM_SETTING_TC_CONFIG (setting), tc_tfilter);
return TRUE;
}
-static gboolean
-_validate_and_remove_tc_tfilter (NMSettingTCConfig *setting,
- const char *value,
- GError **error)
-{
- NMTCTfilter *tfilter;
- gboolean ret;
-
- tfilter = nm_utils_tc_tfilter_from_str (value, error);
- if (!tfilter)
- return FALSE;
-
- ret = nm_setting_tc_config_remove_tfilter_by_value (setting, tfilter);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain tfilter '%s'"), value);
- nm_tc_tfilter_unref (tfilter);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_tc_config_tfilters,
- NM_SETTING_TC_CONFIG,
- nm_setting_tc_config_get_num_tfilters,
- nm_setting_tc_config_remove_tfilter,
- _validate_and_remove_tc_tfilter)
-
static const char *
_validate_fcn_team_config (const char *value, char **out_to_free, GError **error)
{
@@ -4048,214 +3531,129 @@ _validate_fcn_team_config (const char *value, char **out_to_free, GError **error
RETURN_STR_TO_FREE (json);
}
-static gboolean
-_is_valid_team_runner_tx_hash_element (const char *tx_hash_element,
- GError **error)
-{
- nm_assert (!error || !*error);
-
- if (NM_IN_STRSET (tx_hash_element,
- "eth", "vlan", "ipv4", "ipv6", "ip",
- "l3", "tcp", "udp", "sctp", "l4")) {
- return TRUE;
- }
-
- g_set_error (error, 1, 0, "'%s' is not valid. %s", tx_hash_element,
- "Valid tx-hashes: [eth, vlan, ipv4, ipv6, ip, l3, tcp, udp, sctp, l4]");
- return FALSE;
-}
-
-static gboolean
-_set_fcn_team_runner_tx_hash (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
-
- nm_assert (!error || !*error);
-
- strv = nm_utils_strsplit_set (value, " \t,", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- if (!_is_valid_team_runner_tx_hash_element (*iter, error))
- return FALSE;
- }
-
+static void
+_multilist_clear_all_fcn_team_runner_tx_hash (NMSetting *setting)
+{
+ /* Workaround libnm bug (confirmed against version 1.16.0).
+ * We need to both clear the GObject property and call the libnm API.
+ *
+ * This workaround was added in nmcli as [1]. This needs fixing in libnm.
+ *
+ * Without this, CI test "team_abs_set_runner_tx_hash" fails.
+ * Try (without the following workaround): */
+#if 0
+ $ (nmcli connection delete team0 ; :); \
+ nmcli connection add type team con-name team0 ifname team0 autoconnect no \
+ team.runner lacp && \
+ echo ">>> FIRST:" && \
+ PAGER= nmcli -o connection show team0 && \
+ nmcli connection modify team0 team.runner-tx-hash l3 && \
+ echo ">>> AFTER:" && \
+ PAGER= nmcli -o connection show team0
+#endif
+ /* See also:
+ *
+ * - https://github.com/NetworkManager/NetworkManager/pull/318
+ * - https://bugzilla.redhat.com/show_bug.cgi?id=1691619
+ *
+ * [1] https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=350dbb55abf3a80267c398e6f64c2cee4645475a
+ */
+
+ /* it appears, we don't really need _gobject_property_reset(). Just to be sure
+ * also call it. */
+ _gobject_property_reset (setting, NM_SETTING_TEAM_RUNNER_TX_HASH, FALSE);
while (nm_setting_team_get_num_runner_tx_hash (NM_SETTING_TEAM (setting)))
nm_setting_team_remove_runner_tx_hash (NM_SETTING_TEAM (setting), 0);
-
- for (iter = strv; strv && *iter; iter++)
- nm_setting_team_add_runner_tx_hash (NM_SETTING_TEAM (setting), *iter);
-
- return TRUE;
}
-static gboolean
-_validate_and_remove_team_runner_tx_hash (NMSettingTeam *setting,
- const char *tx_hash,
- GError **error)
-{
- if (!nm_setting_team_remove_runner_tx_hash_by_value (setting, tx_hash)) {
- g_set_error (error, 1, 0,
- _("the property doesn't contain string '%s'"),
- tx_hash);
- return FALSE;
+static void
+_objlist_clear_all_fcn_team_link_watchers (NMSetting *setting)
+{
+ /* the same workaround as _multilist_clear_all_fcn_team_runner_tx_hash() above.
+ *
+ * Reproduce with: */
+#if 0
+ $ (nmcli connection delete team0 ; :); \
+ nmcli connection add type team con-name team0 ifname team0 autoconnect no \
+ team.link-watchers 'name=arp_ping source-host=172.16.1.1 target-host=172.16.1.254, name=ethtool delay-up=3' && \
+ echo ">>> FIRST:" && \
+ PAGER= nmcli -o connection show team0 && \
+ nmcli connection modify team0 team.link-watchers 'name=ethtool delay-up=4' && \
+ echo ">>> AFTER:" && \
+ PAGER= nmcli -o connection show team0
+
+ (nmcli connection delete team0-slave ; :); \
+ nmcli connection add type ethernet con-name team0-slave master team0 slave-type team ifname eth0 autoconnect no \
+ team-port.link-watchers 'name=arp_ping source-host=172.16.1.1 target-host=172.16.1.254, name=ethtool delay-up=3' && \
+ echo ">>> FIRST:" && \
+ PAGER= nmcli -o connection show team0-slave && \
+ nmcli connection modify team0-slave team.link-watchers 'name=ethtool delay-up=4' && \
+ echo ">>> AFTER:" && \
+ PAGER= nmcli -o connection show team0-slave
+#endif
+ /* See also:
+ *
+ * - https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=72bf38cad6ca6033d0117bf67b0e726001922d8f
+ * - https://github.com/NetworkManager/NetworkManager/pull/318
+ * - https://bugzilla.redhat.com/show_bug.cgi?id=1691619
+ */
+
+ /* In this case, it appears both GObject reset and nm_setting_team*_clear_link_watchers()
+ * work (on their own). So, we might not need the workaround.
+ * Just to be sure, as something is not right with libnm here. */
+ if (NM_IS_SETTING_TEAM (setting)) {
+ _gobject_property_reset (setting, NM_SETTING_TEAM_LINK_WATCHERS, FALSE);
+ nm_setting_team_clear_link_watchers (NM_SETTING_TEAM (setting));
+ } else {
+ _gobject_property_reset (setting, NM_SETTING_TEAM_PORT_LINK_WATCHERS, FALSE);
+ nm_setting_team_port_clear_link_watchers (NM_SETTING_TEAM_PORT (setting));
}
-
- return TRUE;
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_team_runner_tx_hash,
- NM_SETTING_TEAM,
- nm_setting_team_get_num_runner_tx_hash,
- nm_setting_team_remove_runner_tx_hash,
- _validate_and_remove_team_runner_tx_hash)
-static gconstpointer
-_get_fcn_team_link_watchers (ARGS_GET_FCN)
+static void
+_objlist_obj_to_str_fcn_team_link_watchers (NMMetaAccessorGetType get_type,
+ NMSetting *setting,
+ guint idx,
+ GString *str)
{
- NMSettingTeam *s_team = NM_SETTING_TEAM (setting);
- GString *printable;
- guint num_watchers, i;
NMTeamLinkWatcher *watcher;
- char *watcher_str;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- printable = g_string_new (NULL);
-
- num_watchers = nm_setting_team_get_num_link_watchers (s_team);
- for (i = 0; i < num_watchers; i++) {
- watcher = nm_setting_team_get_link_watcher (s_team, i);
- watcher_str = _dump_team_link_watcher (watcher);
- if (watcher_str) {
- if (printable->len > 0)
- g_string_append (printable, ", ");
- g_string_append (printable, watcher_str);
- g_free (watcher_str);
- }
- }
-
- NM_SET_OUT (out_is_default, num_watchers == 0);
- RETURN_STR_TO_FREE (g_string_free (printable, FALSE));
-}
+ gs_free char *s = NULL;
-static gboolean
-_set_fcn_team_link_watchers (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMTeamLinkWatcher *watcher;
+ if (NM_IS_SETTING_TEAM (setting))
+ watcher = nm_setting_team_get_link_watcher (NM_SETTING_TEAM (setting), idx);
+ else
+ watcher = nm_setting_team_port_get_link_watcher (NM_SETTING_TEAM_PORT (setting), idx);
- nm_setting_team_clear_link_watchers (NM_SETTING_TEAM (setting));
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- watcher = _parse_team_link_watcher (*iter, error);
- if (!watcher)
- return FALSE;
- nm_setting_team_add_link_watcher (NM_SETTING_TEAM (setting), watcher);
- nm_team_link_watcher_unref (watcher);
- }
- return TRUE;
+ s = _dump_team_link_watcher (watcher);
+ if (s)
+ g_string_append (str, s);
}
static gboolean
-_validate_and_remove_team_link_watcher (NMSettingTeam *setting,
- const char *watcher_str,
- GError **error)
+_objlist_set_fcn_team_link_watchers (NMSetting *setting,
+ gboolean do_add,
+ const char *value,
+ GError **error)
{
- NMTeamLinkWatcher *watcher;
- gboolean ret;
+ nm_auto_unref_team_link_watcher NMTeamLinkWatcher *watcher = NULL;
- watcher = _parse_team_link_watcher (watcher_str, error);
+ watcher = _parse_team_link_watcher (value, error);
if (!watcher)
return FALSE;
-
- ret = nm_setting_team_remove_link_watcher_by_value (setting, watcher);
- if (!ret) {
- g_set_error (error, 1, 0, _("the property doesn't contain link watcher '%s'"),
- watcher_str);
- }
- nm_team_link_watcher_unref (watcher);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_team_link_watchers,
- NM_SETTING_TEAM,
- nm_setting_team_get_num_link_watchers,
- nm_setting_team_remove_link_watcher,
- _validate_and_remove_team_link_watcher)
-
-static gconstpointer
-_get_fcn_team_port_link_watchers (ARGS_GET_FCN)
-{
- NMSettingTeamPort *s_team_port = NM_SETTING_TEAM_PORT (setting);
- GString *printable;
- guint num_watchers, i;
- NMTeamLinkWatcher *watcher;
- char *watcher_str;
-
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- printable = g_string_new (NULL);
-
- num_watchers = nm_setting_team_port_get_num_link_watchers (s_team_port);
- for (i = 0; i < num_watchers; i++) {
- watcher = nm_setting_team_port_get_link_watcher (s_team_port, i);
- watcher_str = _dump_team_link_watcher (watcher);
- if (watcher_str) {
- if (printable->len > 0)
- g_string_append (printable, ", ");
- g_string_append (printable, watcher_str);
- g_free (watcher_str);
- }
- }
-
- NM_SET_OUT (out_is_default, num_watchers == 0);
- RETURN_STR_TO_FREE (g_string_free (printable, FALSE));
-}
-
-static gboolean
-_set_fcn_team_port_link_watchers (ARGS_SET_FCN)
-{
- gs_free const char **strv = NULL;
- const char *const*iter;
- NMTeamLinkWatcher *watcher;
-
- nm_setting_team_port_clear_link_watchers (NM_SETTING_TEAM_PORT (setting));
- strv = nm_utils_strsplit_set (value, ",", FALSE);
- for (iter = strv; strv && *iter; iter++) {
- watcher = _parse_team_link_watcher (*iter, error);
- if (!watcher)
- return FALSE;
- nm_setting_team_port_add_link_watcher (NM_SETTING_TEAM_PORT (setting), watcher);
- nm_team_link_watcher_unref (watcher);
+ if (NM_IS_SETTING_TEAM (setting)) {
+ if (do_add)
+ nm_setting_team_add_link_watcher (NM_SETTING_TEAM (setting), watcher);
+ else
+ nm_setting_team_remove_link_watcher_by_value (NM_SETTING_TEAM (setting), watcher);
+ } else {
+ if (do_add)
+ nm_setting_team_port_add_link_watcher (NM_SETTING_TEAM_PORT (setting), watcher);
+ else
+ nm_setting_team_port_remove_link_watcher_by_value (NM_SETTING_TEAM_PORT (setting), watcher);
}
return TRUE;
}
-static gboolean
-_validate_and_remove_team_port_link_watcher (NMSettingTeamPort *setting,
- const char *watcher_str,
- GError **error)
-{
- NMTeamLinkWatcher *watcher;
- gboolean ret;
-
- watcher = _parse_team_link_watcher (watcher_str, error);
- if (!watcher)
- return FALSE;
-
- ret = nm_setting_team_port_remove_link_watcher_by_value (setting, watcher);
- if (!ret) {
- g_set_error (error, 1, 0, _("the property doesn't contain link watcher '%s'"),
- watcher_str);
- }
- nm_team_link_watcher_unref (watcher);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_team_port_link_watchers,
- NM_SETTING_TEAM_PORT,
- nm_setting_team_port_get_num_link_watchers,
- nm_setting_team_port_remove_link_watcher,
- _validate_and_remove_team_port_link_watcher)
-
static gconstpointer
_get_fcn_vlan_flags (ARGS_GET_FCN)
{
@@ -4269,142 +3667,75 @@ _get_fcn_vlan_flags (ARGS_GET_FCN)
RETURN_STR_TO_FREE (vlan_flags_to_string (flags, get_type));
}
-static gconstpointer
-_get_fcn_vlan_ingress_priority_map (ARGS_GET_FCN)
+static NMVlanPriorityMap
+_vlan_priority_map_type_from_property_info (const NMMetaPropertyInfo *property_info)
{
- NMSettingVlan *s_vlan = NM_SETTING_VLAN (setting);
- char *str;
+ nm_assert (property_info);
+ nm_assert (property_info->setting_info == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_VLAN]);
+ nm_assert (NM_IN_STRSET (property_info->property_name, NM_SETTING_VLAN_INGRESS_PRIORITY_MAP,
+ NM_SETTING_VLAN_EGRESS_PRIORITY_MAP));
- RETURN_UNSUPPORTED_GET_TYPE ();
-
- str = vlan_priorities_to_string (s_vlan, NM_VLAN_INGRESS_MAP);
- NM_SET_OUT (out_is_default, !str || !str[0]);
- RETURN_STR_TO_FREE (str);
+ return nm_streq (property_info->property_name, NM_SETTING_VLAN_INGRESS_PRIORITY_MAP)
+ ? NM_VLAN_INGRESS_MAP
+ : NM_VLAN_EGRESS_MAP;
}
static gconstpointer
-_get_fcn_vlan_egress_priority_map (ARGS_GET_FCN)
+_get_fcn_vlan_xgress_priority_map (ARGS_GET_FCN)
{
NMSettingVlan *s_vlan = NM_SETTING_VLAN (setting);
char *str;
RETURN_UNSUPPORTED_GET_TYPE ();
- str = vlan_priorities_to_string (s_vlan, NM_VLAN_EGRESS_MAP);
+ str = vlan_priorities_to_string (s_vlan, _vlan_priority_map_type_from_property_info (property_info));
NM_SET_OUT (out_is_default, !str || !str[0]);
RETURN_STR_TO_FREE (str);
}
static gboolean
-_set_vlan_xgress_priority_map (NMSetting *setting,
- const char *value,
- NMVlanPriorityMap map_type,
- GError **error)
-{
- char **prio_map, **p;
-
- prio_map = _parse_vlan_priority_maps (value, map_type, error);
- if (!prio_map)
- return FALSE;
-
- for (p = prio_map; p && *p; p++)
- nm_setting_vlan_add_priority_str (NM_SETTING_VLAN (setting), map_type, *p);
-
- g_strfreev (prio_map);
- return TRUE;
-}
-
-static gboolean
-_set_fcn_vlan_ingress_priority_map (ARGS_SET_FCN)
-{
- return _set_vlan_xgress_priority_map (setting, value, NM_VLAN_INGRESS_MAP, error);
-}
-
-static gboolean
-_set_fcn_vlan_egress_priority_map (ARGS_SET_FCN)
+_set_fcn_vlan_xgress_priority_map (ARGS_SET_FCN)
{
- return _set_vlan_xgress_priority_map (setting, value, NM_VLAN_EGRESS_MAP, error);
-}
+ NMVlanPriorityMap map_type = _vlan_priority_map_type_from_property_info (property_info);
+ gs_free const char **prio_map = NULL;
+ gsize i, len;
-static gboolean
-_remove_vlan_xgress_priority_map (const NMMetaEnvironment *environment,
- gpointer environment_user_data,
- NMSetting *setting,
- const NMMetaPropertyInfo *property_info,
- const char *value,
- guint32 idx,
- NMVlanPriorityMap map_type,
- GError **error)
-{
- guint32 num;
+ if (_SET_FCN_DO_RESET_DEFAULT_WITH_SUPPORTS_REMOVE (property_info, modifier, value)) {
+ nm_setting_vlan_clear_priorities (NM_SETTING_VLAN (setting), map_type);
+ return TRUE;
+ }
- /* If value != NULL, remove by value */
- if (value) {
- gboolean ret;
- char **prio_map;
- gs_free char *v = g_strdup (value);
+ prio_map = _value_strsplit (value, VALUE_STRSPLIT_MODE_STRIPPED, &len);
- prio_map = _parse_vlan_priority_maps (v, map_type, error);
- if (!prio_map)
+ for (i = 0; i < len; i++) {
+ if (!nm_utils_vlan_priority_map_parse_str (map_type,
+ prio_map[i],
+ _SET_FCN_DO_REMOVE (modifier, value),
+ NULL,
+ NULL,
+ NULL)) {
+ g_set_error (error, 1, 0, _("invalid priority map '%s'"), prio_map[i]);
return FALSE;
- if (prio_map[1]) {
- _env_warn_fcn (environment, environment_user_data,
- NM_META_ENV_WARN_LEVEL_WARN,
- N_("only one mapping at a time is supported; taking the first one (%s)"),
- prio_map[0]);
}
- ret = nm_setting_vlan_remove_priority_str_by_value (NM_SETTING_VLAN (setting),
- map_type,
- prio_map[0]);
-
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain mapping '%s'"), prio_map[0]);
- g_strfreev (prio_map);
- return ret;
}
- /* Else remove by index */
- num = nm_setting_vlan_get_num_priorities (NM_SETTING_VLAN (setting), map_type);
- if (num == 0) {
- g_set_error_literal (error, 1, 0, _("no priority to remove"));
- return FALSE;
- }
- if (idx >= num) {
- g_set_error (error, 1, 0, _("index '%d' is not in the range of <0-%d>"),
- idx, num - 1);
- return FALSE;
- }
+ if (_SET_FCN_DO_SET_ALL (modifier, value))
+ nm_setting_vlan_clear_priorities (NM_SETTING_VLAN (setting), map_type);
- nm_setting_vlan_remove_priority (NM_SETTING_VLAN (setting), map_type, idx);
+ for (i = 0; i < len; i++) {
+ if (_SET_FCN_DO_REMOVE (modifier, value)) {
+ nm_setting_vlan_remove_priority_str_by_value (NM_SETTING_VLAN (setting),
+ map_type,
+ prio_map[i]);
+ } else {
+ nm_setting_vlan_add_priority_str (NM_SETTING_VLAN (setting),
+ map_type,
+ prio_map[i]);
+ }
+ }
return TRUE;
}
-static gboolean
-_remove_fcn_vlan_ingress_priority_map (ARGS_REMOVE_FCN)
-{
- return _remove_vlan_xgress_priority_map (environment,
- environment_user_data,
- setting,
- property_info,
- value,
- idx,
- NM_VLAN_INGRESS_MAP,
- error);
-}
-
-static gboolean
-_remove_fcn_vlan_egress_priority_map (ARGS_REMOVE_FCN)
-{
- return _remove_vlan_xgress_priority_map (environment,
- environment_user_data,
- setting,
- property_info,
- value,
- idx,
- NM_VLAN_EGRESS_MAP,
- error);
-}
-
static gconstpointer
_get_fcn_vpn_data (ARGS_GET_FCN)
{
@@ -4433,65 +3764,31 @@ _get_fcn_vpn_secrets (ARGS_GET_FCN)
RETURN_STR_TO_FREE (g_string_free (secret_str, FALSE));
}
-static const char *
-_validate_vpn_hash_value (const char *option, const char *value, GError **error)
+static gboolean
+_optionlist_set_fcn_vpn_data (NMSetting *setting,
+ const char *option,
+ const char *value,
+ GError **error)
{
- /* nm_setting_vpn_add_data_item() and nm_setting_vpn_add_secret() does not
- * allow empty strings */
- if (!value || !*value) {
- g_set_error (error, 1, 0, _("'%s' cannot be empty"), option);
- return NULL;
- }
- return value;
+ if (value)
+ nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), option, value);
+ else
+ nm_setting_vpn_remove_data_item (NM_SETTING_VPN (setting), option);
+ return TRUE;
}
-DEFINE_SETTER_OPTIONS (_set_fcn_vpn_data,
- NM_SETTING_VPN,
- NMSettingVpn,
- nm_setting_vpn_add_data_item,
- NULL,
- _validate_vpn_hash_value)
-DEFINE_REMOVER_OPTION (_remove_fcn_vpn_data,
- NM_SETTING_VPN,
- nm_setting_vpn_remove_data_item)
-
-DEFINE_SETTER_OPTIONS (_set_fcn_vpn_secrets,
- NM_SETTING_VPN,
- NMSettingVpn,
- nm_setting_vpn_add_secret,
- NULL,
- _validate_vpn_hash_value)
-DEFINE_REMOVER_OPTION (_remove_fcn_vpn_secrets,
- NM_SETTING_VPN,
- nm_setting_vpn_remove_secret)
-
-DEFINE_SETTER_MAC_BLACKLIST (_set_fcn_wired_mac_address_blacklist,
- NM_SETTING_WIRED,
- nm_setting_wired_add_mac_blacklist_item)
-
static gboolean
-_validate_and_remove_wired_mac_blacklist_item (NMSettingWired *setting,
- const char *mac,
- GError **error)
+_optionlist_set_fcn_vpn_secrets (NMSetting *setting,
+ const char *option,
+ const char *value,
+ GError **error)
{
- gboolean ret;
- guint8 buf[32];
-
- if (!nm_utils_hwaddr_aton (mac, buf, ETH_ALEN)) {
- g_set_error (error, 1, 0, _("'%s' is not a valid MAC address"), mac);
- return FALSE;
- }
-
- ret = nm_setting_wired_remove_mac_blacklist_item_by_value (setting, mac);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain MAC address '%s'"), mac);
- return ret;
+ if (value)
+ nm_setting_vpn_add_secret (NM_SETTING_VPN (setting), option, value);
+ else
+ nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), option);
+ return TRUE;
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_wired_mac_address_blacklist,
- NM_SETTING_WIRED,
- nm_setting_wired_get_num_mac_blacklist_items,
- nm_setting_wired_remove_mac_blacklist_item,
- _validate_and_remove_wired_mac_blacklist_item)
static gboolean
_set_fcn_wired_s390_subchannels (ARGS_SET_FCN)
@@ -4499,6 +3796,9 @@ _set_fcn_wired_s390_subchannels (ARGS_SET_FCN)
gs_free const char **strv = NULL;
gsize len;
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
+
strv = nm_utils_strsplit_set (value, " ,\t", FALSE);
len = NM_PTRARRAY_LEN (strv);
if (len != 2 && len != 3) {
@@ -4511,28 +3811,21 @@ _set_fcn_wired_s390_subchannels (ARGS_SET_FCN)
return TRUE;
}
-static const char *
-_validate_s390_option_value (const char *option, const char *value, GError **error)
+static gboolean
+_optionlist_set_fcn_wired_s390_options (NMSetting *setting,
+ const char *name,
+ const char *value,
+ GError **error)
{
- /* nm_setting_wired_add_s390_option() requires value len in <1,199> interval */
- if (!value || !*value || strlen (value) >= 200) {
- g_set_error (error, 1, 0, _("'%s' string value should consist of 1 - 199 characters"), option);
- return NULL;
- }
- return value;
+ if (value)
+ nm_setting_wired_add_s390_option (NM_SETTING_WIRED (setting), name, value);
+ else
+ nm_setting_wired_remove_s390_option (NM_SETTING_WIRED (setting), name);
+ return TRUE;
}
-DEFINE_SETTER_OPTIONS (_set_fcn_wired_s390_options,
- NM_SETTING_WIRED,
- NMSettingWired,
- nm_setting_wired_add_s390_option,
- nm_setting_wired_get_valid_s390_options,
- _validate_s390_option_value)
-DEFINE_REMOVER_OPTION (_remove_fcn_wired_s390_options,
- NM_SETTING_WIRED,
- nm_setting_wired_remove_s390_option)
static const char *const*
-_values_fcn__wired_s390_options (ARGS_VALUES_FCN)
+_values_fcn_wired_s390_options (ARGS_VALUES_FCN)
{
return nm_setting_wired_get_valid_s390_options (NULL);
}
@@ -4579,7 +3872,8 @@ _set_fcn_wireless_channel (ARGS_SET_FCN)
{
unsigned long chan_int;
- nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+ return _gobject_property_reset_default (setting, property_info->property_name);
if (!nmc_string_to_uint (value, FALSE, 0, 0, &chan_int)) {
g_set_error (error, 1, 0, _("'%s' is not a valid channel"), value);
@@ -4596,33 +3890,21 @@ _set_fcn_wireless_channel (ARGS_SET_FCN)
return TRUE;
}
-DEFINE_SETTER_MAC_BLACKLIST (_set_fcn_wireless_mac_address_blacklist,
- NM_SETTING_WIRELESS,
- nm_setting_wireless_add_mac_blacklist_item)
-
-static gboolean
-_validate_and_remove_wifi_mac_blacklist_item (NMSettingWireless *setting,
- const char *mac,
- GError **error)
+static const char *
+_multilist_validate2_fcn_mac_addr (NMSetting *setting,
+ const char *item,
+ GError **error)
{
- gboolean ret;
- guint8 buf[32];
+ guint8 buf[ETH_ALEN];
- if (!nm_utils_hwaddr_aton (mac, buf, ETH_ALEN)) {
- g_set_error (error, 1, 0, _("'%s' is not a valid MAC address"), mac);
- return FALSE;
+ if (!nm_utils_hwaddr_aton (item, buf, ETH_ALEN)) {
+ nm_utils_error_set (error, NM_UTILS_ERROR_INVALID_ARGUMENT,
+ _("'%s' is not a valid MAC address"), item);
+ return NULL;
}
- ret = nm_setting_wireless_remove_mac_blacklist_item_by_value (setting, mac);
- if (!ret)
- g_set_error (error, 1, 0, _("the property doesn't contain MAC address '%s'"), mac);
- return ret;
+ return item;
}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_wireless_mac_address_blacklist,
- NM_SETTING_WIRELESS,
- nm_setting_wireless_get_num_mac_blacklist_items,
- nm_setting_wireless_remove_mac_blacklist_item,
- _validate_and_remove_wifi_mac_blacklist_item)
static gconstpointer
_get_fcn_wireless_security_wep_key (ARGS_GET_FCN)
@@ -4644,114 +3926,6 @@ _get_fcn_wireless_security_wep_key (ARGS_GET_FCN)
RETURN_STR_TO_FREE (key);
}
-static const char *wifi_sec_valid_protos[] = { "wpa", "rsn", NULL };
-
-DEFINE_SETTER_STR_LIST_MULTI (check_and_add_wifi_sec_proto,
- NM_SETTING_WIRELESS_SECURITY,
- nm_setting_wireless_security_add_proto)
-
-static gboolean
-_set_fcn_wireless_security_proto (ARGS_SET_FCN)
-{
- return check_and_add_wifi_sec_proto (setting, property_info->property_name, value, wifi_sec_valid_protos, error);
-}
-
-static gboolean
-_validate_and_remove_wifi_sec_proto (NMSettingWirelessSecurity *setting,
- const char *proto,
- GError **error)
-{
- gboolean ret;
- const char *valid;
-
- valid = nmc_string_is_valid (proto, wifi_sec_valid_protos, error);
- if (!valid)
- return FALSE;
-
- ret = nm_setting_wireless_security_remove_proto_by_value (setting, proto);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain protocol '%s'"), proto);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_wireless_security_proto,
- NM_SETTING_WIRELESS_SECURITY,
- nm_setting_wireless_security_get_num_protos,
- nm_setting_wireless_security_remove_proto,
- _validate_and_remove_wifi_sec_proto)
-
-static const char *wifi_sec_valid_pairwises[] = { "tkip", "ccmp", NULL };
-
-DEFINE_SETTER_STR_LIST_MULTI (check_and_add_wifi_sec_pairwise,
- NM_SETTING_WIRELESS_SECURITY,
- nm_setting_wireless_security_add_pairwise)
-
-static gboolean
-_set_fcn_wireless_security_pairwise (ARGS_SET_FCN)
-{
- return check_and_add_wifi_sec_pairwise (setting, property_info->property_name, value, wifi_sec_valid_pairwises, error);
-}
-
-static gboolean
-_validate_and_remove_wifi_sec_pairwise (NMSettingWirelessSecurity *setting,
- const char *pairwise,
- GError **error)
-{
- gboolean ret;
- const char *valid;
-
- valid = nmc_string_is_valid (pairwise, wifi_sec_valid_pairwises, error);
- if (!valid)
- return FALSE;
-
- ret = nm_setting_wireless_security_remove_pairwise_by_value (setting, pairwise);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain protocol '%s'"), pairwise);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_wireless_security_pairwise,
- NM_SETTING_WIRELESS_SECURITY,
- nm_setting_wireless_security_get_num_pairwise,
- nm_setting_wireless_security_remove_pairwise,
- _validate_and_remove_wifi_sec_pairwise)
-
-static const char *wifi_sec_valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL };
-
-DEFINE_SETTER_STR_LIST_MULTI (check_and_add_wifi_sec_group,
- NM_SETTING_WIRELESS_SECURITY,
- nm_setting_wireless_security_add_group)
-
-static gboolean
-_set_fcn_wireless_security_group (ARGS_SET_FCN)
-{
- return check_and_add_wifi_sec_group (setting, property_info->property_name, value, wifi_sec_valid_groups, error);
-}
-
-static gboolean
-_validate_and_remove_wifi_sec_group (NMSettingWirelessSecurity *setting,
- const char *group,
- GError **error)
-{
- gboolean ret;
- const char *valid;
-
- valid = nmc_string_is_valid (group, wifi_sec_valid_groups, error);
- if (!valid)
- return FALSE;
-
- ret = nm_setting_wireless_security_remove_group_by_value (setting, group);
- if (!ret)
- g_set_error (error, 1, 0,
- _("the property doesn't contain protocol '%s'"), group);
- return ret;
-}
-DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_wireless_security_group,
- NM_SETTING_WIRELESS_SECURITY,
- nm_setting_wireless_security_get_num_groups,
- nm_setting_wireless_security_remove_group,
- _validate_and_remove_wifi_sec_group)
-
static gboolean
_set_fcn_wireless_wep_key (ARGS_SET_FCN)
{
@@ -4761,6 +3935,11 @@ _set_fcn_wireless_wep_key (ARGS_SET_FCN)
nm_assert (!error || !*error);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) {
+ g_object_set (setting, property_info->property_name, NULL, NULL);
+ return TRUE;
+ }
+
/* Get currently set type */
type = nm_setting_wireless_security_get_wep_key_type (NM_SETTING_WIRELESS_SECURITY (setting));
@@ -4872,11 +4051,16 @@ _get_fcn_ethtool (ARGS_GET_FCN)
static gboolean
_set_fcn_ethtool (ARGS_SET_FCN)
{
- gs_free char *value_clone = NULL;
+ gs_free char *value_to_free = NULL;
NMTernary val;
NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
- value = nm_strstrip_avoid_copy (value, &value_clone);
+ if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) {
+ val = NM_TERNARY_DEFAULT;
+ goto set;
+ }
+
+ value = nm_strstrip_avoid_copy (value, &value_to_free);
if (NM_IN_STRSET (value, "1", "yes", "true", "on"))
val = NM_TERNARY_TRUE;
@@ -4891,6 +4075,7 @@ _set_fcn_ethtool (ARGS_SET_FCN)
return FALSE;
}
+set:
nm_setting_ethtool_set_feature (NM_SETTING_ETHTOOL (setting),
nm_ethtool_data[ethtool_id]->optname,
val);
@@ -5082,12 +4267,58 @@ static const NMMetaPropertyType _pt_gobject_devices = {
.complete_fcn = _complete_fcn_gobject_devices,
};
+static const NMMetaPropertyType _pt_dcb_flags = {
+ .get_fcn = _get_fcn_dcb_flags,
+ .set_fcn = _set_fcn_dcb_flags,
+};
+
+static const NMMetaPropertyType _pt_dcb_bool = {
+ .get_fcn = _get_fcn_dcb_bool,
+ .set_fcn = _set_fcn_dcb_bool,
+};
+
+static const NMMetaPropertyType _pt_dcb = {
+ .get_fcn = _get_fcn_dcb,
+ .set_fcn = _set_fcn_dcb,
+};
+
+static const NMMetaPropertyType _pt_cert_8021x = {
+ .get_fcn = _get_fcn_cert_8021x,
+ .set_fcn = _set_fcn_cert_8021x,
+};
+
static const NMMetaPropertyType _pt_ethtool = {
.get_fcn = _get_fcn_ethtool,
.set_fcn = _set_fcn_ethtool,
.complete_fcn = _complete_fcn_ethtool,
};
+static const NMMetaPropertyType _pt_multilist = {
+ .get_fcn = _get_fcn_gobject,
+ .set_fcn = _set_fcn_multilist,
+ .set_supports_remove = TRUE,
+};
+
+static const NMMetaPropertyType _pt_objlist = {
+ .get_fcn = _get_fcn_objlist,
+ .set_fcn = _set_fcn_objlist,
+ .set_supports_remove = TRUE,
+};
+
+#define MULTILIST_GET_NUM_FCN_U32(type, func) (((func) == ((guint32 (*) (type * )) (func))) ? ((guint32 (*) (NMSetting * )) (func)) : NULL)
+#define MULTILIST_GET_NUM_FCN_U(type, func) (((func) == ((guint (*) (type * )) (func))) ? ((guint (*) (NMSetting * )) (func)) : NULL)
+#define MULTILIST_ADD_FCN(type, func) (((func) == ((gboolean (*) (type *, const char *)) (func))) ? ((gboolean (*) (NMSetting *, const char *)) (func)) : NULL)
+#define MULTILIST_ADD2_FCN(type, func) (((func) == ((void (*) (type *, const char *)) (func))) ? ((void (*) (NMSetting *, const char *)) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_IDX_FCN_U32(type, func) (((func) == ((void (*) (type *, guint32 )) (func))) ? ((void (*) (NMSetting *, guint32 )) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_IDX_FCN_S(type, func) (((func) == ((void (*) (type *, int )) (func))) ? ((void (*) (NMSetting *, int )) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_IDX_FCN_U(type, func) (((func) == ((void (*) (type *, guint )) (func))) ? ((void (*) (NMSetting *, guint )) (func)) : NULL)
+#define MULTILIST_REMOVE_BY_VALUE_FCN(type, func) (((func) == ((gboolean (*) (type *, const char *)) (func))) ? ((gboolean (*) (NMSetting *, const char *)) (func)) : NULL)
+
+#define OBJLIST_GET_NUM_FCN(type, func) (((func) == ((guint (*) (type * )) (func))) ? ((guint (*) (NMSetting * )) (func)) : NULL)
+#define OBJLIST_CLEAR_ALL_FCN(type, func) (((func) == ((void (*) (type * )) (func))) ? ((void (*) (NMSetting * )) (func)) : NULL)
+#define OBJLIST_REMOVE_BY_IDX_FCN_U(type, func) (((func) == ((void (*) (type *, guint )) (func))) ? ((void (*) (NMSetting *, guint )) (func)) : NULL)
+#define OBJLIST_REMOVE_BY_IDX_FCN_S(type, func) (((func) == ((void (*) (type *, int )) (func))) ? ((void (*) (NMSetting *, int )) (func)) : NULL)
+
/*****************************************************************************/
#include "settings-docs.h"
@@ -5112,11 +4343,6 @@ static const NMMetaPropertyType _pt_ethtool = {
#define ENUM_VALUE_INFOS(...) (((const NMUtilsEnumValueInfo []) { __VA_ARGS__ { .nick = NULL, }, }))
#define INT_VALUE_INFOS(...) (((const NMMetaUtilsIntValueInfo []) { __VA_ARGS__ { .nick = NULL, }, }))
-#define GET_FCN_WITH_DEFAULT(type, func) \
- /* macro that returns @func as const (gboolean(*)(NMSetting*)) type, but checks
- * that the actual type is (gboolean(*)(type *)). */ \
- ((gboolean (*) (NMSetting *)) ((sizeof (func == ((gboolean (*) (type *)) func))) ? func : func) )
-
#define MTU_GET_FCN(type, func) \
/* macro that returns @func as const (guint32(*)(NMSetting*)) type, but checks
* that the actual type is (guint32(*)(type *)). */ \
@@ -5174,12 +4400,14 @@ static const NMMetaPropertyInfo *const property_infos_6LOWPAN[] = {
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_802_1X
static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_EAP,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_802_1x_eap,
- .remove_fcn = _remove_fcn_802_1x_eap,
- ),
+ .property_type = &_pt_multilist,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSetting8021x, nm_setting_802_1x_get_num_eap_methods),
+ .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_eap_method),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_eap_method),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_eap_method_by_value),
+ ),
.values_static = NM_MAKE_STRV ("leap", "md5", "tls", "peap", "ttls", "sim", "fast", "pwd"),
),
),
@@ -5198,9 +4426,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
" [file://]<file path>\n"
"Note that nmcli does not support specifying certificates as raw blob data.\n"
"Example: /home/cimrman/cacert.crt\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_802_1x_ca_cert,
- .set_fcn = _set_fcn_802_1x_ca_cert,
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_CA_CERT,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CA_CERT_PASSWORD,
@@ -5217,10 +4445,14 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_ALTSUBJECT_MATCHES,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_802_1x_altsubject_matches,
- .remove_fcn = _remove_fcn_802_1x_altsubject_matches,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSetting8021x, nm_setting_802_1x_get_num_altsubject_matches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_altsubject_match),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_altsubject_match),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_altsubject_match_by_value),
+ ),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH,
@@ -5232,9 +4464,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
" [file://]<file path>\n"
"Note that nmcli does not support specifying certificates as raw blob data.\n"
"Example: /home/cimrman/jara.crt\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_802_1x_client_cert,
- .set_fcn = _set_fcn_802_1x_client_cert,
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_CLIENT_CERT,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CLIENT_CERT_PASSWORD,
@@ -5290,9 +4522,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
" [file://]<file path>\n"
"Note that nmcli does not support specifying certificates as raw blob data.\n"
"Example: /home/cimrman/ca-zweite-phase.crt\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_802_1x_phase2_ca_cert,
- .set_fcn = _set_fcn_802_1x_phase2_ca_cert,
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CA_CERT,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD,
@@ -5309,10 +4541,14 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_802_1x_phase2_altsubject_matches,
- .remove_fcn = _remove_fcn_802_1x_phase2_altsubject_matches,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSetting8021x, nm_setting_802_1x_get_num_phase2_altsubject_matches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSetting8021x, nm_setting_802_1x_add_phase2_altsubject_match),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSetting8021x, nm_setting_802_1x_remove_phase2_altsubject_match),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSetting8021x, nm_setting_802_1x_remove_phase2_altsubject_match_by_value),
+ ),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH,
@@ -5325,9 +4561,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
" [file://]<file path>\n"
"Note that nmcli does not support specifying certificates as raw blob data.\n"
"Example: /home/cimrman/jara-zweite-phase.crt\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_802_1x_phase2_client_cert,
- .set_fcn = _set_fcn_802_1x_phase2_client_cert,
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_CLIENT_CERT,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD,
@@ -5368,9 +4604,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
" [file://]<file path> [<password>]\n"
"Note that nmcli does not support specifying private key as raw blob data.\n"
"Example: /home/cimrman/jara-priv-key Dardanely\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_802_1x_private_key,
- .set_fcn = _set_fcn_802_1x_private_key,
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PRIVATE_KEY,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
@@ -5386,9 +4622,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
" [file://]<file path> [<password>]\n"
"Note that nmcli does not support specifying private key as raw blob data.\n"
"Example: /home/cimrman/jara-priv-key Dardanely\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_802_1x_phase2_private_key,
- .set_fcn = _set_fcn_802_1x_phase2_private_key,
+ .property_type = &_pt_cert_8021x,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (cert_8021x,
+ .scheme_type = NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD,
@@ -5498,11 +4734,14 @@ static const NMMetaPropertyInfo property_info_BOND_OPTIONS =
.property_type = DEFINE_PROPERTY_TYPE (
.describe_fcn = _describe_fcn_bond_options,
.get_fcn = _get_fcn_bond_options,
- .set_fcn = _set_fcn_bond_options,
- .remove_fcn = _remove_fcn_bond_options,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
.values_fcn = _values_fcn_bond_options,
),
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _optionlist_set_fcn_bond_options,
+ ),
.nested = &nm_meta_property_typ_data_bond,
),
);
@@ -5714,8 +4953,17 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
"Example: alice bob charlie\n"),
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_connection_permissions,
- .set_fcn = _set_fcn_connection_permissions,
- .remove_fcn = _remove_fcn_connection_permissions,
+ .set_fcn = _set_fcn_multilist,
+ .set_supports_remove = TRUE,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingConnection, nm_setting_connection_get_num_permissions),
+ .add_fcn = _multilist_set_fcn_connection_permissions,
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingConnection, nm_setting_connection_remove_permission),
+ .remove_by_value_fcn = _multilist_remove_by_value_fcn_connection_permissions,
+ .validate2_fcn = _multilist_validate2_fcn_connection_permissions,
+ ),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_ZONE,
@@ -5756,10 +5004,15 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
"VPNs as secondary connections at the moment.\n"
"The items can be separated by commas or spaces.\n\n"
"Example: private-openvpn, fe6ba5d8-c2fc-4aae-b2e3-97efddd8d9a7\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_connection_secondaries,
- .remove_fcn = _remove_fcn_connection_secondaries,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingConnection, nm_setting_connection_get_num_secondaries),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingConnection, nm_setting_connection_add_secondary),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingConnection, nm_setting_connection_remove_secondary),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingConnection, nm_setting_connection_remove_secondary_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_uuid,
+ ),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT,
@@ -5819,10 +5072,7 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_DCB
static const NMMetaPropertyInfo *const property_infos_DCB[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FCOE_FLAGS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_app_fcoe_flags,
- .set_fcn = _set_fcn_dcb_flags,
- ),
+ .property_type = &_pt_dcb_flags,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FCOE_PRIORITY,
DEFINE_DCB_PROPRITY_PROPERTY_TYPE
@@ -5835,69 +5085,73 @@ static const NMMetaPropertyInfo *const property_infos_DCB[] = {
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_ISCSI_FLAGS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_app_iscsi_flags,
- .set_fcn = _set_fcn_dcb_flags,
- ),
+ .property_type = &_pt_dcb_flags,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_ISCSI_PRIORITY,
DEFINE_DCB_PROPRITY_PROPERTY_TYPE
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FIP_FLAGS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_app_fip_flags,
- .set_fcn = _set_fcn_dcb_flags,
- ),
+ .property_type = &_pt_dcb_flags,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_APP_FIP_PRIORITY,
DEFINE_DCB_PROPRITY_PROPERTY_TYPE
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_flow_control_flags,
- .set_fcn = _set_fcn_dcb_flags,
- ),
+ .property_type = &_pt_dcb_flags,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_flow_control,
- .set_fcn = _set_fcn_dcb_priority_flow_control,
+ .property_type = &_pt_dcb_bool,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb_bool,
+ .get_fcn = nm_setting_dcb_get_priority_flow_control,
+ .set_fcn = nm_setting_dcb_set_priority_flow_control,
+ .with_flow_control_flags = TRUE,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_group_flags,
- .set_fcn = _set_fcn_dcb_flags,
- ),
+ .property_type = &_pt_dcb_flags,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_GROUP_ID,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_group_id,
- .set_fcn = _set_fcn_dcb_priority_group_id,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_group_id,
+ .set_fcn = nm_setting_dcb_set_priority_group_id,
+ .max = 7,
+ .other = 15,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_group_bandwidth,
- .set_fcn = _set_fcn_dcb_priority_group_bandwidth,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_group_bandwidth,
+ .set_fcn = nm_setting_dcb_set_priority_group_bandwidth,
+ .max = 100,
+ .other = 0,
+ .is_percent = TRUE,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_BANDWIDTH,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_bandwidth,
- .set_fcn = _set_fcn_dcb_priority_bandwidth,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_bandwidth,
+ .set_fcn = nm_setting_dcb_set_priority_bandwidth,
+ .max = 100,
+ .other = 0,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_strict,
- .set_fcn = _set_fcn_dcb_priority_strict,
+ .property_type = &_pt_dcb_bool,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb_bool,
+ .get_fcn = nm_setting_dcb_get_priority_strict_bandwidth,
+ .set_fcn = nm_setting_dcb_set_priority_strict_bandwidth,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_dcb_priority_traffic_class,
- .set_fcn = _set_fcn_dcb_priority_traffic_class,
+ .property_type = &_pt_dcb,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (dcb,
+ .get_fcn = nm_setting_dcb_get_priority_traffic_class,
+ .set_fcn = nm_setting_dcb_set_priority_traffic_class,
+ .max = 7,
+ .other = 0,
),
),
NULL
@@ -6090,37 +5344,53 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = {
PROPERTY_INFO (NM_SETTING_IP_CONFIG_METHOD, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_METHOD,
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip4_config_method,
+ .set_fcn = _set_fcn_ip_config_method,
),
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
- .values_static = ipv4_valid_methods,
+ .values_static = NM_MAKE_STRV (NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
+ NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP4_CONFIG_METHOD_SHARED,
+ NM_SETTING_IP4_CONFIG_METHOD_DISABLED),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS,
.describe_message =
N_("Enter a list of IPv4 addresses of DNS servers.\n\n"
"Example: 8.8.8.8, 8.8.4.4\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip4_config_dns,
- .remove_fcn = _remove_fcn_ipv4_config_dns,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_ip_config_dns,
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_SEARCH, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip_config_dns_search,
- .remove_fcn = _remove_fcn_ip_config_dns_search,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_searches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns_search),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search_by_value),
+ .validate_fcn = _multilist_validate_fcn_is_domain,
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_OPTIONS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_nmc_with_default,
- .set_fcn = _set_fcn_ip_config_dns_options,
- .remove_fcn = _remove_fcn_ip_config_dns_options,
- ),
- .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (get_with_default,
- .fcn = GET_FCN_WITH_DEFAULT (NMSettingIPConfig, _dns_options_is_default),
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_options),
+ .add_fcn = _multilist_add_fcn_ip_config_dns_options,
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value),
+ ),
+ .is_default_fcn = _is_default_func_ip_config_dns_options,
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_PRIORITY, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY,
@@ -6136,10 +5406,15 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = {
" ip[/prefix], ip[/prefix],...\n"
"Missing prefix is regarded as prefix of 32.\n\n"
"Example: 192.168.1.5/24, 10.0.0.11/24\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_ip_config_addresses,
- .set_fcn = _set_fcn_ip4_config_addresses,
- .remove_fcn = _remove_fcn_ipv4_config_addresses,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_addresses),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_addresses),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_addresses,
+ .set_fcn = _objlist_set_fcn_ip_config_addresses,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_address),
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_GATEWAY, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY,
@@ -6148,7 +5423,7 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = {
.prompt = N_("IPv4 gateway [none]"),
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip4_config_gateway,
+ .set_fcn = _set_fcn_ip_config_gateway,
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTES, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTES,
@@ -6160,10 +5435,16 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = {
"Missing metric means default (NM/kernel will set a default value).\n\n"
"Examples: 192.168.2.0/24 192.168.2.1 3, 10.1.0.0/16 10.0.0.254\n"
" 10.1.2.0/24\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_ip_config_routes,
- .set_fcn = _set_fcn_ip4_config_routes,
- .remove_fcn = _remove_fcn_ipv4_config_routes,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_routes),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_routes),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routes,
+ .set_fcn = _objlist_set_fcn_ip_config_routes,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_route),
+ .delimit_pretty_with_semicolon = TRUE,
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTE_METRIC, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_METRIC,
@@ -6247,10 +5528,15 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = {
PROPERTY_INFO (NM_SETTING_IP_CONFIG_METHOD, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_METHOD,
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip6_config_method,
+ .set_fcn = _set_fcn_ip_config_method,
),
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
- .values_static = ipv6_valid_methods,
+ .values_static = NM_MAKE_STRV (NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+ NM_SETTING_IP6_CONFIG_METHOD_DHCP,
+ NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
+ NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP6_CONFIG_METHOD_SHARED),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS,
@@ -6263,27 +5549,39 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = {
"all other IPv6 configuration methods, these DNS "
"servers are used as the only DNS servers for this connection.\n\n"
"Example: 2607:f0d0:1002:51::4, 2607:f0d0:1002:51::1\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip6_config_dns,
- .remove_fcn = _remove_fcn_ipv6_config_dns,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_ip_config_dns,
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_SEARCH, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip_config_dns_search,
- .remove_fcn = _remove_fcn_ip_config_dns_search,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_searches),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingIPConfig, nm_setting_ip_config_add_dns_search),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_search_by_value),
+ .validate_fcn = _multilist_validate_fcn_is_domain,
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_OPTIONS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_nmc_with_default,
- .set_fcn = _set_fcn_ip_config_dns_options,
- .remove_fcn = _remove_fcn_ip_config_dns_options,
- ),
- .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (get_with_default,
- .fcn = GET_FCN_WITH_DEFAULT (NMSettingIPConfig, _dns_options_is_default),
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingIPConfig, nm_setting_ip_config_get_num_dns_options),
+ .add_fcn = _multilist_add_fcn_ip_config_dns_options,
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingIPConfig, nm_setting_ip_config_remove_dns_option_by_value),
+ ),
+ .is_default_fcn = _is_default_func_ip_config_dns_options,
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_DNS_PRIORITY, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY,
@@ -6299,10 +5597,15 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = {
" ip[/prefix], ip[/prefix],...\n"
"Missing prefix is regarded as prefix of 128.\n\n"
"Example: 2607:f0d0:1002:51::4/64, 1050:0:0:0:5:600:300c:326b\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_ip_config_addresses,
- .set_fcn = _set_fcn_ip6_config_addresses,
- .remove_fcn = _remove_fcn_ipv6_config_addresses,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_addresses),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_addresses),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_addresses,
+ .set_fcn = _objlist_set_fcn_ip_config_addresses,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_address),
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_GATEWAY, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY,
@@ -6311,7 +5614,7 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = {
.prompt = N_("IPv6 gateway [none]"),
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_ip6_config_gateway,
+ .set_fcn = _set_fcn_ip_config_gateway,
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTES, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTES,
@@ -6323,10 +5626,16 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = {
"Missing metric means default (NM/kernel will set a default value).\n\n"
"Examples: 2001:db8:beef:2::/64 2001:db8:beef::2, 2001:db8:beef:3::/64 2001:db8:beef::3 2\n"
" abbe::/64 55\n"),
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_ip_config_routes,
- .set_fcn = _set_fcn_ip6_config_routes,
- .remove_fcn = _remove_fcn_ipv6_config_routes,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingIPConfig, nm_setting_ip_config_get_num_routes),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingIPConfig, nm_setting_ip_config_clear_routes),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_ip_config_routes,
+ .set_fcn = _objlist_set_fcn_ip_config_routes,
+ .remove_by_idx_fcn_s = OBJLIST_REMOVE_BY_IDX_FCN_S (NMSettingIPConfig, nm_setting_ip_config_remove_route),
+ .delimit_pretty_with_semicolon = TRUE,
+ ),
),
),
PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTE_METRIC, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_METRIC,
@@ -6581,8 +5890,17 @@ static const NMMetaPropertyInfo *const property_infos_MATCH[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_INTERFACE_NAME,
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_match_interface_name,
- .set_fcn = _set_fcn_match_interface_name,
- .remove_fcn = _remove_fcn_match_interface_name,
+ .set_fcn = _set_fcn_multilist,
+ .set_supports_remove = TRUE,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingMatch, nm_setting_match_get_num_interface_names),
+ .add2_fcn = MULTILIST_ADD2_FCN (NMSettingMatch, nm_setting_match_add_interface_name),
+ .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (NMSettingMatch, nm_setting_match_remove_interface_name),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_interface_name_by_value),
+ .with_escaped_spaces = TRUE,
+ ),
),
),
NULL
@@ -6893,10 +6211,14 @@ static const NMMetaPropertyInfo *const property_infos_SRIOV[] = {
.property_type = &_pt_gobject_int,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_SRIOV_VFS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_sriov_vfs,
- .set_fcn = _set_fcn_sriov_vfs,
- .remove_fcn = _remove_fcn_sriov_vfs,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingSriov, nm_setting_sriov_get_num_vfs),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingSriov, nm_setting_sriov_clear_vfs),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_sriov_vfs,
+ .set_fcn = _objlist_set_fcn_sriov_vfs,
+ ),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_SRIOV_AUTOPROBE_DRIVERS,
@@ -6909,17 +6231,27 @@ static const NMMetaPropertyInfo *const property_infos_SRIOV[] = {
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_TC_CONFIG
static const NMMetaPropertyInfo *const property_infos_TC_CONFIG[] = {
PROPERTY_INFO (NM_SETTING_TC_CONFIG_QDISCS, DESCRIBE_DOC_NM_SETTING_TC_CONFIG_QDISCS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_tc_config_qdiscs,
- .set_fcn = _set_fcn_tc_config_qdiscs,
- .remove_fcn = _remove_fcn_tc_config_qdiscs,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTCConfig, nm_setting_tc_config_get_num_qdiscs),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingTCConfig, nm_setting_tc_config_clear_qdiscs),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_tc_config_qdiscs,
+ .set_fcn = _objlist_set_fcn_tc_config_qdiscs,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTCConfig, nm_setting_tc_config_remove_qdisc),
+ ),
),
),
PROPERTY_INFO (NM_SETTING_TC_CONFIG_TFILTERS, DESCRIBE_DOC_NM_SETTING_TC_CONFIG_TFILTERS,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_tc_config_tfilters,
- .set_fcn = _set_fcn_tc_config_tfilters,
- .remove_fcn = _remove_fcn_tc_config_tfilters,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTCConfig, nm_setting_tc_config_get_num_tfilters),
+ .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingTCConfig, nm_setting_tc_config_clear_tfilters),
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_tc_config_tfilters,
+ .set_fcn = _objlist_set_fcn_tc_config_tfilters,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTCConfig, nm_setting_tc_config_remove_tfilter),
+ ),
),
),
NULL
@@ -7002,10 +6334,17 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_HASH,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_team_runner_tx_hash,
- .remove_fcn = _remove_fcn_team_runner_tx_hash,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u = MULTILIST_GET_NUM_FCN_U (NMSettingTeam, nm_setting_team_get_num_runner_tx_hash),
+ .clear_all_fcn = _multilist_clear_all_fcn_team_runner_tx_hash,
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingTeam, nm_setting_team_add_runner_tx_hash),
+ .remove_by_idx_fcn_u = MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingTeam, nm_setting_team_remove_runner_tx_hash),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingTeam, nm_setting_team_remove_runner_tx_hash_by_value),
+ ),
+ .values_static = NM_MAKE_STRV ("eth", "vlan", "ipv4", "ipv6", "ip",
+ "l3", "tcp", "udp", "sctp", "l4"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER,
@@ -7065,10 +6404,15 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_LINK_WATCHERS,
.describe_message = TEAM_LINK_WATCHERS_DESCRIBE_MESSAGE,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_team_link_watchers,
- .set_fcn = _set_fcn_team_link_watchers,
- .remove_fcn = _remove_fcn_team_link_watchers,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTeam, nm_setting_team_get_num_link_watchers),
+ .clear_all_fcn = _objlist_clear_all_fcn_team_link_watchers,
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers,
+ .set_fcn = _objlist_set_fcn_team_link_watchers,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeam, nm_setting_team_remove_link_watcher),
+ ),
),
),
NULL
@@ -7136,10 +6480,15 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LINK_WATCHERS,
.describe_message = TEAM_LINK_WATCHERS_DESCRIBE_MESSAGE,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_team_port_link_watchers,
- .set_fcn = _set_fcn_team_port_link_watchers,
- .remove_fcn = _remove_fcn_team_port_link_watchers,
+ .property_type = &_pt_objlist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (objlist,
+ .get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingTeamPort, nm_setting_team_port_get_num_link_watchers),
+ .clear_all_fcn = _objlist_clear_all_fcn_team_link_watchers,
+ .obj_to_str_fcn = _objlist_obj_to_str_fcn_team_link_watchers,
+ .set_fcn = _objlist_set_fcn_team_link_watchers,
+ .remove_by_idx_fcn_u = OBJLIST_REMOVE_BY_IDX_FCN_U (NMSettingTeamPort, nm_setting_team_port_remove_link_watcher),
+ ),
),
),
NULL
@@ -7224,9 +6573,9 @@ static const NMMetaPropertyInfo *const property_infos_VLAN[] = {
.property_alias = "ingress",
.prompt = N_("Ingress priority maps [none]"),
.property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_vlan_ingress_priority_map,
- .set_fcn = _set_fcn_vlan_ingress_priority_map,
- .remove_fcn = _remove_fcn_vlan_ingress_priority_map,
+ .get_fcn = _get_fcn_vlan_xgress_priority_map,
+ .set_fcn = _set_fcn_vlan_xgress_priority_map,
+ .set_supports_remove = TRUE,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_EGRESS_PRIORITY_MAP,
@@ -7234,9 +6583,9 @@ static const NMMetaPropertyInfo *const property_infos_VLAN[] = {
.property_alias = "egress",
.prompt = N_("Egress priority maps [none]"),
.property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_vlan_egress_priority_map,
- .set_fcn = _set_fcn_vlan_egress_priority_map,
- .remove_fcn = _remove_fcn_vlan_egress_priority_map,
+ .get_fcn = _get_fcn_vlan_xgress_priority_map,
+ .set_fcn = _set_fcn_vlan_xgress_priority_map,
+ .set_supports_remove = TRUE,
),
),
NULL
@@ -7266,16 +6615,24 @@ static const NMMetaPropertyInfo *const property_infos_VPN[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_DATA,
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_vpn_data,
- .set_fcn = _set_fcn_vpn_data,
- .remove_fcn = _remove_fcn_vpn_data,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _optionlist_set_fcn_vpn_data,
+ .no_empty_value = TRUE,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_SECRETS,
.is_secret = TRUE,
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_vpn_secrets,
- .set_fcn = _set_fcn_vpn_secrets,
- .remove_fcn = _remove_fcn_vpn_secrets,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _optionlist_set_fcn_vpn_secrets,
+ .no_empty_value = TRUE,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_PERSISTENT,
@@ -7448,10 +6805,15 @@ static const NMMetaPropertyInfo *const property_infos_WIRED[] = {
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_wired_mac_address_blacklist,
- .remove_fcn = _remove_fcn_wired_mac_address_blacklist,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWired, nm_setting_wired_get_num_mac_blacklist_items),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWired, nm_setting_wired_add_mac_blacklist_item),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWired, nm_setting_wired_remove_mac_blacklist_item),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWired, nm_setting_wired_remove_mac_blacklist_item_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_mac_addr,
+ ),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_MTU,
@@ -7482,9 +6844,13 @@ static const NMMetaPropertyInfo *const property_infos_WIRED[] = {
.property_type = DEFINE_PROPERTY_TYPE (
.describe_fcn = _describe_fcn_wired_s390_options,
.get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_wired_s390_options,
- .remove_fcn = _remove_fcn_wired_s390_options,
- .values_fcn = _values_fcn__wired_s390_options,
+ .set_fcn = _set_fcn_optionlist,
+ .set_supports_remove = TRUE,
+ .values_fcn = _values_fcn_wired_s390_options,
+ ),
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist,
+ .set_fcn = _optionlist_set_fcn_wired_s390_options,
+ .no_empty_value = TRUE,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRED_WAKE_ON_LAN,
@@ -7612,10 +6978,15 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS[] = {
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_wireless_mac_address_blacklist,
- .remove_fcn = _remove_fcn_wireless_mac_address_blacklist,
+ .property_type = &_pt_multilist,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWireless, nm_setting_wireless_get_num_mac_blacklist_items),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWireless, nm_setting_wireless_add_mac_blacklist_item),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWireless, nm_setting_wireless_remove_mac_blacklist_item),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWireless, nm_setting_wireless_remove_mac_blacklist_item_by_value),
+ .validate2_fcn = _multilist_validate2_fcn_mac_addr,
+ ),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
@@ -7688,33 +7059,39 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS_SECURITY[] = {
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PROTO,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_wireless_security_proto,
- .remove_fcn = _remove_fcn_wireless_security_proto,
- ),
+ .property_type = &_pt_multilist,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
- .values_static = wifi_sec_valid_protos,
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_get_num_protos),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_proto),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_proto),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_proto_by_value),
+ ),
+ .values_static = NM_MAKE_STRV ("wpa", "rsn"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PAIRWISE,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_wireless_security_pairwise,
- .remove_fcn = _remove_fcn_wireless_security_pairwise,
- ),
+ .property_type = &_pt_multilist,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
- .values_static = wifi_sec_valid_pairwises,
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_get_num_pairwise),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_pairwise),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_pairwise),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_pairwise_by_value),
+ ),
+ .values_static = NM_MAKE_STRV ("tkip", "ccmp"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_GROUP,
- .property_type = DEFINE_PROPERTY_TYPE (
- .get_fcn = _get_fcn_gobject,
- .set_fcn = _set_fcn_wireless_security_group,
- .remove_fcn = _remove_fcn_wireless_security_group,
- ),
+ .property_type = &_pt_multilist,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
- .values_static = wifi_sec_valid_groups,
+ PROPERTY_TYP_DATA_SUBTYPE (multilist,
+ .get_num_fcn_u32 = MULTILIST_GET_NUM_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_get_num_groups),
+ .add_fcn = MULTILIST_ADD_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_add_group),
+ .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_group),
+ .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingWirelessSecurity, nm_setting_wireless_security_remove_group_by_value),
+ ),
+ .values_static = NM_MAKE_STRV ("wep40", "wep104", "tkip", "ccmp"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_PMF,
diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h
index e3f9d230ee..cc94c2547d 100644
--- a/clients/common/nm-meta-setting-desc.h
+++ b/clients/common/nm-meta-setting-desc.h
@@ -209,15 +209,9 @@ struct _NMMetaPropertyType {
const NMMetaEnvironment *environment,
gpointer environment_user_data,
NMSetting *setting,
+ char modifier,
const char *value,
GError **error);
- gboolean (*remove_fcn) (const NMMetaPropertyInfo *property_info,
- const NMMetaEnvironment *environment,
- gpointer environment_user_data,
- NMSetting *setting,
- const char *option,
- guint32 idx,
- GError **error);
const char *const*(*values_fcn) (const NMMetaPropertyInfo *property_info,
char ***out_to_free);
@@ -228,6 +222,10 @@ struct _NMMetaPropertyType {
const NMMetaOperationContext *operation_context,
const char *text,
char ***out_to_free);
+
+ /* Whether set_fcn() supports the '-' modifier. That is, whether the property
+ * is a list type. */
+ bool set_supports_remove:1;
};
struct _NMUtilsEnumValueInfo;
@@ -245,9 +243,6 @@ typedef struct {
struct _NMMetaPropertyTypData {
union {
struct {
- gboolean (*fcn) (NMSetting *setting);
- } get_with_default;
- struct {
GType (*get_gtype) (void);
int min;
int max;
@@ -272,15 +267,77 @@ struct _NMMetaPropertyTypData {
bool legacy_format:1;
} gobject_bytes;
struct {
+ guint32 (*get_num_fcn_u32) (NMSetting *setting);
+ guint (*get_num_fcn_u) (NMSetting *setting);
+ void (*clear_all_fcn) (NMSetting *setting);
+ gboolean (*add_fcn) (NMSetting *setting,
+ const char *item);
+ void (*add2_fcn) (NMSetting *setting,
+ const char *item);
+ const char *(*validate_fcn) (const char *item, GError **error);
+ const char *(*validate2_fcn) (NMSetting *setting, const char *item, GError **error);
+ void (*remove_by_idx_fcn_u32) (NMSetting *setting, guint32 idx);
+ void (*remove_by_idx_fcn_u) (NMSetting *setting, guint idx);
+ void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx);
+ gboolean (*remove_by_value_fcn) (NMSetting *setting, const char *item);
+
+ /* if true, separate the list by space and allow backslash escaping. */
+ bool with_escaped_spaces:1;
+ } multilist;
+ struct {
+ guint (*get_num_fcn) (NMSetting *setting);
+ void (*obj_to_str_fcn) (NMMetaAccessorGetType get_type,
+ NMSetting *setting,
+ guint idx,
+ GString *str);
+ gboolean (*set_fcn) (NMSetting *setting,
+ gboolean do_add /* or else remove. */,
+ const char *value,
+ GError **error);
+ void (*clear_all_fcn) (NMSetting *setting);
+ void (*remove_by_idx_fcn_u) (NMSetting *setting, guint idx);
+ void (*remove_by_idx_fcn_s) (NMSetting *setting, int idx);
+ bool delimit_pretty_with_semicolon:1;
+ } objlist;
+ struct {
+ gboolean (*set_fcn) (NMSetting *setting,
+ const char *option,
+ const char *value,
+ GError **error);
+ bool no_empty_value:1;
+ } optionlist;
+ struct {
guint32 (*get_fcn) (NMSetting *setting);
} mtu;
struct {
+ NMSetting8021xSchemeType scheme_type;
+ } cert_8021x;
+ struct {
NMMetaPropertyTypeMacMode mode;
} mac;
struct {
+ guint (*get_fcn) (NMSettingDcb *setting,
+ guint user_priority);
+ void (*set_fcn) (NMSettingDcb *setting,
+ guint id,
+ guint value);
+ guint max;
+ guint other;
+ bool is_percent:1;
+ } dcb;
+ struct {
+ gboolean (*get_fcn) (NMSettingDcb *s_dcb,
+ guint priority);
+ void (*set_fcn) (NMSettingDcb *setting,
+ guint user_priority,
+ gboolean enabled);
+ bool with_flow_control_flags:1;
+ } dcb_bool;
+ struct {
NMEthtoolID ethtool_id;
} ethtool;
} subtype;
+ gboolean (*is_default_fcn) (NMSetting *setting);
const char *const*values_static;
const NMMetaPropertyTypDataNested *nested;
NMMetaPropertyTypFlags typ_flags;
diff --git a/libnm-core/meson.build b/libnm-core/meson.build
index d10dd1c551..beee290e78 100644
--- a/libnm-core/meson.build
+++ b/libnm-core/meson.build
@@ -189,6 +189,7 @@ libnm_core_sources_all = libnm_core_sources
libnm_core_sources_all += libnm_core_enum
libnm_core_sources_all += shared_nm_meta_setting_c
libnm_core_sources_all += shared_nm_ethtool_utils_c
+libnm_core_sources_all += shared_nm_libnm_core_utils_c
libnm_core_sources_all += [version_header]
libnm_core = static_library(
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index cf2be4a24d..394ecb5677 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -88,6 +88,7 @@
#include "nm-utils.h"
#include "nm-vpn-dbus-interface.h"
#include "nm-vpn-editor-plugin.h"
+#include "nm-libnm-core-utils.h"
/* IEEE 802.1D-1998 timer values */
#define NM_BR_MIN_HELLO_TIME 1
@@ -264,14 +265,6 @@ GHashTable *_nm_ip_route_get_attributes_direct (NMIPRoute *route);
NMSriovVF *_nm_utils_sriov_vf_from_strparts (const char *index, const char *detail, gboolean ignore_unknown, GError **error);
gboolean _nm_sriov_vf_attribute_validate_all (const NMSriovVF *vf, GError **error);
-static inline void
-_nm_auto_ip_route_unref (NMIPRoute **v)
-{
- if (*v)
- nm_ip_route_unref (*v);
-}
-#define nm_auto_ip_route_unref nm_auto (_nm_auto_ip_route_unref)
-
GPtrArray *_nm_utils_copy_array (const GPtrArray *array,
NMUtilsCopyFunc copy_func,
GDestroyNotify free_func);
@@ -554,18 +547,6 @@ gboolean _nm_utils_team_config_set (char **conf,
/*****************************************************************************/
-static inline int
-nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip)
-{
- if (NM_IS_SETTING_IP4_CONFIG (s_ip))
- return AF_INET;
- if (NM_IS_SETTING_IP6_CONFIG (s_ip))
- return AF_INET6;
- g_return_val_if_reached (AF_UNSPEC);
-}
-
-/*****************************************************************************/
-
guint32 _nm_utils_parse_tc_handle (const char *str,
GError **error);
void _nm_utils_string_append_tc_parent (GString *string,
@@ -763,9 +744,6 @@ gboolean _nm_connection_find_secret (NMConnection *self,
/*****************************************************************************/
-#define nm_auto_unref_wgpeer nm_auto(_nm_auto_unref_wgpeer)
-NM_AUTO_DEFINE_FCN0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref)
-
gboolean nm_utils_base64secret_normalize (const char *base64_key,
gsize required_key_len,
char **out_base64_key_norm);
diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c
index e8d008e33d..e4fb70c247 100644
--- a/libnm-core/nm-setting-connection.c
+++ b/libnm-core/nm-setting-connection.c
@@ -397,8 +397,7 @@ nm_setting_connection_add_permission (NMSettingConnection *setting,
GSList *iter;
g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
- g_return_val_if_fail (ptype, FALSE);
- g_return_val_if_fail (strlen (ptype) > 0, FALSE);
+ g_return_val_if_fail (ptype && ptype[0], FALSE);
g_return_val_if_fail (detail == NULL, FALSE);
/* Only "user" for now... */
@@ -470,9 +469,9 @@ nm_setting_connection_remove_permission_by_value (NMSettingConnection *setting,
GSList *iter;
g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
- g_return_val_if_fail (ptype, FALSE);
- g_return_val_if_fail (strlen (ptype) > 0, FALSE);
+ g_return_val_if_fail (ptype && ptype[0], FALSE);
g_return_val_if_fail (detail == NULL, FALSE);
+ g_return_val_if_fail (pitem != NULL, FALSE);
/* Only "user" for now... */
g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE);
diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c
index ec9d2ba02e..9fd070c1fe 100644
--- a/libnm-core/nm-setting-team.c
+++ b/libnm-core/nm-setting-team.c
@@ -1003,6 +1003,7 @@ nm_setting_team_get_runner_tx_hash (NMSettingTeam *setting, guint idx)
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL);
+ g_return_val_if_fail (priv->runner_tx_hash, NULL);
g_return_val_if_fail (idx < priv->runner_tx_hash->len, NULL);
return priv->runner_tx_hash->pdata[idx];
@@ -1023,6 +1024,7 @@ nm_setting_team_remove_runner_tx_hash (NMSettingTeam *setting, guint idx)
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
g_return_if_fail (NM_IS_SETTING_TEAM (setting));
+ g_return_if_fail (priv->runner_tx_hash);
g_return_if_fail (idx < priv->runner_tx_hash->len);
g_ptr_array_remove_index (priv->runner_tx_hash, idx);
diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c
index 5b8a49d48b..f07504aa3e 100644
--- a/libnm-core/nm-setting-vlan.c
+++ b/libnm-core/nm-setting-vlan.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
+#include "nm-libnm-core-utils.h"
#include "nm-utils.h"
#include "nm-core-types-internal.h"
#include "nm-setting-connection.h"
@@ -106,48 +107,33 @@ nm_setting_vlan_get_flags (NMSettingVlan *setting)
return NM_SETTING_VLAN_GET_PRIVATE (setting)->flags;
}
-static guint32
-get_max_prio (NMVlanPriorityMap map, gboolean from)
+static NMVlanQosMapping *
+priority_map_new (guint32 from, guint32 to)
{
- if (map == NM_VLAN_INGRESS_MAP)
- return from ? MAX_8021P_PRIO : MAX_SKB_PRIO;
- else if (map == NM_VLAN_EGRESS_MAP)
- return from ? MAX_SKB_PRIO : MAX_8021P_PRIO;
- g_assert_not_reached ();
+ NMVlanQosMapping *mapping;
+
+ mapping = g_new (NMVlanQosMapping, 1);
+ *mapping = (NMVlanQosMapping) {
+ .from = from,
+ .to = to,
+ };
+ return mapping;
}
static NMVlanQosMapping *
priority_map_new_from_str (NMVlanPriorityMap map, const char *str)
{
- NMVlanQosMapping *p = NULL;
- char **t = NULL;
- guint32 len;
- guint64 from, to;
+ guint32 from, to;
- g_return_val_if_fail (str && str[0], NULL);
-
- t = g_strsplit (str, ":", 0);
- len = g_strv_length (t);
- if (len == 2) {
- from = g_ascii_strtoull (t[0], NULL, 10);
- to = g_ascii_strtoull (t[1], NULL, 10);
-
- if ((from <= get_max_prio (map, TRUE)) && (to <= get_max_prio (map, FALSE))) {
- G_STATIC_ASSERT (sizeof (*p) == sizeof (p->from) + sizeof (p->to));
- p = g_malloc (sizeof (NMVlanQosMapping));
- p->from = from;
- p->to = to;
- }
- }
-
- g_strfreev (t);
- return p;
+ if (!nm_utils_vlan_priority_map_parse_str (map, str, FALSE, &from, &to, NULL))
+ return NULL;
+ return priority_map_new (from, to);
}
static void
priority_map_free (NMVlanQosMapping *map)
{
- g_return_if_fail (map != NULL);
+ nm_assert (map);
g_free (map);
}
@@ -158,7 +144,7 @@ get_map (NMSettingVlan *self, NMVlanPriorityMap map)
return NM_SETTING_VLAN_GET_PRIVATE (self)->ingress_priority_map;
else if (map == NM_VLAN_EGRESS_MAP)
return NM_SETTING_VLAN_GET_PRIVATE (self)->egress_priority_map;
- g_assert_not_reached ();
+ nm_assert_not_reached ();
return NULL;
}
@@ -207,7 +193,7 @@ set_map (NMSettingVlan *self, NMVlanPriorityMap map, GSList *list)
NM_SETTING_VLAN_GET_PRIVATE (self)->egress_priority_map = list;
_notify (self, PROP_EGRESS_PRIORITY_MAP);
} else
- g_assert_not_reached ();
+ nm_assert_not_reached ();
}
static gboolean
@@ -489,6 +475,36 @@ nm_setting_vlan_remove_priority (NMSettingVlan *setting,
set_map (setting, map, g_slist_delete_link (list, item));
}
+static gboolean
+priority_map_remove_by_value (NMSettingVlan *setting,
+ NMVlanPriorityMap map,
+ guint32 from,
+ guint32 to,
+ gboolean wildcard_to)
+{
+ GSList *list = NULL, *iter = NULL;
+ NMVlanQosMapping *item;
+
+ nm_assert (NM_IS_SETTING_VLAN (setting));
+ nm_assert (NM_IN_SET (map, NM_VLAN_INGRESS_MAP, NM_VLAN_EGRESS_MAP));
+
+ list = get_map (setting, map);
+ for (iter = list; iter; iter = g_slist_next (iter)) {
+ item = iter->data;
+
+ if (item->from != from)
+ continue;
+ if ( !wildcard_to
+ && item->to != to)
+ continue;
+
+ priority_map_free ((NMVlanQosMapping *) (iter->data));
+ set_map (setting, map, g_slist_delete_link (list, iter));
+ return TRUE;
+ }
+ return FALSE;
+}
+
/**
* nm_setting_vlan_remove_priority_by_value:
* @setting: the #NMSettingVlan
@@ -508,22 +524,10 @@ nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting,
guint32 from,
guint32 to)
{
- GSList *list = NULL, *iter = NULL;
- NMVlanQosMapping *item;
-
g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE);
g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE);
- list = get_map (setting, map);
- for (iter = list; iter; iter = g_slist_next (iter)) {
- item = iter->data;
- if (item->from == from && item->to == to) {
- priority_map_free ((NMVlanQosMapping *) (iter->data));
- set_map (setting, map, g_slist_delete_link (list, iter));
- return TRUE;
- }
- }
- return FALSE;
+ return priority_map_remove_by_value (setting, map, from, to, FALSE);
}
/**
@@ -543,19 +547,15 @@ nm_setting_vlan_remove_priority_str_by_value (NMSettingVlan *setting,
NMVlanPriorityMap map,
const char *str)
{
- NMVlanQosMapping *item;
- gboolean found;
+ gboolean is_wildcard_to;
+ guint32 from, to;
g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE);
g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE);
- item = priority_map_new_from_str (map, str);
- if (!item)
+ if (!nm_utils_vlan_priority_map_parse_str (map, str, TRUE, &from, &to, &is_wildcard_to))
return FALSE;
-
- found = nm_setting_vlan_remove_priority_by_value (setting, map, item->from, item->to);
- g_free (item);
- return found;
+ return priority_map_remove_by_value (setting, map, from, to, is_wildcard_to);
}
/**
@@ -703,18 +703,16 @@ static GSList *
priority_strv_to_maplist (NMVlanPriorityMap map, char **strv)
{
GSList *list = NULL;
- int i;
+ gsize i;
for (i = 0; strv && strv[i]; i++) {
- NMVlanQosMapping *item;
+ guint32 from, to;
- item = priority_map_new_from_str (map, strv[i]);
- if (item) {
- if (!check_replace_duplicate_priority (list, item->from, item->to))
- list = g_slist_prepend (list, item);
- else
- g_free (item);
- }
+ if (!nm_utils_vlan_priority_map_parse_str (map, strv[i], FALSE, &from, &to, NULL))
+ continue;
+ if (check_replace_duplicate_priority (list, from, to))
+ continue;
+ list = g_slist_prepend (list, priority_map_new (from, to));
}
return g_slist_sort (list, prio_map_compare);
}
diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c
index 20a0ae14a0..fc4b538ad2 100644
--- a/libnm-core/nm-setting-vpn.c
+++ b/libnm-core/nm-setting-vpn.c
@@ -173,10 +173,8 @@ nm_setting_vpn_add_data_item (NMSettingVpn *setting,
const char *item)
{
g_return_if_fail (NM_IS_SETTING_VPN (setting));
- g_return_if_fail (key != NULL);
- g_return_if_fail (strlen (key) > 0);
- g_return_if_fail (item != NULL);
- g_return_if_fail (strlen (item) > 0);
+ g_return_if_fail (key && key[0]);
+ g_return_if_fail (item && item[0]);
g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data,
g_strdup (key), g_strdup (item));
@@ -242,6 +240,7 @@ nm_setting_vpn_remove_data_item (NMSettingVpn *setting, const char *key)
gboolean found;
g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
+ g_return_val_if_fail (key, FALSE);
found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);
if (found)
@@ -350,10 +349,8 @@ nm_setting_vpn_add_secret (NMSettingVpn *setting,
const char *secret)
{
g_return_if_fail (NM_IS_SETTING_VPN (setting));
- g_return_if_fail (key != NULL);
- g_return_if_fail (strlen (key) > 0);
- g_return_if_fail (secret != NULL);
- g_return_if_fail (strlen (secret) > 0);
+ g_return_if_fail (key && key[0]);
+ g_return_if_fail (secret && secret[0]);
g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets,
g_strdup (key), g_strdup (secret));
@@ -419,6 +416,7 @@ nm_setting_vpn_remove_secret (NMSettingVpn *setting, const char *key)
gboolean found;
g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE);
+ g_return_val_if_fail (key, FALSE);
found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key);
if (found)
diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c
index ef23294fda..7f0843046d 100644
--- a/libnm-core/nm-setting-wired.c
+++ b/libnm-core/nm-setting-wired.c
@@ -483,8 +483,7 @@ nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting,
const char *key)
{
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
- g_return_val_if_fail (key != NULL, NULL);
- g_return_val_if_fail (strlen (key), NULL);
+ g_return_val_if_fail (key && key[0], NULL);
return g_hash_table_lookup (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key);
}
@@ -508,17 +507,11 @@ nm_setting_wired_add_s390_option (NMSettingWired *setting,
const char *key,
const char *value)
{
- size_t value_len;
-
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
- g_return_val_if_fail (key != NULL, FALSE);
- g_return_val_if_fail (strlen (key), FALSE);
+ g_return_val_if_fail (key && key[0], FALSE);
g_return_val_if_fail (g_strv_contains (valid_s390_opts, key), FALSE);
g_return_val_if_fail (value != NULL, FALSE);
- value_len = strlen (value);
- g_return_val_if_fail (value_len > 0 && value_len < 200, FALSE);
-
g_hash_table_insert (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options,
g_strdup (key),
g_strdup (value));
@@ -544,8 +537,7 @@ nm_setting_wired_remove_s390_option (NMSettingWired *setting,
gboolean found;
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
- g_return_val_if_fail (key != NULL, FALSE);
- g_return_val_if_fail (strlen (key), FALSE);
+ g_return_val_if_fail (key && key[0], FALSE);
found = g_hash_table_remove (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key);
if (found)
@@ -683,7 +675,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_hash_table_iter_init (&iter, priv->s390_options);
while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
if ( !g_strv_contains (valid_s390_opts, key)
- || !strlen (value)
+ || value[0] == '\0'
|| (strlen (value) > 200)) {
g_set_error (error,
NM_CONNECTION_ERROR,
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 854bfec794..9f3b209ccf 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -2962,8 +2962,7 @@ nm_utils_sriov_vf_from_str (const char *str, GError **error)
detail = strchr (str, ' ');
if (detail) {
- index_free = g_strndup (str, detail - str);
- str = index_free;
+ str = nm_strndup_a (200, str, detail - str, &index_free);
detail++;
}
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 7d97296ab4..6d5eeb2810 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -80,6 +80,29 @@ G_STATIC_ASSERT (sizeof (bool) <= sizeof (int));
/*****************************************************************************/
+static void
+test_nm_ascii_spaces (void)
+{
+ int i;
+ const char *const S = NM_ASCII_SPACES;
+
+ for (i = 0; S[i]; i++)
+ g_assert (!strchr (&S[i + 1], S[i]));
+
+ for (i = 0; S[i] != '\0'; i++)
+ g_assert (g_ascii_isspace (S[i]));
+
+ g_assert (!g_ascii_isspace ((char) 0));
+ for (i = 1; i < 0x100; i++) {
+ if (g_ascii_isspace ((char) i))
+ g_assert (strchr (S, (char) i));
+ else
+ g_assert (!strchr (S, (char) i));
+ }
+}
+
+/*****************************************************************************/
+
typedef struct _nm_packed {
int v0;
char v1;
@@ -809,54 +832,54 @@ test_setting_vpn_items (void)
nm_setting_vpn_remove_data_item (s_vpn, "foobar4-flags");
/* Try to add some blank values and make sure they are rejected */
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_data_item (s_vpn, NULL, NULL);
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_data_item (s_vpn, "", "");
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item != NULL));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item && item[0]));
nm_setting_vpn_add_data_item (s_vpn, "foobar1", NULL);
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (item) > 0));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (item && item[0]));
nm_setting_vpn_add_data_item (s_vpn, "foobar1", "");
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_data_item (s_vpn, NULL, "blahblah1");
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_data_item (s_vpn, "", "blahblah1");
g_test_assert_expected_messages ();
nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_empty_func, NULL);
/* Try to add some blank secrets and make sure they are rejected */
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_secret (s_vpn, NULL, NULL);
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_secret (s_vpn, "", "");
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret != NULL));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret && secret[0]));
nm_setting_vpn_add_secret (s_vpn, "foobar1", NULL);
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (secret) > 0));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (secret && secret[0]));
nm_setting_vpn_add_secret (s_vpn, "foobar1", "");
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key != NULL));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_secret (s_vpn, NULL, "blahblah1");
g_test_assert_expected_messages ();
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (strlen (key) > 0));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (key && key[0]));
nm_setting_vpn_add_secret (s_vpn, "", "blahblah1");
g_test_assert_expected_messages ();
@@ -2347,7 +2370,7 @@ test_setting_connection_permissions_helpers (void)
g_assert (!success);
/* Ensure a bad [type] is rejected */
- NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (ptype));
+ NMTST_EXPECT_LIBNM_CRITICAL (NMTST_G_RETURN_MSG (ptype && ptype[0]));
success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL);
g_test_assert_expected_messages ();
g_assert (!success);
@@ -7734,23 +7757,72 @@ test_nm_utils_escape_spaces (void)
}
static void
-test_nm_utils_unescape_spaces (void)
+_do_test_unescape_spaces (const char *in, const char *out)
{
-#define CHECK_STR(in, out) \
- G_STMT_START { \
- gs_free char *str = g_strdup (in); \
- \
- g_assert_cmpstr (_nm_utils_unescape_spaces (str), ==, out); \
- } G_STMT_END
+ nm_auto_free_gstring GString *str_out = g_string_new (NULL);
+ nm_auto_free_gstring GString *str_in = g_string_new (NULL);
+ guint i;
- CHECK_STR ("\\a", "\\a");
- CHECK_STR ("foobar", "foobar");
- CHECK_STR ("foo bar", "foo bar");
- CHECK_STR ("foo\\ bar", "foo bar");
- CHECK_STR ("foo\\", "foo\\");
- CHECK_STR ("\\\\\t", "\\\t");
+ for (i = 0; i < 10; i++) {
-#undef CHECK_STR
+ g_string_set_size (str_in, 0);
+
+ g_string_append (str_in, in);
+
+ if (i == 0)
+ g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, out);
+ else if (i == 1)
+ g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out);
+ else {
+ bool do_strip = nmtst_get_rand_bool ();
+ guint n = nmtst_get_rand_int () % 20;
+ guint j;
+
+ g_string_set_size (str_out, 0);
+ if (!do_strip)
+ g_string_append (str_out, out);
+
+ for (j = 0; j < n; j++) {
+ gboolean append = nmtst_get_rand_bool ();
+ char ch = nmtst_rand_select (' ', '\t');
+
+ if (append && out[strlen (out) - 1] == '\\')
+ append = FALSE;
+
+ g_string_insert_c (str_in, append ? -1 : 0, ch);
+ if (!do_strip)
+ g_string_insert_c (str_out, append ? -1 : 0, ch);
+ }
+
+ if (do_strip)
+ g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, TRUE), ==, out);
+ else
+ g_assert_cmpstr (_nm_utils_unescape_spaces (str_in->str, FALSE), ==, str_out->str);
+ }
+ }
+}
+
+static void
+test_nm_utils_unescape_spaces (void)
+{
+ _do_test_unescape_spaces ("", "");
+ _do_test_unescape_spaces ("\\", "\\");
+ _do_test_unescape_spaces ("\\ ", " ");
+ _do_test_unescape_spaces ("\\\t", "\t");
+ _do_test_unescape_spaces ("a", "a");
+ _do_test_unescape_spaces ("\\a", "\\a");
+ _do_test_unescape_spaces ("foobar", "foobar");
+ _do_test_unescape_spaces ("foo bar", "foo bar");
+ _do_test_unescape_spaces ("foo\\ bar", "foo bar");
+ _do_test_unescape_spaces ("foo\\", "foo\\");
+ _do_test_unescape_spaces ("\\\\", "\\\\");
+ _do_test_unescape_spaces ("foo bar", "foo bar");
+ _do_test_unescape_spaces ("\\ foo bar", " foo bar");
+ _do_test_unescape_spaces ("\\ foo bar\\ ", " foo bar ");
+ _do_test_unescape_spaces ("\\\tfoo bar\\\t", "\tfoo bar\t");
+ _do_test_unescape_spaces ("\\\tfoo bar \\\t", "\tfoo bar \t");
+ _do_test_unescape_spaces ("\\\t", "\t");
+ _do_test_unescape_spaces ("\\\t \\ ", "\t ");
}
/*****************************************************************************/
@@ -7761,6 +7833,7 @@ int main (int argc, char **argv)
{
nmtst_init (&argc, &argv, TRUE);
+ g_test_add_func ("/core/general/test_nm_ascii_spaces", test_nm_ascii_spaces);
g_test_add_func ("/core/general/test_nm_hash", test_nm_hash);
g_test_add_func ("/core/general/test_nm_g_slice_free_fcn", test_nm_g_slice_free_fcn);
g_test_add_func ("/core/general/test_c_list_sort", test_c_list_sort);
diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c
index 56a88b004f..40485ab6c0 100644
--- a/libnm/nm-secret-agent-old.c
+++ b/libnm/nm-secret-agent-old.c
@@ -892,8 +892,7 @@ nm_secret_agent_old_get_secrets (NMSecretAgentOld *self,
g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
g_return_if_fail (NM_IS_CONNECTION (connection));
g_return_if_fail (nm_connection_get_path (connection));
- g_return_if_fail (setting_name != NULL);
- g_return_if_fail (strlen (setting_name) > 0);
+ g_return_if_fail (setting_name && setting_name[0]);
g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM));
g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS));
g_return_if_fail (callback != NULL);
diff --git a/shared/meson.build b/shared/meson.build
index a6e94d6b88..f9d9e62bff 100644
--- a/shared/meson.build
+++ b/shared/meson.build
@@ -75,6 +75,8 @@ version_header = configure_file(
shared_nm_ethtool_utils_c = files('nm-ethtool-utils.c')
+shared_nm_libnm_core_utils_c = files('nm-libnm-core-utils.c')
+
shared_nm_meta_setting_c = files('nm-meta-setting.c')
shared_nm_test_utils_impl_c = files('nm-test-utils-impl.c')
diff --git a/shared/nm-libnm-core-utils.c b/shared/nm-libnm-core-utils.c
new file mode 100644
index 0000000000..d1e5f75460
--- /dev/null
+++ b/shared/nm-libnm-core-utils.c
@@ -0,0 +1,76 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include "nm-default.h"
+
+#include "nm-libnm-core-utils.h"
+
+/*****************************************************************************/
+
+gboolean
+nm_utils_vlan_priority_map_parse_str (NMVlanPriorityMap map_type,
+ const char *str,
+ gboolean allow_wildcard_to,
+ guint32 *out_from,
+ guint32 *out_to,
+ gboolean *out_has_wildcard_to)
+{
+ const char *s2;
+ gint64 v1, v2;
+
+ nm_assert (str);
+
+ s2 = strchr (str, ':');
+
+ if (!s2) {
+ if (!allow_wildcard_to)
+ return FALSE;
+ v1 = _nm_utils_ascii_str_to_int64 (str, 10, 0, G_MAXUINT32, -1);
+ v2 = -1;
+ } else {
+ gs_free char *s1_free = NULL;
+ gsize s1_len = (s2 - str);
+
+ s2 = nm_str_skip_leading_spaces (&s2[1]);
+ if ( s2[0] == '\0'
+ || ( s2[0] == '*'
+ && NM_STRCHAR_ALL (&s2[1], ch, g_ascii_isspace (ch)))) {
+ if (!allow_wildcard_to)
+ return FALSE;
+ v2 = -1;
+ } else {
+ v2 = _nm_utils_ascii_str_to_int64 (s2, 10, 0, G_MAXUINT32, -1);
+ if ( v2 < 0
+ || (guint32) v2 > nm_utils_vlan_priority_map_get_max_prio (map_type, FALSE))
+ return FALSE;
+ }
+
+ v1 = _nm_utils_ascii_str_to_int64 (nm_strndup_a (100, str, s1_len, &s1_free),
+ 10, 0, G_MAXUINT32, -1);
+ }
+
+ if ( v1 < 0
+ || (guint32) v1 > nm_utils_vlan_priority_map_get_max_prio (map_type, TRUE))
+ return FALSE;
+
+ NM_SET_OUT (out_from, v1);
+ NM_SET_OUT (out_to, v2 < 0
+ ? 0u
+ : (guint) v2);
+ NM_SET_OUT (out_has_wildcard_to, v2 < 0);
+ return TRUE;
+}
diff --git a/shared/nm-libnm-core-utils.h b/shared/nm-libnm-core-utils.h
new file mode 100644
index 0000000000..3d06de00a2
--- /dev/null
+++ b/shared/nm-libnm-core-utils.h
@@ -0,0 +1,90 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __NM_LIBNM_SHARED_UTILS_H__
+#define __NM_LIBNM_SHARED_UTILS_H__
+
+/****************************************************************************/
+
+#include "nm-setting-connection.h"
+#include "nm-setting-ip-config.h"
+#include "nm-setting-ip4-config.h"
+#include "nm-setting-ip6-config.h"
+#include "nm-setting-sriov.h"
+#include "nm-setting-team.h"
+#include "nm-setting-vlan.h"
+#include "nm-setting-wireguard.h"
+
+/****************************************************************************/
+
+#define nm_auto_unref_ip_address nm_auto (_nm_ip_address_unref)
+NM_AUTO_DEFINE_FCN0 (NMIPAddress *, _nm_ip_address_unref, nm_ip_address_unref)
+
+#define nm_auto_unref_ip_route nm_auto (_nm_auto_unref_ip_route)
+NM_AUTO_DEFINE_FCN0 (NMIPRoute *, _nm_auto_unref_ip_route, nm_ip_route_unref)
+
+#define nm_auto_unref_sriov_vf nm_auto (_nm_auto_unref_sriov_vf)
+NM_AUTO_DEFINE_FCN0 (NMSriovVF *, _nm_auto_unref_sriov_vf, nm_sriov_vf_unref)
+
+#define nm_auto_unref_tc_qdisc nm_auto (_nm_auto_unref_tc_qdisc)
+NM_AUTO_DEFINE_FCN0 (NMTCQdisc *, _nm_auto_unref_tc_qdisc, nm_tc_qdisc_unref)
+
+#define nm_auto_unref_tc_tfilter nm_auto (_nm_auto_unref_tc_tfilter)
+NM_AUTO_DEFINE_FCN0 (NMTCTfilter *, _nm_auto_unref_tc_tfilter, nm_tc_tfilter_unref)
+
+#define nm_auto_unref_team_link_watcher nm_auto (_nm_auto_unref_team_link_watcher)
+NM_AUTO_DEFINE_FCN0 (NMTeamLinkWatcher *, _nm_auto_unref_team_link_watcher, nm_team_link_watcher_unref)
+
+#define nm_auto_unref_wgpeer nm_auto (_nm_auto_unref_wgpeer)
+NM_AUTO_DEFINE_FCN0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref)
+
+/****************************************************************************/
+
+static inline guint32
+nm_utils_vlan_priority_map_get_max_prio (NMVlanPriorityMap map, gboolean from)
+{
+ if (map == NM_VLAN_INGRESS_MAP) {
+ return from
+ ? 7u /* MAX_8021P_PRIO */
+ : (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */;
+ }
+ nm_assert (map == NM_VLAN_EGRESS_MAP);
+ return from
+ ? (guint32) G_MAXUINT32 /* MAX_SKB_PRIO */
+ : 7u /* MAX_8021P_PRIO */;
+}
+
+gboolean nm_utils_vlan_priority_map_parse_str (NMVlanPriorityMap map_type,
+ const char *str,
+ gboolean allow_wildcard_to,
+ guint32 *out_from,
+ guint32 *out_to,
+ gboolean *out_has_wildcard_to);
+
+/*****************************************************************************/
+
+static inline int
+nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip)
+{
+ if (NM_IS_SETTING_IP4_CONFIG (s_ip))
+ return AF_INET;
+ if (NM_IS_SETTING_IP6_CONFIG (s_ip))
+ return AF_INET6;
+ g_return_val_if_reached (AF_UNSPEC);
+}
+
+#endif /* __NM_LIBNM_SHARED_UTILS_H__ */
diff --git a/shared/nm-meta-setting.c b/shared/nm-meta-setting.c
index e666e0b2a2..8d1d4ecd2a 100644
--- a/shared/nm-meta-setting.c
+++ b/shared/nm-meta-setting.c
@@ -82,6 +82,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
.uri_func = nm_setting_802_1x_get_ca_cert_uri,
.passwd_func = nm_setting_802_1x_get_ca_cert_password,
.pwflag_func = nm_setting_802_1x_get_ca_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_ca_cert,
.file_suffix = "ca-cert",
},
@@ -94,6 +95,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
.uri_func = nm_setting_802_1x_get_phase2_ca_cert_uri,
.passwd_func = nm_setting_802_1x_get_phase2_ca_cert_password,
.pwflag_func = nm_setting_802_1x_get_phase2_ca_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_phase2_ca_cert,
.file_suffix = "inner-ca-cert",
},
@@ -106,6 +108,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
.uri_func = nm_setting_802_1x_get_client_cert_uri,
.passwd_func = nm_setting_802_1x_get_client_cert_password,
.pwflag_func = nm_setting_802_1x_get_client_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_client_cert,
.file_suffix = "client-cert",
},
@@ -118,6 +121,7 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
.uri_func = nm_setting_802_1x_get_phase2_client_cert_uri,
.passwd_func = nm_setting_802_1x_get_phase2_client_cert_password,
.pwflag_func = nm_setting_802_1x_get_phase2_client_cert_password_flags,
+ .set_cert_func = nm_setting_802_1x_set_phase2_client_cert,
.file_suffix = "inner-client-cert",
},
@@ -130,7 +134,9 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
.uri_func = nm_setting_802_1x_get_private_key_uri,
.passwd_func = nm_setting_802_1x_get_private_key_password,
.pwflag_func = nm_setting_802_1x_get_private_key_password_flags,
+ .set_private_key_func = nm_setting_802_1x_set_private_key,
.file_suffix = "private-key",
+ .is_secret = TRUE,
},
[NM_SETTING_802_1X_SCHEME_TYPE_PHASE2_PRIVATE_KEY] = {
@@ -142,7 +148,9 @@ const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[] = {
.uri_func = nm_setting_802_1x_get_phase2_private_key_uri,
.passwd_func = nm_setting_802_1x_get_phase2_private_key_password,
.pwflag_func = nm_setting_802_1x_get_phase2_private_key_password_flags,
+ .set_private_key_func = nm_setting_802_1x_set_phase2_private_key,
.file_suffix = "inner-private-key",
+ .is_secret = TRUE,
},
[NM_SETTING_802_1X_SCHEME_TYPE_UNKNOWN] = { NULL },
diff --git a/shared/nm-meta-setting.h b/shared/nm-meta-setting.h
index 18727a1638..73ee103ee5 100644
--- a/shared/nm-meta-setting.h
+++ b/shared/nm-meta-setting.h
@@ -89,7 +89,19 @@ typedef struct {
const char * (*uri_func) (NMSetting8021x *setting);
const char * (*passwd_func) (NMSetting8021x *setting);
NMSettingSecretFlags (*pwflag_func) (NMSetting8021x *setting);
+ gboolean (*set_cert_func) (NMSetting8021x *setting,
+ const char *value,
+ NMSetting8021xCKScheme scheme,
+ NMSetting8021xCKFormat *out_format,
+ GError **error);
+ gboolean (*set_private_key_func) (NMSetting8021x *setting,
+ const char *value,
+ const char *password,
+ NMSetting8021xCKScheme scheme,
+ NMSetting8021xCKFormat *out_format,
+ GError **error);
const char *file_suffix;
+ bool is_secret:1;
} NMSetting8021xSchemeVtable;
extern const NMSetting8021xSchemeVtable nm_setting_8021x_scheme_vtable[_NM_SETTING_802_1X_SCHEME_TYPE_NUM + 1];
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index 42299c9635..2f4fd86de7 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -1334,6 +1334,9 @@ _NM_BACKPORT_SYMBOL_IMPL(version, return_type, func, _##func##_##version, args_t
/*****************************************************************************/
+/* mirrors g_ascii_isspace() and what we consider spaces in general. */
+#define NM_ASCII_SPACES "\t\n\f\r "
+
#define nm_str_skip_leading_spaces(str) \
({ \
typeof (*(str)) *_str = (str); \
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 93e0b97e20..215a87b59b 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -635,8 +635,16 @@ nm_utils_parse_inaddr (int addr_family,
NMIPAddr addrbin;
char addrstr_buf[MAX (INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
- if (!nm_utils_parse_inaddr_bin (addr_family, text, &addr_family, &addrbin))
+ g_return_val_if_fail (text, FALSE);
+
+ if (addr_family == AF_UNSPEC)
+ addr_family = strchr (text, ':') ? AF_INET6 : AF_INET;
+ else
+ g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE);
+
+ if (inet_pton (addr_family, text, &addrbin) != 1)
return FALSE;
+
NM_SET_OUT (out_addr, g_strdup (inet_ntop (addr_family, &addrbin, addrstr_buf, sizeof (addrstr_buf))));
return TRUE;
}
@@ -954,6 +962,15 @@ comp_l:
/*****************************************************************************/
+static void
+_char_lookup_table_init (guint8 lookup[static 256],
+ const char *candidates)
+{
+ memset (lookup, 0, 256);
+ while (candidates[0] != '\0')
+ lookup[(guint8) ((candidates++)[0])] = 1;
+}
+
/**
* nm_utils_strsplit_set:
* @str: the string to split.
@@ -979,6 +996,8 @@ comp_l:
* The strings to which the result strv array points to are allocated
* after the returned result itself. Don't free the strings themself,
* but free everything with g_free().
+ * It is however safe and allowed to modify the indiviual strings,
+ * like "g_strstrip((char *) iter[0])".
*/
const char **
nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_escaping)
@@ -997,9 +1016,8 @@ nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_e
/* initialize lookup table for delimiter */
if (!delimiters)
delimiters = " \t\n";
- memset (delimiters_table, 0, sizeof (delimiters_table));
- for (i = 0; delimiters[i]; i++)
- delimiters_table[(guint8) delimiters[i]] = 1;
+
+ _char_lookup_table_init (delimiters_table, delimiters);
#define _is_delimiter(ch, delimiters_table, allow_esc, esc) \
((delimiters_table)[(guint8) (ch)] != 0 && (!allow_esc || !esc))
@@ -2412,23 +2430,26 @@ _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...)
/*****************************************************************************/
-#define IS_SPACE(c) NM_IN_SET ((c), ' ', '\t')
+#define _CH_LOOKUP(ch_lookup, ch) (!!((ch_lookup)[(guint8) (ch)]))
const char *
-_nm_utils_escape_spaces (const char *str, char **to_free)
+_nm_utils_escape_plain (const char *str, const char *candidates, char **to_free)
{
const char *ptr = str;
char *ret, *r;
+ guint8 ch_lookup[256];
*to_free = NULL;
if (!str)
return NULL;
+ _char_lookup_table_init (ch_lookup, candidates ?: NM_ASCII_SPACES);
+
while (TRUE) {
if (!*ptr)
return str;
- if (IS_SPACE (*ptr))
+ if (_CH_LOOKUP (ch_lookup, *ptr))
break;
ptr++;
}
@@ -2438,7 +2459,7 @@ _nm_utils_escape_spaces (const char *str, char **to_free)
r = ret;
*to_free = ret;
while (*ptr) {
- if (IS_SPACE (*ptr))
+ if (_CH_LOOKUP (ch_lookup, *ptr))
*r++ = '\\';
*r++ = *ptr++;
}
@@ -2448,25 +2469,42 @@ _nm_utils_escape_spaces (const char *str, char **to_free)
}
char *
-_nm_utils_unescape_spaces (char *str)
+_nm_utils_unescape_plain (char *str, const char *candidates, gboolean do_strip)
{
- guint i, j = 0;
+ gsize i = 0;
+ gsize j = 0;
+ gsize preserve_space_at = 0;
+ guint8 ch_lookup[256];
if (!str)
return NULL;
- for (i = 0; str[i]; i++) {
- if (str[i] == '\\' && IS_SPACE (str[i+1]))
+ _char_lookup_table_init (ch_lookup, candidates ?: NM_ASCII_SPACES);
+
+ if (do_strip) {
+ while (str[i] && _CH_LOOKUP (ch_lookup, str[i]))
i++;
+ }
+
+ for (; str[i]; i++) {
+ if ( str[i] == '\\'
+ && _CH_LOOKUP (ch_lookup, str[i+1])) {
+ preserve_space_at = j;
+ i++;
+ }
str[j++] = str[i];
}
str[j] = '\0';
+ if (do_strip && j > 0) {
+ while ( --j > preserve_space_at
+ && _CH_LOOKUP (ch_lookup, str[j]))
+ str[j] = '\0';
+ }
+
return str;
}
-#undef IS_SPACE
-
/*****************************************************************************/
typedef struct {
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 51e57ee03f..f48bfede7e 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -1084,8 +1084,20 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...);
/*****************************************************************************/
-const char *_nm_utils_escape_spaces (const char *str, char **to_free);
-char *_nm_utils_unescape_spaces (char *str);
+const char *_nm_utils_escape_plain (const char *str, const char *candidates, char **to_free);
+char *_nm_utils_unescape_plain (char *str, const char *candidates, gboolean do_strip);
+
+static inline const char *
+_nm_utils_escape_spaces (const char *str, char **to_free)
+{
+ return _nm_utils_escape_plain (str, NM_ASCII_SPACES, to_free);
+}
+
+static inline char *
+_nm_utils_unescape_spaces (char *str, gboolean do_strip)
+{
+ return _nm_utils_unescape_plain (str, NM_ASCII_SPACES, do_strip);
+}
/*****************************************************************************/
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index 7c1db225c0..7779319b7f 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -820,7 +820,7 @@ parse_route_line (const char *line,
NMIPRoute **out_route,
GError **error)
{
- nm_auto_ip_route_unref NMIPRoute *route = NULL;
+ nm_auto_unref_ip_route NMIPRoute *route = NULL;
gs_free const char **words_free = NULL;
const char *const*words;
const char *s;
@@ -1284,7 +1284,7 @@ read_route_file (int addr_family,
for (line = strtok_r (contents, "\n", &contents_rest);
line;
line = strtok_r (NULL, "\n", &contents_rest)) {
- nm_auto_ip_route_unref NMIPRoute *route = NULL;
+ nm_auto_unref_ip_route NMIPRoute *route = NULL;
gs_free_error GError *local = NULL;
int e;
@@ -1449,7 +1449,7 @@ make_match_setting (shvarFile *ifcfg)
if (!s_match)
s_match = (NMSettingMatch *) nm_setting_match_new ();
nm_setting_match_add_interface_name (s_match,
- _nm_utils_unescape_spaces ((char *) strv[i]));
+ _nm_utils_unescape_spaces ((char *) strv[i], TRUE));
}
}