diff options
author | Thomas Haller <thaller@redhat.com> | 2015-07-08 11:42:54 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-07-08 11:44:40 +0200 |
commit | ce2964c021e1164081855fd9eefebf586356ebeb (patch) | |
tree | d708ce53007b274a57ee2ba677d76e4e1ae1f6af | |
parent | bb1692707f8029f14d17d6c6642c370fd9b58322 (diff) | |
download | NetworkManager-ce2964c021e1164081855fd9eefebf586356ebeb.tar.gz |
route-manager: restore shadowed gateway routes after direct routes
-rw-r--r-- | src/nm-route-manager.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c index c38b0bc863..975c95b887 100644 --- a/src/nm-route-manager.c +++ b/src/nm-route-manager.c @@ -715,6 +715,8 @@ next: **************************************************************************/ if (ipx_routes_changed) { + GArray *gateway_routes = NULL; + /* @effective_metrics_reverse contains the list of assigned metrics from the last * sync. Walk through it and see what changes there are (and possibly restore a * shadowed route). @@ -754,7 +756,31 @@ next: * or add any further routes then this. That means there might be some stale routes * (with a higher metric!). They will only be removed on the next sync of that other * ifindex. */ - vtable->vt->route_add (priv->platform, 0, cur_ipx_route, *p_effective_metric); + + if (!VTABLE_IS_DEVICE_ROUTE (vtable, cur_ipx_route)) { + /* the route to restore has a gateway. We can only restore the route + * when we also have a direct route to the gateway. There can be cases + * where the direct route is shadowed too, and we cannot restore the gateway + * route. + * + * Restore first the direct-routes, and gateway-routes afterwards. + * This can avoid some cases where we would fail to add the + * gateway route. */ + if (!gateway_routes) + gateway_routes = g_array_new (FALSE, FALSE, sizeof (guint)); + g_array_append_val (gateway_routes, i_ipx_routes); + } else + vtable->vt->route_add (priv->platform, 0, cur_ipx_route, *p_effective_metric); + } + + if (gateway_routes) { + for (i = 0; i < gateway_routes->len; i++) { + i_ipx_routes = g_array_index (gateway_routes, guint, i); + vtable->vt->route_add (priv->platform, 0, + ipx_routes->index->entries[i_ipx_routes], + effective_metrics[i_ipx_routes]); + } + g_array_unref (gateway_routes); } } |