summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shared/nm-test-utils.h39
-rw-r--r--src/devices/tests/Makefile.am3
-rw-r--r--src/nm-default-route-manager.c40
-rw-r--r--src/nm-route-manager.c26
-rw-r--r--src/platform/nm-fake-platform.c268
-rw-r--r--src/platform/nm-linux-platform.c243
-rw-r--r--src/platform/nm-platform.c408
-rw-r--r--src/platform/nm-platform.h100
-rw-r--r--src/platform/nmp-object.c59
-rw-r--r--src/platform/nmp-object.h4
-rw-r--r--src/platform/tests/test-cleanup.c33
-rw-r--r--src/platform/tests/test-common.c414
-rw-r--r--src/platform/tests/test-common.h70
-rw-r--r--src/platform/tests/test-link.c187
-rw-r--r--src/platform/tests/test-route.c200
-rw-r--r--src/tests/test-route-manager.c126
16 files changed, 1530 insertions, 690 deletions
diff --git a/shared/nm-test-utils.h b/shared/nm-test-utils.h
index 0875518cdd..e044ae59ac 100644
--- a/shared/nm-test-utils.h
+++ b/shared/nm-test-utils.h
@@ -1177,6 +1177,13 @@ _nmtst_assert_resolve_relative_path_equals (const char *f1, const char *f2, cons
#ifdef __NETWORKMANAGER_PLATFORM_H__
+#define nmtst_ip4_address_to_ptr(addr) \
+ ({ \
+ guint32 *__addr = g_alloca (sizeof (guint32)); \
+ *__addr = (addr); \
+ (const NMIPAddr *) __addr; \
+ })
+
inline static NMPlatformIP4Address *
nmtst_platform_ip4_address (const char *address, const char *peer_address, guint plen)
{
@@ -1251,7 +1258,9 @@ nmtst_platform_ip6_address_full (const char *address, const char *peer_address,
}
inline static NMPlatformIP4Route *
-nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway)
+nmtst_platform_ip4_route (const char *network,
+ guint8 plen,
+ const char *gateway)
{
static NMPlatformIP4Route route;
@@ -1266,10 +1275,15 @@ nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway)
}
inline static NMPlatformIP4Route *
-nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gateway,
- int ifindex, NMIPConfigSource source,
- guint metric, guint mss,
+nmtst_platform_ip4_route_full (int ifindex,
+ const char *network,
+ guint8 plen,
+ const char *gateway,
+ NMIPConfigSource source,
+ guint32 metric,
+ guint32 mss,
guint8 scope,
+ bool scope_is_set,
const char *pref_src)
{
NMPlatformIP4Route *route = nmtst_platform_ip4_route (network, plen, gateway);
@@ -1278,14 +1292,17 @@ nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gate
route->rt_source = source;
route->metric = metric;
route->mss = mss;
- route->scope_inv = nm_platform_route_scope_inv (scope);
+ route->rt_scope = scope;
+ route->rt_scope_is_set = scope_is_set;
route->pref_src = nmtst_inet4_from_string (pref_src);
return route;
}
inline static NMPlatformIP6Route *
-nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
+nmtst_platform_ip6_route (const char *network,
+ guint8 plen,
+ const char *gateway)
{
static NMPlatformIP6Route route;
@@ -1300,9 +1317,13 @@ nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
}
inline static NMPlatformIP6Route *
-nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gateway,
- int ifindex, NMIPConfigSource source,
- guint metric, guint mss)
+nmtst_platform_ip6_route_full (int ifindex,
+ const char *network,
+ guint8 plen,
+ const char *gateway,
+ NMIPConfigSource source,
+ guint32 metric,
+ guint32 mss)
{
NMPlatformIP6Route *route = nmtst_platform_ip6_route (network, plen, gateway);
diff --git a/src/devices/tests/Makefile.am b/src/devices/tests/Makefile.am
index cd1ef6edd3..6fd5f8f5a3 100644
--- a/src/devices/tests/Makefile.am
+++ b/src/devices/tests/Makefile.am
@@ -12,7 +12,8 @@ AM_CPPFLAGS = \
-I$(top_builddir)/src \
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
- $(GLIB_CFLAGS)
+ $(GLIB_CFLAGS) \
+ $(GUDEV_CFLAGS)
AM_CFLAGS = $(CODE_COVERAGE_CFLAGS)
AM_LDFLAGS = $(GLIB_LIBS) $(CODE_COVERAGE_LDFLAGS)
diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c
index a637c6cb88..4e824c7a6d 100644
--- a/src/nm-default-route-manager.c
+++ b/src/nm-default-route-manager.c
@@ -287,24 +287,25 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g
return FALSE;
if (vtable->vt->is_ip4) {
- success = nm_platform_ip4_route_add (priv->platform,
- entry->route.rx.ifindex,
- entry->route.rx.rt_source,
- 0,
- 0,
- entry->route.r4.gateway,
- 0,
- entry->effective_metric,
- entry->route.rx.mss);
+ NMPlatformIP4Route r = {
+ .ifindex = entry->route.rx.ifindex,
+ .rt_source = entry->route.rx.rt_source,
+ .gateway = entry->route.r4.gateway,
+ .metric = entry->effective_metric,
+ .mss = entry->route.rx.mss,
+ };
+
+ success = nm_platform_ip4_route_add (priv->platform, &r);
} else {
- success = nm_platform_ip6_route_add (priv->platform,
- entry->route.rx.ifindex,
- entry->route.rx.rt_source,
- in6addr_any,
- 0,
- entry->route.r6.gateway,
- entry->effective_metric,
- entry->route.rx.mss);
+ NMPlatformIP6Route r = {
+ .ifindex = entry->route.rx.ifindex,
+ .rt_source = entry->route.rx.rt_source,
+ .gateway = entry->route.r6.gateway,
+ .metric = entry->effective_metric,
+ .mss = entry->route.rx.mss,
+ };
+
+ success = nm_platform_ip6_route_add (priv->platform, &r);
}
if (!success) {
_LOGW (vtable->vt->addr_family, "failed to add default route %s with effective metric %u",
@@ -332,6 +333,9 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self,
route = _vt_route_index (vtable, routes, i);
+ nm_assert (memcmp (route->network_ptr, &nm_ip_addr_zero, vtable->vt->is_ip4 ? sizeof (in_addr_t) : sizeof (struct in6_addr)) == 0);
+ nm_assert (route->plen == 0);
+
/* look at all entries and see if the route for this ifindex pair is
* a known entry. */
for (j = 0; j < entries->len; j++) {
@@ -355,7 +359,7 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self,
*/
if ( !entry
&& (has_ifindex_synced || ifindex_to_flush == route->ifindex)) {
- vtable->vt->route_delete_default (priv->platform, route->ifindex, route->metric);
+ vtable->vt->route_delete (priv->platform, (NMPlatformIPXRoute *) route);
changed = TRUE;
}
}
diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c
index 2d4c7d9595..54b54b84e3 100644
--- a/src/nm-route-manager.c
+++ b/src/nm-route-manager.c
@@ -574,9 +574,10 @@ _vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const
&& cur_plat_route->rx.metric == *p_effective_metric) {
/* we are about to delete cur_ipx_route and we have a matching route
* in platform. Delete it. */
+ nm_assert (cur_plat_route->rx.ifindex == ifindex);
_LOGt (vtable->vt->addr_family, "%3d: platform rt-rm #%u - %s", ifindex, i_plat_routes,
vtable->vt->route_to_string (cur_plat_route, NULL, 0));
- vtable->vt->route_delete (priv->platform, ifindex, cur_plat_route);
+ vtable->vt->route_delete (priv->platform, cur_plat_route);
}
}
}
@@ -741,8 +742,10 @@ next:
/* if @cur_ipx_route is not equal to @plat_route, the route must be deleted. */
if ( !cur_ipx_route
|| route_dest_cmp_result != 0
- || *p_effective_metric != cur_plat_route->rx.metric)
- vtable->vt->route_delete (priv->platform, ifindex, cur_plat_route);
+ || *p_effective_metric != cur_plat_route->rx.metric) {
+ nm_assert (cur_plat_route->rx.ifindex == ifindex);
+ vtable->vt->route_delete (priv->platform, cur_plat_route);
+ }
cur_plat_route = _get_next_plat_route (plat_routes_idx, FALSE, &i_plat_routes);
}
@@ -815,15 +818,15 @@ next:
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);
+ vtable->vt->route_add (priv->platform, cur_ipx_route, 0, *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,
+ vtable->vt->route_add (priv->platform,
ipx_routes->index->entries[i_ipx_routes],
- effective_metrics[i_ipx_routes]);
+ 0, effective_metrics[i_ipx_routes]);
}
g_array_unref (gateway_routes);
}
@@ -872,7 +875,7 @@ next:
|| route_dest_cmp_result != 0
|| !_route_equals_ignoring_ifindex (vtable, cur_plat_route, cur_ipx_route, *p_effective_metric)) {
- if (!vtable->vt->route_add (priv->platform, ifindex, cur_ipx_route, *p_effective_metric)) {
+ if (!vtable->vt->route_add (priv->platform, cur_ipx_route, ifindex, *p_effective_metric)) {
if (cur_ipx_route->rx.rt_source < NM_IP_CONFIG_SOURCE_USER) {
_LOGD (vtable->vt->addr_family,
"ignore error adding IPv%c route to kernel: %s",
@@ -986,6 +989,7 @@ _ip4_device_routes_idle_cb (IP4DeviceRoutePurgeEntry *entry)
{
NMRouteManager *self;
NMRouteManagerPrivate *priv;
+ NMPObject obj;
nm_clear_g_source (&entry->idle_id);
@@ -998,11 +1002,9 @@ _ip4_device_routes_idle_cb (IP4DeviceRoutePurgeEntry *entry)
_LOGt (vtable_v4.vt->addr_family, "device-route: delete %s", nmp_object_to_string (entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0));
- nm_platform_ip4_route_delete (priv->platform,
- entry->obj->ip4_route.ifindex,
- entry->obj->ip4_route.network,
- entry->obj->ip4_route.plen,
- entry->obj->ip4_route.metric);
+ nmp_object_stackinit_id_ip4_route (&obj, &entry->obj->ip4_route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+
+ nm_platform_ip4_route_delete (priv->platform, &obj.ip4_route);
g_hash_table_remove (priv->ip4_device_routes.entries, entry->obj);
_ip4_device_routes_cancel (self);
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index 6582b0cf03..69e4982a78 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -69,8 +69,8 @@ typedef struct {
GArray *links;
GArray *ip4_addresses;
GArray *ip6_addresses;
- GArray *ip4_routes;
- GArray *ip6_routes;
+ GPtrArray *ip4_routes;
+ GPtrArray *ip6_routes;
} NMFakePlatformPrivate;
typedef struct {
@@ -109,6 +109,37 @@ _ip4_address_equal_peer_net (in_addr_t peer1, in_addr_t peer2, guint8 plen)
/******************************************************************/
+static NMPObject *
+_get_at_idx (GPtrArray *array, gsize idx, NMPObjectType expected_type)
+{
+ NMPObject *obj;
+
+ g_assert (array);
+ g_assert (idx < array->len);
+
+ obj = array->pdata[idx];
+
+ g_assert (NMP_OBJECT_IS_VALID (obj));
+ if (expected_type != NMP_OBJECT_TYPE_UNKNOWN)
+ g_assert (expected_type == NMP_OBJECT_GET_TYPE (obj));
+
+ return obj;
+}
+
+static NMPlatformIP4Route *
+_get_at_idx_ip4_route (GPtrArray *array, gsize idx)
+{
+ return &(_get_at_idx (array, idx, NMP_OBJECT_TYPE_IP4_ROUTE))->ip4_route;
+}
+
+static NMPlatformIP6Route *
+_get_at_idx_ip6_route (GPtrArray *array, gsize idx)
+{
+ return &(_get_at_idx (array, idx, NMP_OBJECT_TYPE_IP6_ROUTE))->ip6_route;
+}
+
+/******************************************************************/
+
static gboolean
sysctl_set (NMPlatform *platform, const char *path, const char *value)
{
@@ -352,13 +383,13 @@ link_delete (NMPlatform *platform, int 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);
+ NMPlatformIP4Route *route = _get_at_idx_ip4_route (priv->ip4_routes, 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);
+ NMPlatformIP6Route *route = _get_at_idx_ip6_route (priv->ip6_routes, i);
if (route->ifindex == ifindex)
memset (route, 0, sizeof (*route));
@@ -1098,7 +1129,7 @@ ip4_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl
/* Fill routes */
for (i = 0; i < priv->ip4_routes->len; i++) {
- route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
+ route = _get_at_idx_ip4_route (priv->ip4_routes, 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))
@@ -1128,7 +1159,7 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl
/* Fill routes */
for (i = 0; i < priv->ip6_routes->len; i++) {
- route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
+ route = _get_at_idx_ip6_route (priv->ip6_routes, 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))
@@ -1144,224 +1175,191 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl
}
static gboolean
-ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
+ip4_route_delete (NMPlatform *platform, const NMPlatformIP4Route *route)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
- int i;
+ NMPObject obj, o;
+ NMPlatformIP4Route *r;
+ guint i;
+
+ nmp_object_stackinit_id_ip4_route (&obj, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
- NMPlatformIP4Route deleted_route;
+ r = _get_at_idx_ip4_route (priv->ip4_routes, i);
- if ( route->ifindex != ifindex
- || route->network != network
- || route->plen != plen
- || route->metric != metric)
+ nmp_object_stackinit_id_ip4_route (&o, r, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+ if (!nmp_object_id_equal (&obj, &o))
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, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex, &deleted_route, NM_PLATFORM_SIGNAL_REMOVED);
+ g_ptr_array_remove_index (priv->ip4_routes, i);
+ g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP4_ROUTE, obj.ip_route.ifindex, &obj.ip4_route, NM_PLATFORM_SIGNAL_REMOVED);
}
return TRUE;
}
static gboolean
-ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
+ip6_route_delete (NMPlatform *platform, const NMPlatformIP6Route *route)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
- int i;
+ NMPObject obj, o;
+ NMPlatformIP6Route *r;
+ guint i;
- metric = nm_utils_ip6_route_metric_normalize (metric);
+ nmp_object_stackinit_id_ip6_route (&obj, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
- NMPlatformIP6Route deleted_route;
+ r = _get_at_idx_ip6_route (priv->ip6_routes, i);
- if ( route->ifindex != ifindex
- || !IN6_ARE_ADDR_EQUAL (&route->network, &network)
- || route->plen != plen
- || route->metric != metric)
+ nmp_object_stackinit_id_ip6_route (&o, r, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+ if (!nmp_object_id_equal (&obj, &o))
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, NMP_OBJECT_TYPE_IP6_ROUTE, ifindex, &deleted_route, NM_PLATFORM_SIGNAL_REMOVED);
+ g_ptr_array_remove_index (priv->ip6_routes, i);
+ g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP6_ROUTE, obj.ip_route.ifindex, &obj.ip6_route, NM_PLATFORM_SIGNAL_REMOVED);
}
return TRUE;
}
static gboolean
-ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
- in_addr_t network, guint8 plen, in_addr_t gateway,
- in_addr_t pref_src, guint32 metric, guint32 mss)
+ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
- NMPlatformIP4Route route;
+ NMPObject obj, o;
+ NMPlatformIP4Route *r;
guint i;
- guint8 scope;
+ NMPlatformSignalChangeType change_type = NM_PLATFORM_SIGNAL_CHANGED;
- g_assert (plen <= 32);
+ g_assert (route && route->plen <= 32);
- scope = gateway == 0 ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE;
+ nmp_object_stackinit_id_ip4_route (&obj, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
- memset (&route, 0, sizeof (route));
- route.ifindex = ifindex;
- route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source);
- route.network = nm_utils_ip4_address_clear_host_address (network, plen);
- route.plen = plen;
- route.gateway = gateway;
- route.metric = metric;
- route.mss = mss;
- route.scope_inv = nm_platform_route_scope_inv (scope);
-
- if (gateway) {
+ if (obj.ip4_route.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 (gateway) >> (32 - item->plen);
+ guint32 gate, host;
+
+ r = _get_at_idx_ip4_route (priv->ip4_routes, i);
- if (ifindex == item->ifindex && gate == host)
+ gate = ntohl (r->network) >> (32 - r->plen);
+ host = ntohl (obj.ip4_route.gateway) >> (32 - r->plen);
+
+ if (obj.ip_route.ifindex == r->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",
- route.ifindex, nm_utils_inet4_ntop (route.network, NULL), route.plen, route.metric);
+ nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip4-route '%s': Network Unreachable",
+ nm_platform_ip4_route_to_string (route, NULL, 0));
return FALSE;
}
}
for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *item = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
-
- if (item->network != route.network)
- continue;
- if (item->plen != route.plen)
- continue;
- if (item->metric != metric)
- continue;
+ r = _get_at_idx_ip4_route (priv->ip4_routes, i);
- if (item->ifindex != route.ifindex) {
- ip4_route_delete (platform, item->ifindex, item->network, item->plen, item->metric);
- i--;
+ nmp_object_stackinit_id_ip4_route (&o, r, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+ if (!nmp_object_id_equal (&obj, &o))
continue;
- }
- memcpy (item, &route, sizeof (route));
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex, &route, NM_PLATFORM_SIGNAL_CHANGED);
- return TRUE;
+ *r = obj.ip4_route;
+ goto out;
}
- g_array_append_val (priv->ip4_routes, route);
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex, &route, NM_PLATFORM_SIGNAL_ADDED);
-
+ g_ptr_array_add (priv->ip4_routes, nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, &obj.object));
+ r = _get_at_idx_ip4_route (priv->ip4_routes, priv->ip4_routes->len - 1);
+ change_type = NM_PLATFORM_SIGNAL_ADDED;
+out:
+ g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP4_ROUTE, r->ifindex, r, change_type);
return TRUE;
}
static gboolean
-ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
- struct in6_addr network, guint8 plen, struct in6_addr gateway,
- guint32 metric, guint32 mss)
+ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
- NMPlatformIP6Route route;
+ NMPObject obj, o;
+ NMPlatformIP6Route *r;
guint i;
+ NMPlatformSignalChangeType change_type = NM_PLATFORM_SIGNAL_CHANGED;
- metric = nm_utils_ip6_route_metric_normalize (metric);
+ g_assert (route && route->plen <= 128);
- memset (&route, 0, sizeof (route));
- route.ifindex = ifindex;
- route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source);
- nm_utils_ip6_address_clear_host_address (&route.network, &network, plen);
- route.plen = plen;
- route.gateway = gateway;
- route.metric = metric;
- route.mss = mss;
+ nmp_object_stackinit_id_ip6_route (&obj, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
- if (!IN6_IS_ADDR_UNSPECIFIED(&gateway)) {
+ if (!IN6_IS_ADDR_UNSPECIFIED (&obj.ip6_route.gateway)) {
for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *item = &g_array_index (priv->ip6_routes,
- NMPlatformIP6Route, i);
- guint8 gate_bits = 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 ( ifindex == item->ifindex
- && memcmp (&gateway, &item->network, item->plen / 8) == 0
- && gate_bits == host_bits)
+ struct in6_addr a_gateway, a_network;
+
+ r = _get_at_idx_ip6_route (priv->ip6_routes, i);
+ if (obj.ip_route.ifindex != r->ifindex)
+ continue;
+
+ nm_utils_ip6_address_clear_host_address (&a_gateway, &obj.ip6_route.gateway, r->plen);
+ nm_utils_ip6_address_clear_host_address (&a_network, &r->network, r->plen);
+ if (memcmp (&a_gateway, &a_network, sizeof (struct in6_addr)) == 0)
break;
}
if (i == priv->ip6_routes->len) {
- nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip6-route '%d: %s/%d %d': Network Unreachable",
- route.ifindex, nm_utils_inet6_ntop (&route.network, NULL), route.plen, route.metric);
+ nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip6-route '%s': Network Unreachable",
+ nm_platform_ip6_route_to_string (route, NULL, 0));
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, &route.network))
- continue;
- if (item->plen != route.plen)
- continue;
- if (item->metric != metric)
- continue;
+ r = _get_at_idx_ip6_route (priv->ip6_routes, i);
- if (item->ifindex != route.ifindex) {
- ip6_route_delete (platform, item->ifindex, item->network, item->plen, item->metric);
- i--;
+ nmp_object_stackinit_id_ip6_route (&o, r, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+ if (!nmp_object_id_equal (&obj, &o))
continue;
- }
- memcpy (item, &route, sizeof (route));
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP6_ROUTE, ifindex, &route, NM_PLATFORM_SIGNAL_CHANGED);
- return TRUE;
+ *r = obj.ip6_route;
+ goto out;
}
- g_array_append_val (priv->ip6_routes, route);
- g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP6_ROUTE, ifindex, &route, NM_PLATFORM_SIGNAL_ADDED);
-
+ g_ptr_array_add (priv->ip6_routes, nmp_object_new (NMP_OBJECT_TYPE_IP6_ROUTE, &obj.object));
+ r = _get_at_idx_ip6_route (priv->ip6_routes, priv->ip6_routes->len - 1);
+ change_type = NM_PLATFORM_SIGNAL_ADDED;
+out:
+ g_signal_emit_by_name (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NMP_OBJECT_TYPE_IP6_ROUTE, r->ifindex, r, change_type);
return TRUE;
}
static const NMPlatformIP4Route *
-ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
+ip4_route_get (NMPlatform *platform, const NMPlatformIP4Route *route)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
- int i;
+ guint i;
+ NMPObject obj_id, o;
+
+ nmp_object_stackinit_id_ip4_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
for (i = 0; i < priv->ip4_routes->len; i++) {
- NMPlatformIP4Route *route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i);
+ const NMPlatformIP4Route *r = _get_at_idx_ip4_route (priv->ip4_routes, i);
- if (route->ifindex == ifindex
- && route->network == network
- && route->plen == plen
- && route->metric == metric)
- return route;
+ nmp_object_stackinit_id_ip4_route (&o, r, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+ if (nmp_object_id_equal (&obj_id, &o))
+ return r;
}
return NULL;
}
static const NMPlatformIP6Route *
-ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
+ip6_route_get (NMPlatform *platform, const NMPlatformIP6Route *route)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
- int i;
+ guint i;
+ NMPObject obj_id, o;
- metric = nm_utils_ip6_route_metric_normalize (metric);
+ nmp_object_stackinit_id_ip6_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
for (i = 0; i < priv->ip6_routes->len; i++) {
- NMPlatformIP6Route *route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i);
+ NMPlatformIP6Route *r = _get_at_idx_ip6_route (priv->ip6_routes, i);
- if (route->ifindex == ifindex
- && IN6_ARE_ADDR_EQUAL (&route->network, &network)
- && route->plen == plen
- && route->metric == metric)
- return route;
+ nmp_object_stackinit_id_ip6_route (&o, r, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+ if (nmp_object_id_equal (&obj_id, &o))
+ return r;
}
return NULL;
@@ -1378,8 +1376,8 @@ 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));
+ priv->ip4_routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+ priv->ip6_routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
}
void
@@ -1419,8 +1417,8 @@ nm_fake_platform_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_ptr_array_unref (priv->ip4_routes);
+ g_ptr_array_unref (priv->ip6_routes);
G_OBJECT_CLASS (nm_fake_platform_parent_class)->finalize (object);
}
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 82e673a3c1..baf4d7ccab 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -1864,8 +1864,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
else
obj->ip6_route.gateway = nh.gateway.addr6;
- if (is_v4)
- obj->ip4_route.scope_inv = nm_platform_route_scope_inv (rtm->rtm_scope);
+ if (is_v4) {
+ obj->ip4_route.rt_scope = rtm->rtm_scope;
+ obj->ip4_route.rt_scope_is_set = TRUE;
+ }
if (is_v4) {
if (_check_addr_or_errout (tb, RTA_PREFSRC, addr_len))
@@ -2229,77 +2231,79 @@ nla_put_failure:
static struct nl_msg *
_nl_msg_new_route (int nlmsg_type,
int nlmsg_flags,
- int family,
- int ifindex,
- NMIPConfigSource source,
- unsigned char scope,
- gconstpointer network,
- guint8 plen,
- gconstpointer gateway,
- guint32 metric,
- guint32 mss,
- gconstpointer pref_src)
+ const NMPObject *obj)
{
- struct nl_msg *msg;
- struct rtmsg rtmsg = {
- .rtm_family = family,
- .rtm_tos = 0,
- .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */
- .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (source),
- .rtm_scope = scope,
- .rtm_type = RTN_UNICAST,
- .rtm_flags = 0,
- .rtm_dst_len = plen,
- .rtm_src_len = 0,
- };
+ int addr_family;
+ gboolean is_v4;
+ const NMIPAddr *gateway;
NMIPAddr network_clean;
-
gsize addr_len;
+ struct nl_msg *msg;
- nm_assert (NM_IN_SET (family, AF_INET, AF_INET6));
+ nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
nm_assert (NM_IN_SET (nlmsg_type, RTM_NEWROUTE, RTM_DELROUTE));
- nm_assert (network);
msg = nlmsg_alloc_simple (nlmsg_type, nlmsg_flags);
if (!msg)
- g_return_val_if_reached (NULL);
+ return NULL;
- if (nlmsg_append (msg, &rtmsg, sizeof (rtmsg), NLMSG_ALIGNTO) < 0)
- goto nla_put_failure;
+ addr_family = NMP_OBJECT_GET_CLASS (obj)->addr_family;
+ is_v4 = (addr_family == AF_INET);
+ addr_len = is_v4 ? sizeof (in_addr_t) : sizeof (struct in6_addr);
+
+ gateway = is_v4
+ ? (gpointer) &obj->ip4_route.gateway
+ : (gpointer) &obj->ip6_route.gateway;
+
+ {
+ struct rtmsg rtmsg = {
+ .rtm_family = addr_family,
+ .rtm_tos = 0,
+ .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */
+ .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (obj->ip_route.rt_source),
+ .rtm_scope = is_v4
+ ? nm_platform_route_scope_from_ip4_route (&obj->ip4_route)
+ : nm_platform_route_scope_for_ip6_gateway (&gateway->addr6),
+ .rtm_type = RTN_UNICAST,
+ .rtm_flags = 0,
+ .rtm_dst_len = obj->ip_route.plen,
+ .rtm_src_len = 0,
+ };
- addr_len = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr);
+ if (nlmsg_append (msg, &rtmsg, sizeof (rtmsg), NLMSG_ALIGNTO) < 0)
+ goto nla_put_failure;
+ }
- nm_utils_ipx_address_clear_host_address (family, &network_clean, network, plen);
+ nm_utils_ipx_address_clear_host_address (addr_family, &network_clean, obj->ip_route.network_ptr, obj->ip_route.plen);
NLA_PUT (msg, RTA_DST, addr_len, &network_clean);
- NLA_PUT_U32 (msg, RTA_PRIORITY, metric);
+ NLA_PUT_U32 (msg, RTA_PRIORITY, obj->ip_route.metric);
- if (pref_src)
- NLA_PUT (msg, RTA_PREFSRC, addr_len, pref_src);
+ if (is_v4 && obj->ip4_route.pref_src)
+ NLA_PUT (msg, RTA_PREFSRC, addr_len, &obj->ip4_route.pref_src);
- if (mss > 0) {
+ if (obj->ip_route.mss > 0) {
struct nlattr *metrics;
metrics = nla_nest_start (msg, RTA_METRICS);
if (!metrics)
goto nla_put_failure;
- NLA_PUT_U32 (msg, RTAX_ADVMSS, mss);
+ NLA_PUT_U32 (msg, RTAX_ADVMSS, obj->ip_route.mss);
nla_nest_end(msg, metrics);
}
/* We currently don't have need for multi-hop routes... */
- if ( gateway
- && memcmp (gateway, &nm_ip_addr_zero, addr_len) != 0)
+ if (memcmp (gateway, &nm_ip_addr_zero, addr_len) != 0)
NLA_PUT (msg, RTA_GATEWAY, addr_len, gateway);
- NLA_PUT_U32 (msg, RTA_OIF, ifindex);
+ NLA_PUT_U32 (msg, RTA_OIF, obj->ip_route.ifindex);
return msg;
nla_put_failure:
nlmsg_free (msg);
- g_return_val_if_reached (NULL);
+ return NULL;
}
/******************************************************************/
@@ -3902,6 +3906,7 @@ do_add_addrroute (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN;
+ gboolean success = FALSE;
int nle;
char s_buf[256];
const NMPObject *obj;
@@ -3925,9 +3930,15 @@ do_add_addrroute (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *
nm_assert (seq_result);
- _NMLOG (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK
- ? LOGL_DEBUG
- : LOGL_ERR,
+ if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK)
+ success = TRUE;
+ else if ( (int) seq_result == -EEXIST
+ && NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_id),
+ NMP_OBJECT_TYPE_IP4_ROUTE,
+ NMP_OBJECT_TYPE_IP6_ROUTE))
+ success = TRUE;
+
+ _NMLOG (success ? LOGL_DEBUG : LOGL_ERR,
"do-add-%s[%s]: %s",
NMP_OBJECT_GET_CLASS (obj_id)->obj_type_name,
nmp_object_to_string (obj_id, NMP_OBJECT_TO_STRING_ID, NULL, 0),
@@ -3950,7 +3961,7 @@ do_add_addrroute (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *
/* Adding is only successful, if kernel reported success *and* we have the
* expected object in cache afterwards. */
- return obj && seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK;
+ return obj && success;
}
static gboolean
@@ -3963,8 +3974,6 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *
gboolean success = TRUE;
const char *log_detail = "";
- event_handler_read_netlink (platform, FALSE);
-
nle = _nl_send_auto_with_seq (platform, nlmsg, &seq_result, NULL);
if (nle < 0) {
_LOGE ("do-delete-%s[%s]: failure sending netlink request \"%s\" (%d)",
@@ -4122,6 +4131,8 @@ link_delete (NMPlatform *platform, int ifindex)
NMPObject obj_id;
const NMPObject *obj;
+ delayed_action_handle_all (platform, TRUE);
+
obj = nmp_cache_lookup_link (priv->cache, ifindex);
if (!obj || !obj->_link.netlink.is_in_netlink)
return FALSE;
@@ -4132,6 +4143,8 @@ link_delete (NMPlatform *platform, int ifindex)
NULL,
0,
0);
+ if (!nlmsg)
+ g_return_val_if_reached (FALSE);
nmp_object_stackinit_id_link (&obj_id, ifindex);
return do_delete_object (platform, &obj_id, nlmsg);
@@ -5494,6 +5507,8 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, guint8 pl
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
NMPObject obj_id;
+ delayed_action_handle_all (platform, TRUE);
+
nlmsg = _nl_msg_new_address (RTM_DELADDR,
0,
AF_INET,
@@ -5519,6 +5534,8 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, gui
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
NMPObject obj_id;
+ delayed_action_handle_all (platform, TRUE);
+
nlmsg = _nl_msg_new_address (RTM_DELADDR,
0,
AF_INET6,
@@ -5618,146 +5635,93 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteFlags fl
}
static gboolean
-ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
- in_addr_t network, guint8 plen, in_addr_t gateway,
- in_addr_t pref_src, guint32 metric, guint32 mss)
+ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route)
{
NMPObject obj_id;
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
+ nmp_object_stackinit_id_ip4_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+
nlmsg = _nl_msg_new_route (RTM_NEWROUTE,
- NLM_F_CREATE | NLM_F_REPLACE,
- AF_INET,
- ifindex,
- source,
- gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK,
- &network,
- plen,
- &gateway,
- metric,
- mss,
- pref_src ? &pref_src : NULL);
-
- nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric);
+ NLM_F_CREATE | NLM_F_APPEND,
+ &obj_id);
+ if (!nlmsg)
+ g_return_val_if_reached (FALSE);
+
return do_add_addrroute (platform, &obj_id, nlmsg);
}
static gboolean
-ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
- struct in6_addr network, guint8 plen, struct in6_addr gateway,
- guint32 metric, guint32 mss)
+ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route)
{
NMPObject obj_id;
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
+ nmp_object_stackinit_id_ip6_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+
nlmsg = _nl_msg_new_route (RTM_NEWROUTE,
- NLM_F_CREATE | NLM_F_REPLACE,
- AF_INET6,
- ifindex,
- source,
- !IN6_IS_ADDR_UNSPECIFIED (&gateway) ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK,
- &network,
- plen,
- &gateway,
- metric,
- mss,
- NULL);
-
- nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric);
+ NLM_F_CREATE | NLM_F_APPEND,
+ &obj_id);
+ if (!nlmsg)
+ g_return_val_if_reached (FALSE);
+
return do_add_addrroute (platform, &obj_id, nlmsg);
}
static gboolean
-ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
+ip4_route_delete (NMPlatform *platform, const NMPlatformIP4Route *route)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
NMPObject obj_id;
- nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric);
+ nmp_object_stackinit_id_ip4_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
- if (metric == 0) {
- /* Deleting an IPv4 route with metric 0 does not only delete an exectly matching route.
- * If no route with metric 0 exists, it might delete another route to the same destination.
- * For nm_platform_ip4_route_delete() we don't want this semantic.
- *
- * Instead, make sure that we have the most recent state and process all
- * delayed actions (including re-reading data from netlink). */
- delayed_action_handle_all (platform, TRUE);
-
- if (!nmp_cache_lookup_obj (priv->cache, &obj_id)) {
- /* hmm... we are about to delete an IP4 route with metric 0. We must only
- * send the delete request if such a route really exists. Above we refreshed
- * the platform cache, still no such route exists.
- *
- * Be extra careful and reload the routes. We must be sure that such a
- * route doesn't exists, because when we add an IPv4 address, we immediately
- * afterwards try to delete the kernel-added device route with metric 0.
- * It might be, that we didn't yet get the notification about that route.
- *
- * FIXME: once our ip4_address_add() is sure that upon return we have
- * the latest state from in the platform cache, we might save this
- * additional expensive cache-resync. */
- do_request_one_type (platform, NMP_OBJECT_TYPE_IP4_ROUTE);
+ delayed_action_handle_all (platform, TRUE);
- if (!nmp_cache_lookup_obj (priv->cache, &obj_id))
- return TRUE;
- }
- }
+ if (!nmp_cache_lookup_obj (priv->cache, &obj_id))
+ return TRUE;
nlmsg = _nl_msg_new_route (RTM_DELROUTE,
0,
- AF_INET,
- ifindex,
- NM_IP_CONFIG_SOURCE_UNKNOWN,
- RT_SCOPE_NOWHERE,
- &network,
- plen,
- NULL,
- metric,
- 0,
- NULL);
+ &obj_id);
if (!nlmsg)
- return FALSE;
+ g_return_val_if_reached (FALSE);
return do_delete_object (platform, &obj_id, nlmsg);
}
static gboolean
-ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
+ip6_route_delete (NMPlatform *platform, const NMPlatformIP6Route *route)
{
+ NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
NMPObject obj_id;
- metric = nm_utils_ip6_route_metric_normalize (metric);
+ nmp_object_stackinit_id_ip6_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+
+ delayed_action_handle_all (platform, TRUE);
+
+ if (!nmp_cache_lookup_obj (priv->cache, &obj_id))
+ return TRUE;
nlmsg = _nl_msg_new_route (RTM_DELROUTE,
0,
- AF_INET6,
- ifindex,
- NM_IP_CONFIG_SOURCE_UNKNOWN,
- RT_SCOPE_NOWHERE,
- &network,
- plen,
- NULL,
- metric,
- 0,
- NULL);
+ &obj_id);
if (!nlmsg)
- return FALSE;
-
- nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric);
+ g_return_val_if_reached (FALSE);
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)
+ip4_route_get (NMPlatform *platform, const NMPlatformIP4Route *route)
{
NMPObject obj_id;
const NMPObject *obj;
- nmp_object_stackinit_id_ip4_route (&obj_id, ifindex, network, plen, metric);
+ nmp_object_stackinit_id_ip4_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_id);
if (nmp_object_is_visible (obj))
return &obj->ip4_route;
@@ -5765,14 +5729,13 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen
}
static const NMPlatformIP6Route *
-ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
+ip6_route_get (NMPlatform *platform, const NMPlatformIP6Route *route)
{
NMPObject obj_id;
const NMPObject *obj;
- metric = nm_utils_ip6_route_metric_normalize (metric);
+ nmp_object_stackinit_id_ip6_route (&obj_id, route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
- nmp_object_stackinit_id_ip6_route (&obj_id, ifindex, &network, plen, metric);
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_id);
if (nmp_object_is_visible (obj))
return &obj->ip6_route;
@@ -5928,7 +5891,7 @@ continue_reading:
int errsv = e->error > 0 ? e->error : -e->error;
/* Error message reported back from kernel. */
- _LOGD ("netlink: recvmsg: error message from kernel: %s (%d) for request %d",
+ _LOGT ("netlink: recvmsg: error message from kernel: %s (%d) for request %d",
strerror (errsv),
errsv,
nlmsg_hdr (msg)->nlmsg_seq);
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 500db9b621..6fdfda27a2 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -2870,14 +2870,7 @@ nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRoute
/**
* nm_platform_ip4_route_add:
* @self:
- * @ifindex:
- * @source:
- * network:
- * plen:
- * gateway:
- * pref_src:
- * metric:
- * mss:
+ * @route:
*
* For kernel, a gateway can be either explicitly set or left
* at zero (0.0.0.0). In addition, there is the scope of the IPv4
@@ -2898,99 +2891,69 @@ nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRoute
* Returns: %TRUE in case of success.
*/
gboolean
-nm_platform_ip4_route_add (NMPlatform *self,
- int ifindex, NMIPConfigSource source,
- in_addr_t network, guint8 plen,
- in_addr_t gateway, in_addr_t pref_src,
- guint32 metric, guint32 mss)
+nm_platform_ip4_route_add (NMPlatform *self, const NMPlatformIP4Route *route)
{
_CHECK_SELF (self, klass, FALSE);
- g_return_val_if_fail (plen <= 32, FALSE);
+ g_return_val_if_fail (route, FALSE);
+ g_return_val_if_fail (route->plen <= 32, FALSE);
- if (_LOGD_ENABLED ()) {
- NMPlatformIP4Route route = { 0 };
-
- route.ifindex = ifindex;
- route.rt_source = source;
- route.network = network;
- route.plen = plen;
- route.gateway = gateway;
- route.metric = metric;
- route.mss = mss;
- route.pref_src = pref_src;
-
- _LOGD ("route: adding or updating IPv4 route: %s", nm_platform_ip4_route_to_string (&route, NULL, 0));
- }
- return klass->ip4_route_add (self, ifindex, source, network, plen, gateway, pref_src, metric, mss);
+ _LOGD ("route: adding or updating IPv4 route: %s", nm_platform_ip4_route_to_string (route, NULL, 0));
+ return klass->ip4_route_add (self, route);
}
gboolean
-nm_platform_ip6_route_add (NMPlatform *self,
- int ifindex, NMIPConfigSource source,
- struct in6_addr network, guint8 plen, struct in6_addr gateway,
- guint32 metric, guint32 mss)
+nm_platform_ip6_route_add (NMPlatform *self, const NMPlatformIP6Route *route)
{
_CHECK_SELF (self, klass, FALSE);
- g_return_val_if_fail (plen <= 128, FALSE);
+ g_return_val_if_fail (route, FALSE);
+ g_return_val_if_fail (route->plen <= 128, FALSE);
- if (_LOGD_ENABLED ()) {
- NMPlatformIP6Route route = { 0 };
-
- route.ifindex = ifindex;
- route.rt_source = source;
- route.network = network;
- route.plen = plen;
- route.gateway = gateway;
- route.metric = metric;
- route.mss = mss;
-
- _LOGD ("route: adding or updating IPv6 route: %s", nm_platform_ip6_route_to_string (&route, NULL, 0));
- }
- return klass->ip6_route_add (self, ifindex, source, network, plen, gateway, metric, mss);
+ _LOGD ("route: adding or updating IPv6 route: %s", nm_platform_ip6_route_to_string (route, NULL, 0));
+ return klass->ip6_route_add (self, route);
}
gboolean
-nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
+nm_platform_ip4_route_delete (NMPlatform *self, const NMPlatformIP4Route *route)
{
- char str_dev[TO_STRING_DEV_BUF_SIZE];
-
_CHECK_SELF (self, klass, FALSE);
- _LOGD ("route: deleting IPv4 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s",
- nm_utils_inet4_ntop (network, NULL), plen, metric, ifindex,
- _to_string_dev (self, ifindex, str_dev, sizeof (str_dev)));
- return klass->ip4_route_delete (self, ifindex, network, plen, metric);
+ g_return_val_if_fail (route, FALSE);
+
+ _LOGD ("route: deleting IPv4 route %s", nm_platform_ip4_route_to_string (route, NULL, 0));
+ return klass->ip4_route_delete (self, route);
}
gboolean
-nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
+nm_platform_ip6_route_delete (NMPlatform *self, const NMPlatformIP6Route *route)
{
- char str_dev[TO_STRING_DEV_BUF_SIZE];
-
_CHECK_SELF (self, klass, FALSE);
- _LOGD ("route: deleting IPv6 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s",
- nm_utils_inet6_ntop (&network, NULL), plen, metric, ifindex,
- _to_string_dev (self, ifindex, str_dev, sizeof (str_dev)));
- return klass->ip6_route_delete (self, ifindex, network, plen, metric);
+ g_return_val_if_fail (route, FALSE);
+
+ _LOGD ("route: deleting IPv6 route %s", nm_platform_ip6_route_to_string (route, NULL, 0));
+ return klass->ip6_route_delete (self, route);
}
const NMPlatformIP4Route *
-nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric)
+nm_platform_ip4_route_get (NMPlatform *self, const NMPlatformIP4Route *route)
{
_CHECK_SELF (self, klass, FALSE);
- return klass->ip4_route_get (self ,ifindex, network, plen, metric);
+ g_return_val_if_fail (route, NULL);
+
+ return klass->ip4_route_get (self, route);
}
const NMPlatformIP6Route *
-nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric)
+nm_platform_ip6_route_get (NMPlatform *self, const NMPlatformIP6Route *route)
{
_CHECK_SELF (self, klass, FALSE);
- return klass->ip6_route_get (self, ifindex, network, plen, metric);
+ g_return_val_if_fail (route, NULL);
+
+ return klass->ip6_route_get (self, route);
}
/******************************************************************/
@@ -3626,6 +3589,8 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
char s_pref_src[INET_ADDRSTRLEN];
char str_dev[TO_STRING_DEV_BUF_SIZE];
char str_scope[30], s_source[50];
+ guint8 scope;
+ gboolean scope_print;
if (!nm_utils_to_string_buffer_init_null (route, &buf, &len))
return buf;
@@ -3635,6 +3600,9 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
_to_string_dev (NULL, route->ifindex, str_dev, sizeof (str_dev));
+ scope = nm_platform_route_scope_from_ip4_route (route);
+ scope_print = route->rt_scope_is_set || scope != RT_SCOPE_NOWHERE;
+
g_snprintf (buf, len,
"%s/%d"
" via %s"
@@ -3654,8 +3622,8 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi
route->mss,
nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)),
route->rt_cloned ? " cloned" : "",
- route->scope_inv ? " scope " : "",
- route->scope_inv ? (nm_platform_route_scope2str (nm_platform_route_scope_inv (route->scope_inv), str_scope, sizeof (str_scope))) : "",
+ scope_print ? " scope " : "",
+ scope_print ? nm_platform_route_scope2str (scope, str_scope, sizeof (str_scope)) : "",
route->pref_src ? " pref-src " : "",
route->pref_src ? inet_ntop (AF_INET, &route->pref_src, s_pref_src, sizeof(s_pref_src)) : "");
return buf;
@@ -3960,35 +3928,256 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A
int
nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b)
{
+ return nm_platform_ip4_route_cmp_full (a, b, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+}
+
+int
+nm_platform_ip4_route_cmp_full (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, NMPlatformIPRouteIdType id_type)
+{
+ guint8 rtprot_a, rtprot_b;
+ guint8 scope_a, scope_b;
+ guint32 network_a, network_b;
+
_CMP_SELF (a, b);
+
_CMP_FIELD (a, b, ifindex);
- _CMP_FIELD (a, b, network);
+
+ network_a = nm_utils_ip4_address_clear_host_address (a->network, a->plen);
+ network_b = nm_utils_ip4_address_clear_host_address (b->network, b->plen);
+ _CMP_DIRECT (network_a, network_b);
+
_CMP_FIELD (a, b, plen);
_CMP_FIELD (a, b, metric);
_CMP_FIELD (a, b, gateway);
- _CMP_FIELD (a, b, rt_source);
+
+ rtprot_a = nmp_utils_ip_config_source_coerce_to_rtprot (a->rt_source);
+ rtprot_b = nmp_utils_ip_config_source_coerce_to_rtprot (b->rt_source);
+ _CMP_DIRECT (rtprot_a, rtprot_b);
+
_CMP_FIELD (a, b, mss);
- _CMP_FIELD (a, b, scope_inv);
+
+ scope_a = nm_platform_route_scope_from_ip4_route (a);
+ scope_b = nm_platform_route_scope_from_ip4_route (b);
+ _CMP_DIRECT (scope_a, scope_b);
+
_CMP_FIELD (a, b, pref_src);
_CMP_FIELD (a, b, rt_cloned);
+
+ /* currently we have two id-types, ID and ALL. Let ALL be a stricter
+ * ordering then ID, but yield the same order. Thus, above we first check
+ * all the ID fields, only if those are all equal, dig deeper. */
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ break;
+ default:
+ _CMP_FIELD (a, b, network);
+ _CMP_FIELD (a, b, rt_source);
+ _CMP_FIELD (a, b, rt_scope);
+ _CMP_FIELD (a, b, rt_scope_is_set);
+ break;
+ }
return 0;
}
+guint
+nm_platform_ip4_route_hash_full (const NMPlatformIP4Route *a, NMPlatformIPRouteIdType id_type)
+{
+ guint h = 0x8202baf9;
+
+ if (!a)
+ return h;
+
+ h += (h * 33) + ((guint) a->ifindex);
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ h += (h * 33) + ((guint) nm_utils_ip4_address_clear_host_address (a->network, a->plen));
+ break;
+ default:
+ h += (h * 33) + ((guint) a->network);
+ break;
+ }
+
+ h += (h * 33) + ((guint) a->plen);
+ h += (h * 33) + ((guint) a->metric);
+ h += (h * 33) + ((guint) a->gateway);
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ h += (h * 33) + ((guint) nmp_utils_ip_config_source_coerce_to_rtprot (a->rt_source));
+ break;
+ default:
+ h += (h * 33) + ((guint) a->rt_source);
+ break;
+ }
+
+ h += (h * 33) + ((guint) a->mss);
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ h += (h * 33) + ((guint) nm_platform_route_scope_from_ip4_route (a));
+ break;
+ default:
+ h += (h * 33) + (((guint) a->rt_scope) + (((guint) a->rt_scope_is_set) << 8));
+ break;
+ }
+
+ h += (h * 33) + ((guint) a->pref_src);
+ h += (h * 33) + ((guint) a->rt_cloned);
+
+ return h;
+}
+
+NMPlatformIP4Route *
+nm_platform_ip4_route_normalize (NMPlatformIP4Route *dst, const NMPlatformIP4Route *src, NMPlatformIPRouteIdType id_type)
+{
+ nm_assert (dst);
+
+ if (src && src != dst)
+ *dst = *src;
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ dst->network = nm_utils_ip4_address_clear_host_address (dst->network, dst->plen);
+ dst->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (dst->rt_source);
+ dst->rt_scope = nm_platform_route_scope_from_ip4_route (dst);
+ dst->rt_scope_is_set = TRUE;
+ break;
+ default:
+ break;
+ }
+ return dst;
+}
+
int
nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b)
{
+ return nm_platform_ip6_route_cmp_full (a, b, NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL);
+}
+
+int
+nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, NMPlatformIPRouteIdType id_type)
+{
+ struct in6_addr network_a, network_b;
+ guint32 metric_a, metric_b;
+ guint8 rtprot_a, rtprot_b;
+
_CMP_SELF (a, b);
+
_CMP_FIELD (a, b, ifindex);
- _CMP_FIELD_MEMCMP (a, b, network);
+
+ nm_utils_ip6_address_clear_host_address (&network_a, &a->network, a->plen);
+ nm_utils_ip6_address_clear_host_address (&network_b, &b->network, b->plen);
+ _CMP_DIRECT_MEMCMP (&network_a, &network_b, sizeof (struct in6_addr));
+
_CMP_FIELD (a, b, plen);
- _CMP_FIELD (a, b, metric);
+
+ metric_a = nm_utils_ip6_route_metric_normalize (a->metric);
+ metric_b = nm_utils_ip6_route_metric_normalize (b->metric);
+ _CMP_DIRECT (metric_a, metric_b);
+
_CMP_FIELD_MEMCMP (a, b, gateway);
- _CMP_FIELD (a, b, rt_source);
+
+ rtprot_a = nmp_utils_ip_config_source_coerce_to_rtprot (a->rt_source);
+ rtprot_b = nmp_utils_ip_config_source_coerce_to_rtprot (b->rt_source);
+ _CMP_DIRECT (rtprot_a, rtprot_b);
+
_CMP_FIELD (a, b, mss);
_CMP_FIELD (a, b, rt_cloned);
+
+ /* currently we have two id-types, ID and ALL. Let ALL be a stricter
+ * ordering then ID, but yield the same order. Thus, above we first check
+ * all the ID fields, only if those are all equal, dig deeper. */
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ break;
+ default:
+ _CMP_FIELD_MEMCMP (a, b, network);
+ _CMP_FIELD (a, b, metric);
+ _CMP_FIELD (a, b, rt_source);
+ break;
+ }
return 0;
}
+guint
+nm_platform_ip6_route_hash_full (const NMPlatformIP6Route *a, NMPlatformIPRouteIdType id_type)
+{
+ struct in6_addr network;
+
+ guint h = 0x0569b8f4;
+
+ if (!a)
+ return h;
+
+ h += (h * 33) + ((guint) a->ifindex);
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ nm_utils_ip6_address_clear_host_address (&network, &a->network, a->plen);
+ h += (h * 33) + ((guint) network.s6_addr32[0]);
+ h += (h * 33) + ((guint) network.s6_addr32[1]);
+ h += (h * 33) + ((guint) network.s6_addr32[2]);
+ h += (h * 33) + ((guint) network.s6_addr32[3]);
+ break;
+ default:
+ h += (h * 33) + ((guint) a->network.s6_addr32[0]);
+ h += (h * 33) + ((guint) a->network.s6_addr32[1]);
+ h += (h * 33) + ((guint) a->network.s6_addr32[2]);
+ h += (h * 33) + ((guint) a->network.s6_addr32[3]);
+ break;
+ }
+
+ h += (h * 33) + ((guint) a->plen);
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ h += (h * 33) + ((guint) nm_utils_ip6_route_metric_normalize (a->metric));
+ break;
+ default:
+ h += (h * 33) + ((guint) a->metric);
+ break;
+ }
+
+ h += (h * 33) + ((guint) a->gateway.s6_addr32[0]);
+ h += (h * 33) + ((guint) a->gateway.s6_addr32[1]);
+ h += (h * 33) + ((guint) a->gateway.s6_addr32[2]);
+ h += (h * 33) + ((guint) a->gateway.s6_addr32[3]);
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ h += (h * 33) + ((guint) nmp_utils_ip_config_source_coerce_to_rtprot (a->rt_source));
+ break;
+ default:
+ h += (h * 33) + ((guint) a->rt_source);
+ break;
+ }
+
+ h += (h * 33) + ((guint) a->mss);
+ h += (h * 33) + ((guint) a->rt_cloned);
+ return h;
+}
+
+NMPlatformIP6Route *
+nm_platform_ip6_route_normalize (NMPlatformIP6Route *dst, const NMPlatformIP6Route *src, NMPlatformIPRouteIdType id_type)
+{
+ nm_assert (dst);
+
+ if (src && src != dst)
+ *dst = *src;
+
+ switch (id_type) {
+ case NM_PLATFORM_IP_ROUTE_ID_TYPE_ID:
+ nm_utils_ip6_address_clear_host_address (&dst->network, &dst->network, dst->plen);
+ dst->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (dst->rt_source);
+ dst->metric = nm_utils_ip6_route_metric_normalize (dst->metric);
+ break;
+ default:
+ break;
+ }
+ return dst;
+}
+
/**
* nm_platform_ip_address_cmp_expiry:
* @a: a NMPlatformIPAddress to compare
@@ -4114,50 +4303,45 @@ nm_platform_netns_push (NMPlatform *platform, NMPNetns **netns)
/******************************************************************/
static gboolean
-_vtr_v4_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric)
+_vtr_v4_route_add (NMPlatform *self, const NMPlatformIPXRoute *route, int ifindex, gint64 metric)
{
- return nm_platform_ip4_route_add (self,
- ifindex > 0 ? ifindex : route->rx.ifindex,
- route->rx.rt_source,
- route->r4.network,
- route->rx.plen,
- route->r4.gateway,
- route->r4.pref_src,
- metric >= 0 ? (guint32) metric : route->rx.metric,
- route->rx.mss);
+ NMPlatformIPXRoute r_storage;
+
+ if ( (ifindex > 0 && ifindex != route->rx.ifindex)
+ || (metric >= 0 && metric != route->rx.metric)) {
+ r_storage.r4 = route->r4;
+ r_storage.rx.ifindex = ifindex;
+ r_storage.rx.metric = metric;
+ route = &r_storage;
+ }
+ return nm_platform_ip4_route_add (self, &route->r4);
}
static gboolean
-_vtr_v6_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric)
+_vtr_v6_route_add (NMPlatform *self, const NMPlatformIPXRoute *route, int ifindex, gint64 metric)
{
- return nm_platform_ip6_route_add (self,
- ifindex > 0 ? ifindex : route->rx.ifindex,
- route->rx.rt_source,
- route->r6.network,
- route->rx.plen,
- route->r6.gateway,
- metric >= 0 ? (guint32) metric : route->rx.metric,
- route->rx.mss);
+ NMPlatformIPXRoute r_storage;
+
+ if ( (ifindex > 0 && ifindex != route->rx.ifindex)
+ || (metric >= 0 && metric != route->rx.metric)) {
+ r_storage.r6 = route->r6;
+ r_storage.rx.ifindex = ifindex;
+ r_storage.rx.metric = nm_utils_ip6_route_metric_normalize (metric);
+ route = &r_storage;
+ }
+ return nm_platform_ip6_route_add (self, &route->r6);
}
static gboolean
-_vtr_v4_route_delete (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route)
+_vtr_v4_route_delete (NMPlatform *self, const NMPlatformIPXRoute *route)
{
- return nm_platform_ip4_route_delete (self,
- ifindex > 0 ? ifindex : route->rx.ifindex,
- route->r4.network,
- route->rx.plen,
- route->rx.metric);
+ return nm_platform_ip4_route_delete (self, &route->r4);
}
static gboolean
-_vtr_v6_route_delete (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route)
+_vtr_v6_route_delete (NMPlatform *self, const NMPlatformIPXRoute *route)
{
- return nm_platform_ip6_route_delete (self,
- ifindex > 0 ? ifindex : route->rx.ifindex,
- route->r6.network,
- route->rx.plen,
- route->rx.metric);
+ return nm_platform_ip6_route_delete (self, &route->r6);
}
static guint32
@@ -4166,18 +4350,6 @@ _vtr_v4_metric_normalize (guint32 metric)
return metric;
}
-static gboolean
-_vtr_v4_route_delete_default (NMPlatform *self, int ifindex, guint32 metric)
-{
- return nm_platform_ip4_route_delete (self, ifindex, 0, 0, metric);
-}
-
-static gboolean
-_vtr_v6_route_delete_default (NMPlatform *self, int ifindex, guint32 metric)
-{
- return nm_platform_ip6_route_delete (self, ifindex, in6addr_any, 0, metric);
-}
-
/******************************************************************/
const NMPlatformVTableRoute nm_platform_vtable_route_v4 = {
@@ -4189,7 +4361,6 @@ const NMPlatformVTableRoute nm_platform_vtable_route_v4 = {
.route_get_all = nm_platform_ip4_route_get_all,
.route_add = _vtr_v4_route_add,
.route_delete = _vtr_v4_route_delete,
- .route_delete_default = _vtr_v4_route_delete_default,
.metric_normalize = _vtr_v4_metric_normalize,
};
@@ -4202,7 +4373,6 @@ const NMPlatformVTableRoute nm_platform_vtable_route_v6 = {
.route_get_all = nm_platform_ip6_route_get_all,
.route_add = _vtr_v6_route_add,
.route_delete = _vtr_v6_route_delete,
- .route_delete_default = _vtr_v6_route_delete_default,
.metric_normalize = nm_utils_ip6_route_metric_normalize,
};
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index ae12aa8e95..28d7b39689 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -338,13 +338,20 @@ struct _NMPlatformIP4Route {
in_addr_t network;
in_addr_t gateway;
- /* The bitwise inverse of the route scope. It is inverted so that the
- * default value (RT_SCOPE_NOWHERE) is nul. */
- guint8 scope_inv;
-
/* RTA_PREFSRC/rtnl_route_get_pref_src(). A value of zero means that
* no pref-src is set. */
in_addr_t pref_src;
+
+ /* The route scope rtm_scope.
+ *
+ * Note, that for IPv4, the scope is part of the ID for a route.
+ * That means, when we receive a route from kernel, we set rt_scope
+ * and rt_scope_is_set=1 to indicate that the scope is fully determined.
+ *
+ * When adding a route, we allow the user to autodetect the scope based
+ * on the gateway. That is controlled by leaving rt_scope_is_set=0. */
+ guint8 rt_scope;
+ bool rt_scope_is_set:1;
};
struct _NMPlatformIP6Route {
@@ -372,9 +379,8 @@ typedef struct {
int (*route_cmp) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b);
const char *(*route_to_string) (const NMPlatformIPXRoute *route, char *buf, gsize len);
GArray *(*route_get_all) (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags);
- gboolean (*route_add) (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric);
- gboolean (*route_delete) (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route);
- gboolean (*route_delete_default) (NMPlatform *self, int ifindex, guint32 metric);
+ gboolean (*route_add) (NMPlatform *self, const NMPlatformIPXRoute *route, int ifindex, gint64 metric);
+ gboolean (*route_delete) (NMPlatform *self, const NMPlatformIPXRoute *route);
guint32 (*metric_normalize) (guint32 metric);
} NMPlatformVTableRoute;
@@ -630,16 +636,12 @@ typedef struct {
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 *, int ifindex, NMIPConfigSource source,
- in_addr_t network, guint8 plen, in_addr_t gateway,
- in_addr_t pref_src, guint32 metric, guint32 mss);
- gboolean (*ip6_route_add) (NMPlatform *, int ifindex, NMIPConfigSource source,
- struct in6_addr network, guint8 plen, struct in6_addr gateway,
- guint32 metric, guint32 mss);
- 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 (*ip4_route_add) (NMPlatform *, const NMPlatformIP4Route *route);
+ gboolean (*ip6_route_add) (NMPlatform *, const NMPlatformIP6Route *route);
+ gboolean (*ip4_route_delete) (NMPlatform *, const NMPlatformIP4Route *route);
+ gboolean (*ip6_route_delete) (NMPlatform *, const NMPlatformIP6Route *route);
+ const NMPlatformIP4Route *(*ip4_route_get) (NMPlatform *, const NMPlatformIP4Route *route);
+ const NMPlatformIP6Route *(*ip6_route_get) (NMPlatform *, const NMPlatformIP6Route *route);
gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *);
gboolean (*check_support_user_ipv6ll) (NMPlatform *);
@@ -676,23 +678,37 @@ NMPlatform *nm_platform_try_get (void);
/******************************************************************/
-/**
- * nm_platform_route_scope_inv:
- * @scope: the route scope, either its original value, or its inverse.
- *
- * This function is useful, because the constants such as RT_SCOPE_NOWHERE
- * are 'int', so ~scope also gives an 'int'. This function gets the type
- * casts to guint8 right.
- *
- * Returns: the bitwise inverse of the route scope.
- * */
-#define nm_platform_route_scope_inv _nm_platform_uint8_inv
static inline guint8
_nm_platform_uint8_inv (guint8 scope)
{
return (guint8) ~scope;
}
+static inline guint8
+nm_platform_route_scope_for_ip4_gateway (guint32 gateway)
+{
+ return gateway
+ ? 0 /* RT_SCOPE_UNIVERSE */
+ : 253 /* RT_SCOPE_LINK */;
+}
+
+static inline guint8
+nm_platform_route_scope_for_ip6_gateway (const struct in6_addr *gateway)
+{
+ return gateway && !IN6_IS_ADDR_UNSPECIFIED (gateway)
+ ? 0 /* RT_SCOPE_UNIVERSE */
+ : 253 /* RT_SCOPE_LINK */;
+}
+
+static inline guint8
+nm_platform_route_scope_from_ip4_route (const NMPlatformIP4Route *route)
+{
+ nm_assert (route);
+ return route->rt_scope_is_set
+ ? route->rt_scope
+ : nm_platform_route_scope_for_ip4_gateway (route->gateway);
+}
+
NMPNetns *nm_platform_netns_get (NMPlatform *self);
gboolean nm_platform_netns_push (NMPlatform *platform, NMPNetns **netns);
@@ -907,18 +923,14 @@ gboolean nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArr
gboolean nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, gboolean keep_link_local);
gboolean nm_platform_address_flush (NMPlatform *self, int ifindex);
-const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric);
-const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric);
+const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, const NMPlatformIP4Route *route);
+const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, const NMPlatformIP6Route *route);
GArray *nm_platform_ip4_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags);
GArray *nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags);
-gboolean nm_platform_ip4_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source,
- in_addr_t network, guint8 plen, in_addr_t gateway,
- in_addr_t pref_src, guint32 metric, guint32 mss);
-gboolean nm_platform_ip6_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source,
- struct in6_addr network, guint8 plen, struct in6_addr gateway,
- guint32 metric, guint32 mss);
-gboolean nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, guint8 plen, guint32 metric);
-gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, guint8 plen, guint32 metric);
+gboolean nm_platform_ip4_route_add (NMPlatform *self, const NMPlatformIP4Route *route);
+gboolean nm_platform_ip6_route_add (NMPlatform *self, const NMPlatformIP6Route *route);
+gboolean nm_platform_ip4_route_delete (NMPlatform *self, const NMPlatformIP4Route *route);
+gboolean nm_platform_ip6_route_delete (NMPlatform *self, const NMPlatformIP6Route *route);
const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len);
const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len);
@@ -954,6 +966,18 @@ int nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatform
int nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b);
int nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b);
+typedef enum {
+ NM_PLATFORM_IP_ROUTE_ID_TYPE_ID,
+ NM_PLATFORM_IP_ROUTE_ID_TYPE_ALL,
+} NMPlatformIPRouteIdType;
+
+int nm_platform_ip4_route_cmp_full (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, NMPlatformIPRouteIdType id_type);
+int nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, NMPlatformIPRouteIdType id_type);
+guint nm_platform_ip4_route_hash_full (const NMPlatformIP4Route *a, NMPlatformIPRouteIdType id_type);
+guint nm_platform_ip6_route_hash_full (const NMPlatformIP6Route *a, NMPlatformIPRouteIdType id_type);
+NMPlatformIP4Route *nm_platform_ip4_route_normalize (NMPlatformIP4Route *dst, const NMPlatformIP4Route *src, NMPlatformIPRouteIdType id_type);
+NMPlatformIP6Route *nm_platform_ip6_route_normalize (NMPlatformIP6Route *dst, const NMPlatformIP6Route *src, NMPlatformIPRouteIdType id_type);
+
gboolean nm_platform_check_support_kernel_extended_ifa_flags (NMPlatform *self);
gboolean nm_platform_check_support_user_ipv6ll (NMPlatform *self);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 55ffd7cffb..8902881642 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -377,38 +377,33 @@ _vt_cmd_obj_stackinit_id_ip6_address (NMPObject *obj, const NMPObject *src)
}
const NMPObject *
-nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric)
+nmp_object_stackinit_id_ip4_route (NMPObject *obj, const NMPlatformIP4Route *route, NMPlatformIPRouteIdType id_type)
{
nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
- obj->ip4_route.ifindex = ifindex;
- obj->ip4_route.network = network;
- obj->ip4_route.plen = plen;
- obj->ip4_route.metric = metric;
+ if (route)
+ nm_platform_ip4_route_normalize (&obj->ip4_route, route, id_type);
return obj;
}
static void
_vt_cmd_obj_stackinit_id_ip4_route (NMPObject *obj, const NMPObject *src)
{
- nmp_object_stackinit_id_ip4_route (obj, src->ip_route.ifindex, src->ip4_route.network, src->ip_route.plen, src->ip_route.metric);
+ nmp_object_stackinit_id_ip4_route (obj, &src->ip4_route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
}
const NMPObject *
-nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric)
+nmp_object_stackinit_id_ip6_route (NMPObject *obj, const NMPlatformIP6Route *route, NMPlatformIPRouteIdType id_type)
{
nmp_object_stackinit (obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
- obj->ip6_route.ifindex = ifindex;
- if (network)
- obj->ip6_route.network = *network;
- obj->ip6_route.plen = plen;
- obj->ip6_route.metric = metric;
+ if (route)
+ nm_platform_ip6_route_normalize (&obj->ip6_route, route, id_type);
return obj;
}
static void
_vt_cmd_obj_stackinit_id_ip6_route (NMPObject *obj, const NMPObject *src)
{
- nmp_object_stackinit_id_ip6_route (obj, src->ip_route.ifindex, &src->ip6_route.network, src->ip_route.plen, src->ip_route.metric);
+ nmp_object_stackinit_id_ip6_route (obj, &src->ip6_route, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
}
/******************************************************************/
@@ -567,8 +562,6 @@ _vt_cmd_plobj_to_string_id (ip4_address, NMPlatformIP4Address, "%d: %s/%d%s%s",
obj->peer_address != obj->address ? "," : "",
obj->peer_address != obj->address ? nm_utils_inet4_ntop (obj->peer_address & nm_utils_ip4_prefix_to_netmask (obj->plen), buf2) : "");
_vt_cmd_plobj_to_string_id (ip6_address, NMPlatformIP6Address, "%d: %s", obj->ifindex, nm_utils_inet6_ntop (&obj->address, buf1));
-_vt_cmd_plobj_to_string_id (ip4_route, NMPlatformIP4Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet4_ntop ( obj->network, buf1), obj->plen, obj->metric);
-_vt_cmd_plobj_to_string_id (ip6_route, NMPlatformIP6Route, "%d: %s/%d %d", obj->ifindex, nm_utils_inet6_ntop (&obj->network, buf1), obj->plen, obj->metric);
int
nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2)
@@ -733,16 +726,10 @@ _vt_cmd_plobj_id_copy (ip6_address, NMPlatformIP6Address, {
dst->address = src->address;
});
_vt_cmd_plobj_id_copy (ip4_route, NMPlatformIP4Route, {
- dst->ifindex = src->ifindex;
- dst->plen = src->plen;
- dst->metric = src->metric;
- dst->network = src->network;
+ nm_platform_ip4_route_normalize (dst, src, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
});
_vt_cmd_plobj_id_copy (ip6_route, NMPlatformIP6Route, {
- dst->ifindex = src->ifindex;
- dst->plen = src->plen;
- dst->metric = src->metric;
- dst->network = src->network;
+ nm_platform_ip6_route_normalize (dst, src, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
});
/* Uses internally nmp_object_copy(), hence it also violates the const
@@ -804,15 +791,9 @@ _vt_cmd_plobj_id_equal (ip6_address, NMPlatformIP6Address,
/* for IPv6 addresses, the prefix length is not part of the primary identifier. */
&& IN6_ARE_ADDR_EQUAL (&obj1->address, &obj2->address));
_vt_cmd_plobj_id_equal (ip4_route, NMPlatformIP4Route,
- obj1->ifindex == obj2->ifindex
- && obj1->plen == obj2->plen
- && obj1->metric == obj2->metric
- && obj1->network == obj2->network);
+ nm_platform_ip4_route_cmp_full (obj1, obj2, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID) == 0);
_vt_cmd_plobj_id_equal (ip6_route, NMPlatformIP6Route,
- obj1->ifindex == obj2->ifindex
- && obj1->plen == obj2->plen
- && obj1->metric == obj2->metric
- && IN6_ARE_ADDR_EQUAL( &obj1->network, &obj2->network));
+ nm_platform_ip6_route_cmp_full (obj1, obj2, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID) == 0);
guint
nmp_object_id_hash (const NMPObject *obj)
@@ -862,18 +843,10 @@ _vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, {
hash = hash * 33 + _id_hash_ip6_addr (&obj->address);
})
_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, {
- hash = (guint) 2569857221u;
- hash = hash + ((guint) obj->ifindex);
- hash = hash * 33 + ((guint) obj->plen);
- hash = hash * 33 + ((guint) obj->metric);
- hash = hash * 33 + ((guint) obj->network);
+ hash = nm_platform_ip4_route_hash_full (obj, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
})
_vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, {
- hash = (guint) 3999787007u;
- hash = hash + ((guint) obj->ifindex);
- hash = hash * 33 + ((guint) obj->plen);
- hash = hash * 33 + ((guint) obj->metric);
- hash = hash * 33 + _id_hash_ip6_addr (&obj->network);
+ hash = nm_platform_ip6_route_hash_full (obj, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
})
gboolean
@@ -2172,7 +2145,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route,
.cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip4_route,
.cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip4_route,
- .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_route,
+ .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_route_cmp,
},
@@ -2192,7 +2165,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route,
.cmd_plobj_id_equal = _vt_cmd_plobj_id_equal_ip6_route,
.cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip6_route,
- .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_route,
+ .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp,
},
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index 062d01d29d..55c7d57766 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -373,8 +373,8 @@ const NMPObject *nmp_object_stackinit_id (NMPObject *obj, const NMPObject *src)
const NMPObject *nmp_object_stackinit_id_link (NMPObject *obj, int ifindex);
const NMPObject *nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, guint8 plen, guint32 peer_address);
const NMPObject *nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address, guint8 plen);
-const NMPObject *nmp_object_stackinit_id_ip4_route (NMPObject *obj, int ifindex, guint32 network, guint8 plen, guint32 metric);
-const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric);
+const NMPObject *nmp_object_stackinit_id_ip4_route (NMPObject *obj, const NMPlatformIP4Route *route, NMPlatformIPRouteIdType id_type);
+const NMPObject *nmp_object_stackinit_id_ip6_route (NMPObject *obj, const NMPlatformIP6Route *route, NMPlatformIPRouteIdType id_type);
const char *nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size);
int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2);
diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c
index 3b52487a56..15af4909c7 100644
--- a/src/platform/tests/test-cleanup.c
+++ b/src/platform/tests/test-cleanup.c
@@ -33,26 +33,21 @@ test_cleanup_internal (void)
GArray *addresses6;
GArray *routes4;
GArray *routes6;
- in_addr_t addr4;
- in_addr_t network4;
int plen4 = 24;
- in_addr_t gateway4;
- struct in6_addr addr6;
- struct in6_addr network6;
int plen6 = 64;
- struct in6_addr gateway6;
int lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
int preferred = NM_PLATFORM_LIFETIME_PERMANENT;
int metric = 20;
int mss = 1000;
guint32 flags = 0;
-
- inet_pton (AF_INET, "192.0.2.1", &addr4);
- inet_pton (AF_INET, "192.0.3.0", &network4);
- inet_pton (AF_INET, "198.51.100.1", &gateway4);
- inet_pton (AF_INET6, "2001:db8:a:b:1:2:3:4", &addr6);
- inet_pton (AF_INET6, "2001:db8:c:d:0:0:0:0", &network6);
- inet_pton (AF_INET6, "2001:db8:e:f:1:2:3:4", &gateway6);
+ const char *const ADDR4 = "192.0.2.1";
+ const char *const NETWORK4 = "192.0.3.0";
+ const char *const GATEWAY4 = "198.51.100.1";
+ const char *const ADDR6 = "2001:db8:a:b:1:2:3:4";
+ const char *const NETWORK6 = "2001:db8:c:d:0:0:0:0";
+ const char *const GATEWAY6 = "2001:db8:e:f:1:2:3:4";
+ const guint32 addr4 = nmtst_inet4_from_string (ADDR4);
+ const struct in6_addr addr6 = *nmtst_inet6_from_string (ADDR6);
/* Create and set up device */
g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS);
@@ -65,12 +60,12 @@ test_cleanup_internal (void)
/* Add routes and addresses */
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, plen4, addr4, lifetime, preferred, 0, NULL));
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr6, plen6, in6addr_any, lifetime, preferred, flags));
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway4, 32, INADDR_ANY, 0, metric, mss));
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network4, plen4, gateway4, 0, metric, mss));
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway4, 0, metric, mss));
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway6, 128, in6addr_any, metric, mss));
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network6, plen6, gateway6, metric, mss));
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway6, metric, mss));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, nmtst_platform_ip4_route_full (ifindex, GATEWAY4, 32, NULL, NM_IP_CONFIG_SOURCE_USER, metric, mss, 0, FALSE, NULL)));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, nmtst_platform_ip4_route_full (ifindex, NETWORK4, plen4, GATEWAY4, NM_IP_CONFIG_SOURCE_USER, metric, mss, 0, FALSE, NULL)));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, nmtst_platform_ip4_route_full (ifindex, NULL, 0, GATEWAY4, NM_IP_CONFIG_SOURCE_USER, metric, mss, 0, FALSE, NULL)));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, nmtst_platform_ip6_route_full (ifindex, GATEWAY6, 128, NULL, NM_IP_CONFIG_SOURCE_USER, metric, mss)));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, nmtst_platform_ip6_route_full (ifindex, NETWORK6, plen6, GATEWAY6, NM_IP_CONFIG_SOURCE_USER, metric, mss)));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, nmtst_platform_ip6_route_full (ifindex, NULL, 0, GATEWAY6, NM_IP_CONFIG_SOURCE_USER, metric, mss)));
addresses4 = nm_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex);
addresses6 = nm_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex);
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index b1947a6d11..2177d58252 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -25,6 +25,9 @@
#include <sys/wait.h>
#include <fcntl.h>
+#include "nm-platform-utils.h"
+#include "nmp-object.h"
+
#include "test-common.h"
#define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)"
@@ -196,8 +199,156 @@ link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlat
/*****************************************************************************/
+static int
+_sort_routes (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
+{
+ gboolean is_v4 = GPOINTER_TO_INT (user_data);
+
+ if (is_v4)
+ return nm_platform_ip4_route_cmp (p_a, p_b);
+ else
+ return nm_platform_ip6_route_cmp (p_a, p_b);
+}
+
+const NMPlatformIPXRoute **
+nmtstp_ip_route_get_by_destination (NMPlatform *platform,
+ gboolean is_v4,
+ int ifindex,
+ const NMIPAddr *network,
+ guint8 plen,
+ guint32 metric,
+ const NMIPAddr *gateway,
+ guint *out_len)
+{
+ gs_unref_array GArray *routes = NULL;
+ GPtrArray *result = NULL;
+ gs_unref_hashtable GHashTable *check_dupes = NULL;
+ NMIPAddr network_clean;
+ guint i;
+
+ g_assert (ifindex >= 0);
+ g_assert (plen >= 0 && plen <= (is_v4 ? 32 : 128));
+
+ NM_SET_OUT (out_len, 0);
+
+ _init_platform (&platform, FALSE);
+
+ check_dupes = g_hash_table_new ((GHashFunc) nmp_object_id_hash, (GEqualFunc) nmp_object_id_equal);
+ result = g_ptr_array_new ();
+
+ network = nm_utils_ipx_address_clear_host_address (is_v4 ? AF_INET : AF_INET6,
+ &network_clean,
+ network ?: &nm_ip_addr_zero,
+ plen);
+
+ if (!is_v4)
+ metric = nm_utils_ip6_route_metric_normalize (metric);
+
+ if (is_v4)
+ routes = nm_platform_ip4_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_RTPROT_KERNEL);
+ else
+ routes = nm_platform_ip6_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_RTPROT_KERNEL);
+
+ for (i = 0; routes && i < routes->len; i++) {
+ const NMPlatformIPXRoute *r_i = is_v4
+ ? (NMPlatformIPXRoute *) &g_array_index (routes, NMPlatformIP4Route, i)
+ : (NMPlatformIPXRoute *) &g_array_index (routes, NMPlatformIP6Route, i);
+ const NMPlatformIPXRoute *r_2;
+ const NMPObject *o_2;
+
+ g_assert (r_i->rx.ifindex == ifindex);
+
+ if ( r_i->rx.plen != plen
+ || r_i->rx.metric != metric)
+ continue;
+
+ if (is_v4) {
+ if (r_i->r4.network != *((guint32 *) network))
+ continue;
+ if ( gateway
+ && r_i->r4.gateway != *((guint32 *) gateway))
+ continue;
+ } else {
+ if (!IN6_ARE_ADDR_EQUAL (&r_i->r6.network, network))
+ continue;
+ if ( gateway
+ && !IN6_ARE_ADDR_EQUAL (&r_i->r6.gateway, gateway))
+ continue;
+ }
+
+ r_2 = is_v4
+ ? (NMPlatformIPXRoute *) nm_platform_ip4_route_get (platform, &r_i->r4)
+ : (NMPlatformIPXRoute *) nm_platform_ip6_route_get (platform, &r_i->r6);
+ g_assert (r_2);
+ g_assert ( ( is_v4 && nm_platform_ip4_route_cmp (&r_i->r4, &r_2->r4) == 0)
+ || (!is_v4 && nm_platform_ip6_route_cmp (&r_i->r6, &r_2->r6) == 0));
+
+ o_2 = NMP_OBJECT_UP_CAST (r_2);
+ g_assert (NMP_OBJECT_IS_VALID (o_2));
+ g_assert (NMP_OBJECT_GET_TYPE (o_2) == (is_v4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE));
+
+ g_ptr_array_add (result, (gpointer) r_2);
+ if (!nm_g_hash_table_add (check_dupes, (gpointer) o_2))
+ g_assert_not_reached ();
+ }
+
+ /* check whether the multi-index of the platform cache agrees... */
+ if (NM_IS_LINUX_PLATFORM (platform)) {
+ const NMPlatformObject *const *routes_cached;
+ NMPCacheId cache_id;
+ guint len;
+
+ if (is_v4)
+ nmp_cache_id_init_routes_by_destination_ip4 (&cache_id, network->addr4, plen, metric);
+ else
+ nmp_cache_id_init_routes_by_destination_ip6 (&cache_id, &network->addr6, plen, metric);
+
+ routes_cached = nm_linux_platform_lookup (platform, &cache_id, &len);
+
+ if (len)
+ g_assert (routes_cached && routes_cached[len] == NULL);
+ else
+ g_assert (!routes_cached);
+
+ for (i =0; routes_cached && i < len; i++) {
+ const NMPObject *o;
+ const NMPObject *o_2;
+
+ g_assert (routes_cached [i]);
+ o = NMP_OBJECT_UP_CAST (routes_cached [i]);
+ g_assert (NMP_OBJECT_IS_VALID (o));
+ g_assert (NMP_OBJECT_GET_TYPE (o) == (is_v4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE));
+
+ if (gateway) {
+ if ( ( is_v4 && o->ip4_route.gateway != *((guint32 *) gateway))
+ || (!is_v4 && !IN6_ARE_ADDR_EQUAL (&o->ip6_route.gateway, gateway)))
+ continue;
+ }
+
+ o_2 = g_hash_table_lookup (check_dupes, o);
+ g_assert (o_2);
+ g_assert (o_2 == o);
+
+ if (!g_hash_table_remove (check_dupes, o))
+ g_assert_not_reached ();
+ }
+
+ g_assert (g_hash_table_size (check_dupes) == 0);
+ }
+
+ if (result->len > 0) {
+ g_ptr_array_sort_with_data (result, _sort_routes, GINT_TO_POINTER (!!is_v4));
+ NM_SET_OUT (out_len, result->len);
+ g_ptr_array_add (result, NULL);
+ return (gpointer) g_ptr_array_free (result, FALSE);
+ }
+ g_ptr_array_unref (result);
+ return NULL;
+}
+
+
gboolean
-nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric)
+nmtstp_ip4_route_exists (const char *ifname, guint32 network, guint8 plen, guint32 metric, const guint32 *gateway)
{
gs_free char *arg_network = NULL;
const char *argv[] = {
@@ -216,6 +367,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32
gboolean success;
gs_free_error GError *error = NULL;
gs_free char *metric_pattern = NULL;
+ gs_free char *via_pattern = NULL;
g_assert (ifname && nm_utils_iface_valid_name (ifname));
g_assert (!strstr (ifname, " metric "));
@@ -253,6 +405,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32
g_assert (std_out);
metric_pattern = g_strdup_printf (" metric %u", metric);
+ via_pattern = gateway ? g_strdup_printf (" via %s", nm_utils_inet4_ntop (*gateway, NULL)) : NULL;
out = std_out;
while (out) {
char *eol = strchr (out, '\n');
@@ -264,44 +417,93 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32
continue;
if (metric == 0) {
- if (!strstr (line, " metric "))
- return TRUE;
+ if (strstr (line, " metric "))
+ continue;
+ } else {
+ p = strstr (line, metric_pattern);
+ if (!p || !NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0'))
+ continue;
+ }
+
+ if (gateway) {
+ if (*gateway == 0) {
+ if (strstr (line, " via "))
+ continue;
+ } else {
+ p = strstr (line, via_pattern);
+ if (!p || !NM_IN_SET (p[strlen (via_pattern)], ' ', '\0'))
+ continue;
+ }
}
- p = strstr (line, metric_pattern);
- if (p && NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0'))
- return TRUE;
+ return TRUE;
}
return FALSE;
}
-void
-_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric)
+const NMPlatformIP4Route *
+_nmtstp_assert_ip4_route_exists (const char *file,
+ guint line,
+ const char *func,
+ NMPlatform *platform,
+ gboolean exists,
+ const char *ifname,
+ guint32 network,
+ guint8 plen,
+ guint32 metric,
+ const guint32 *gateway)
{
int ifindex;
gboolean exists_checked;
+ char s_buf[NM_UTILS_INET_ADDRSTRLEN];
+ gs_free const NMPlatformIP4Route **routes = NULL;
+ guint len;
_init_platform (&platform, FALSE);
/* Check for existance of the route by spawning iproute2. Do this because platform
* code might be entirely borked, but we expect ip-route to give a correct result.
* If the ip command cannot be found, we accept this as success. */
- exists_checked = nmtstp_ip4_route_exists (ifname, network, plen, metric);
+ exists_checked = nmtstp_ip4_route_exists (ifname, network, plen, metric, gateway);
if (exists_checked != -1 && !exists_checked != !exists) {
- g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d metric %u %s, but it %s",
+ g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d%s metric %u %s, but it %s",
file, line, func,
- nm_utils_inet4_ntop (network, NULL), plen, metric,
+ nm_utils_inet4_ntop (network, NULL), plen,
+ gateway ? nm_sprintf_bufa (100, " gateway %s", nm_utils_inet4_ntop (*gateway, s_buf)) : " no-gateway",
+ metric,
exists ? "to exist" : "not to exist",
exists ? "doesn't" : "does");
}
ifindex = nm_platform_link_get_ifindex (platform, ifname);
g_assert (ifindex > 0);
- if (!nm_platform_ip4_route_get (platform, ifindex, network, plen, metric) != !exists) {
- g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s",
- file, line, func,
- nm_utils_inet4_ntop (network, NULL), plen, metric,
- exists ? "exists" : "does not exist",
- exists ? "it doesn't" : "it does");
+
+ routes = (gpointer) nmtstp_ip_route_get_by_destination (platform, TRUE, ifindex, (NMIPAddr *) &network,
+ plen, metric, (NMIPAddr *) gateway, &len);
+ if (routes) {
+ if (!exists) {
+ g_error ("[%s:%u] %s(): The ip4 route %s/%d via %s metric %u %s, but platform thinks %s",
+ file, line, func,
+ nm_utils_inet4_ntop (network, NULL),
+ plen,
+ nm_utils_inet4_ntop (gateway ? *gateway : 0, s_buf),
+ metric,
+ exists ? "exists" : "does not exist",
+ exists ? "it doesn't" : "it does");
+ }
+ g_assert (len == 1);
+ return routes[0];
+ } else {
+ if (exists) {
+ g_error ("[%s:%u] %s(): The ip4 route %s/%d via %s metric %u %s, but platform thinks %s",
+ file, line, func,
+ nm_utils_inet4_ntop (network, NULL),
+ plen,
+ nm_utils_inet4_ntop (gateway ? *gateway : 0, s_buf),
+ metric,
+ exists ? "exists" : "does not exist",
+ exists ? "it doesn't" : "it does");
+ }
+ return NULL;
}
}
@@ -414,7 +616,7 @@ nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms)
const NMPlatformLink *
nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms)
{
- return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms);
+ return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
}
const NMPlatformLink *
@@ -443,7 +645,7 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType
const NMPlatformLink *
nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms)
{
- return nmtstp_assert_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms);
+ return nmtstp_assert_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
}
const NMPlatformLink *
@@ -458,6 +660,55 @@ nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NML
/*****************************************************************************/
+static const void *
+_wait_for_ip_route_until (NMPlatform *platform, int is_v4, int ifindex, const NMIPAddr *network, guint8 plen, guint32 metric, const NMIPAddr *gateway, gint64 until_ms)
+{
+ gint64 now;
+
+ _init_platform (&platform, FALSE);
+
+ while (TRUE) {
+ gs_free const NMPlatformIPXRoute **routes = NULL;
+
+ now = nm_utils_get_monotonic_timestamp_ms ();
+
+ routes = nmtstp_ip_route_get_by_destination (platform, is_v4, ifindex, network, plen, metric, gateway, NULL);
+ if (routes)
+ return routes[0];
+
+ if (until_ms < now)
+ return NULL;
+
+ nmtstp_wait_for_signal (platform, MAX (1, until_ms - now));
+ }
+}
+
+const NMPlatformIP4Route *
+nmtstp_wait_for_ip4_route (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, guint timeout_ms)
+{
+ return _wait_for_ip_route_until (platform, TRUE, ifindex, (NMIPAddr *) &network, plen, metric, (NMIPAddr *) &gateway, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
+}
+
+const NMPlatformIP4Route *
+nmtstp_wait_for_ip4_route_until (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, gint64 until_ms)
+{
+ return _wait_for_ip_route_until (platform, TRUE, ifindex, (NMIPAddr *) &network, plen, metric, (NMIPAddr *) &gateway, until_ms);
+}
+
+const NMPlatformIP6Route *
+nmtstp_wait_for_ip6_route (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, guint timeout_ms)
+{
+ return _wait_for_ip_route_until (platform, FALSE, ifindex, (NMIPAddr *) network, plen, metric, (NMIPAddr *) gateway, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
+}
+
+const NMPlatformIP6Route *
+nmtstp_wait_for_ip6_route_until (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, gint64 until_ms)
+{
+ return _wait_for_ip_route_until (platform, FALSE, ifindex, (NMIPAddr *) network, plen, metric, (NMIPAddr *) gateway, until_ms);
+}
+
+/*****************************************************************************/
+
int
nmtstp_run_command_check_external_global (void)
{
@@ -592,7 +843,7 @@ _ip_address_add (NMPlatform *platform,
gboolean is_v4,
int ifindex,
const NMIPAddr *address,
- int plen,
+ guint8 plen,
const NMIPAddr *peer_address,
guint32 lifetime,
guint32 preferred,
@@ -730,7 +981,7 @@ nmtstp_ip4_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address,
guint32 lifetime,
guint32 preferred,
@@ -755,7 +1006,7 @@ nmtstp_ip6_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen,
+ guint8 plen,
struct in6_addr peer_address,
guint32 lifetime,
guint32 preferred,
@@ -782,7 +1033,7 @@ _ip_address_del (NMPlatform *platform,
gboolean is_v4,
int ifindex,
const NMIPAddr *address,
- int plen,
+ guint8 plen,
const NMIPAddr *peer_address)
{
gint64 end_time;
@@ -873,7 +1124,7 @@ nmtstp_ip4_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address)
{
_ip_address_del (platform,
@@ -890,7 +1141,7 @@ nmtstp_ip6_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen)
+ guint8 plen)
{
_ip_address_del (platform,
external_command,
@@ -903,6 +1154,119 @@ nmtstp_ip6_address_del (NMPlatform *platform,
/*****************************************************************************/
+static gconstpointer
+_ip_route_add (NMPlatform *platform,
+ gboolean external_command,
+ gboolean is_v4,
+ const NMPlatformIPXRoute *route)
+{
+ gint64 end_time;
+ char s_network[NM_UTILS_INET_ADDRSTRLEN];
+ char s_gateway[NM_UTILS_INET_ADDRSTRLEN];
+ char s_pref_src[NM_UTILS_INET_ADDRSTRLEN];
+ const NMPlatformLink *pllink;
+ NMPObject obj_normalized;
+ const NMPlatformIPXRoute *route_orig;
+ guint i, len;
+
+ g_assert (route);
+ g_assert (route->rx.ifindex > 0);
+
+ external_command = nmtstp_run_command_check_external (external_command);
+
+ _init_platform (&platform, external_command);
+
+ route_orig = route;
+ if (is_v4)
+ nmp_object_stackinit_id_ip4_route (&obj_normalized, &route->r4, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+ else
+ nmp_object_stackinit_id_ip6_route (&obj_normalized, &route->r6, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+ route = &obj_normalized.ipx_route;
+
+ pllink = nmtstp_link_get (platform, route->rx.ifindex, NULL);
+ g_assert (pllink);
+
+ if (external_command) {
+ s_network[0] = '\0';
+ s_gateway[0] = '\0';
+ s_pref_src[0] = '\0';
+ if (is_v4) {
+ nm_utils_inet4_ntop (route->r4.network, s_network);
+ if (route->r4.gateway)
+ nm_utils_inet4_ntop (route->r4.gateway, s_gateway);
+ if (route->r4.pref_src)
+ nm_utils_inet4_ntop (route->r4.pref_src, s_pref_src);
+ } else {
+ nm_utils_inet6_ntop (&route->r6.network, s_network);
+ if (!IN6_IS_ADDR_UNSPECIFIED (&route->r6.gateway))
+ nm_utils_inet6_ntop (&route->r6.gateway, s_gateway);
+ }
+
+ nmtstp_run_command_check ("ip route append %s/%u%s dev '%s' metric %u proto %u%s%s",
+ s_network,
+ route->rx.plen,
+ s_gateway[0] ? nm_sprintf_bufa (100, " via %s", s_gateway) : "",
+ pllink->name,
+ route->rx.metric,
+ nmp_utils_ip_config_source_coerce_to_rtprot (route->r4.rt_source),
+ s_pref_src[0] ? nm_sprintf_bufa (100, " src %s", s_pref_src) : "",
+ route->rx.mss ? nm_sprintf_bufa (100, " advmss %u", route->rx.mss) : "");
+ } else {
+ gboolean success;
+
+ if (is_v4)
+ success = nm_platform_ip4_route_add (platform, &route_orig->r4);
+ else
+ success = nm_platform_ip6_route_add (platform, &route_orig->r6);
+ g_assert (success);
+ }
+
+ /* Let's wait until we see the address. */
+ end_time = nm_utils_get_monotonic_timestamp_ms () + 250;
+ do {
+ gs_free const NMPlatformIPXRoute **routes = NULL;
+
+ if (external_command)
+ nm_platform_process_events (platform);
+
+ /* let's wait until we see the address as we added it. */
+ routes = nmtstp_ip_route_get_by_destination (platform, is_v4, route->rx.ifindex,
+ (NMIPAddr *) route->rx.network_ptr,
+ route->rx.plen,
+ route->rx.metric,
+ is_v4 ? (NMIPAddr *) &route->r4.gateway : (NMIPAddr *) &route->r6.gateway,
+ &len);
+ for (i = 0; i < len; i++) {
+ const NMPObject *o2;
+
+ o2 = NMP_OBJECT_UP_CAST (routes[i]);
+ if (nmp_object_equal (o2, &obj_normalized))
+ return &o2->ipx_route;
+ }
+
+ /* for internal command, we expect not to reach this line.*/
+ g_assert (external_command);
+
+ nmtstp_assert_wait_for_signal_until (platform, end_time);
+ } while (TRUE);
+}
+
+const NMPlatformIP4Route *
+nmtstp_ip4_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP4Route *route)
+{
+ return _ip_route_add (platform, external_command, TRUE, (const NMPlatformIPXRoute *) route);
+}
+
+const NMPlatformIP6Route *
+nmtstp_ip6_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP6Route *route)
+{
+ return _ip_route_add (platform, external_command, FALSE, (const NMPlatformIPXRoute *) route);
+}
+
+/*****************************************************************************/
+
#define _assert_pllink(platform, success, pllink, name, type) \
G_STMT_START { \
const NMPlatformLink *_pllink = (pllink); \
diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h
index 0e3cf10ba4..c4c0e4abd7 100644
--- a/src/platform/tests/test-common.h
+++ b/src/platform/tests/test-common.h
@@ -109,6 +109,47 @@ const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const ch
const NMPlatformLink *nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms);
const NMPlatformLink *nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms);
+const NMPlatformIP4Route *nmtstp_wait_for_ip4_route (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, guint timeout_ms);
+const NMPlatformIP4Route *nmtstp_wait_for_ip4_route_until (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, gint64 until_ms);
+const NMPlatformIP6Route *nmtstp_wait_for_ip6_route (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, guint timeout_ms);
+const NMPlatformIP6Route *nmtstp_wait_for_ip6_route_until (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, gint64 until_ms);
+
+#define nmtstp_assert_wait_for_ip4_route(platform, ifindex, network, plen, metric, gateway, timeout_ms) \
+ ({ \
+ const NMPlatformIP4Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip4_route (platform, ifindex, network, plen, metric, gateway, timeout_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
+#define nmtstp_assert_wait_for_ip4_route_until(platform, ifindex, network, plen, metric, gateway, until_ms) \
+ ({ \
+ const NMPlatformIP4Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip4_route_until (platform, ifindex, network, plen, metric, gateway, until_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
+#define nmtstp_assert_wait_for_ip6_route(platform, ifindex, network, plen, metric, gateway, timeout_ms) \
+ ({ \
+ const NMPlatformIP6Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip6_route (platform, ifindex, network, plen, metric, gateway, timeout_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
+#define nmtstp_assert_wait_for_ip6_route_until(platform, ifindex, network, plen, metric, gateway, until_ms) \
+ ({ \
+ const NMPlatformIP6Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip6_route_until (platform, ifindex, network, plen, metric, gateway, until_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
/*****************************************************************************/
int nmtstp_run_command_check_external_global (void);
@@ -116,10 +157,19 @@ gboolean nmtstp_run_command_check_external (int external_command);
/*****************************************************************************/
-gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric);
+const NMPlatformIPXRoute **nmtstp_ip_route_get_by_destination (NMPlatform *platform,
+ gboolean is_v4,
+ int ifindex,
+ const NMIPAddr *network,
+ guint8 plen,
+ guint32 metric,
+ const NMIPAddr *gateway,
+ guint *out_len);
+
+gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, guint8 plen, guint32 metric, const guint32 *gateway);
-void _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric);
-#define nmtstp_assert_ip4_route_exists(platform, exists, ifname, network, plen, metric) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, exists, ifname, network, plen, metric)
+const NMPlatformIP4Route *_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, guint8 plen, guint32 metric, const guint32 *gateway);
+#define nmtstp_assert_ip4_route_exists(platform, exists, ifname, network, plen, metric, gateway) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, exists, ifname, network, plen, metric, gateway)
/*****************************************************************************/
@@ -136,7 +186,7 @@ void nmtstp_ip4_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address,
guint32 lifetime,
guint32 preferred,
@@ -146,7 +196,7 @@ void nmtstp_ip6_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen,
+ guint8 plen,
struct in6_addr peer_address,
guint32 lifetime,
guint32 preferred,
@@ -155,13 +205,19 @@ void nmtstp_ip4_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address);
void nmtstp_ip6_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen);
+ guint8 plen);
+
+const NMPlatformIP4Route *nmtstp_ip4_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP4Route *route);
+
+const NMPlatformIP6Route *nmtstp_ip6_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP6Route *route);
/*****************************************************************************/
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index 9d548aabdb..258b6f3476 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -2292,6 +2292,188 @@ test_netns_bind_to_path (gpointer fixture, gconstpointer test_data)
/*****************************************************************************/
+static void
+test_route_external (gconstpointer user_data)
+{
+ const gboolean EX = (nmtst_get_rand_int () % 3) - 1;
+ const char *const MODE = user_data;
+ const char *IF[2] = { "IF0", "IF1" };
+ int ifindex[2];
+ const char *gateway[2] = {
+ "192.168.171.1",
+ "192.168.172.1",
+ };
+ gs_unref_object NMPlatform *pl = NULL;
+ int delete_idx;
+ gs_free const NMPlatformIPXRoute **routes = NULL;
+ guint routes_len;
+
+ g_object_unref (NM_PLATFORM_GET);
+
+ g_assert (NM_IN_STRSET (MODE, "change", "append"));
+
+ pl = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
+
+ ifindex[0] = nmtstp_link_dummy_add (pl, EX, IF[0])->ifindex;
+ ifindex[1] = nmtstp_link_dummy_add (pl, EX, IF[1])->ifindex;
+ nmtstp_link_set_updown (pl, EX, ifindex[0], TRUE);
+ nmtstp_link_set_updown (pl, EX, ifindex[1], TRUE);
+
+ nmtstp_ip4_address_add (pl, EX, ifindex[0],
+ nmtst_inet4_from_string ("192.168.171.5"), 24,
+ nmtst_inet4_from_string ("192.168.171.5"),
+ NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL);
+ nmtstp_ip4_address_add (pl, EX, ifindex[1],
+ nmtst_inet4_from_string ("192.168.172.5"), 24,
+ nmtst_inet4_from_string ("192.168.172.5"),
+ NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL);
+
+#define ADDR4(addr_str) (nmtst_ip4_address_to_ptr (nmtst_inet4_from_string (addr_str)))
+
+ nmtstp_run_command_check ("ip route add 192.168.200.0/24 via %s metric 423", gateway[0]);
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex[0], nmtst_inet4_from_string ("192.168.200.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[0]), 100);
+
+ nmtstp_run_command_check ("ip route %s 192.168.200.0/24 via 192.168.172.1 metric 423", MODE);
+
+ if (NM_IN_STRSET (MODE, "changed")) {
+
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex[1], nmtst_inet4_from_string ("192.168.200.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[1]), 100);
+ /* is the route still on ifindex[0]? */
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[0],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[0]), NULL);
+ g_assert (!routes);
+ } else if (NM_IN_STRSET (MODE, "append")) {
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex[1], nmtst_inet4_from_string ("192.168.200.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[1]), 100);
+ /* the route on ifindex[0] should continue to exist */
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[0],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[0]), &routes_len);
+ g_assert (routes_len == 1);
+ g_clear_pointer (&routes, g_free);
+
+ delete_idx = nmtst_get_rand_int () % 2;
+
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[delete_idx],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[delete_idx]), &routes_len);
+ g_assert (routes_len == 1);
+ if (!nm_platform_ip4_route_delete (pl, &routes[0]->r4))
+ g_assert_not_reached ();
+ g_clear_pointer (&routes, g_free);
+
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[delete_idx],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[delete_idx]), &routes_len);
+ g_assert (!routes);
+
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[!delete_idx],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[!delete_idx]), &routes_len);
+ g_assert (routes_len == 1);
+ g_clear_pointer (&routes, g_free);
+ }
+
+ nmtstp_link_del (pl, EX, ifindex[0], IF[0]);
+ nmtstp_link_del (pl, EX, ifindex[1], IF[1]);
+
+ SETUP ();
+}
+
+/*****************************************************************************/
+
+static void
+test_route_modify (gconstpointer test_data)
+{
+#if 0
+ const char *const MODE = test_data;
+ const gboolean EX = (nmtst_get_rand_int () % 3) - 1;
+ const char *IF = "IF0";
+ int ifindex;
+ const char *gateway[2] = {
+ "192.168.181.1",
+ "192.168.181.2",
+ };
+ guint idx[2] = { 0, 1, };
+ guint i;
+ gs_unref_object NMPlatform *pl = NULL;
+
+ g_assert (NM_IN_STRSET (MODE, "delete", "update"));
+
+ g_object_unref (NM_PLATFORM_GET);
+
+ pl = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
+
+ nmtst_rand_perm (NULL, idx, idx, sizeof (idx[0]), G_N_ELEMENTS (idx));
+
+ ifindex = nmtstp_link_dummy_add (pl, EX, IF)->ifindex;
+ nmtstp_link_set_updown (pl, EX, ifindex, TRUE);
+
+ nmtstp_ip4_address_add (pl, EX, ifindex,
+ nmtst_inet4_from_string ("192.168.181.5"), 24,
+ nmtst_inet4_from_string ("192.168.181.5"),
+ NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL);
+
+ nmtstp_run_command_check ("ip route add 192.168.213.0/24 via %s metric 423", gateway[idx[0]]);
+ if (nmtst_get_rand_int () % 2) {
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex, nmtst_inet4_from_string ("192.168.213.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[idx[0]]), 100);
+ }
+
+ if (nmtst_get_rand_int () % 2) {
+ nmtstp_run_command_check ("ip route append 192.168.213.0/24 via %s metric 423", gateway[idx[1]]);
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex, nmtst_inet4_from_string ("192.168.213.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[idx[1]]), 100);
+ } else {
+ nmtstp_ip4_route_add (pl, EX, ifindex, NM_IP_CONFIG_SOURCE_RTPROT_BOOT,
+ nmtst_inet4_from_string ("192.168.213.0"), 24,
+ nmtst_inet4_from_string (gateway[idx[1]]), 0,
+ 423, 0);
+ }
+
+ g_assert (nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[0]])));
+ g_assert (nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[1]])));
+
+ nmtst_rand_perm (NULL, idx, idx, sizeof (idx[0]), G_N_ELEMENTS (idx));
+
+ for (i = 0; i < G_N_ELEMENTS (idx); i++) {
+ const NMPlatformIP4Route *plroute;
+
+ if (NM_IN_STRSET (MODE, "delete")) {
+ g_assert (nm_platform_ip4_route_delete (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[i]])));
+ g_assert (!nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[i]])));
+
+ plroute = nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[!i]]));
+ g_assert ((i == 0 && plroute) || (i == 1 && !plroute));
+ } else if (NM_IN_STRSET (MODE, "update")) {
+ plroute = nmtstp_ip4_route_add (pl, FALSE, ifindex, NM_IP_CONFIG_SOURCE_USER,
+ nmtst_inet4_from_string ("192.168.213.0"), 24,
+ nmtst_inet4_from_string (gateway[idx[i]]), 0,
+ 423, 1400);
+ }
+ }
+
+ nmtstp_link_del (pl, EX, ifindex, IF);
+
+ SETUP ();
+#endif
+}
+
+/*****************************************************************************/
+
void
_nmtstp_init_tests (int *argc, char ***argv)
{
@@ -2335,6 +2517,11 @@ _nmtstp_setup_tests (void)
g_test_add_data_func ("/link/create-many-links/20", GUINT_TO_POINTER (20), test_create_many_links);
g_test_add_data_func ("/link/create-many-links/1000", GUINT_TO_POINTER (1000), test_create_many_links);
+ g_test_add_data_func ("/route/external/change", "change", test_route_external);
+ g_test_add_data_func ("/route/external/append", "append", test_route_external);
+ g_test_add_data_func ("/route/modify/delete", "delete", test_route_modify);
+ g_test_add_data_func ("/route/modify/update", "update", test_route_modify);
+
g_test_add_func ("/link/nl-bugs/veth", test_nl_bugs_veth);
g_test_add_func ("/link/nl-bugs/spurious-newlink", test_nl_bugs_spuroius_newlink);
g_test_add_func ("/link/nl-bugs/spurious-dellink", test_nl_bugs_spuroius_dellink);
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index 360404e944..781d6d922b 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -76,56 +76,70 @@ test_ip4_route_metric0 (void)
SignalData *route_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_route_callback);
SignalData *route_changed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip4_route_callback);
SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_route_callback);
- in_addr_t network = nmtst_inet4_from_string ("192.0.2.5"); /* from 192.0.2.0/24 (TEST-NET-1) (rfc5737) */
+ const char *const NETWORK = "192.0.2.5"; /* from 192.0.2.0/24 (TEST-NET-1) (rfc5737) */
+ const guint32 network = nmtst_inet4_from_string (NETWORK);
int plen = 32;
int metric = 22987;
int mss = 1000;
+ NMPlatformIP4Route r = {
+ .ifindex = ifindex,
+ .network = network,
+ .plen = plen,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ .metric = metric,
+ .mss = mss,
+ };
+ NMPlatformIP4Route r_metric0;
+
+ r_metric0 = r;
+ r_metric0.metric = 0;
/* No routes initially */
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
/* add the first route */
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss));
+
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r));
accept_signal (route_added);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Deleting route with metric 0 does nothing */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r_metric0));
ensure_no_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* add the second route */
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_metric0));
accept_signal (route_added);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Delete route with metric 0 */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r_metric0));
accept_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Delete route with metric 0 again (we expect nothing to happen) */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r_metric0));
ensure_no_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Delete the other route */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r));
accept_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
free_signal (route_added);
free_signal (route_changed);
@@ -141,38 +155,61 @@ test_ip4_route (void)
SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_route_callback);
GArray *routes;
NMPlatformIP4Route rts[3];
- in_addr_t network;
guint8 plen = 24;
- in_addr_t gateway;
/* Choose a high metric so that we hopefully don't conflict. */
int metric = 22986;
int mss = 1000;
-
- inet_pton (AF_INET, "192.0.3.0", &network);
- inet_pton (AF_INET, "198.51.100.1", &gateway);
+ const char *const NETWORK = "192.0.3.0";
+ const char *const GATEWAY = "198.51.100.1";
+ const guint32 network = nmtst_inet4_from_string (NETWORK);
+ const guint32 gateway = nmtst_inet4_from_string (GATEWAY);
+ NMPlatformIP4Route r = {
+ .ifindex = ifindex,
+ .network = network,
+ .plen = plen,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP4Route r_gateway = {
+ .ifindex = ifindex,
+ .network = gateway,
+ .plen = 32,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP4Route r_default = {
+ .ifindex = ifindex,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
/* Add route to gateway */
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 32, INADDR_ANY, 0, metric, mss));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_gateway));
accept_signal (route_added);
/* Add route */
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss));
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r));
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
accept_signal (route_added);
/* Add route again */
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r));
accept_signals (route_changed, 0, 1);
/* Add default route */
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric);
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss));
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric, NULL);
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_default));
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric, NULL);
accept_signal (route_added);
/* Add default route again */
- g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_default));
accept_signals (route_changed, 0, 1);
/* Test route listing */
@@ -185,7 +222,8 @@ test_ip4_route (void)
rts[0].gateway = INADDR_ANY;
rts[0].metric = metric;
rts[0].mss = mss;
- rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK);
+ rts[0].rt_scope = RT_SCOPE_LINK;
+ rts[0].rt_scope_is_set = TRUE;
rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[1].network = network;
rts[1].plen = plen;
@@ -193,7 +231,8 @@ test_ip4_route (void)
rts[1].gateway = gateway;
rts[1].metric = metric;
rts[1].mss = mss;
- rts[1].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE);
+ rts[1].rt_scope = RT_SCOPE_UNIVERSE;
+ rts[1].rt_scope_is_set = TRUE;
rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[2].network = 0;
rts[2].plen = 0;
@@ -201,18 +240,19 @@ test_ip4_route (void)
rts[2].gateway = gateway;
rts[2].metric = metric;
rts[2].mss = mss;
- rts[2].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE);
+ rts[2].rt_scope = RT_SCOPE_UNIVERSE;
+ rts[2].rt_scope_is_set = TRUE;
g_assert_cmpint (routes->len, ==, 3);
nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, rts, routes->len, TRUE);
g_array_unref (routes);
/* Remove route */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r));
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
accept_signal (route_removed);
/* Remove route again */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r));
free_signal (route_added);
free_signal (route_changed);
@@ -228,38 +268,60 @@ test_ip6_route (void)
SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_route_callback);
GArray *routes;
NMPlatformIP6Route rts[3];
- struct in6_addr network;
+ const char *const NETWORK = "2001:db8:a:b:0:0:0:0";
+ const char *const GATEWAY = "2001:db8:c:d:1:2:3:4";
+ const struct in6_addr network = *nmtst_inet6_from_string (NETWORK);
+ const struct in6_addr gateway = *nmtst_inet6_from_string (GATEWAY);
guint8 plen = 64;
- struct in6_addr gateway;
- /* Choose a high metric so that we hopefully don't conflict. */
int metric = 22987;
int mss = 1000;
-
- inet_pton (AF_INET6, "2001:db8:a:b:0:0:0:0", &network);
- inet_pton (AF_INET6, "2001:db8:c:d:1:2:3:4", &gateway);
+ NMPlatformIP6Route r = {
+ .ifindex = ifindex,
+ .network = network,
+ .plen = plen,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP6Route r_gateway = {
+ .ifindex = ifindex,
+ .network = gateway,
+ .plen = 128,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP6Route r_default = {
+ .ifindex = ifindex,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
/* Add route to gateway */
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 128, in6addr_any, metric, mss));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r_gateway));
accept_signal (route_added);
/* Add route */
- g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss));
- g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, &r));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r));
+ g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, &r));
accept_signal (route_added);
/* Add route again */
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r));
accept_signals (route_changed, 0, 1);
/* Add default route */
- g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss));
- g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
+ g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, &r_default));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r_default));
+ g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, &r_default));
accept_signal (route_added);
/* Add default route again */
- g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r_default));
accept_signals (route_changed, 0, 1);
/* Test route listing */
@@ -291,12 +353,12 @@ test_ip6_route (void)
g_array_unref (routes);
/* Remove route */
- g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
- g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, &r));
+ g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, &r));
accept_signal (route_removed);
/* Remove route again */
- g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, &r));
free_signal (route_added);
free_signal (route_changed);
@@ -309,14 +371,30 @@ static void
test_ip4_zero_gateway (void)
{
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+ NMPlatformIP4Route r_global = {
+ .ifindex = ifindex,
+ .network = nmtst_inet4_from_string ("1.2.3.1"),
+ .plen = 32,
+ .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_BOOT,
+ .rt_scope = RT_SCOPE_UNIVERSE,
+ .rt_scope_is_set = TRUE,
+ };
+ NMPlatformIP4Route r_local = {
+ .ifindex = ifindex,
+ .network = nmtst_inet4_from_string ("1.2.3.2"),
+ .plen = 32,
+ .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_BOOT,
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
+ };
nmtstp_run_command_check ("ip route add 1.2.3.1/32 via 0.0.0.0 dev %s", DEVICE_NAME);
nmtstp_run_command_check ("ip route add 1.2.3.2/32 dev %s", DEVICE_NAME);
NMTST_WAIT_ASSERT (100, {
nmtstp_wait_for_signal (NM_PLATFORM_GET, 10);
- if ( nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.1"), 32, 0)
- && nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.2"), 32, 0))
+ if ( nm_platform_ip4_route_get (NM_PLATFORM_GET, &r_global)
+ && nm_platform_ip4_route_get (NM_PLATFORM_GET, &r_local))
break;
});
diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c
index b81c263c08..d79dcd2bd7 100644
--- a/src/tests/test-route-manager.c
+++ b/src/tests/test-route-manager.c
@@ -76,14 +76,9 @@ setup_dev1_ip4 (int ifindex)
/* Add some route outside of route manager. The route manager
* should get rid of it upon sync. */
if (!nm_platform_ip4_route_add (NM_PLATFORM_GET,
- route.ifindex,
- NM_IP_CONFIG_SOURCE_USER,
- nmtst_inet4_from_string ("9.0.0.0"),
- 8,
- INADDR_ANY,
- 0,
- 10,
- route.mss))
+ nmtst_platform_ip4_route_full (route.ifindex, "9.0.0.0", 8, NULL,
+ NM_IP_CONFIG_SOURCE_USER, 10, route.mss,
+ 0, FALSE, NULL)))
g_assert_not_reached ();
route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
@@ -169,7 +164,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 20,
.mss = 1000,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -179,7 +175,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = nmtst_inet4_from_string ("6.6.6.1"),
.metric = 21021,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE),
+ .rt_scope = RT_SCOPE_UNIVERSE,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -189,7 +186,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 22,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -199,7 +197,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 21,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -209,7 +208,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = nmtst_inet4_from_string ("6.6.6.2"),
.metric = 22,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE),
+ .rt_scope = RT_SCOPE_UNIVERSE,
+ .rt_scope_is_set = TRUE,
},
};
@@ -222,7 +222,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 20,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -232,7 +233,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 21,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -242,7 +244,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 22,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -252,7 +255,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 21,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -262,7 +266,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = nmtst_inet4_from_string ("6.6.6.2"),
.metric = 22,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE),
+ .rt_scope = RT_SCOPE_UNIVERSE,
+ .rt_scope_is_set = TRUE,
},
};
@@ -275,7 +280,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 22,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -285,7 +291,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = INADDR_ANY,
.metric = 20,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -295,7 +302,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
.gateway = nmtst_inet4_from_string ("6.6.6.2"),
.metric = 22,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE),
+ .rt_scope = RT_SCOPE_UNIVERSE,
+ .rt_scope_is_set = TRUE,
},
{
.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER),
@@ -307,7 +315,8 @@ test_ip4 (test_fixture *fixture, gconstpointer user_data)
* with metric 20 (above). But we don't remove the metric 21. */
.metric = 21,
.mss = 0,
- .scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK),
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
},
};
@@ -382,28 +391,28 @@ setup_dev0_ip6 (int ifindex)
3600,
0);
- route = nmtst_platform_ip6_route_full ("2001:db8:8086::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:8086::",
48,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
20,
0);
g_array_append_val (routes, *route);
- route = nmtst_platform_ip6_route_full ("2001:db8:1337::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:1337::",
48,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
0,
0);
g_array_append_val (routes, *route);
- route = nmtst_platform_ip6_route_full ("2001:db8:abad:c0de::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:abad:c0de::",
64,
"2001:db8:8086::1",
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
21,
0);
@@ -422,46 +431,41 @@ setup_dev1_ip6 (int ifindex)
/* Add some route outside of route manager. The route manager
* should get rid of it upon sync. */
if (!nm_platform_ip6_route_add (NM_PLATFORM_GET,
- ifindex,
- NM_IP_CONFIG_SOURCE_USER,
- *nmtst_inet6_from_string ("2001:db8:8088::"),
- 48,
- in6addr_any,
- 10,
- 0))
+ nmtst_platform_ip6_route_full (ifindex, "2001:db8:8088::", 48, NULL,
+ NM_IP_CONFIG_SOURCE_USER, 10, 0)))
g_assert_not_reached ();
- route = nmtst_platform_ip6_route_full ("2001:db8:8086::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:8086::",
48,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
20,
0);
g_array_append_val (routes, *route);
- route = nmtst_platform_ip6_route_full ("2001:db8:1337::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:1337::",
48,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
1024,
0);
g_array_append_val (routes, *route);
- route = nmtst_platform_ip6_route_full ("2001:db8:d34d::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:d34d::",
64,
"2001:db8:8086::2",
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
20,
0);
g_array_append_val (routes, *route);
- route = nmtst_platform_ip6_route_full ("2001:db8:abad:c0de::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:abad:c0de::",
64,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
22,
0);
@@ -487,28 +491,28 @@ update_dev0_ip6 (int ifindex)
3600,
0);
- route = nmtst_platform_ip6_route_full ("2001:db8:8086::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:8086::",
48,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
20,
0);
g_array_append_val (routes, *route);
- route = nmtst_platform_ip6_route_full ("2001:db8:1337::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:1337::",
48,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
0,
0);
g_array_append_val (routes, *route);
- route = nmtst_platform_ip6_route_full ("2001:db8:abad:c0de::",
+ route = nmtst_platform_ip6_route_full (ifindex,
+ "2001:db8:abad:c0de::",
64,
NULL,
- ifindex,
NM_IP_CONFIG_SOURCE_USER,
21,
0);
@@ -791,9 +795,9 @@ _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NM
g_assert (route);
if (vtable->is_ip4)
- r = (const NMPlatformIPXRoute *) nm_platform_ip4_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r4.network, route->rx.plen, route->rx.metric);
+ r = (const NMPlatformIPXRoute *) nm_platform_ip4_route_get (NM_PLATFORM_GET, &route->r4);
else
- r = (const NMPlatformIPXRoute *) nm_platform_ip6_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r6.network, route->rx.plen, route->rx.metric);
+ r = (const NMPlatformIPXRoute *) nm_platform_ip6_route_get (NM_PLATFORM_GET, &route->r6);
if (!has) {
g_assert (!r);
@@ -824,15 +828,15 @@ test_ip4_full_sync (test_fixture *fixture, gconstpointer user_data)
nm_log_dbg (LOGD_CORE, "TEST start test_ip4_full_sync(): start");
- r01 = *nmtst_platform_ip4_route_full ("12.3.4.0", 24, NULL,
- fixture->ifindex0, NM_IP_CONFIG_SOURCE_USER,
- 100, 0, RT_SCOPE_LINK, NULL);
- r02 = *nmtst_platform_ip4_route_full ("13.4.5.6", 32, "12.3.4.1",
- fixture->ifindex0, NM_IP_CONFIG_SOURCE_USER,
- 100, 0, RT_SCOPE_UNIVERSE, NULL);
- r03 = *nmtst_platform_ip4_route_full ("14.5.6.7", 32, "12.3.4.1",
- fixture->ifindex0, NM_IP_CONFIG_SOURCE_USER,
- 110, 0, RT_SCOPE_UNIVERSE, NULL);
+ r01 = *nmtst_platform_ip4_route_full (fixture->ifindex0, "12.3.4.0", 24, NULL,
+ NM_IP_CONFIG_SOURCE_USER,
+ 100, 0, RT_SCOPE_LINK, TRUE, NULL);
+ r02 = *nmtst_platform_ip4_route_full (fixture->ifindex0, "13.4.5.6", 32, "12.3.4.1",
+ NM_IP_CONFIG_SOURCE_USER,
+ 100, 0, RT_SCOPE_UNIVERSE, TRUE, NULL);
+ r03 = *nmtst_platform_ip4_route_full (fixture->ifindex0, "14.5.6.7", 32, "12.3.4.1",
+ NM_IP_CONFIG_SOURCE_USER,
+ 110, 0, RT_SCOPE_UNIVERSE, TRUE, NULL);
g_array_set_size (routes, 2);
g_array_index (routes, NMPlatformIP4Route, 0) = r01;
g_array_index (routes, NMPlatformIP4Route, 1) = r02;
@@ -842,7 +846,7 @@ test_ip4_full_sync (test_fixture *fixture, gconstpointer user_data)
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r02);
_assert_route_check (vtable, FALSE, (const NMPlatformIPXRoute *) &r03);
- vtable->route_add (NM_PLATFORM_GET, 0, (const NMPlatformIPXRoute *) &r03, -1);
+ vtable->route_add (NM_PLATFORM_GET, (const NMPlatformIPXRoute *) &r03, 0, -1);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r01);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r02);