diff options
author | Pavel Šimerda <psimerda@redhat.com> | 2013-05-02 08:02:44 +0200 |
---|---|---|
committer | Pavel Šimerda <psimerda@redhat.com> | 2013-06-25 09:50:35 +0200 |
commit | ef73aa3b2c10092324a7dcf62e7bb427b2ea6437 (patch) | |
tree | 5452ed1c154a2ff1404d1ce46d53fe1759b8a7e5 | |
parent | bd0fd1cd1dc0a5167c5c2cb0c0a86c4a293eeb31 (diff) |
platform: route utility functions
-rw-r--r-- | src/platform/nm-platform.c | 129 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 3 |
2 files changed, 132 insertions, 0 deletions
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 6140d7a8..287d953d 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1404,6 +1404,135 @@ nm_platform_ip6_route_exists (int ifindex, struct in6_addr network, int plen, in return klass->ip6_route_exists (platform, ifindex, network, plen, metric); } +static gboolean +array_contains_ip4_route (const GArray *routes, const NMPlatformIP4Route *route) +{ + int i; + + for (i = 0; i < routes->len; i++) { + if (!memcmp (&g_array_index (routes, NMPlatformIP4Route, i), route, sizeof (*route))) + return TRUE; + } + + return FALSE; +} + +static gboolean +array_contains_ip6_route (const GArray *routes, const NMPlatformIP6Route *route) +{ + int i; + + for (i = 0; i < routes->len; i++) { + if (!memcmp (&g_array_index (routes, NMPlatformIP6Route, i), route, sizeof (*route))) + return TRUE; + } + + return FALSE; +} + +/** + * nm_platform_ip4_route_sync: + * @ifindex: Interface index + * @known_routes: List of routes + * + * A convenience function to synchronize routes for a specific interface + * with the least possible disturbance. It simply removes routes that are + * not listed and adds routes that are. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes) +{ + GArray *routes; + NMPlatformIP4Route *route; + const NMPlatformIP4Route *known_route; + int i; + + /* Delete unknown routes */ + routes = nm_platform_ip4_route_get_all (ifindex); + for (i = 0; i < routes->len; i++) { + route = &g_array_index (routes, NMPlatformIP4Route, i); + route->ifindex = 0; + + if (!known_routes || !array_contains_ip4_route (known_routes, route)) + nm_platform_ip4_route_delete (ifindex, route->network, route->plen, route->metric); + } + g_array_free (routes, TRUE); + + if (!known_routes) + return TRUE; + + /* Add missing routes */ + for (i = 0; i < known_routes->len; i++) { + known_route = &g_array_index (known_routes, NMPlatformIP4Route, i); + + if (!nm_platform_ip4_route_exists (ifindex, + known_route->network, known_route->plen, known_route->metric)) + if (!nm_platform_ip4_route_add (ifindex, + known_route->network, known_route->plen, known_route->gateway, + known_route->metric, known_route->mss)) + return FALSE; + } + + return TRUE; +} + +/** + * nm_platform_ip6_route_sync: + * @ifindex: Interface index + * @known_routes: List of routes + * + * A convenience function to synchronize routes for a specific interface + * with the least possible disturbance. It simply removes routes that are + * not listed and adds routes that are. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes) +{ + GArray *routes; + NMPlatformIP6Route *route; + const NMPlatformIP6Route *known_route; + int i; + + /* Delete unknown routes */ + routes = nm_platform_ip6_route_get_all (ifindex); + for (i = 0; i < routes->len; i++) { + route = &g_array_index (routes, NMPlatformIP6Route, i); + route->ifindex = 0; + + if (!known_routes || !array_contains_ip6_route (known_routes, route)) + nm_platform_ip6_route_delete (ifindex, route->network, route->plen, route->metric); + } + g_array_free (routes, TRUE); + + if (!known_routes) + return TRUE; + + /* Add missing routes */ + for (i = 0; i < known_routes->len; i++) { + known_route = &g_array_index (known_routes, NMPlatformIP6Route, i); + + if (!nm_platform_ip6_route_exists (ifindex, + known_route->network, known_route->plen, known_route->metric)) + if (!nm_platform_ip6_route_add (ifindex, + known_route->network, known_route->plen, known_route->gateway, + known_route->metric, known_route->mss)) + return FALSE; + } + + return TRUE; +} + +gboolean +nm_platform_route_flush (int ifindex) +{ + return nm_platform_ip4_route_sync (ifindex, NULL) + && nm_platform_ip6_route_sync (ifindex, NULL); +} + /******************************************************************/ static void diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 6a262465..fbc7976a 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -383,6 +383,9 @@ gboolean nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, gboolean nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, int metric); gboolean nm_platform_ip4_route_exists (int ifindex, in_addr_t network, int plen, int metric); gboolean nm_platform_ip6_route_exists (int ifindex, struct in6_addr network, int plen, int metric); +gboolean nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes); +gboolean nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes); +gboolean nm_platform_route_flush (int ifindex); #define auto_g_free __attribute__((cleanup(put_g_free))) static void __attribute__((unused)) |