summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-10-26 13:43:49 +0200
committerThomas Haller <thaller@redhat.com>2016-10-27 11:53:18 +0200
commit4c52bc7fa90d0d6460303529b8e6701615f21bb8 (patch)
tree34f1e3cf71638c25896e66c99b4a59e5e7d21bc7
parentcb34de174db52238afa60cacfc2a90d8ff20c4fc (diff)
downloadNetworkManager-th/preserve-fake-perm-hwaddr-bgo772880.tar.gz
device: don't evaluate IP config changes until device is initializedth/preserve-fake-perm-hwaddr-bgo772880
The unmanaged flags PLATFORM_INIT indicates whether UDEV is done initializing the device. We should not handle IP config changes before that pointer. This avoids codepaths that require the permanent MAC address of the device. We should not freeze the permanent MAC address before UDEV initialized the device, for two reasons: - getting the permanent MAC address using ethtool is racy as UDEV might still rename the interface. - freezing a fake permanent MAC address should only happen after UDEV is done configuring the MAC address of software devices. #0 0x000055555568bc7a in nm_device_update_permanent_hw_address (self=self@entry=0x555555f0fb70 [NMDeviceVeth], force_freeze=force_freeze@entry=1) at src/devices/nm-device.c:11817 #1 0x000055555568c443 in nm_device_get_permanent_hw_address_full (self=self@entry=0x555555f0fb70 [NMDeviceVeth], force_freeze=force_freeze@entry=1, out_is_fake=out_is_fake@entry=0x0) at src/devices/nm-device.c:12227 #2 0x000055555568cb06 in nm_device_get_permanent_hw_address (self=self@entry=0x555555f0fb70 [NMDeviceVeth]) at src/devices/nm-device.c:12237 #3 0x000055555568cb50 in spec_match_list (self=0x555555f0fb70 [NMDeviceVeth], specs=0x555555a5c000 = {...}) at src/devices/nm-device.c:12294 #4 0x00005555556a4ee6 in spec_match_list (device=0x555555f0fb70 [NMDeviceVeth], specs=0x555555a5c000 = {...}) at src/devices/nm-device-ethernet.c:1461 #5 0x00005555556978db in nm_device_spec_match_list (self=self@entry=0x555555f0fb70 [NMDeviceVeth], specs=0x555555a5c000 = {...}) at src/devices/nm-device.c:12277 #6 0x000055555558e187 in _match_section_infos_lookup (match_section_infos=0x555555a5d500, keyfile=0x555555a46f80, property=property@entry=0x555555793123 "ipv4.route-metric", device=device@entry=0x555555f0fb70 [NMDeviceVeth], out_value=out_value@entry=0x7fffffffe018) at src/nm-config-data.c:1169 #7 0x00005555555922ca in nm_config_data_get_connection_default (self=0x555555a548c0 [NMConfigData], property=property@entry=0x555555793123 "ipv4.route-metric", device=device@entry=0x555555f0fb70 [NMDeviceVeth]) at src/nm-config-data.c:1234 #8 0x00005555556790cd in _get_ipx_route_metric (self=self@entry=0x555555f0fb70 [NMDeviceVeth], is_v4=is_v4@entry=1) at src/devices/nm-device.c:1142 #9 0x000055555567912e in nm_device_get_ip4_route_metric (self=self@entry=0x555555f0fb70 [NMDeviceVeth]) at src/devices/nm-device.c:1161 #10 0x000055555567da6c in ip4_config_merge_and_apply (self=self@entry=0x555555f0fb70 [NMDeviceVeth], config=config@entry=0x0, commit=commit@entry=0, out_reason=out_reason@entry=0x0) at src/devices/nm-device.c:4787 #11 0x000055555567e0fb in update_ip4_config (self=self@entry=0x555555f0fb70 [NMDeviceVeth], initial=initial@entry=0) at src/devices/nm-device.c:9532 #12 0x0000555555693acd in queued_ip4_config_change (user_data=0x555555f0fb70) at src/devices/nm-device.c:9651 #13 0x00007ffff4c966ba in g_main_context_dispatch (context=0x555555a46af0) at gmain.c:3154 #14 0x00007ffff4c966ba in g_main_context_dispatch (context=context@entry=0x555555a46af0) at gmain.c:3769 #15 0x00007ffff4c96a70 in g_main_context_iterate (context=0x555555a46af0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3840 #16 0x00007ffff4c96d92 in g_main_loop_run (loop=0x555555a47400) at gmain.c:4034 #17 0x000055555558372a in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:411
-rw-r--r--src/devices/nm-device.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 4df78089cc..11aa0126b7 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -233,7 +233,12 @@ typedef struct _NMDevicePrivate {
};
guint8 /*HwAddrType*/ hw_addr_type;
- bool real;
+ bool real:1;
+
+ /* there was a IP config change, but no idle action was scheduled because device
+ * is still not platform-init */
+ bool queued_ip4_config_pending:1;
+ bool queued_ip6_config_pending:1;
char * ip_iface;
int ip_ifindex;
@@ -2323,9 +2328,8 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
_notify (self, PROP_UDI);
}
- /* trigger initial ip config change to initialize ip-config */
- priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
- priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
+ priv->queued_ip4_config_pending = TRUE;
+ priv->queued_ip6_config_pending = TRUE;
nm_device_update_hw_address (self);
nm_device_update_initial_hw_address (self);
@@ -7698,6 +7702,7 @@ _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type)
if (nm_clear_g_source (&priv->queued_ip4_config_id))
_LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
+ priv->queued_ip4_config_pending = FALSE;
dhcp4_cleanup (self, cleanup_type, FALSE);
arp_cleanup (self);
@@ -7714,6 +7719,7 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
if (nm_clear_g_source (&priv->queued_ip6_config_id))
_LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
+ priv->queued_ip6_config_pending = FALSE;
g_clear_object (&priv->dad6_ip6_config);
dhcp6_cleanup (self, cleanup_type, FALSE);
@@ -9409,6 +9415,7 @@ update_ip4_config (NMDevice *self, gboolean initial)
&& activation_source_is_scheduled (self,
activate_stage5_ip4_config_commit,
AF_INET)) {
+ priv->queued_ip4_config_pending = FALSE;
priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
_LOGT (LOGD_DEVICE, "IP4 update was postponed");
return;
@@ -9499,6 +9506,7 @@ update_ip6_config (NMDevice *self, gboolean initial)
&& activation_source_is_scheduled (self,
activate_stage5_ip6_config_commit,
AF_INET6)) {
+ priv->queued_ip6_config_pending = FALSE;
priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
_LOGT (LOGD_DEVICE, "IP6 update was postponed");
return;
@@ -9576,6 +9584,8 @@ queued_ip4_config_change (gpointer user_data)
priv = NM_DEVICE_GET_PRIVATE (self);
+ nm_assert (!priv->queued_ip4_config_pending);
+
/* Wait for any queued state changes */
if (priv->queued_state.id)
return TRUE;
@@ -9600,6 +9610,8 @@ queued_ip6_config_change (gpointer user_data)
priv = NM_DEVICE_GET_PRIVATE (self);
+ nm_assert (!priv->queued_ip4_config_pending);
+
/* Wait for any queued state changes */
if (priv->queued_state.id)
return TRUE;
@@ -9679,7 +9691,11 @@ device_ipx_changed (NMPlatform *platform,
switch (obj_type) {
case NMP_OBJECT_TYPE_IP4_ADDRESS:
case NMP_OBJECT_TYPE_IP4_ROUTE:
- if (!priv->queued_ip4_config_id) {
+ if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
+ priv->queued_ip4_config_pending = TRUE;
+ nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id));
+ } else if (!priv->queued_ip4_config_id) {
+ priv->queued_ip4_config_pending = FALSE;
priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
_LOGD (LOGD_DEVICE, "queued IP4 config change");
}
@@ -9696,7 +9712,11 @@ device_ipx_changed (NMPlatform *platform,
}
/* fallthrough */
case NMP_OBJECT_TYPE_IP6_ROUTE:
- if (!priv->queued_ip6_config_id) {
+ if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
+ priv->queued_ip6_config_pending = TRUE;
+ nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id));
+ } else if (!priv->queued_ip6_config_id) {
+ priv->queued_ip6_config_pending = FALSE;
priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
_LOGD (LOGD_DEVICE, "queued IP6 config change");
}
@@ -9951,6 +9971,18 @@ _set_unmanaged_flags (NMDevice *self,
NM_UNMANAGED_USER_SETTINGS,
!!unmanaged);
}
+
+ if (priv->queued_ip4_config_pending) {
+ priv->queued_ip4_config_pending = FALSE;
+ nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id));
+ priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
+ }
+
+ if (priv->queued_ip6_config_pending) {
+ priv->queued_ip6_config_pending = FALSE;
+ nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id));
+ priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
+ }
}
old_flags = priv->unmanaged_flags;