core/platform: sort routes before adding them in nm_platform_ipX_route_sync()

A gateway route can only be added, if there exists a device route
for that gateway. Therefore, nm_platform_ip4_route_sync() and
nm_platform_ip6_route_sync() has to add the device routes first,
before adding gateway routes.

Note: usually for all configured addresses, there is also a device
route for the subnet added by the kernel. This means, NM must first
configure the addresses before route_sync, so that these implicit device
routes already exist -- this is however already done correctly.

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller
2014-01-23 09:11:19 +01:00
committed by Dan Williams
parent c8d7a06d64
commit 8959b6dbcb

View File

@@ -1607,7 +1607,7 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes)
NMPlatformIP4Route *route;
const NMPlatformIP4Route *known_route;
gboolean success;
int i;
int i, i_type;
/* Delete unknown routes */
routes = nm_platform_ip4_route_get_all (ifindex, FALSE);
@@ -1624,9 +1624,16 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes)
}
/* Add missing routes */
for (i = 0, success = TRUE; i < known_routes->len && success; i++) {
for (i_type = 0, success = TRUE; i_type < 2 && success; i_type++) {
for (i = 0; i < known_routes->len && success; i++) {
known_route = &g_array_index (known_routes, NMPlatformIP4Route, i);
if ((known_route->gateway == 0) ^ (i_type != 0)) {
/* Make two runs over the list of routes. On the first, only add
* device routes, on the second the others (gateway routes). */
continue;
}
/* Ignore routes that already exist */
if (!array_contains_ip4_route (routes, known_route)) {
success = nm_platform_ip4_route_add (ifindex,
@@ -1642,6 +1649,7 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes)
}
}
}
}
g_array_free (routes, TRUE);
return success;
@@ -1665,7 +1673,7 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes)
NMPlatformIP6Route *route;
const NMPlatformIP6Route *known_route;
gboolean success;
int i;
int i, i_type;
/* Delete unknown routes */
routes = nm_platform_ip6_route_get_all (ifindex, FALSE);
@@ -1683,9 +1691,16 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes)
}
/* Add missing routes */
for (i = 0, success = TRUE; i < known_routes->len && success; i++) {
for (i_type = 0, success = TRUE; i_type < 2 && success; i_type++) {
for (i = 0; i < known_routes->len && success; i++) {
known_route = &g_array_index (known_routes, NMPlatformIP6Route, i);
if (IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway) ^ (i_type != 0)) {
/* Make two runs over the list of routes. On the first, only add
* device routes, on the second the others (gateway routes). */
continue;
}
/* Ignore routes that already exist */
if (!array_contains_ip6_route (routes, known_route)) {
success = nm_platform_ip6_route_add (ifindex,
@@ -1701,6 +1716,7 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes)
}
}
}
}
g_array_free (routes, TRUE);
return success;