From 1cd8d520611915136f5e3e95f64e823f7cbf3b49 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 7 Dec 2011 13:15:18 +0100 Subject: [PATCH] bonding: add nm_connection_get_virtual_iface_name() to abstract kernel interface binding 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 --- 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 7ec6b43a23..e312aa19c0 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 9bae63b56b..a63050e85c 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) { @@ -1188,6 +1215,30 @@ nm_connection_get_path (NMConnection *connection) return NM_CONNECTION_GET_PRIVATE (connection)->path; } +/** + * 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: * diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index abe74d2888..28dce127fc 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 582e1f9668..3aa9cf3d92 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 2b3bdc58d7..9402bc96af 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 3edf2a1f31..843b7918a3 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 1c311eb7e8..4951c943d6 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 6cd61e8401..49a26d796e 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