Some connection types such as bonding, bridging and VLAN require
specific virtual kernel interfaces identified by name to be auto
connected to the connection.

The function nm_connection_get_virtual_iface_name() returns the name
of the kernel interface if the connection type requires this
functionatlity.

Each connection base type settings class can implement the function
get_virtual_iface_name() if the connection needs to be auto connected
to a specific kernel interface.

Signed-off-by: Thomas Graf <[email protected]>
---
 libnm-util/libnm-util.ver    |    2 +
 libnm-util/nm-connection.c   |   51 ++++++++++++++++++++++++++++++++++++++++++
 libnm-util/nm-connection.h   |    2 +
 libnm-util/nm-setting-bond.c |    9 +++++++
 libnm-util/nm-setting.c      |   20 ++++++++++++++++
 libnm-util/nm-setting.h      |    5 +++-
 src/nm-device-ethernet.c     |   26 ++-------------------
 src/settings/nm-settings.c   |    7 +++--
 8 files changed, 95 insertions(+), 27 deletions(-)

diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index 7ec6b43a..e312aa1 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -33,6 +33,7 @@ global:
        nm_connection_get_setting_wired;
        nm_connection_get_setting_wireless;
        nm_connection_get_setting_wireless_security;
+       nm_connection_get_virtual_iface_name;
        nm_connection_get_type;
        nm_connection_get_uuid;
        nm_connection_is_type;
@@ -303,6 +304,7 @@ global:
        nm_setting_ip6_config_remove_dns;
        nm_setting_ip6_config_remove_dns_search;
        nm_setting_ip6_config_remove_route;
+       nm_setting_get_virtual_iface_name;
        nm_setting_need_secrets;
        nm_setting_new_from_hash;
        nm_setting_olpc_mesh_error_get_type;
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index 9bae63b..a63050e 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -496,6 +496,33 @@ nm_connection_get_setting_by_name (NMConnection 
*connection, const char *name)
        return type ? nm_connection_get_setting (connection, type) : NULL;
 }
 
+/**
+ * nm_connection_get_type_setting:
+ * @connection: a #NMConnection
+ *
+ * Returns: (transfer none): the #NMSetting of the connection base type
+ */
+static NMSetting *
+nm_connection_get_type_setting (NMConnection *connection)
+{
+       NMSettingConnection *s_con;
+       const char *type;
+       NMSetting *base;
+
+       g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
+
+       s_con = nm_connection_get_setting_connection (connection);
+       g_assert (s_con);
+
+       type = nm_setting_connection_get_connection_type (s_con);
+       g_assert (type);
+
+       base = nm_connection_get_setting_by_name (connection, type);
+       g_assert (base);
+
+       return base;
+}
+
 static gboolean
 validate_permissions_type (GHashTable *hash, GError **error)
 {
@@ -1189,6 +1216,30 @@ nm_connection_get_path (NMConnection *connection)
 }
 
 /**
+ * nm_connection_get_virtual_iface_name:
+ * @connection: The #NMConnection
+ *
+ * Returns the name of the virtual kernel interface which the connection
+ * needs to use if specified in the settings. This function abstracts all
+ * connection types which require this functionality. For all other
+ * connection types, this function will return NULL.
+ *
+ * Returns: Name of the kernel interface or NULL
+ */
+const char *
+nm_connection_get_virtual_iface_name (NMConnection *connection)
+{
+       NMSetting *base;
+
+       g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
+
+       base = nm_connection_get_type_setting (connection);
+       g_assert (base);
+
+       return nm_setting_get_virtual_iface_name (base);
+}
+
+/**
  * nm_connection_new:
  *
  * Creates a new #NMConnection object with no #NMSetting objects.
diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h
index abe74d2..28dce12 100644
--- a/libnm-util/nm-connection.h
+++ b/libnm-util/nm-connection.h
@@ -164,6 +164,8 @@ void          nm_connection_set_path      (NMConnection 
*connection,
 
 const char *  nm_connection_get_path      (NMConnection *connection);
 
+const char *  nm_connection_get_virtual_iface_name (NMConnection *connection);
+
 gboolean      nm_connection_is_type (NMConnection *connection, const char 
*type);
 
 void          nm_connection_for_each_setting_value (NMConnection *connection,
diff --git a/libnm-util/nm-setting-bond.c b/libnm-util/nm-setting-bond.c
index 582e1f9..3aa9cf3 100644
--- a/libnm-util/nm-setting-bond.c
+++ b/libnm-util/nm-setting-bond.c
@@ -287,6 +287,14 @@ verify (NMSetting *setting, GSList *all_settings, GError 
**error)
        return TRUE;
 }
 
+static const char *
+get_virtual_iface_name (NMSetting *setting)
+{
+       NMSettingBond *self = NM_SETTING_BOND (setting);
+
+       return nm_setting_bond_get_interface_name (self);
+}
+
 static void
 nm_setting_bond_init (NMSettingBond *setting)
 {
@@ -389,6 +397,7 @@ nm_setting_bond_class_init (NMSettingBondClass 
*setting_class)
        object_class->get_property = get_property;
        object_class->finalize     = finalize;
        parent_class->verify       = verify;
+       parent_class->get_virtual_iface_name = get_virtual_iface_name;
 
        /* Properties */
        /**
diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c
index 2b3bdc5..9402bc9 100644
--- a/libnm-util/nm-setting.c
+++ b/libnm-util/nm-setting.c
@@ -992,6 +992,26 @@ nm_setting_to_string (NMSetting *setting)
        return g_string_free (string, FALSE);
 }
 
+/**
+ * nm_setting_get_virtual_iface_name:
+ * @setting: the #NMSetting
+ *
+ * Returns the name of the virtual kernel interface which the connection
+ * needs to use if specified in the settings.
+ *
+ * Returns: (transfer full) (element-type utf8): Name of the virtual interface
+ **/
+const char *
+nm_setting_get_virtual_iface_name (NMSetting *setting)
+{
+       g_return_val_if_fail (NM_IS_SETTING (setting), NULL);
+
+       if (NM_SETTING_GET_CLASS (setting)->get_virtual_iface_name)
+               return NM_SETTING_GET_CLASS (setting)->get_virtual_iface_name 
(setting);
+
+       return NULL;
+}
+
 /*****************************************************************************/
 
 static void
diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h
index 3edf2a1..843b791 100644
--- a/libnm-util/nm-setting.h
+++ b/libnm-util/nm-setting.h
@@ -203,9 +203,10 @@ typedef struct {
                                                 
NMSettingClearSecretsWithFlagsFn func,
                                                 gpointer user_data);
 
+       const char *(*get_virtual_iface_name) (NMSetting *setting);
+
        /* Padding for future expansion */
        void (*_reserved1) (void);
-       void (*_reserved2) (void);
 } NMSettingClass;
 
 /**
@@ -308,6 +309,8 @@ gboolean    nm_setting_set_secret_flags (NMSetting *setting,
                                          NMSettingSecretFlags flags,
                                          GError **error);
 
+const char *nm_setting_get_virtual_iface_name (NMSetting *setting);
+
 G_END_DECLS
 
 #endif /* NM_SETTING_H */
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index 1c311eb..4951c94 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -379,23 +379,6 @@ nm_device_ethernet_new (const char *udi,
                                          NULL);
 }
 
-
-gboolean
-nm_device_bond_connection_matches (NMDevice *device, NMConnection *connection)
-{
-       NMSettingBond *s_bond;
-       const char *devname;
-
-       devname = nm_device_get_iface (device);
-       g_assert(devname);
-
-       s_bond = nm_connection_get_setting_bond (connection);
-       if (s_bond && !strcmp (devname, nm_setting_bond_get_interface_name 
(s_bond)))
-               return TRUE;
-
-       return FALSE;
-}
-
 /* Returns speed in Mb/s */
 static guint32
 nm_device_ethernet_get_speed (NMDeviceEthernet *self)
@@ -645,7 +628,7 @@ real_get_best_auto_connection (NMDevice *dev,
                NMConnection *connection = NM_CONNECTION (iter->data);
                NMSettingConnection *s_con;
                NMSettingWired *s_wired;
-               const char *connection_type;
+               const char *connection_type, *iface;
                gboolean is_pppoe = FALSE;
                const GSList *mac_blacklist, *mac_blacklist_iter;
                gboolean mac_blacklist_found = FALSE;
@@ -655,12 +638,9 @@ real_get_best_auto_connection (NMDevice *dev,
 
                connection_type = nm_setting_connection_get_connection_type 
(s_con);
 
-               if (!strcmp (connection_type, NM_SETTING_BOND_SETTING_NAME)) {
-                       if (nm_device_bond_connection_matches (dev, connection))
-                               return connection;
-
+               iface = nm_connection_get_virtual_iface_name (connection);
+               if (iface && strcmp (nm_device_get_iface (dev), iface))
                        continue;
-               }
        
                if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
                        is_pppoe = TRUE;
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 6cd61e8..49a26d7 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -1239,13 +1239,14 @@ have_connection_for_device (NMSettings *self, 
GByteArray *mac, NMDevice *device)
        g_hash_table_iter_init (&iter, priv->connections);
        while (g_hash_table_iter_next (&iter, NULL, &data)) {
                NMConnection *connection = NM_CONNECTION (data);
-               const char *ctype;
+               const char *ctype, *iface;
 
                s_con = nm_connection_get_setting_connection (connection);
                ctype = nm_setting_connection_get_connection_type (s_con);
 
-               if (!strcmp (ctype, NM_SETTING_BOND_SETTING_NAME)) {
-                       if (nm_device_bond_connection_matches (device, 
connection)) {
+               iface = nm_connection_get_virtual_iface_name (connection);
+               if (iface) {
+                       if (!strcmp (iface, nm_device_get_iface (device))) {
                                ret = TRUE;
                                break;
                        } else
-- 
1.7.7.3

_______________________________________________
networkmanager-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to