[PATCH 2/2] settings: add match for driver



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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]