about summary refs log tree commit diff
path: root/clients/common/nm-meta-setting-desc.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/common/nm-meta-setting-desc.c')
-rw-r--r--clients/common/nm-meta-setting-desc.c280
1 files changed, 211 insertions, 69 deletions
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c
index 920a5af9..dd5fd6f3 100644
--- a/clients/common/nm-meta-setting-desc.c
+++ b/clients/common/nm-meta-setting-desc.c
@@ -783,6 +783,17 @@ _coerce_str_emptyunset (NMMetaAccessorGetType get_type,
 	return cstr;
 }
 
+#define RETURN_STR_EMPTYUNSET(get_type, is_default, cstr) \
+	G_STMT_START { \
+		char *_str = NULL; \
+		const char *_cstr; \
+		\
+		_cstr = _coerce_str_emptyunset ((get_type), (is_default), (cstr), &_str); \
+		if (_str) \
+			RETURN_STR_TO_FREE (_str); \
+		RETURN_STR_TEMPORARY (_cstr); \
+	} G_STMT_END
+
 static gboolean
 _is_default (const NMMetaPropertyInfo *property_info,
              NMSetting *setting)
@@ -836,6 +847,19 @@ _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info,
 	           || (   gtype_prop == G_TYPE_STRV
 	               && !glib_handles_str_transform));
 
+	if (gtype_prop == G_TYPE_STRING) {
+		nm_assert (glib_handles_str_transform);
+		nm_assert (!handle_emptyunset);
+		if (   property_info->property_typ_data
+		    && property_info->property_typ_data->subtype.gobject_string.handle_emptyunset) {
+			/* This string property can both be empty and NULL. We need to
+			 * signal them differently. */
+			cstr = g_value_get_string (&val);
+			nm_assert ((!!is_default) == (cstr == NULL));
+			RETURN_STR_EMPTYUNSET (get_type, is_default, NULL);
+		}
+	}
+
 	if (glib_handles_str_transform)
 		RETURN_STR_TEMPORARY (g_value_get_string (&val));
 
@@ -857,15 +881,9 @@ _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info,
 		if (strv && strv[0])
 			RETURN_STR_TO_FREE (g_strjoinv (",", (char **) strv));
 
-		/* special hack for handling properties that can be empty and unset
-		 * (see multilist.clear_emptyunset_fcn). */
 		if (handle_emptyunset) {
-			char *str = NULL;
-
-			cstr = _coerce_str_emptyunset (get_type, is_default, NULL, &str);
-			if (str)
-				RETURN_STR_TO_FREE (str);
-			RETURN_STR_TEMPORARY (cstr);
+			/* we need to express empty lists from unset lists differently. */
+			RETURN_STR_EMPTYUNSET (get_type, is_default, NULL);
 		}
 
 		return "";
@@ -1183,6 +1201,22 @@ _set_fcn_gobject_string (ARGS_SET_FCN)
 		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.handle_emptyunset) {
+			if (   value
+			    && value[0]
+			    && NM_STRCHAR_ALL (value, ch, ch == ' ')) {
+				/* this string property can both be %NULL and empty. To express that, we coerce
+				 * a value of all whitespaces to dropping the first whitespace. That means,
+				 * " " gives "", "  " gives " ", and so on.
+				 *
+				 * This way the user can set the string value to "" (meaning NULL) and to
+				 * " " (meaning ""), and any other string.
+				 *
+				 * This is and non-obvious escaping mechanism. But out of all the possible
+				 * solutions, it seems the most sensible one. */
+				value++;
+			}
+		}
 		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);
 			if (!value)
@@ -3397,35 +3431,6 @@ _objlist_set_fcn_ip_config_routing_rules (NMSetting *setting,
 }
 
 static gconstpointer
-_get_fcn_match_interface_name (ARGS_GET_FCN)
-{
-	NMSettingMatch *s_match = NM_SETTING_MATCH (setting);
-	GString *str = NULL;
-	guint i, num;
-
-	RETURN_UNSUPPORTED_GET_TYPE ();
-
-	num = nm_setting_match_get_num_interface_names (s_match);
-	for (i = 0; i < num; i++) {
-		const char *name;
-
-		name = nm_setting_match_get_interface_name (s_match, i);
-		if (!name || !name[0])
-			continue;
-		if (!str)
-			str = g_string_new ("");
-		else
-			g_string_append_c (str, ESCAPED_TOKENS_WITH_SPACES_DELIMTER);
-		nm_utils_escaped_tokens_escape_gstr (name, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS, str);
-	}
-
-	NM_SET_OUT (out_is_default, num == 0);
-	if (!str)
-		return NULL;
-	RETURN_STR_TO_FREE (g_string_free (str, FALSE));
-}
-
-static gconstpointer
 _get_fcn_olpc_mesh_ssid (ARGS_GET_FCN)
 {
 	NMSettingOlpcMesh *s_olpc_mesh = NM_SETTING_OLPC_MESH (setting);
@@ -4092,25 +4097,38 @@ _gobject_enum_pre_set_notify_fcn_wireless_security_wep_key_type (const NMMetaPro
 static gconstpointer
 _get_fcn_ethtool (ARGS_GET_FCN)
 {
-	const char *s;
-	NMTernary val;
 	NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
+	const char *s;
+	guint32 u32;
+	gboolean b;
 
 	RETURN_UNSUPPORTED_GET_TYPE ();
 
-	val = nm_setting_ethtool_get_feature (NM_SETTING_ETHTOOL (setting),
-	                                      nm_ethtool_data[ethtool_id]->optname);
+	if (   nm_ethtool_id_is_coalesce (ethtool_id)
+	    || nm_ethtool_id_is_ring (ethtool_id)) {
+		if (!nm_setting_option_get_uint32 (setting,
+		                                   nm_ethtool_data[ethtool_id]->optname,
+		                                   &u32)) {
+			NM_SET_OUT (out_is_default, TRUE);
+			return NULL;
+		}
+
+		RETURN_STR_TO_FREE (nm_strdup_int (u32));
+	}
 
-	if (val == NM_TERNARY_TRUE)
-		s = N_("on");
-	else if (val == NM_TERNARY_FALSE)
-		s = N_("off");
-	else {
-		s = NULL;
+	nm_assert (nm_ethtool_id_is_feature (ethtool_id));
+
+	if (!nm_setting_option_get_boolean (setting,
+	                                    nm_ethtool_data[ethtool_id]->optname,
+	                                    &b)) {
 		NM_SET_OUT (out_is_default, TRUE);
+		return NULL;
 	}
 
-	if (s && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
+	s =   b
+	    ? N_("on")
+	    : N_("off");
+	if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
 		s = gettext (s);
 	return s;
 }
@@ -4118,23 +4136,40 @@ _get_fcn_ethtool (ARGS_GET_FCN)
 static gboolean
 _set_fcn_ethtool (ARGS_SET_FCN)
 {
-	gs_free char *value_to_free = NULL;
-	NMTernary val;
 	NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
+	gs_free char *value_to_free = NULL;
+	gint64 i64;
+	gboolean b;
 
-	if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value)) {
-		val = NM_TERNARY_DEFAULT;
-		goto set;
+	if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
+		goto do_unset;
+
+	if (   nm_ethtool_id_is_coalesce (ethtool_id)
+	    || nm_ethtool_id_is_ring (ethtool_id)) {
+
+		i64 = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1);
+		if (i64 == -1) {
+			g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT,
+			             _("'%s' is out of range [%"G_GUINT32_FORMAT", %"G_GUINT32_FORMAT"]"),
+			             value, 0, G_MAXUINT32);
+			return FALSE;
+		}
+
+		nm_setting_option_set_uint32 (setting,
+		                              nm_ethtool_data[ethtool_id]->optname,
+		                              i64);
+		return TRUE;
 	}
 
-	value = nm_strstrip_avoid_copy_a (300, value, &value_to_free);
+	nm_assert (nm_ethtool_id_is_feature (ethtool_id));
 
+	value = nm_strstrip_avoid_copy_a (300, value, &value_to_free);
 	if (NM_IN_STRSET (value, "1", "yes", "true", "on"))
-		val = NM_TERNARY_TRUE;
+		b = TRUE;
 	else if (NM_IN_STRSET (value, "0", "no", "false", "off"))
-		val = NM_TERNARY_FALSE;
+		b = FALSE;
 	else if (NM_IN_STRSET (value, "", "ignore", "default"))
-		val = NM_TERNARY_DEFAULT;
+		goto do_unset;
 	else {
 		g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT,
 		             _("'%s' is not valid; use 'on', 'off', or 'ignore'"),
@@ -4142,10 +4177,15 @@ _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);
+	nm_setting_option_set_boolean (setting,
+	                               nm_ethtool_data[ethtool_id]->optname,
+	                               b);
+	return TRUE;
+
+do_unset:
+	nm_setting_option_set (setting,
+	                       nm_ethtool_data[ethtool_id]->optname,
+	                       NULL);
 	return TRUE;
 }
 
@@ -4165,10 +4205,14 @@ _complete_fcn_ethtool (ARGS_COMPLETE_FCN)
 		"ignore",
 		NULL,
 	};
+	NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id;
 
-	if (!text || !text[0])
-		return &v[7];
-	return v;
+	if (nm_ethtool_id_is_feature (ethtool_id)) {
+		if (!text || !text[0])
+			return &v[7];
+		return v;
+	}
+	return NULL;
 }
 
 /*****************************************************************************/
@@ -4905,10 +4949,38 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = {
 	    .prompt =                       N_("Group forward mask [0]"),
 	    .property_type =                &_pt_gobject_int,
 	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_HASH_MAX,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
 	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERIER,
 	    .property_type =                &_pt_gobject_bool,
 	    .hide_if_default =              TRUE,
 	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
 	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR,
 	    .property_type =                &_pt_gobject_bool,
 	    .hide_if_default =              TRUE,
@@ -4919,6 +4991,14 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = {
 	    .prompt =                       N_("Enable IGMP snooping [no]"),
 	    .property_type =                &_pt_gobject_bool,
 	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL,
+	    .property_type =                &_pt_gobject_int,
+	    .hide_if_default =              TRUE,
+	),
 	PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_ROUTER,
 	    .property_type =                &_pt_gobject_string,
 	    .hide_if_default =              TRUE,
@@ -5227,6 +5307,10 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
 	        ),
 	    ),
 	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_MUD_URL,
+	    .property_type =                &_pt_gobject_string,
+	    .hide_if_default =              TRUE,
+	),
 	PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT,
 	    .property_type =                &_pt_gobject_int,
 	),
@@ -5386,6 +5470,32 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = {
 	PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION),
 	PROPERTY_INFO_ETHTOOL (FEATURE_TX_UDP_TNL_SEGMENTATION),
 	PROPERTY_INFO_ETHTOOL (FEATURE_TX_VLAN_STAG_HW_INSERT),
+	PROPERTY_INFO_ETHTOOL (COALESCE_ADAPTIVE_RX),
+	PROPERTY_INFO_ETHTOOL (COALESCE_ADAPTIVE_TX),
+	PROPERTY_INFO_ETHTOOL (COALESCE_PKT_RATE_HIGH),
+	PROPERTY_INFO_ETHTOOL (COALESCE_PKT_RATE_LOW),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES_IRQ),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES_HIGH),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_FRAMES_LOW),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS_IRQ),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS_HIGH),
+	PROPERTY_INFO_ETHTOOL (COALESCE_RX_USECS_LOW),
+	PROPERTY_INFO_ETHTOOL (COALESCE_SAMPLE_INTERVAL),
+	PROPERTY_INFO_ETHTOOL (COALESCE_STATS_BLOCK_USECS),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES_IRQ),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES_HIGH),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_FRAMES_LOW),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_IRQ),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_HIGH),
+	PROPERTY_INFO_ETHTOOL (COALESCE_TX_USECS_LOW),
+	PROPERTY_INFO_ETHTOOL (RING_RX),
+	PROPERTY_INFO_ETHTOOL (RING_RX_JUMBO),
+	PROPERTY_INFO_ETHTOOL (RING_RX_MINI),
+	PROPERTY_INFO_ETHTOOL (RING_TX),
 	NULL,
 };
 
@@ -6120,11 +6230,7 @@ static const NMMetaPropertyInfo *const property_infos_MACVLAN[] = {
 #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MATCH
 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_multilist,
-	        .set_supports_remove =      TRUE,
-	    ),
+	    .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       (NMSettingMatch, nm_setting_match_get_num_interface_names),
@@ -6135,6 +6241,42 @@ static const NMMetaPropertyInfo *const property_infos_MATCH[] = {
 	        ),
 	    ),
 	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_KERNEL_COMMAND_LINE,
+	    .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       (NMSettingMatch, nm_setting_match_get_num_kernel_command_lines),
+	            .add2_fcn =             MULTILIST_ADD2_FCN            (NMSettingMatch, nm_setting_match_add_kernel_command_line),
+	            .remove_by_idx_fcn_u =  MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingMatch, nm_setting_match_remove_kernel_command_line),
+	            .remove_by_value_fcn =  MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_kernel_command_line_by_value),
+	            .strsplit_with_spaces = TRUE,
+	        ),
+	    ),
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_DRIVER,
+	    .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       (NMSettingMatch, nm_setting_match_get_num_drivers),
+	            .add2_fcn =             MULTILIST_ADD2_FCN            (NMSettingMatch, nm_setting_match_add_driver),
+	            .remove_by_idx_fcn_u =  MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingMatch, nm_setting_match_remove_driver),
+	            .remove_by_value_fcn =  MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_driver_by_value),
+	            .strsplit_with_spaces = TRUE,
+	        ),
+	    ),
+	),
+	PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_PATH,
+	    .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       (NMSettingMatch, nm_setting_match_get_num_paths),
+	            .add2_fcn =             MULTILIST_ADD2_FCN            (NMSettingMatch, nm_setting_match_add_path),
+	            .remove_by_idx_fcn_u =  MULTILIST_REMOVE_BY_IDX_FCN_U (NMSettingMatch, nm_setting_match_remove_path),
+	            .remove_by_value_fcn =  MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingMatch, nm_setting_match_remove_path_by_value),
+	            .strsplit_with_spaces = TRUE,
+	        ),
+	    ),
+	),
 	NULL
 };