merge: branch 'th/lr/conn-device-ifname'

https://bugzilla.gnome.org/show_bug.cgi?id=762154
This commit is contained in:
Lubomir Rintel 2016-02-17 19:03:35 +01:00
commit 84543df1db
13 changed files with 102 additions and 147 deletions

View file

@ -75,7 +75,6 @@ check_connection_available (NMDevice *device,
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
const char *iface;
NMSettingBond *s_bond;
if (!NM_DEVICE_CLASS (nm_device_bond_parent_class)->check_connection_compatible (device, connection))
@ -85,11 +84,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_bond || !nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME))
return FALSE;
/* Bond connections must specify the virtual interface name */
iface = nm_connection_get_interface_name (connection);
if (!iface || strcmp (nm_device_get_iface (device), iface))
return FALSE;
/* FIXME: match bond properties like mode, etc? */
return TRUE;

View file

@ -73,7 +73,6 @@ check_connection_available (NMDevice *device,
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
const char *iface;
NMSettingBridge *s_bridge;
const char *mac_address;
@ -84,11 +83,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_bridge || !nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME))
return FALSE;
/* Bridge connections must specify the virtual interface name */
iface = nm_connection_get_interface_name (connection);
if (!iface || strcmp (nm_device_get_iface (device), iface))
return FALSE;
mac_address = nm_setting_bridge_get_mac_address (s_bridge);
if (mac_address && nm_device_is_real (device)) {
const char *hw_addr;

View file

@ -157,57 +157,31 @@ nm_device_factory_get_connection_parent (NMDeviceFactory *factory,
return NULL;
}
static char *
get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
const char *iface;
/* For any other virtual connection, NMSettingConnection:interface-name is
* the virtual device name.
*/
iface = nm_connection_get_interface_name (connection);
g_return_val_if_fail (iface != NULL, NULL);
return g_strdup (iface);
}
char *
nm_device_factory_get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface,
GError **error)
nm_device_factory_get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface,
GError **error)
{
NMDeviceFactoryInterface *klass;
char *ifname;
g_return_val_if_fail (factory != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (!error || !*error, NULL);
if (!nm_connection_is_virtual (connection)) {
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"failed to determine virtual interface name: connection type '%s' is not a software device",
nm_connection_get_connection_type (connection));
return NULL;
}
klass = NM_DEVICE_FACTORY_GET_INTERFACE (factory);
if (!NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_virtual_iface_name) {
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"failed to determine virtual interface name: cannot generate name for %s",
nm_connection_get_connection_type (connection));
return NULL;
}
if (klass->get_connection_iface)
ifname = klass->get_connection_iface (factory, connection, parent_iface);
else
ifname = g_strdup (nm_connection_get_interface_name (connection));
ifname = NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_virtual_iface_name (factory, connection, parent_iface);
if (!ifname) {
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"failed to determine virtual interface name: error generating name for %s",
"failed to determine interface name: error determine name for %s",
nm_connection_get_connection_type (connection));
return NULL;
}
@ -216,7 +190,7 @@ nm_device_factory_get_virtual_iface_name (NMDeviceFactory *factory,
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"failed to determine virtual interface name: invalid name \"%s\" generated",
"failed to determine interface name: name \"%s\" is invalid",
ifname);
g_free (ifname);
return NULL;
@ -230,8 +204,6 @@ nm_device_factory_get_virtual_iface_name (NMDeviceFactory *factory,
static void
nm_device_factory_default_init (NMDeviceFactoryInterface *factory_iface)
{
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
/* Signals */
signals[DEVICE_ADDED] = g_signal_new (NM_DEVICE_FACTORY_DEVICE_ADDED,
NM_TYPE_DEVICE_FACTORY,

View file

@ -101,19 +101,19 @@ typedef struct {
NMConnection *connection);
/**
* get_virtual_iface_name:
* get_connection_iface:
* @factory: the #NMDeviceFactory
* @connection: the #NMConnection to return the virtual interface name for
* @parent_iface: parent interface name
* @connection: the #NMConnection to return the interface name for
* @parent_iface: optional parent interface name for virtual devices
*
* Given a connection, returns the interface name that a device activating
* that connection would have.
*
* Returns: the interface name, or %NULL
*/
char * (*get_virtual_iface_name) (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface);
char * (*get_connection_iface) (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface);
/**
* create_device:
@ -175,10 +175,10 @@ void nm_device_factory_get_supported_types (NMDeviceFactory *factory,
const char *nm_device_factory_get_connection_parent (NMDeviceFactory *factory,
NMConnection *connection);
char * nm_device_factory_get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface,
GError **error);
char * nm_device_factory_get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface,
GError **error);
void nm_device_factory_start (NMDeviceFactory *factory);

View file

@ -399,9 +399,9 @@ get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
}
static char *
get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
NMSettingInfiniband *s_infiniband;
@ -423,6 +423,6 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL (INFINIBAND, Infiniband, infiniband,
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_INFINIBAND_SETTING_NAME),
factory_iface->create_device = create_device;
factory_iface->get_connection_parent = get_connection_parent;
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
factory_iface->get_connection_iface = get_connection_iface;
)

View file

@ -1023,9 +1023,9 @@ get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
}
static char *
get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
const char *ifname;
NMSettingIPTunnel *s_ip_tunnel;
@ -1048,5 +1048,5 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL (IP_TUNNEL, IPTunnel, ip_tunnel,
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_IP_TUNNEL_SETTING_NAME),
factory_iface->create_device = create_device;
factory_iface->get_connection_parent = get_connection_parent;
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
factory_iface->get_connection_iface = get_connection_iface;
)

View file

@ -376,7 +376,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
NMSettingMacvlan *s_macvlan;
const char *parent, *iface = NULL;
const char *parent = NULL;
if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->check_connection_compatible (device, connection))
return FALSE;
@ -409,13 +409,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
}
}
/* Ensure the interface name matches */
iface = nm_connection_get_interface_name (connection);
if (iface) {
if (g_strcmp0 (nm_device_get_ip_iface (device), iface) != 0)
return FALSE;
}
return TRUE;
}
@ -744,9 +737,9 @@ get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
}
static char *
get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
NMSettingMacvlan *s_macvlan;
const char *ifname;
@ -768,6 +761,6 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL (MACVLAN, Macvlan, macvlan,
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_MACVLAN_SETTING_NAME),
factory_iface->create_device = create_device;
factory_iface->get_connection_parent = get_connection_parent;
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
factory_iface->get_connection_iface = get_connection_iface;
)

View file

@ -390,7 +390,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device);
NMSettingVlan *s_vlan;
const char *parent, *iface = NULL;
const char *parent = NULL;
if (!NM_DEVICE_CLASS (nm_device_vlan_parent_class)->check_connection_compatible (device, connection))
return FALSE;
@ -416,16 +416,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
}
}
/* Ensure the interface name matches. If not specified we assume a match
* since both the parent interface and the VLAN ID matched by the time we
* get here.
*/
iface = nm_connection_get_interface_name (connection);
if (iface) {
if (g_strcmp0 (nm_device_get_ip_iface (device), iface) != 0)
return FALSE;
}
return TRUE;
}
@ -758,9 +748,9 @@ get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
}
static char *
get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
const char *ifname;
NMSettingVlan *s_vlan;
@ -789,6 +779,6 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL (VLAN, Vlan, vlan,
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_VLAN_SETTING_NAME),
factory_iface->create_device = create_device;
factory_iface->get_connection_parent = get_connection_parent;
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
factory_iface->get_connection_iface = get_connection_iface;
)

View file

@ -296,7 +296,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
NMSettingVxlan *s_vxlan;
const char *iface, *parent;
const char *parent;
if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->check_connection_compatible (device, connection))
return FALSE;
@ -305,12 +305,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_vxlan)
return FALSE;
iface = nm_connection_get_interface_name (connection);
if (iface) {
if (g_strcmp0 (nm_device_get_ip_iface (device), iface) != 0)
return FALSE;
}
if (nm_device_is_real (device)) {
parent = nm_setting_vxlan_get_parent (s_vxlan);
if ( parent
@ -810,9 +804,9 @@ get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
}
static char *
get_virtual_iface_name (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
get_connection_iface (NMDeviceFactory *factory,
NMConnection *connection,
const char *parent_iface)
{
const char *ifname;
NMSettingVxlan *s_vxlan;
@ -834,6 +828,6 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL (VXLAN, Vxlan, vxlan,
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_VXLAN_SETTING_NAME),
factory_iface->create_device = create_device;
factory_iface->get_connection_parent = get_connection_parent;
factory_iface->get_virtual_iface_name = get_virtual_iface_name;
factory_iface->get_connection_iface = get_connection_iface;
)

View file

@ -2958,15 +2958,18 @@ nm_device_complete_connection (NMDevice *self,
static gboolean
check_connection_compatible (NMDevice *self, NMConnection *connection)
{
NMSettingConnection *s_con;
const char *config_iface, *device_iface;
const char *device_iface = nm_device_get_iface (self);
gs_free char *conn_iface = nm_manager_get_connection_iface (nm_manager_get (),
connection,
NULL, NULL);
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
/* We always need a interface name for virtual devices, but for
* physical ones a connection without interface name is fine for
* any device. */
if (!conn_iface)
return !nm_connection_is_virtual (connection);
config_iface = nm_setting_connection_get_interface_name (s_con);
device_iface = nm_device_get_iface (self);
if (config_iface && strcmp (config_iface, device_iface) != 0)
if (strcmp (conn_iface, device_iface) != 0)
return FALSE;
return TRUE;

View file

@ -85,7 +85,6 @@ check_connection_available (NMDevice *device,
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
const char *iface;
NMSettingTeam *s_team;
if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->check_connection_compatible (device, connection))
@ -95,11 +94,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_team || !nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME))
return FALSE;
/* Team connections must specify the virtual interface name */
iface = nm_connection_get_interface_name (connection);
if (!iface || strcmp (nm_device_get_iface (device), iface))
return FALSE;
/* FIXME: match team properties like mode, etc? */
return TRUE;

View file

@ -896,7 +896,7 @@ nm_manager_get_state (NMManager *manager)
/***************************/
static NMDevice *
find_parent_device_for_connection (NMManager *self, NMConnection *connection)
find_parent_device_for_connection (NMManager *self, NMConnection *connection, NMDeviceFactory *cached_factory)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMDeviceFactory *factory;
@ -907,9 +907,12 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection)
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
factory = nm_device_factory_manager_find_factory_for_connection (connection);
if (!factory)
return NULL;
if (!cached_factory) {
factory = nm_device_factory_manager_find_factory_for_connection (connection);
if (!factory)
return NULL;
} else
factory = cached_factory;
parent_name = nm_device_factory_get_connection_parent (factory, connection);
if (!parent_name)
@ -948,24 +951,24 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection)
}
/**
* get_virtual_iface_name:
* nm_manager_get_connection_iface:
* @self: the #NMManager
* @connection: the #NMConnection representing a virtual interface
* @connection: the #NMConnection to get the interface for
* @out_parent: on success, the parent device if any
* @error: an error if determining the virtual interface name failed
*
* Given @connection, returns the interface name that the connection
* would represent if it is a virtual connection. %NULL is returned and
* @error is set if the connection is not virtual, or if the name could
* not be determined.
* would need to use when activated. %NULL is returned if the name
* is not specified in connection or a the name for a virtual device
* could not be generated.
*
* Returns: the expected interface name (caller takes ownership), or %NULL
*/
static char *
get_virtual_iface_name (NMManager *self,
NMConnection *connection,
NMDevice **out_parent,
GError **error)
char *
nm_manager_get_connection_iface (NMManager *self,
NMConnection *connection,
NMDevice **out_parent,
GError **error)
{
NMDeviceFactory *factory;
char *iface = NULL;
@ -984,11 +987,25 @@ get_virtual_iface_name (NMManager *self,
return NULL;
}
parent = find_parent_device_for_connection (self, connection);
iface = nm_device_factory_get_virtual_iface_name (factory,
connection,
parent ? nm_device_get_ip_iface (parent) : NULL,
error);
if ( !out_parent
&& !NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_connection_iface) {
/* optimization. Shortcut lookup of the partent device. */
iface = g_strdup (nm_connection_get_interface_name (connection));
if (!iface) {
g_set_error (error,
NM_MANAGER_ERROR,
NM_MANAGER_ERROR_FAILED,
"failed to determine interface name: error determine name for %s",
nm_connection_get_connection_type (connection));
}
return iface;
}
parent = find_parent_device_for_connection (self, connection, factory);
iface = nm_device_factory_get_connection_iface (factory,
connection,
parent ? nm_device_get_ip_iface (parent) : NULL,
error);
if (!iface)
return NULL;
@ -1021,7 +1038,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
iface = get_virtual_iface_name (self, connection, &parent, &error);
iface = nm_manager_get_connection_iface (self, connection, &parent, &error);
if (!iface) {
nm_log_warn (LOGD_DEVICE, "(%s) can't get a name of a virtual device: %s",
nm_connection_get_id (connection), error->message);
@ -1033,9 +1050,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
NMDevice *candidate = iter->data;
if ( g_strcmp0 (nm_device_get_iface (candidate), iface) == 0
&& nm_device_check_connection_compatible (candidate, connection)) {
if (nm_device_check_connection_compatible (candidate, connection)) {
if (nm_device_is_real (candidate)) {
nm_log_dbg (LOGD_DEVICE, "(%s) already created virtual interface name %s",
nm_connection_get_id (connection), iface);
@ -1121,7 +1136,7 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device)
NMConnection *candidate = iter->data;
NMDevice *parent;
parent = find_parent_device_for_connection (self, candidate);
parent = find_parent_device_for_connection (self, candidate, NULL);
if (parent == device)
connection_changed (priv->settings, candidate, self);
}
@ -2772,7 +2787,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
if (!nm_device_is_real (device)) {
NMDevice *parent;
parent = find_parent_device_for_connection (self, (NMConnection *) connection);
parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL);
if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
return FALSE;
@ -3219,7 +3234,7 @@ validate_activation_request (NMManager *self,
char *iface;
/* Look for an existing device with the connection's interface name */
iface = get_virtual_iface_name (self, connection, NULL, error);
iface = nm_manager_get_connection_iface (self, connection, NULL, error);
if (!iface)
goto error;

View file

@ -101,6 +101,11 @@ const GSList * nm_manager_get_devices (NMManager *manager);
NMDevice * nm_manager_get_device_by_ifindex (NMManager *manager,
int ifindex);
char * nm_manager_get_connection_iface (NMManager *self,
NMConnection *connection,
NMDevice **out_parent,
GError **error);
NMActiveConnection *nm_manager_activate_connection (NMManager *manager,
NMSettingsConnection *connection,
const char *specific_object,
@ -113,4 +118,5 @@ gboolean nm_manager_deactivate_connection (NMManager *manager,
NMDeviceStateReason reason,
GError **error);
#endif /* __NETWORKMANAGER_MANAGER_H__ */