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 <tgraf@redhat.com>
This commit is contained in:
Thomas Graf 2011-12-07 13:15:18 +01:00 committed by Dan Williams
parent b366ebe321
commit 1cd8d52061
8 changed files with 95 additions and 27 deletions

View file

@ -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;

View file

@ -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:
*

View file

@ -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,

View file

@ -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 */
/**

View file

@ -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

View file

@ -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 */

View file

@ -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;

View file

@ -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