diff options
author | Thomas Haller <thaller@redhat.com> | 2015-07-13 19:20:08 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-07-13 20:05:50 +0200 |
commit | e18ac75713e394a4c5cf964139080b0e7f69ea0e (patch) | |
tree | ca8dfe90aa3df47553690136ed10ef02cff9313c | |
parent | 8b1f0a4d3d361add3e5f731d73a5d2a90567d474 (diff) | |
download | NetworkManager-th/route-full-sync.tar.gz |
routes: fix race synching routes by not doing full-syncth/route-full-sync
In most cases, when synching routes, we should only remove routes
that were configured by us previously. Otherwise, there is a race
that we can remove routes added externally.
-rw-r--r-- | src/devices/nm-device.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 0fa5bdf9b0..415465ada2 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -351,6 +351,7 @@ static gboolean nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, guint32 default_route_metric, gboolean commit, + gboolean routes_full_sync, NMDeviceStateReason *reason); static gboolean ip4_config_merge_and_apply (NMDevice *self, NMIP4Config *config, @@ -360,6 +361,7 @@ static gboolean ip4_config_merge_and_apply (NMDevice *self, static gboolean nm_device_set_ip6_config (NMDevice *self, NMIP6Config *config, gboolean commit, + gboolean routes_full_sync, NMDeviceStateReason *reason); static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure); @@ -3248,6 +3250,7 @@ ip4_config_merge_and_apply (NMDevice *self, const guint32 default_route_metric = nm_device_get_ip4_route_metric (self); guint32 gateway; gboolean connection_has_default_route, connection_is_never_default; + gboolean routes_full_sync; /* Merge all the configs into the composite config */ if (config) { @@ -3312,6 +3315,10 @@ ip4_config_merge_and_apply (NMDevice *self, priv->default_route.v4_has = FALSE; priv->default_route.v4_is_assumed = TRUE; + routes_full_sync = commit + && priv->default_route.v4_configure_first_time + && !nm_device_uses_assumed_connection (self); + if (!commit) { /* during a non-commit event, we always pickup whatever is configured. */ goto END_ADD_DEFAULT_ROUTE; @@ -3391,7 +3398,7 @@ END_ADD_DEFAULT_ROUTE: NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite); } - success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, out_reason); + success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync, out_reason); g_object_unref (composite); return success; } @@ -3864,6 +3871,7 @@ ip6_config_merge_and_apply (NMDevice *self, gboolean has_direct_route; const struct in6_addr *gateway; gboolean connection_has_default_route, connection_is_never_default; + gboolean routes_full_sync; /* If no config was passed in, create a new one */ composite = nm_ip6_config_new (nm_device_get_ip_ifindex (self)); @@ -3926,6 +3934,10 @@ ip6_config_merge_and_apply (NMDevice *self, priv->default_route.v6_has = FALSE; priv->default_route.v6_is_assumed = TRUE; + routes_full_sync = commit + && priv->default_route.v6_configure_first_time + && !nm_device_uses_assumed_connection (self); + if (!commit) { /* during a non-commit event, we always pickup whatever is configured. */ goto END_ADD_DEFAULT_ROUTE; @@ -4008,7 +4020,7 @@ END_ADD_DEFAULT_ROUTE: NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite); } - success = nm_device_set_ip6_config (self, composite, commit, out_reason); + success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync, out_reason); g_object_unref (composite); return success; } @@ -6317,6 +6329,7 @@ nm_device_set_ip4_config (NMDevice *self, NMIP4Config *new_config, guint32 default_route_metric, gboolean commit, + gboolean routes_full_sync, NMDeviceStateReason *reason) { NMDevicePrivate *priv; @@ -6351,7 +6364,7 @@ nm_device_set_ip4_config (NMDevice *self, * FIXME: this is wrong in case where "assumed" means "take-over-seamlessly". In this * case, we should manage the device route, for example on new DHCP lease. */ success = nm_ip4_config_commit (new_config, ip_ifindex, - TRUE, + routes_full_sync, assumed ? (gint64) -1 : (gint64) default_route_metric); if (!success) reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED; @@ -6457,6 +6470,7 @@ static gboolean nm_device_set_ip6_config (NMDevice *self, NMIP6Config *new_config, gboolean commit, + gboolean routes_full_sync, NMDeviceStateReason *reason) { NMDevicePrivate *priv; @@ -6486,7 +6500,7 @@ nm_device_set_ip6_config (NMDevice *self, nm_device_ipv6_set_mtu (self, priv->ip6_mtu); success = nm_ip6_config_commit (new_config, ip_ifindex, - TRUE); + routes_full_sync); if (!success) reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED; } @@ -7940,8 +7954,8 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) /* Clean up IP configs; this does not actually deconfigure the * interface; the caller must flush routes and addresses explicitly. */ - nm_device_set_ip4_config (self, NULL, 0, TRUE, &ignored); - nm_device_set_ip6_config (self, NULL, TRUE, &ignored); + nm_device_set_ip4_config (self, NULL, 0, TRUE, TRUE, &ignored); + nm_device_set_ip6_config (self, NULL, TRUE, TRUE, &ignored); g_clear_object (&priv->con_ip4_config); g_clear_object (&priv->dev_ip4_config); g_clear_object (&priv->ext_ip4_config); |