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.
This commit is contained in:
@@ -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));
|
||||
g_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
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 {
|
||||
if (NM_FLAGS_HAS (flags, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT))
|
||||
g_array_append_val (routes, *route);
|
||||
}
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
for (i = 0; i < objs->len; i++) {
|
||||
nm_platform_cache_update_emit_signal (platform,
|
||||
NMP_CACHE_OPS_REMOVED,
|
||||
objs->pdata[i],
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return routes;
|
||||
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 ipx_route_delete (platform, AF_INET6, ifindex, &network, &plen, &metric);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if ( rt->ifindex == item->ifindex
|
||||
&& nm_utils_ip6_address_same_prefix (&rt6->gateway, &item->network, item->plen)) {
|
||||
has_route_to_gw = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
return ipx_route_add (platform, AF_INET, (const NMPlatformObject *) route);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route)
|
||||
{
|
||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform);
|
||||
NMPlatformIP6Route rt = *route;
|
||||
guint i;
|
||||
|
||||
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 (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);
|
||||
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);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const NMPlatformIP4Route *
|
||||
ip4_route_get (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);
|
||||
|
||||
if (route->ifindex == ifindex
|
||||
&& route->network == network
|
||||
&& route->plen == plen
|
||||
&& route->metric == metric)
|
||||
return route;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const NMPlatformIP6Route *
|
||||
ip6_route_get (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);
|
||||
|
||||
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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@@ -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 *);
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user