summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-06-29 13:05:52 +0200
committerThomas Haller <thaller@redhat.com>2017-07-05 18:37:39 +0200
commitc9cd6d995482b9c7d1a06e0601d321968abcf9f7 (patch)
tree12047f89fb4f2f1c406badad96c73c5c3fa6dc7c
parent16aefdd865361bba2a11a9245cdfdda83f061198 (diff)
downloadNetworkManager-c9cd6d995482b9c7d1a06e0601d321968abcf9f7.tar.gz
platform: track routes in NMFakePlatform via NMPCache
NMPlatform's cache should be directly accessible to the users, at least the NMPLookup part and the fact that the cache contains ref-counted, immutable NMPObjects. This allows users to inspect the cache with zero overhead. Meaning, they can obtain an NMDedupMultiHeadEntry and iterate the objects themself. It also means, the are free to take and keep references of the NMPObject instances (of course, without modifying them!). NMFakePlatform will use the very same cache. The fake platform should only differ when modifying the objects. Another reason why this makes sense is because NMFakePlatform is for one a test-stup but also tests behavior of platform itself. Using a separate internal implementation for the caching is a pointless excecise, because only the real NMPCache's implementation really matters for production. So, either NMFakePlatform behaves idential, or it is buggy. Reuse it. Port fake platform's tracking of routes to NMPCache and move duplicate code from NMLinuxPlatform to the base class. This commit only ports IP routes, eventually also addresses and links should be tracked via the NMPCache instance.
-rw-r--r--src/platform/nm-fake-platform.c392
-rw-r--r--src/platform/nm-linux-platform.c84
-rw-r--r--src/platform/nm-platform.c64
-rw-r--r--src/platform/nm-platform.h4
-rw-r--r--src/platform/nmp-object.h18
5 files changed, 219 insertions, 343 deletions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 27fde50d61..028931c8c8 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -32,6 +32,7 @@
#include "nm-core-utils.h"
#include "nm-platform-utils.h"
+#include "nm-platform-private.h"
#include "nmp-object.h"
#include "nm-test-utils-core.h"
@@ -51,8 +52,6 @@ typedef struct {
GArray *links;
GArray *ip4_addresses;
GArray *ip6_addresses;
- GArray *ip4_routes;
- GArray *ip6_routes;
} NMFakePlatformPrivate;
struct _NMFakePlatform {
@@ -98,6 +97,13 @@ G_DEFINE_TYPE (NMFakePlatform, nm_fake_platform, NM_TYPE_PLATFORM)
static void link_changed (NMPlatform *platform, NMFakePlatformLink *device, gboolean raise_signal);
+static gboolean ipx_route_delete (NMPlatform *platform,
+ int addr_family,
+ int ifindex,
+ gconstpointer network,
+ const guint8 *plen,
+ const guint32 *metric);
+
static gboolean ip6_address_add (NMPlatform *platform,
int ifindex,
struct in6_addr addr,
@@ -399,18 +405,8 @@ link_delete (NMPlatform *platform, int ifindex)
if (address->ifindex == ifindex)
memset (address, 0, sizeof (*address));
}
- for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
-
- if (route->ifindex == ifindex)
- memset (route, 0, sizeof (*route));
- }
- for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
-
- if (route->ifindex == ifindex)
- memset (route, 0, sizeof (*route));
- }
+ ipx_route_delete (platform, AF_INET, ifindex, NULL, NULL, NULL);
+ ipx_route_delete (platform, AF_INET6, ifindex, NULL, NULL, NULL);
g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, (int) NMP_OBJECT_TYPE_LINK, ifindex, &deleted_device, (int) NM_PLATFORM_SIGNAL_REMOVED);
@@ -1152,270 +1148,174 @@ ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr)
/*****************************************************************************/
-static GArray *
-ip4_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags flags)
+static gboolean
+ipx_route_delete (NMPlatform *platform,
+ int addr_family,
+ int ifindex,
+ gconstpointer network,
+ const guint8 *plen,
+ const guint32 *metric)
{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- GArray *routes;
- NMPlatformIP4Route *route;
+ gs_unref_ptrarray GPtrArray *objs = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+ NMDedupMultiIter iter;
+ const NMPObject *o = NULL;
guint i;
- routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP4Route));
-
- if (!NM_FLAGS_ANY (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT))
- flags |= NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT;
-
- /* Fill routes */
- for (i = 0; i < priv->ip4_routes->len; i++) {
- route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
- if (route && (!ifindex || route->ifindex == ifindex)) {
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
- if (NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT))
- g_array_append_val (routes, *route);
- } else {
- if (NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT))
- g_array_append_val (routes, *route);
- }
+ g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
+
+ nmp_cache_iter_for_each (&iter,
+ nm_platform_lookup_addrroute (platform,
+ addr_family == AF_INET
+ ? NMP_OBJECT_TYPE_IP4_ROUTE
+ : NMP_OBJECT_TYPE_IP6_ROUTE,
+ 0,
+ FALSE),
+ &o) {
+ const NMPObject *obj_old = NULL;
+
+ if (addr_family == AF_INET) {
+ const NMPlatformIP4Route *route = NMP_OBJECT_CAST_IP4_ROUTE (o);
+
+ if ( route->ifindex != ifindex
+ || (network && route->network != *((guint32 *) network))
+ || (plen && route->plen != *plen)
+ || (metric && route->metric != *metric))
+ continue;
+ } else {
+ const NMPlatformIP6Route *route = NMP_OBJECT_CAST_IP6_ROUTE (o);
+
+ if ( route->ifindex != ifindex
+ || (network && !IN6_ARE_ADDR_EQUAL (&route->network, network))
+ || (plen && route->plen != *plen)
+ || (metric && route->metric != *metric))
+ continue;
}
- }
- return routes;
-}
-
-static GArray *
-ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags flags)
-{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- GArray *routes;
- NMPlatformIP6Route *route;
- guint i;
-
- routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP6Route));
-
- if (!NM_FLAGS_ANY (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT))
- flags |= NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT;
-
- /* Fill routes */
- for (i = 0; i < priv->ip6_routes->len; i++) {
- route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
- if (route && (!ifindex || route->ifindex == ifindex)) {
- if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
- if (NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT))
- g_array_append_val (routes, *route);
- } else {
- if (NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT))
- g_array_append_val (routes, *route);
- }
- }
+ if (nmp_cache_remove (nm_platform_get_cache (platform),
+ o,
+ TRUE,
+ &obj_old) != NMP_CACHE_OPS_REMOVED)
+ g_assert_not_reached ();
+ g_assert (obj_old);
+ g_ptr_array_add (objs, (gpointer) obj_old);
}
- return routes;
+ for (i = 0; i < objs->len; i++) {
+ nm_platform_cache_update_emit_signal (platform,
+ NMP_CACHE_OPS_REMOVED,
+ objs->pdata[i],
+ NULL);
+ }
+ return TRUE;
}
static gboolean
ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- int i;
-
- for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
- NMPlatformIP4Route deleted_route;
-
- if ( route->ifindex != ifindex
- || route->network != network
- || route->plen != plen
- || route->metric != metric)
- continue;
-
- memcpy (&deleted_route, route, sizeof (deleted_route));
- g_array_remove_index (priv->ip4_routes, i);
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, (int) NMP_OBJECT_TYPE_IP4_ROUTE, ifindex, &deleted_route, (int) NM_PLATFORM_SIGNAL_REMOVED);
- }
-
- return TRUE;
+ return ipx_route_delete (platform, AF_INET, ifindex, &network, &plen, &metric);
}
static gboolean
ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- int i;
-
metric = nm_utils_ip6_route_metric_normalize (metric);
-
- for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
- NMPlatformIP6Route deleted_route;
-
- if ( route->ifindex != ifindex
- || !IN6_ARE_ADDR_EQUAL (&route->network, &network)
- || route->plen != plen
- || route->metric != metric)
- continue;
-
- memcpy (&deleted_route, route, sizeof (deleted_route));
- g_array_remove_index (priv->ip6_routes, i);
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, (int) NMP_OBJECT_TYPE_IP6_ROUTE, ifindex, &deleted_route, (int) NM_PLATFORM_SIGNAL_REMOVED);
- }
-
- return TRUE;
+ return ipx_route_delete (platform, AF_INET6, ifindex, &network, &plen, &metric);
}
static gboolean
-ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route)
-{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- NMPlatformIP4Route rt = *route;
- guint i;
-
- rt.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (rt.rt_source);
- rt.network = nm_utils_ip4_address_clear_host_address (rt.network, rt.plen);
- rt.scope_inv = nm_platform_route_scope_inv (rt.gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK);
-
- if (rt.gateway) {
- for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *item = &g_array_index (priv->ip4_routes,
- NMPlatformIP4Route, i);
- guint32 gate = ntohl (item->network) >> (32 - item->plen);
- guint32 host = ntohl (rt.gateway) >> (32 - item->plen);
-
- if (rt.ifindex == item->ifindex && gate == host)
- break;
- }
- if (i == priv->ip4_routes->len) {
- nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip4-route '%d: %s/%d %d': Network Unreachable",
- rt.ifindex, nm_utils_inet4_ntop (rt.network, NULL), rt.plen, rt.metric);
- return FALSE;
- }
+ipx_route_add (NMPlatform *platform, int addr_family, const NMPlatformObject *route)
+{
+ NMDedupMultiIter iter;
+ nm_auto_nmpobj NMPObject *obj = NULL;
+ NMPlatformIPRoute *rt;
+ NMPCacheOpsType cache_op;
+ const NMPObject *o = NULL;
+ nm_auto_nmpobj const NMPObject *obj_old = NULL;
+ nm_auto_nmpobj const NMPObject *obj_new = NULL;
+ NMPCache *cache = nm_platform_get_cache (platform);
+ gboolean has_gateway = FALSE;
+ NMPlatformIP4Route *rt4 = NULL;
+ NMPlatformIP6Route *rt6 = NULL;
+
+ g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
+
+ obj = nmp_object_new (addr_family == AF_INET
+ ? NMP_OBJECT_TYPE_IP4_ROUTE
+ : NMP_OBJECT_TYPE_IP6_ROUTE,
+ route);
+ rt = &obj->ip_route;
+ rt->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (rt->rt_source);
+
+ if (addr_family == AF_INET) {
+ rt4 = NMP_OBJECT_CAST_IP4_ROUTE (obj);
+ rt4->scope_inv = nm_platform_route_scope_inv (rt4->gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK);
+ rt4->network = nm_utils_ip4_address_clear_host_address (rt4->network, rt4->plen);
+ if (rt4->gateway)
+ has_gateway = TRUE;
+ } else {
+ rt6 = NMP_OBJECT_CAST_IP6_ROUTE (obj);
+ rt->metric = nm_utils_ip6_route_metric_normalize (rt->metric);
+ nm_utils_ip6_address_clear_host_address (&rt6->network, &rt6->network, rt->plen);
+ if (!IN6_IS_ADDR_UNSPECIFIED (&rt6->gateway))
+ has_gateway = TRUE;
}
- for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *item = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
-
- if (item->network != rt.network)
- continue;
- if (item->plen != rt.plen)
- continue;
- if (item->metric != rt.metric)
- continue;
-
- if (item->ifindex != rt.ifindex) {
- ip4_route_delete (platform, item->ifindex, item->network, item->plen, item->metric);
- i--;
- continue;
- }
-
- memcpy (item, &rt, sizeof (rt));
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, (int) NMP_OBJECT_TYPE_IP4_ROUTE,
- rt.ifindex, &rt, (int) NM_PLATFORM_SIGNAL_CHANGED);
- return TRUE;
- }
-
- g_array_append_val (priv->ip4_routes, rt);
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, (int) NMP_OBJECT_TYPE_IP4_ROUTE,
- rt.ifindex, &rt, (int) NM_PLATFORM_SIGNAL_ADDED);
-
- return TRUE;
-}
-
-static gboolean
-ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route)
-{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- NMPlatformIP6Route rt = *route;
- guint i;
+ if (has_gateway) {
+ gboolean has_route_to_gw = FALSE;
+
+ nmp_cache_iter_for_each (&iter,
+ nm_platform_lookup_addrroute (platform,
+ NMP_OBJECT_GET_TYPE (obj),
+ 0,
+ FALSE),
+ &o) {
+ if (addr_family == AF_INET) {
+ const NMPlatformIP4Route *item = NMP_OBJECT_CAST_IP4_ROUTE (o);
+ guint32 n = nm_utils_ip4_address_clear_host_address (item->network, item->plen);
+ guint32 g = nm_utils_ip4_address_clear_host_address (rt4->gateway, item->plen);
+
+ if ( rt->ifindex == item->ifindex
+ && n == g) {
+ has_route_to_gw = TRUE;
+ break;
+ }
+ } else {
+ const NMPlatformIP6Route *item = NMP_OBJECT_CAST_IP6_ROUTE (o);
- rt.metric = nm_utils_ip6_route_metric_normalize (rt.metric);
- rt.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (rt.rt_source);
- nm_utils_ip6_address_clear_host_address (&rt.network, &rt.network, rt.plen);
-
- if (!IN6_IS_ADDR_UNSPECIFIED (&rt.gateway)) {
- for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *item = &g_array_index (priv->ip6_routes,
- NMPlatformIP6Route, i);
- guint8 gate_bits = rt.gateway.s6_addr[item->plen / 8] >> (8 - item->plen % 8);
- guint8 host_bits = item->network.s6_addr[item->plen / 8] >> (8 - item->plen % 8);
-
- if ( rt.ifindex == item->ifindex
- && memcmp (&rt.gateway, &item->network, item->plen / 8) == 0
- && gate_bits == host_bits)
- break;
+ if ( rt->ifindex == item->ifindex
+ && nm_utils_ip6_address_same_prefix (&rt6->gateway, &item->network, item->plen)) {
+ has_route_to_gw = TRUE;
+ break;
+ }
+ }
}
- if (i == priv->ip6_routes->len) {
- nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip6-route '%d: %s/%d %d': Network Unreachable",
- rt.ifindex, nm_utils_inet6_ntop (&rt.network, NULL), rt.plen, rt.metric);
+ if (!has_route_to_gw) {
+ if (addr_family == AF_INET) {
+ nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip4-route '%d: %s/%d %d': Network Unreachable",
+ rt->ifindex, nm_utils_inet4_ntop (rt4->network, NULL), rt->plen, rt->metric);
+ } else {
+ nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip6-route '%d: %s/%d %d': Network Unreachable",
+ rt->ifindex, nm_utils_inet6_ntop (&rt6->network, NULL), rt->plen, rt->metric);
+ }
return FALSE;
}
}
- for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *item = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
-
- if (!IN6_ARE_ADDR_EQUAL (&item->network, &rt.network))
- continue;
- if (item->plen != rt.plen)
- continue;
- if (item->metric != rt.metric)
- continue;
-
- if (item->ifindex != rt.ifindex) {
- ip6_route_delete (platform, item->ifindex, item->network, item->plen, item->metric);
- i--;
- continue;
- }
-
- memcpy (item, &rt, sizeof (rt));
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, (int) NMP_OBJECT_TYPE_IP6_ROUTE,
- rt.ifindex, &rt, (int) NM_PLATFORM_SIGNAL_CHANGED);
- return TRUE;
- }
-
- g_array_append_val (priv->ip6_routes, rt);
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, (int) NMP_OBJECT_TYPE_IP6_ROUTE,
- rt.ifindex, &rt, (int) NM_PLATFORM_SIGNAL_ADDED);
-
+ cache_op = nmp_cache_update_netlink (cache, obj, &obj_old, &obj_new);
+ nm_platform_cache_update_emit_signal (platform, cache_op, obj_old, obj_new);
return TRUE;
}
-static const NMPlatformIP4Route *
-ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
+static gboolean
+ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route)
{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- int i;
-
- for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
-
- if (route->ifindex == ifindex
- && route->network == network
- && route->plen == plen
- && route->metric == metric)
- return route;
- }
-
- return NULL;
+ return ipx_route_add (platform, AF_INET, (const NMPlatformObject *) route);
}
-static const NMPlatformIP6Route *
-ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
+static gboolean
+ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route)
{
- NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
- int i;
-
- metric = nm_utils_ip6_route_metric_normalize (metric);
-
- for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
-
- if (route->ifindex == ifindex
- && IN6_ARE_ADDR_EQUAL (&route->network, &network)
- && route->plen == plen
- && route->metric == metric)
- return route;
- }
-
- return NULL;
+ return ipx_route_add (platform, AF_INET6, (const NMPlatformObject *) route);
}
/*****************************************************************************/
@@ -1429,8 +1329,6 @@ nm_fake_platform_init (NMFakePlatform *fake_platform)
priv->links = g_array_new (TRUE, TRUE, sizeof (NMFakePlatformLink));
priv->ip4_addresses = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP4Address));
priv->ip6_addresses = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP6Address));
- priv->ip4_routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP4Route));
- priv->ip6_routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP6Route));
}
void
@@ -1472,8 +1370,6 @@ finalize (GObject *object)
g_array_unref (priv->links);
g_array_unref (priv->ip4_addresses);
g_array_unref (priv->ip6_addresses);
- g_array_unref (priv->ip4_routes);
- g_array_unref (priv->ip6_routes);
G_OBJECT_CLASS (nm_fake_platform_parent_class)->finalize (object);
}
@@ -1550,10 +1446,6 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->ip4_address_delete = ip4_address_delete;
platform_class->ip6_address_delete = ip6_address_delete;
- platform_class->ip4_route_get = ip4_route_get;
- platform_class->ip6_route_get = ip6_route_get;
- platform_class->ip4_route_get_all = ip4_route_get_all;
- platform_class->ip6_route_get_all = ip6_route_get_all;
platform_class->ip4_route_add = ip4_route_add;
platform_class->ip6_route_add = ip6_route_add;
platform_class->ip4_route_delete = ip4_route_delete;
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 4a7531fd9d..65dc6e0168 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -5889,58 +5889,6 @@ ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr)
/*****************************************************************************/
-static GArray *
-ipx_route_get_all (NMPlatform *platform, int ifindex, NMPObjectType obj_type, NMPlatformGetRouteFlags flags)
-{
- NMDedupMultiIter iter;
- NMPLookup lookup;
- const NMDedupMultiHeadEntry *head_entry;
- GArray *array;
- const NMPClass *klass;
- const NMPObject *o;
- gboolean with_rtprot_kernel;
-
- nm_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
-
- if (!NM_FLAGS_ANY (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT))
- flags |= NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT;
-
- klass = nmp_class_from_type (obj_type);
-
- head_entry = nmp_cache_lookup (nm_platform_get_cache (platform),
- nmp_lookup_init_route_visible (&lookup,
- obj_type,
- ifindex,
- NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT),
- NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT)));
-
- array = g_array_sized_new (FALSE, FALSE, klass->sizeof_public, head_entry ? head_entry->len : 0);
-
- with_rtprot_kernel = NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_RTPROT_KERNEL);
-
- nmp_cache_iter_for_each (&iter,
- head_entry,
- &o) {
- nm_assert (NMP_OBJECT_GET_CLASS (o) == klass);
- if ( with_rtprot_kernel
- || o->ip_route.rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
- g_array_append_vals (array, &o->ip_route, 1);
- }
- return array;
-}
-
-static GArray *
-ip4_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags flags)
-{
- return ipx_route_get_all (platform, ifindex, NMP_OBJECT_TYPE_IP4_ROUTE, flags);
-}
-
-static GArray *
-ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags flags)
-{
- return ipx_route_get_all (platform, ifindex, NMP_OBJECT_TYPE_IP6_ROUTE, flags);
-}
-
static guint32
ip_route_get_lock_flag (NMPlatformIPRoute *route)
{
@@ -6130,34 +6078,6 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, gu
return do_delete_object (platform, &obj_id, nlmsg);
}
-static const NMPlatformIP4Route *
-ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
-{
- NMPObject obj_id;
- const NMPObject *obj;
-
- nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric);
- obj = nmp_cache_lookup_obj (nm_platform_get_cache (platform), &obj_id);
- if (nmp_object_is_visible (obj))
- return &obj->ip4_route;
- return NULL;
-}
-
-static const NMPlatformIP6Route *
-ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
-{
- NMPObject obj_id;
- const NMPObject *obj;
-
- metric = nm_utils_ip6_route_metric_normalize (metric);
-
- nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric);
- obj = nmp_cache_lookup_obj (nm_platform_get_cache (platform), &obj_id);
- if (nmp_object_is_visible (obj))
- return &obj->ip6_route;
- return NULL;
-}
-
/*****************************************************************************/
#define EVENT_CONDITIONS ((GIOCondition) (G_IO_IN | G_IO_PRI))
@@ -6898,10 +6818,6 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->ip4_address_delete = ip4_address_delete;
platform_class->ip6_address_delete = ip6_address_delete;
- platform_class->ip4_route_get = ip4_route_get;
- platform_class->ip6_route_get = ip6_route_get;
- platform_class->ip4_route_get_all = ip4_route_get_all;
- platform_class->ip6_route_get_all = ip6_route_get_all;
platform_class->ip4_route_add = ip4_route_add;
platform_class->ip6_route_add = ip6_route_add;
platform_class->ip4_route_delete = ip4_route_delete;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index d19dc7cca3..d529cdd713 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -3160,6 +3160,46 @@ nm_platform_address_flush (NMPlatform *self, int ifindex)
/*****************************************************************************/
+static GArray *
+ipx_route_get_all (NMPlatform *platform, int ifindex, NMPObjectType obj_type, NMPlatformGetRouteFlags flags)
+{
+ NMDedupMultiIter iter;
+ NMPLookup lookup;
+ const NMDedupMultiHeadEntry *head_entry;
+ GArray *array;
+ const NMPClass *klass;
+ const NMPObject *o;
+ gboolean with_rtprot_kernel;
+
+ nm_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
+
+ if (!NM_FLAGS_ANY (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT))
+ flags |= NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT;
+
+ klass = nmp_class_from_type (obj_type);
+
+ head_entry = nmp_cache_lookup (nm_platform_get_cache (platform),
+ nmp_lookup_init_route_visible (&lookup,
+ obj_type,
+ ifindex,
+ NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT),
+ NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT)));
+
+ array = g_array_sized_new (FALSE, FALSE, klass->sizeof_public, head_entry ? head_entry->len : 0);
+
+ with_rtprot_kernel = NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_RTPROT_KERNEL);
+
+ nmp_cache_iter_for_each (&iter,
+ head_entry,
+ &o) {
+ nm_assert (NMP_OBJECT_GET_CLASS (o) == klass);
+ if ( with_rtprot_kernel
+ || o->ip_route.rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
+ g_array_append_vals (array, &o->ip_route, 1);
+ }
+ return array;
+}
+
GArray *
nm_platform_ip4_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags)
{
@@ -3167,7 +3207,7 @@ nm_platform_ip4_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRoute
g_return_val_if_fail (ifindex >= 0, NULL);
- return klass->ip4_route_get_all (self, ifindex, flags);
+ return ipx_route_get_all (self, ifindex, NMP_OBJECT_TYPE_IP4_ROUTE, flags);
}
GArray *
@@ -3177,7 +3217,7 @@ nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRoute
g_return_val_if_fail (ifindex >= 0, NULL);
- return klass->ip6_route_get_all (self, ifindex, flags);
+ return ipx_route_get_all (self, ifindex, NMP_OBJECT_TYPE_IP6_ROUTE, flags);
}
/**
@@ -3258,17 +3298,33 @@ nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr net
const NMPlatformIP4Route *
nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
{
+ NMPObject obj_id;
+ const NMPObject *obj;
+
_CHECK_SELF (self, klass, FALSE);
- return klass->ip4_route_get (self ,ifindex, network, plen, metric);
+ nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric);
+ obj = nmp_cache_lookup_obj (nm_platform_get_cache (self), &obj_id);
+ if (nmp_object_is_visible (obj))
+ return &obj->ip4_route;
+ return NULL;
}
const NMPlatformIP6Route *
nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
{
+ NMPObject obj_id;
+ const NMPObject *obj;
+
_CHECK_SELF (self, klass, FALSE);
- return klass->ip6_route_get (self, ifindex, network, plen, metric);
+ metric = nm_utils_ip6_route_metric_normalize (metric);
+
+ nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric);
+ obj = nmp_cache_lookup_obj (nm_platform_get_cache (self), &obj_id);
+ if (nmp_object_is_visible (obj))
+ return &obj->ip6_route;
+ return NULL;
}
/*****************************************************************************/
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index b14a75a71a..bbb43269f2 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -667,14 +667,10 @@ typedef struct {
const NMPlatformIP4Address *(*ip4_address_get) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address);
const NMPlatformIP6Address *(*ip6_address_get) (NMPlatform *, int ifindex, struct in6_addr address);
- GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags);
- GArray * (*ip6_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags);
gboolean (*ip4_route_add) (NMPlatform *, const NMPlatformIP4Route *route);
gboolean (*ip6_route_add) (NMPlatform *, const NMPlatformIP6Route *route);
gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, guint8 plen, guint32 metric);
gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, guint8 plen, guint32 metric);
- const NMPlatformIP4Route *(*ip4_route_get) (NMPlatform *, int ifindex, in_addr_t network, guint8 plen, guint32 metric);
- const NMPlatformIP6Route *(*ip6_route_get) (NMPlatform *, int ifindex, struct in6_addr network, guint8 plen, guint32 metric);
gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *);
gboolean (*check_support_user_ipv6ll) (NMPlatform *);
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index 914e756daf..18c9220ab8 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -339,7 +339,23 @@ NMP_OBJECT_GET_TYPE (const NMPObject *obj)
return obj ? obj->_class->obj_type : NMP_OBJECT_TYPE_UNKNOWN;
}
-
+#define NMP_OBJECT_CAST_IP4_ROUTE(obj) \
+ ({ \
+ typeof (*(obj)) *_obj = (obj); \
+ _nm_unused const NMPObject *_obj_type_check = _obj; \
+ \
+ nm_assert (NMP_OBJECT_GET_TYPE (_obj) == NMP_OBJECT_TYPE_IP4_ROUTE); \
+ &_obj->ip4_route; \
+ })
+
+#define NMP_OBJECT_CAST_IP6_ROUTE(obj) \
+ ({ \
+ typeof (*(obj)) *_obj = (obj); \
+ _nm_unused const NMPObject *_obj_type_check = _obj; \
+ \
+ nm_assert (NMP_OBJECT_GET_TYPE (_obj) == NMP_OBJECT_TYPE_IP6_ROUTE); \
+ &_obj->ip6_route; \
+ })
const NMPClass *nmp_class_from_type (NMPObjectType obj_type);