Commit 4dbaac4b authored by Dan Williams's avatar Dan Williams Committed by Thomas Haller

core: create devices first and realize them later

Unrealized devices aren't backed by kernel resources and so won't know
all of their attributes.  That means three things:

1) they must update their attributes when they become realized
2) they must clear those attributes when unrealized
3) they must be looser in checking compatible connections until
they are realized

This requires that the setup() function be split into two parts, start & finish,
because finish must be run after add_device()

Also, we can simplify whether to pay attention to 'recheck-assume', which
is now dependent on priv->is_nm_owned, because the only case where NM should
*not* listen for the 'recheck-assume' signal is when the device is a
software device created by NM itself.  That logic was previously spread
across the callers of add_device() but is now consolidated into
nm-manager.c::device_realized() and nm-device.c::nm_device_create_and_realize().
parent b7eb622c
......@@ -97,7 +97,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
return FALSE;
mac_address = nm_setting_bridge_get_mac_address (s_bridge);
if (mac_address) {
if (mac_address && nm_device_is_real (device)) {
const char *hw_addr;
hw_addr = nm_device_get_hw_address (device);
......
......@@ -305,9 +305,9 @@ nm_device_ethernet_init (NMDeviceEthernet *self)
}
static void
setup (NMDevice *device, NMPlatformLink *plink)
setup_start (NMDevice *device, NMPlatformLink *plink)
{
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->setup (device, plink);
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->setup_start (device, plink);
g_object_notify (G_OBJECT (device), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
}
......@@ -1716,7 +1716,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
object_class->set_property = set_property;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->setup = setup;
parent_class->setup_start = setup_start;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->complete_connection = complete_connection;
parent_class->new_default_connection = new_default_connection;
......
......@@ -61,13 +61,13 @@ get_type_description (NMDevice *device)
}
static void
setup (NMDevice *device, NMPlatformLink *plink)
setup_start (NMDevice *device, NMPlatformLink *plink)
{
NMDeviceGeneric *self = NM_DEVICE_GENERIC (device);
NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self);
int ifindex;
NM_DEVICE_CLASS (nm_device_generic_parent_class)->setup (device, plink);
NM_DEVICE_CLASS (nm_device_generic_parent_class)->setup_start (device, plink);
g_clear_pointer (&priv->type_description, g_free);
ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self));
......@@ -203,7 +203,7 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
parent_class->setup = setup;
parent_class->setup_start = setup_start;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->get_type_description = get_type_description;
parent_class->check_connection_compatible = check_connection_compatible;
......
......@@ -149,7 +149,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_infiniband)
return FALSE;
if (s_infiniband) {
if (nm_device_is_real (device)) {
const char *mac;
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
......
......@@ -503,41 +503,43 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_ip_tunnel)
return FALSE;
/* Check parent interface; could be an interface name or a UUID */
parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
if (parent) {
if (!match_parent (priv->parent, parent))
return FALSE;
}
if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode)
return FALSE;
if (!address_equal_pp (priv->addr_family,
nm_setting_ip_tunnel_get_local (s_ip_tunnel),
priv->local))
return FALSE;
if (!address_equal_pp (priv->addr_family,
nm_setting_ip_tunnel_get_remote (s_ip_tunnel),
priv->remote))
return FALSE;
if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl)
return FALSE;
if (nm_device_is_real (device)) {
/* Check parent interface; could be an interface name or a UUID */
parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
if (parent) {
if (!match_parent (priv->parent, parent))
return FALSE;
}
if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos)
return FALSE;
if (!address_equal_pp (priv->addr_family,
nm_setting_ip_tunnel_get_local (s_ip_tunnel),
priv->local))
return FALSE;
if (priv->addr_family == AF_INET) {
if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery)
if (!address_equal_pp (priv->addr_family,
nm_setting_ip_tunnel_get_remote (s_ip_tunnel),
priv->remote))
return FALSE;
} else {
if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit)
if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl)
return FALSE;
if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label)
if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos)
return FALSE;
if (priv->addr_family == AF_INET) {
if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery)
return FALSE;
} else {
if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit)
return FALSE;
if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label)
return FALSE;
}
}
return TRUE;
......@@ -751,9 +753,9 @@ create_and_realize (NMDevice *device,
}
static void
setup (NMDevice *device, NMPlatformLink *plink)
setup_start (NMDevice *device, NMPlatformLink *plink)
{
NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->setup (device, plink);
NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->setup_start (device, plink);
update_properties (device);
}
......@@ -847,7 +849,7 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
device_class->check_connection_compatible = check_connection_compatible;
device_class->create_and_realize = create_and_realize;
device_class->realize = realize;
device_class->setup = setup;
device_class->setup_start = setup_start;
device_class->unrealize = unrealize;
device_class->connection_type = NM_SETTING_IP_TUNNEL_SETTING_NAME;
......
......@@ -226,6 +226,13 @@ realize (NMDevice *device, NMPlatformLink *plink, GError **error)
return TRUE;
}
static void
setup_start (NMDevice *device, NMPlatformLink *plink)
{
NM_DEVICE_CLASS (nm_device_tun_parent_class)->setup_start (device, plink);
reload_tun_properties (device);
}
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
......@@ -235,8 +242,6 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
NMSettingTun *s_tun;
gint64 user, group;
reload_tun_properties (self);
if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->check_connection_compatible (device, connection))
return FALSE;
......@@ -244,23 +249,25 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_tun)
return FALSE;
mode = tun_mode_from_string (priv->mode);
if (mode != nm_setting_tun_get_mode (s_tun))
return FALSE;
user = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_owner (s_tun), 10, 0, G_MAXINT32, -1);
group = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_group (s_tun), 10, 0, G_MAXINT32, -1);
if (user != priv->props.owner)
return FALSE;
if (group != priv->props.group)
return FALSE;
if (nm_setting_tun_get_pi (s_tun) == priv->props.no_pi)
return FALSE;
if (nm_setting_tun_get_vnet_hdr (s_tun) != priv->props.vnet_hdr)
return FALSE;
if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue)
return FALSE;
if (nm_device_is_real (device)) {
mode = tun_mode_from_string (priv->mode);
if (mode != nm_setting_tun_get_mode (s_tun))
return FALSE;
user = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_owner (s_tun), 10, 0, G_MAXINT32, -1);
group = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_group (s_tun), 10, 0, G_MAXINT32, -1);
if (user != priv->props.owner)
return FALSE;
if (group != priv->props.group)
return FALSE;
if (nm_setting_tun_get_pi (s_tun) == priv->props.no_pi)
return FALSE;
if (nm_setting_tun_get_vnet_hdr (s_tun) != priv->props.vnet_hdr)
return FALSE;
if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue)
return FALSE;
}
return TRUE;
}
......@@ -367,6 +374,7 @@ nm_device_tun_class_init (NMDeviceTunClass *klass)
device_class->check_connection_compatible = check_connection_compatible;
device_class->create_and_realize = create_and_realize;
device_class->realize = realize;
device_class->setup_start = setup_start;
device_class->unrealize = unrealize;
device_class->update_connection = update_connection;
......
......@@ -148,12 +148,12 @@ nm_device_vlan_set_parent (NMDeviceVlan *self, NMDevice *parent)
}
static void
setup (NMDevice *device, NMPlatformLink *plink)
setup_start (NMDevice *device, NMPlatformLink *plink)
{
NMDeviceVlan *self = NM_DEVICE_VLAN (device);
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);
NM_DEVICE_CLASS (nm_device_vlan_parent_class)->setup (device, plink);
NM_DEVICE_CLASS (nm_device_vlan_parent_class)->setup_start (device, plink);
_LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s",
priv->vlan_id, nm_device_get_iface (priv->parent));
......@@ -311,6 +311,9 @@ notify_new_device_added (NMDevice *device, NMDevice *new_device)
if (priv->parent)
return;
if (!nm_device_is_real (device))
return;
plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink);
if (!plnk) {
_LOGW (LOGD_VLAN, "failed to get VLAN interface info while checking added component.");
......@@ -397,18 +400,21 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
if (!s_vlan)
return FALSE;
if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id)
return FALSE;
/* Check parent interface; could be an interface name or a UUID */
parent = nm_setting_vlan_get_parent (s_vlan);
if (parent) {
if (!match_parent (NM_DEVICE_VLAN (device), parent))
return FALSE;
} else {
/* Parent could be a MAC address in an NMSettingWired */
if (!match_hwaddr (device, connection, TRUE))
/* Before the device is realized some properties will not be set */
if (nm_device_is_real (device)) {
if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id)
return FALSE;
/* Check parent interface; could be an interface name or a UUID */
parent = nm_setting_vlan_get_parent (s_vlan);
if (parent) {
if (!match_parent (NM_DEVICE_VLAN (device), parent))
return FALSE;
} else {
/* Parent could be a MAC address in an NMSettingWired */
if (!match_hwaddr (device, connection, TRUE))
return FALSE;
}
}
/* Ensure the interface name matches. If not specified we assume a match
......@@ -672,7 +678,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
parent_class->create_and_realize = create_and_realize;
parent_class->realize = realize;
parent_class->setup = setup;
parent_class->setup_start = setup_start;
parent_class->unrealize = unrealize;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->bring_up = bring_up;
......
......@@ -133,11 +133,11 @@ link_changed (NMDevice *device, NMPlatformLink *info)
}
static void
setup (NMDevice *device, NMPlatformLink *plink)
setup_start (NMDevice *device, NMPlatformLink *plink)
{
g_assert (plink->type == NM_LINK_TYPE_VXLAN);
NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->setup (device, plink);
NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->setup_start (device, plink);
update_properties (device);
}
......@@ -247,7 +247,7 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
object_class->get_property = get_property;
device_class->link_changed = link_changed;
device_class->setup = setup;
device_class->setup_start = setup_start;
device_class->unrealize = unrealize;
/* properties */
......
......@@ -556,7 +556,7 @@ nm_device_get_iface (NMDevice *self)
int
nm_device_get_ifindex (NMDevice *self)
{
g_return_val_if_fail (self != NULL, 0);
g_return_val_if_fail (NM_IS_DEVICE (self), 0);
return NM_DEVICE_GET_PRIVATE (self)->ifindex;
}
......@@ -1152,8 +1152,7 @@ nm_device_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure
static gboolean
can_unmanaged_external_down (NMDevice *self)
{
return nm_device_is_software (self)
&& !nm_device_get_is_nm_owned (self);
return nm_device_is_software (self) && !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
}
/**
......@@ -1385,23 +1384,31 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier)
}
static void
device_set_master (NMDevice *self, int ifindex)
device_recheck_slave_status (NMDevice *self, NMPlatformLink *plink)
{
NMDevice *master;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
master = nm_manager_get_device_by_ifindex (nm_manager_get (), ifindex);
if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) {
g_clear_object (&priv->master);
priv->master = g_object_ref (master);
nm_device_master_add_slave (master, self, FALSE);
} else if (master) {
_LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring",
nm_device_get_iface (master));
} else {
_LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
ifindex,
nm_platform_link_get_name (NM_PLATFORM_GET, ifindex));
g_return_if_fail (plink != NULL);
if (priv->enslaved && plink->master != nm_device_get_ifindex (priv->master))
nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
if (plink->master && !priv->enslaved) {
NMDevice *master;
master = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->master);
if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) {
g_clear_object (&priv->master);
priv->master = g_object_ref (master);
nm_device_master_add_slave (master, self, FALSE);
} else if (master) {
_LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring",
nm_device_get_iface (master));
} else {
_LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
plink->master,
nm_platform_link_get_name (NM_PLATFORM_GET, plink->master));
}
}
}
......@@ -1449,6 +1456,12 @@ device_link_changed (NMDevice *self)
g_object_notify (G_OBJECT (self), NM_DEVICE_MTU);
}
if (info.driver && g_strcmp0 (priv->driver, info.driver) != 0) {
g_free (priv->driver);
priv->driver = g_strdup (info.driver);
g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER);
}
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
priv->ifindex, priv->iface, info.name);
......@@ -1471,15 +1484,6 @@ device_link_changed (NMDevice *self)
nm_device_emit_recheck_auto_activate (self);
}
/* Update slave status for external changes */
if (priv->enslaved && info.master != nm_device_get_ifindex (priv->master))
nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
if (info.master && !priv->enslaved) {
device_set_master (self, info.master);
if (priv->master)
nm_device_enslave_slave (priv->master, self, NULL);
}
if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) {
_LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
if (nm_rdisc_set_iid (priv->rdisc, token_iid))
......@@ -1562,6 +1566,7 @@ device_link_changed (NMDevice *self)
if (emit_link_initialized)
g_signal_emit (self, signals[LINK_INITIALIZED], 0);
device_recheck_slave_status (self, &info);
return G_SOURCE_REMOVE;
}
......@@ -1635,7 +1640,8 @@ link_changed (NMDevice *self, NMPlatformLink *info)
* @plink: an existing platform link or %NULL
* @error: location to store error, or %NULL
*
* Initializes and sets up the device using existing backing resources.
* Initializes and sets up the device using existing backing resources. Before
* the device is ready for use nm_device_setup_finish() must be called.
*
* Returns: %TRUE on success, %FALSE on error
*/
......@@ -1648,7 +1654,7 @@ nm_device_realize (NMDevice *self, NMPlatformLink *plink, GError **error)
return FALSE;
}
NM_DEVICE_GET_CLASS (self)->setup (self, plink);
NM_DEVICE_GET_CLASS (self)->setup_start (self, plink);
return TRUE;
}
......@@ -1671,15 +1677,20 @@ nm_device_create_and_realize (NMDevice *self,
NMDevice *parent,
GError **error)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMPlatformLink plink = { .type = NM_LINK_TYPE_UNKNOWN };
/* Must be set before device is realized */
priv->is_nm_owned = !nm_platform_link_get_by_ifname (NM_PLATFORM_GET, priv->iface);
/* Create any resources the device needs */
if (NM_DEVICE_GET_CLASS (self)->create_and_realize) {
if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error))
return FALSE;
}
NM_DEVICE_GET_CLASS (self)->setup (self, (plink.type != NM_LINK_TYPE_UNKNOWN) ? &plink : NULL);
NM_DEVICE_GET_CLASS (self)->setup_start (self, (plink.type != NM_LINK_TYPE_UNKNOWN) ? &plink : NULL);
nm_device_setup_finish (self, (plink.type != NM_LINK_TYPE_UNKNOWN) ? &plink : NULL);
g_return_val_if_fail (nm_device_check_connection_compatible (self, connection), TRUE);
return TRUE;
......@@ -1742,7 +1753,7 @@ check_carrier (NMDevice *self)
}
static void
setup (NMDevice *self, NMPlatformLink *plink)
setup_start (NMDevice *self, NMPlatformLink *plink)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
static guint32 id = 0;
......@@ -1751,6 +1762,7 @@ setup (NMDevice *self, NMPlatformLink *plink)
g_return_if_fail (priv->ip_ifindex <= 0);
g_return_if_fail (priv->ip_iface == NULL);
/* Balanced by a thaw in nm_device_setup_finish() */
g_object_freeze_notify (G_OBJECT (self));
if (plink) {
......@@ -1759,7 +1771,7 @@ setup (NMDevice *self, NMPlatformLink *plink)
}
if (priv->ifindex > 0) {
_LOGD (LOGD_DEVICE, "setup(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex);
_LOGD (LOGD_DEVICE, "setup_start(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex);
priv->physical_port_id = nm_platform_link_get_physical_port_id (NM_PLATFORM_GET, priv->ifindex);
g_object_notify (G_OBJECT (self), NM_DEVICE_PHYSICAL_PORT_ID);
......@@ -1844,17 +1856,29 @@ setup (NMDevice *self, NMPlatformLink *plink)
g_object_notify (G_OBJECT (self), NM_DEVICE_CAPABILITIES);
/* Enslave ourselves */
if (priv->ifindex > 0) {
int master = nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex);
priv->real = TRUE;
}
if (master > 0)
device_set_master (self, master);
static void
setup_finish (NMDevice *self, NMPlatformLink *plink)
{
if (plink) {
update_device_from_platform_link (self, plink);
device_recheck_slave_status (self, plink);
}
}
priv->real = TRUE;
void
nm_device_setup_finish (NMDevice *self, NMPlatformLink *plink)
{
NM_DEVICE_GET_CLASS (self)->setup_finish (self, plink);
NM_DEVICE_GET_PRIVATE (self)->real = TRUE;
g_object_notify (G_OBJECT (self), NM_DEVICE_REAL);
nm_device_recheck_available_connections (self);
/* Balanced by a freeze in setup_start() */
g_object_thaw_notify (G_OBJECT (self));
}
......@@ -2810,7 +2834,8 @@ nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection)
static gboolean
nm_device_can_assume_connections (NMDevice *self)
{
return !!NM_DEVICE_GET_CLASS (self)->update_connection;
return !!NM_DEVICE_GET_CLASS (self)->update_connection
&& !NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
}
/**
......@@ -6547,14 +6572,6 @@ nm_device_get_is_nm_owned (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned;
}
void
nm_device_set_nm_owned (NMDevice *self)
{
g_return_if_fail (NM_IS_DEVICE (self));
NM_DEVICE_GET_PRIVATE (self)->is_nm_owned = TRUE;
}
/*
* delete_on_deactivate_link_delete
*
......@@ -8461,6 +8478,7 @@ _nm_device_check_connection_available (NMDevice *self,
&& nm_device_get_unmanaged (self, NM_UNMANAGED_ALL & ~NM_UNMANAGED_DEFAULT))
return FALSE;
if ( state < NM_DEVICE_STATE_DISCONNECTED
&& !nm_device_is_software (self)
&& ( ( !NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
&& !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE))
|| ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)
......@@ -10324,7 +10342,8 @@ nm_device_class_init (NMDeviceClass *klass)
klass->check_connection_compatible = check_connection_compatible;
klass->check_connection_available = check_connection_available;
klass->can_unmanaged_external_down = can_unmanaged_external_down;
klass->setup = setup;
klass->setup_start = setup_start;
klass->setup_finish = setup_finish;
klass->unrealize = unrealize;
klass->is_up = is_up;
klass->bring_up = bring_up;
......
......@@ -174,14 +174,28 @@ typedef struct {
GError **error);
/**
* setup():
* setup_start():
* @self: the #NMDevice
* @plink: the #NMPlatformLink if backed by a kernel netdevice
*
* Update the device from backing resource properties (like hardware
* addresses, carrier states, driver/firmware info, etc).
* addresses, carrier states, driver/firmware info, etc). This function
* should only change properties for this device, and should not perform
* any tasks that affect other interfaces (like master/slave or parent/child
* stuff).
*/
void (*setup) (NMDevice *self, NMPlatformLink *plink);
void (*setup_start) (NMDevice *self, NMPlatformLink *plink);
/**
* setup_finish():
* @self: the #NMDevice
* @plink: the #NMPlatformLink if backed by a kernel netdevice
*
* Update the device's master/slave or parent/child relationships from
* backing resource properties. After this function finishes, the device
* is ready for network connectivity.
*/
void (*setup_finish) (NMDevice *self, NMPlatformLink *plink);
/**
* unrealize():
......@@ -466,7 +480,6 @@ void nm_device_set_unmanaged_initial (NMDevice *device,
gboolean unmanaged);
gboolean nm_device_get_is_nm_owned (NMDevice *device);
void nm_device_set_nm_owned (NMDevice *device);
gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
......@@ -477,6 +490,8 @@ gboolean nm_device_create_and_realize (NMDevice *self,
NMConnection *connection,
NMDevice *parent,
GError **error);
void nm_device_setup_finish (NMDevice *self,
NMPlatformLink *plink);
gboolean nm_device_unrealize (NMDevice *device,
gboolean remove_resources,
GError **error);
......
......@@ -424,9 +424,9 @@ periodic_update_cb (gpointer user_data)
}
static void
setup (NMDevice *device, NMPlatformLink *plink)
setup_start (NMDevice *device, NMPlatformLink *plink)
{
NM_DEVICE_CLASS (nm_device_wifi_parent_class)->setup (device, plink);
NM_DEVICE_CLASS (nm_device_wifi_parent_class)->setup_start (device, plink);
g_object_notify (G_OBJECT (device), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
}
......@@ -3040,7 +3040,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
object_class->dispose = dispose;
object_class->finalize = finalize;
parent_class->setup = setup;
parent_class->setup_start = setup_start;
parent_class->bring_up = bring_up;
parent_class->can_auto_connect = can_auto_connect;
parent_class->is_available = is_available;
......
......@@ -598,17 +598,17 @@ master_state_cb (NMActiveConnection *master,
gpointer user_data)
{
NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
NMActiveConnectionState master_state = nm_active_connection_get_state (master);
NMDevice *master_device = nm_active_connection_get_device (master);
check_master_ready (self);