Add a new "driver" match option to nm-settings. It allows to disable a network connection configuration if a pattern is found or is not found in the device driver name. --- clients/common/nm-meta-setting-desc.c | 45 +++++++ clients/common/settings-docs.h.in | 1 + libnm-core/nm-setting-match.c | 174 ++++++++++++++++++++++++++ libnm-core/nm-setting-match.h | 19 +++ libnm/libnm.ver | 7 ++ src/devices/nm-device.c | 13 ++ 6 files changed, 259 insertions(+)
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 373841484..739c22477 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -3469,6 +3469,35 @@ _get_fcn_match_kernel_command_line (ARGS_GET_FCN) RETURN_STR_TO_FREE (g_string_free (str, FALSE)); } +static gconstpointer +_get_fcn_match_driver (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_drivers (s_match); + for (i = 0; i < num; i++) { + const char *name; + + name = nm_setting_match_get_driver (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) { @@ -6152,6 +6181,22 @@ static const NMMetaPropertyInfo *const property_infos_MATCH[] = { ), ), ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_DRIVER, + .property_type = DEFINE_PROPERTY_TYPE ( + .get_fcn = _get_fcn_match_driver, + .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_drivers), + .add2_fcn = MULTILIST_ADD2_FCN (NMSettingMatch, nm_setting_match_add_driver), + .remove_by_idx_fcn_s = MULTILIST_REMOVE_BY_IDX_FCN_S (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, + ), + ), + ), NULL }; diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in index 37f680133..898ac0f78 100644 --- a/clients/common/settings-docs.h.in +++ b/clients/common/settings-docs.h.in @@ -264,6 +264,7 @@ #define DESCRIBE_DOC_NM_SETTING_MACVLAN_TAP N_("Whether the interface should be a MACVTAP.") #define DESCRIBE_DOC_NM_SETTING_MATCH_INTERFACE_NAME N_("A list of interface names to match. Each element is a shell wildcard pattern. When an element is prefixed with exclamation mark (!) the condition is inverted. A candidate interface name is considered matching when both these conditions are satisfied: (a) any of the elements not prefixed with '!' matches or there aren't such elements; (b) none of the elements prefixed with '!' match.") #define DESCRIBE_DOC_NM_SETTING_MATCH_KERNEL_COMMAND_LINE N_("A list of strings searched in the kernel command line arguments. When an element is prefixed with exclamation mark (!) the condition is inverted.") +#define DESCRIBE_DOC_NM_SETTING_MATCH_DRIVER N_("A list of strings comparad against the name of the driver of a device. When an element is prefixed with exclamation mark (!) the condition is inverted.") #define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_DATAPATH_TYPE N_("The data path type. One of \"system\", \"netdev\" or empty.") #define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_FAIL_MODE N_("The bridge failure mode. One of \"secure\", \"standalone\" or empty.") #define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE N_("Enable or disable multicast snooping.") diff --git a/libnm-core/nm-setting-match.c b/libnm-core/nm-setting-match.c index a56539bba..e7e7ca540 100644 --- a/libnm-core/nm-setting-match.c +++ b/libnm-core/nm-setting-match.c @@ -21,6 +21,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingMatch, PROP_INTERFACE_NAME, PROP_KERNEL_COMMAND_LINE, + PROP_DRIVER, ); /** @@ -34,6 +35,7 @@ struct _NMSettingMatch { NMSetting parent; GPtrArray *interface_name; GPtrArray *kernel_command_line; + GPtrArray *driver; }; struct _NMSettingMatchClass { @@ -340,6 +342,154 @@ nm_setting_match_get_kernel_command_lines (NMSettingMatch *setting, guint *lengt /*****************************************************************************/ +/** + * nm_setting_match_get_num_drivers: + * @setting: the #NMSettingMatch + * + * Returns: the number of configured drivers + * + * Since: 1.24 + **/ +guint +nm_setting_match_get_num_drivers (NMSettingMatch *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), 0); + + return setting->driver->len; +} + +/** + * nm_setting_match_get_driver: + * @setting: the #NMSettingMatch + * @idx: index number of the DNS search domain to return + * + * Returns: the driver at index @idx + * + * Since: 1.24 + **/ +const char * +nm_setting_match_get_driver (NMSettingMatch *setting, int idx) +{ + g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), NULL); + + g_return_val_if_fail (idx >= 0 && idx < setting->driver->len, NULL); + + return setting->driver->pdata[idx]; +} + +/** + * nm_setting_match_add_driver: + * @setting: the #NMSettingMatch + * @driver: the driver to add + * + * Adds a new driver to the setting. + * + * Since: 1.24 + **/ +void +nm_setting_match_add_driver (NMSettingMatch *setting, + const char *driver) +{ + g_return_if_fail (NM_IS_SETTING_MATCH (setting)); + g_return_if_fail (driver != NULL); + g_return_if_fail (driver[0] != '\0'); + + g_ptr_array_add (setting->driver, g_strdup (driver)); + _notify (setting, PROP_DRIVER); +} + +/** + * nm_setting_match_remove_driver: + * @setting: the #NMSettingMatch + * @idx: index number of the driver + * + * Removes the driver at index @idx. + * + * Since: 1.24 + **/ +void +nm_setting_match_remove_driver (NMSettingMatch *setting, int idx) +{ + g_return_if_fail (NM_IS_SETTING_MATCH (setting)); + + g_return_if_fail (idx >= 0 && idx < setting->driver->len); + + g_ptr_array_remove_index (setting->driver, idx); + _notify (setting, PROP_DRIVER); +} + +/** + * nm_setting_match_remove_driver_by_value: + * @setting: the #NMSettingMatch + * @driver: the driver to remove + * + * Removes @driver. + * + * Returns: %TRUE if the driver was found and removed; %FALSE if it was not. + * + * Since: 1.24 + **/ +gboolean +nm_setting_match_remove_driver_by_value (NMSettingMatch *setting, + const char *driver) +{ + guint i; + + g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), FALSE); + g_return_val_if_fail (driver != NULL, FALSE); + g_return_val_if_fail (driver[0] != '\0', FALSE); + + for (i = 0; i < setting->driver->len; i++) { + if (nm_streq (driver, setting->driver->pdata[i])) { + g_ptr_array_remove_index (setting->driver, i); + _notify (setting, PROP_DRIVER); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_match_clear_drivers: + * @setting: the #NMSettingMatch + * + * Removes all configured drivers. + * + * Since: 1.24 + **/ +void +nm_setting_match_clear_drivers (NMSettingMatch *setting) +{ + g_return_if_fail (NM_IS_SETTING_MATCH (setting)); + + if (setting->driver->len != 0) { + g_ptr_array_set_size (setting->driver, 0); + _notify (setting, PROP_DRIVER); + } +} + +/** + * nm_setting_match_get_drivers: + * @setting: the #NMSettingMatch + * + * Returns all the drivers. + * + * Returns: (transfer none): the configured drivers. + * + * Since: 1.24 + **/ +const char *const * +nm_setting_match_get_drivers (NMSettingMatch *setting, guint *length) +{ + g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), NULL); + g_return_val_if_fail (length, NULL); + + NM_SET_OUT (length, setting->driver->len); + return (const char *const *) setting->driver->pdata; +} + +/*****************************************************************************/ + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -353,6 +503,9 @@ get_property (GObject *object, guint prop_id, case PROP_KERNEL_COMMAND_LINE: g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (self->kernel_command_line)); break; + case PROP_DRIVER: + g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (self->driver)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -374,6 +527,10 @@ set_property (GObject *object, guint prop_id, g_ptr_array_unref (self->kernel_command_line); self->kernel_command_line = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value)); break; + case PROP_DRIVER: + g_ptr_array_unref (self->driver); + self->driver = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -387,6 +544,7 @@ nm_setting_match_init (NMSettingMatch *setting) { setting->interface_name = g_ptr_array_new_with_free_func (g_free); setting->kernel_command_line = g_ptr_array_new_with_free_func (g_free); + setting->driver = g_ptr_array_new_with_free_func (g_free); } /** @@ -411,6 +569,7 @@ finalize (GObject *object) g_ptr_array_unref (self->interface_name); g_ptr_array_unref (self->kernel_command_line); + g_ptr_array_unref (self->driver); G_OBJECT_CLASS (nm_setting_match_parent_class)->finalize (object); } @@ -461,6 +620,21 @@ nm_setting_match_class_init (NMSettingMatchClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * NMSettingMatch:driver + * + * A list of strings compared against the device driver name. When an + * element is prefixed with exclamation mark (!) the condition is inverted. + * + * Since: 1.24 + **/ + obj_properties[PROP_DRIVER] = + g_param_spec_boxed (NM_SETTING_MATCH_DRIVER, "", "", + G_TYPE_STRV, + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); _nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_MATCH); diff --git a/libnm-core/nm-setting-match.h b/libnm-core/nm-setting-match.h index f9b493471..34bb64635 100644 --- a/libnm-core/nm-setting-match.h +++ b/libnm-core/nm-setting-match.h @@ -25,6 +25,7 @@ G_BEGIN_DECLS #define NM_SETTING_MATCH_INTERFACE_NAME "interface-name" #define NM_SETTING_MATCH_KERNEL_COMMAND_LINE "kernel-command-line" +#define NM_SETTING_MATCH_DRIVER "driver" typedef struct _NMSettingMatchClass NMSettingMatchClass; @@ -68,6 +69,24 @@ NM_AVAILABLE_IN_1_24 void nm_setting_match_clear_kernel_command_lines (NMSettingMatch *setting); NM_AVAILABLE_IN_1_24 const char *const *nm_setting_match_get_kernel_command_lines (NMSettingMatch *setting, guint *length); + + +NM_AVAILABLE_IN_1_24 +guint nm_setting_match_get_num_drivers (NMSettingMatch *setting); +NM_AVAILABLE_IN_1_24 +const char *nm_setting_match_get_driver (NMSettingMatch *setting, int idx); +NM_AVAILABLE_IN_1_24 +void nm_setting_match_remove_driver (NMSettingMatch *setting, int idx); +NM_AVAILABLE_IN_1_24 +gboolean nm_setting_match_remove_driver_by_value (NMSettingMatch *setting, + const char *driver); +NM_AVAILABLE_IN_1_24 +void nm_setting_match_add_driver (NMSettingMatch *setting, + const char *driver); +NM_AVAILABLE_IN_1_24 +void nm_setting_match_clear_drivers (NMSettingMatch *setting); +NM_AVAILABLE_IN_1_24 +const char *const *nm_setting_match_get_drivers (NMSettingMatch *setting, guint *length); G_END_DECLS #endif /* NM_SETTING_MATCH_H */ diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 5d7873f4d..bf5f6cffd 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1418,6 +1418,13 @@ global: nm_setting_match_get_num_kernel_command_lines; nm_setting_match_remove_kernel_command_line; nm_setting_match_remove_kernel_command_line_by_value; + nm_setting_match_add_driver; + nm_setting_match_clear_drivers; + nm_setting_match_get_driver; + nm_setting_match_get_drivers; + nm_setting_match_get_num_drivers; + nm_setting_match_remove_driver; + nm_setting_match_remove_driver_by_value; nm_setting_sriov_add_vf; nm_setting_sriov_clear_vfs; nm_setting_sriov_get_autoprobe_drivers; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 2a0a58792..f24c16660 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6059,6 +6059,19 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError ** _LOGD (LOGD_DEVICE, "satisfies match.kernel-command-line: %s", proc_cmdline); } } + + const char *device_driver = nm_device_get_driver (self); + if (device_driver) { + patterns = nm_setting_match_get_drivers (s_match, &num_patterns); + if (!nm_wildcard_match_check (device_driver, patterns, num_patterns)) { + nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not satisfy match.driver property"); + _LOGD (LOGD_DEVICE, "does not satisfy match.driver: %s", device_driver); + return FALSE; + } else { + _LOGD (LOGD_DEVICE, "satisfies match.driver: %s", device_driver); + } + } } return TRUE; -- 2.24.1 _______________________________________________ networkmanager-list mailing list networkmanager-list@gnome.org https://mail.gnome.org/mailman/listinfo/networkmanager-list