summary refs log tree commit diff
path: root/src/core/platform/tests/test-route.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/platform/tests/test-route.c')
-rw-r--r--src/core/platform/tests/test-route.c388
1 files changed, 221 insertions, 167 deletions
diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c
index 4b1db7fa..cf0236e0 100644
--- a/src/core/platform/tests/test-route.c
+++ b/src/core/platform/tests/test-route.c
@@ -10,7 +10,7 @@
 
 #include "nm-core-utils.h"
 #include "libnm-platform/nm-platform-utils.h"
-#include "libnm-platform/nmp-rules-manager.h"
+#include "libnm-platform/nmp-route-manager.h"
 
 #include "test-common.h"
 
@@ -51,7 +51,7 @@ _wait_for_ipv4_addr_device_route(NMPlatform *platform,
 }
 
 static void
-_wait_for_ipv6_addr_non_tentative(NMPlatform *           platform,
+_wait_for_ipv6_addr_non_tentative(NMPlatform            *platform,
                                   gint64                 timeout_msec,
                                   int                    ifindex,
                                   guint                  addr_n,
@@ -83,17 +83,17 @@ _wait_for_ipv6_addr_non_tentative(NMPlatform *           platform,
 }
 
 static void
-ip4_route_callback(NMPlatform *              platform,
+ip4_route_callback(NMPlatform               *platform,
                    int                       obj_type_i,
                    int                       ifindex,
                    const NMPlatformIP4Route *received,
                    int                       change_type_i,
-                   SignalData *              data)
+                   SignalData               *data)
 {
     const NMPObjectType              obj_type    = obj_type_i;
     const NMPlatformSignalChangeType change_type = change_type_i;
     NMPObject                        o_id;
-    nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new(NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
+    nm_auto_nmpobj NMPObject        *o_id_p = nmp_object_new(NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
 
     g_assert_cmpint(obj_type, ==, NMP_OBJECT_TYPE_IP4_ROUTE);
     g_assert(received);
@@ -119,17 +119,17 @@ ip4_route_callback(NMPlatform *              platform,
 }
 
 static void
-ip6_route_callback(NMPlatform *              platform,
+ip6_route_callback(NMPlatform               *platform,
                    int                       obj_type_i,
                    int                       ifindex,
                    const NMPlatformIP6Route *received,
                    int                       change_type_i,
-                   SignalData *              data)
+                   SignalData               *data)
 {
     const NMPObjectType              obj_type    = obj_type_i;
     const NMPlatformSignalChangeType change_type = change_type_i;
     NMPObject                        o_id;
-    nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new(NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
+    nm_auto_nmpobj NMPObject        *o_id_p = nmp_object_new(NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
 
     g_assert_cmpint(obj_type, ==, NMP_OBJECT_TYPE_IP6_ROUTE);
     g_assert(received);
@@ -244,16 +244,16 @@ static void
 test_ip4_route(void)
 {
     int                ifindex       = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
-    SignalData *       route_added   = add_signal(NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED,
+    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,
+    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,
+    SignalData        *route_removed = add_signal(NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED,
                                            NM_PLATFORM_SIGNAL_REMOVED,
                                            ip4_route_callback);
-    GPtrArray *        routes;
+    GPtrArray         *routes;
     NMPlatformIP4Route rts[3];
     in_addr_t          network;
     guint8             plen = 24;
@@ -332,33 +332,30 @@ test_ip4_route(void)
     /* Test route listing */
     routes = nmtstp_ip4_route_get_all(NM_PLATFORM_GET, ifindex);
     memset(rts, 0, sizeof(rts));
-    rts[0].rt_source   = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
-    rts[0].network     = gateway;
-    rts[0].plen        = 32;
-    rts[0].ifindex     = ifindex;
-    rts[0].gateway     = INADDR_ANY;
-    rts[0].metric      = metric;
-    rts[0].mss         = mss;
-    rts[0].is_external = TRUE;
-    rts[0].scope_inv   = nm_platform_route_scope_inv(RT_SCOPE_LINK);
-    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;
-    rts[1].ifindex     = ifindex;
-    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].is_external = 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;
-    rts[2].ifindex     = ifindex;
-    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].is_external = TRUE;
+    rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
+    rts[0].network   = gateway;
+    rts[0].plen      = 32;
+    rts[0].ifindex   = ifindex;
+    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[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
+    rts[1].network   = network;
+    rts[1].plen      = plen;
+    rts[1].ifindex   = ifindex;
+    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[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
+    rts[2].network   = 0;
+    rts[2].plen      = 0;
+    rts[2].ifindex   = ifindex;
+    rts[2].gateway   = gateway;
+    rts[2].metric    = metric;
+    rts[2].mss       = mss;
+    rts[2].scope_inv = nm_platform_route_scope_inv(RT_SCOPE_UNIVERSE);
     g_assert_cmpint(routes->len, ==, 3);
     nmtst_platform_ip4_routes_equal_aptr((const NMPObject *const *) routes->pdata,
                                          rts,
@@ -391,16 +388,16 @@ static void
 test_ip6_route(void)
 {
     int                ifindex       = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
-    SignalData *       route_added   = add_signal(NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
+    SignalData        *route_added   = add_signal(NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
                                          NM_PLATFORM_SIGNAL_ADDED,
                                          ip6_route_callback);
-    SignalData *       route_changed = add_signal(NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
+    SignalData        *route_changed = add_signal(NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
                                            NM_PLATFORM_SIGNAL_CHANGED,
                                            ip6_route_callback);
-    SignalData *       route_removed = add_signal(NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
+    SignalData        *route_removed = add_signal(NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
                                            NM_PLATFORM_SIGNAL_REMOVED,
                                            ip6_route_callback);
-    GPtrArray *        routes;
+    GPtrArray         *routes;
     NMPlatformIP6Route rts[3];
     struct in6_addr    network;
     guint8             plen = 64;
@@ -492,33 +489,30 @@ test_ip6_route(void)
     /* Test route listing */
     routes = nmtstp_ip6_route_get_all(NM_PLATFORM_GET, ifindex);
     memset(rts, 0, sizeof(rts));
-    rts[0].rt_source   = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
-    rts[0].network     = gateway;
-    rts[0].plen        = 128;
-    rts[0].ifindex     = ifindex;
-    rts[0].gateway     = in6addr_any;
-    rts[0].pref_src    = in6addr_any;
-    rts[0].metric      = metric;
-    rts[0].mss         = mss;
-    rts[0].is_external = 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;
-    rts[1].ifindex     = ifindex;
-    rts[1].gateway     = gateway;
-    rts[1].pref_src    = pref_src;
-    rts[1].metric      = metric;
-    rts[1].mss         = mss;
-    rts[1].is_external = TRUE;
-    rts[2].rt_source   = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
-    rts[2].network     = in6addr_any;
-    rts[2].plen        = 0;
-    rts[2].ifindex     = ifindex;
-    rts[2].gateway     = gateway;
-    rts[2].pref_src    = in6addr_any;
-    rts[2].metric      = metric;
-    rts[2].mss         = mss;
-    rts[2].is_external = TRUE;
+    rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
+    rts[0].network   = gateway;
+    rts[0].plen      = 128;
+    rts[0].ifindex   = ifindex;
+    rts[0].gateway   = in6addr_any;
+    rts[0].pref_src  = in6addr_any;
+    rts[0].metric    = metric;
+    rts[0].mss       = mss;
+    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;
+    rts[1].ifindex   = ifindex;
+    rts[1].gateway   = gateway;
+    rts[1].pref_src  = pref_src;
+    rts[1].metric    = metric;
+    rts[1].mss       = mss;
+    rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER);
+    rts[2].network   = in6addr_any;
+    rts[2].plen      = 0;
+    rts[2].ifindex   = ifindex;
+    rts[2].gateway   = gateway;
+    rts[2].pref_src  = in6addr_any;
+    rts[2].metric    = metric;
+    rts[2].mss       = mss;
     g_assert_cmpint(routes->len, ==, 3);
     nmtst_platform_ip6_routes_equal_aptr((const NMPObject *const *) routes->pdata,
                                          rts,
@@ -552,9 +546,9 @@ test_ip6_route(void)
 static void
 test_ip4_route_get(void)
 {
-    int            ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
-    in_addr_t      a;
-    int            result;
+    int                       ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
+    in_addr_t                 a;
+    int                       result;
     nm_auto_nmpobj NMPObject *route = NULL;
     const NMPlatformIP4Route *r;
 
@@ -626,8 +620,8 @@ test_ip4_zero_gateway(void)
 static void
 test_ip4_route_options(gconstpointer test_data)
 {
-    const int         TEST_IDX = GPOINTER_TO_INT(test_data);
-    const int         IFINDEX  = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
+    const int TEST_IDX = GPOINTER_TO_INT(test_data);
+    const int IFINDEX  = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
     gs_unref_ptrarray GPtrArray *routes = NULL;
 #define RTS_MAX 3
     NMPlatformIP4Route   rts_add[RTS_MAX] = {};
@@ -656,13 +650,13 @@ test_ip4_route_options(gconstpointer test_data)
         break;
     case 2:
         addr[addr_n++]   = ((NMPlatformIP4Address){
-            .ifindex      = IFINDEX,
-            .address      = nmtst_inet4_from_string("172.16.1.5"),
-            .peer_address = nmtst_inet4_from_string("172.16.1.5"),
-            .plen         = 24,
-            .lifetime     = NM_PLATFORM_LIFETIME_PERMANENT,
-            .preferred    = NM_PLATFORM_LIFETIME_PERMANENT,
-            .n_ifa_flags  = 0,
+              .ifindex      = IFINDEX,
+              .address      = nmtst_inet4_from_string("172.16.1.5"),
+              .peer_address = nmtst_inet4_from_string("172.16.1.5"),
+              .plen         = 24,
+              .lifetime     = NM_PLATFORM_LIFETIME_PERMANENT,
+              .preferred    = NM_PLATFORM_LIFETIME_PERMANENT,
+              .n_ifa_flags  = 0,
         });
         rts_add[rts_n++] = ((NMPlatformIP4Route){
             .ifindex   = IFINDEX,
@@ -715,7 +709,6 @@ test_ip4_route_options(gconstpointer test_data)
     for (i = 0; i < rts_n; i++) {
         rts_cmp[i] = rts_add[i];
         nm_platform_ip_route_normalize(AF_INET, NM_PLATFORM_IP_ROUTE_CAST(&rts_cmp[i]));
-        rts_cmp[i].is_external = TRUE;
     }
 
     routes = nmtstp_ip4_route_get_all(NM_PLATFORM_GET, IFINDEX);
@@ -738,9 +731,9 @@ test_ip4_route_options(gconstpointer test_data)
 static void
 test_ip6_route_get(void)
 {
-    int                    ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
-    const struct in6_addr *a;
-    int                    result;
+    int                       ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
+    const struct in6_addr    *a;
+    int                       result;
     nm_auto_nmpobj NMPObject *route = NULL;
     const NMPlatformIP6Route *r;
 
@@ -783,8 +776,8 @@ test_ip6_route_get(void)
 static void
 test_ip6_route_options(gconstpointer test_data)
 {
-    const int         TEST_IDX = GPOINTER_TO_INT(test_data);
-    const int         IFINDEX  = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
+    const int TEST_IDX = GPOINTER_TO_INT(test_data);
+    const int IFINDEX  = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME);
     gs_unref_ptrarray GPtrArray *routes = NULL;
 #define RTS_MAX 3
     NMPlatformIP6Route   rts_add[RTS_MAX]             = {};
@@ -814,13 +807,13 @@ test_ip6_route_options(gconstpointer test_data)
         break;
     case 2:
         addr[addr_n++]   = ((NMPlatformIP6Address){
-            .ifindex      = IFINDEX,
-            .address      = *nmtst_inet6_from_string("2000::2"),
-            .plen         = 128,
-            .peer_address = in6addr_any,
-            .lifetime     = NM_PLATFORM_LIFETIME_PERMANENT,
-            .preferred    = NM_PLATFORM_LIFETIME_PERMANENT,
-            .n_ifa_flags  = 0,
+              .ifindex      = IFINDEX,
+              .address      = *nmtst_inet6_from_string("2000::2"),
+              .plen         = 128,
+              .peer_address = in6addr_any,
+              .lifetime     = NM_PLATFORM_LIFETIME_PERMANENT,
+              .preferred    = NM_PLATFORM_LIFETIME_PERMANENT,
+              .n_ifa_flags  = 0,
         });
         rts_add[rts_n++] = ((NMPlatformIP6Route){
             .ifindex   = IFINDEX,
@@ -834,13 +827,13 @@ test_ip6_route_options(gconstpointer test_data)
         break;
     case 3:
         addr[addr_n++]   = ((NMPlatformIP6Address){
-            .ifindex      = IFINDEX,
-            .address      = *nmtst_inet6_from_string("2001:db8:8086::5"),
-            .plen         = 128,
-            .peer_address = in6addr_any,
-            .lifetime     = NM_PLATFORM_LIFETIME_PERMANENT,
-            .preferred    = NM_PLATFORM_LIFETIME_PERMANENT,
-            .n_ifa_flags  = 0,
+              .ifindex      = IFINDEX,
+              .address      = *nmtst_inet6_from_string("2001:db8:8086::5"),
+              .plen         = 128,
+              .peer_address = in6addr_any,
+              .lifetime     = NM_PLATFORM_LIFETIME_PERMANENT,
+              .preferred    = NM_PLATFORM_LIFETIME_PERMANENT,
+              .n_ifa_flags  = 0,
         });
         rts_add[rts_n++] = ((NMPlatformIP6Route){
             .ifindex   = IFINDEX,
@@ -887,7 +880,6 @@ test_ip6_route_options(gconstpointer test_data)
     for (i = 0; i < rts_n; i++) {
         rts_cmp[i] = rts_add[i];
         nm_platform_ip_route_normalize(AF_INET6, NM_PLATFORM_IP_ROUTE_CAST(&rts_cmp[i]));
-        rts_cmp[i].is_external = TRUE;
     }
 
     routes = nmtstp_ip6_route_get_all(NM_PLATFORM_GET, IFINDEX);
@@ -923,7 +915,7 @@ test_ip(gconstpointer test_data)
     char                  ifname[IFNAMSIZ];
     char                  ifname2[IFNAMSIZ];
     char                  s1[NM_UTILS_INET_ADDRSTRLEN];
-    NMPlatform *          platform = NM_PLATFORM_GET;
+    NMPlatform           *platform = NM_PLATFORM_GET;
     const int             EX_      = -1;
     struct {
         int ifindex;
@@ -965,7 +957,7 @@ test_ip(gconstpointer test_data)
     order_len = 0;
     for (try = 0; try < 5 * G_N_ELEMENTS(order_idx); try++) {
         NMPObject                    o;
-        NMPlatformIP4Route *         r;
+        NMPlatformIP4Route          *r;
         guint                        idx;
         const NMDedupMultiHeadEntry *head_entry;
         NMPLookup                    lookup;
@@ -1052,8 +1044,8 @@ _rule_find_by_priority(NMPlatform *platform, guint32 priority)
 {
     const NMDedupMultiHeadEntry *head_entry;
     NMDedupMultiIter             iter;
-    const NMPObject *            o;
-    const NMPObject *            obj = NULL;
+    const NMPObject             *o;
+    const NMPObject             *obj = NULL;
     NMPLookup                    lookup;
 
     nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE);
@@ -1128,9 +1120,9 @@ _rule_check_kernel_support(NMPlatform *platform, int attribute)
     {
         nm_auto_nmpobj const NMPObject *obj = NULL;
         const NMPlatformRoutingRule     rr  = {
-            .addr_family              = AF_INET,
-            .priority                 = PROBE_PRORITY,
-            .suppress_ifgroup_inverse = ~((guint32) 1245),
+                 .addr_family              = AF_INET,
+                 .priority                 = PROBE_PRORITY,
+                 .suppress_ifgroup_inverse = ~((guint32) 1245),
         };
 
         obj = _rule_check_kernel_support_one(platform, &rr);
@@ -1143,9 +1135,9 @@ _rule_check_kernel_support(NMPlatform *platform, int attribute)
     {
         nm_auto_nmpobj const NMPObject *obj = NULL;
         const NMPlatformRoutingRule     rr  = {
-            .addr_family                = AF_INET,
-            .priority                   = PROBE_PRORITY,
-            .suppress_prefixlen_inverse = ~((guint32) 1245),
+                 .addr_family                = AF_INET,
+                 .priority                   = PROBE_PRORITY,
+                 .suppress_prefixlen_inverse = ~((guint32) 1245),
         };
 
         obj = _rule_check_kernel_support_one(platform, &rr);
@@ -1158,9 +1150,9 @@ _rule_check_kernel_support(NMPlatform *platform, int attribute)
     {
         nm_auto_nmpobj const NMPObject *obj = NULL;
         const NMPlatformRoutingRule     rr  = {
-            .addr_family = AF_INET,
-            .priority    = PROBE_PRORITY,
-            .l3mdev      = TRUE,
+                 .addr_family = AF_INET,
+                 .priority    = PROBE_PRORITY,
+                 .l3mdev      = TRUE,
         };
 
         obj = _rule_check_kernel_support_one(platform, &rr);
@@ -1172,14 +1164,14 @@ _rule_check_kernel_support(NMPlatform *platform, int attribute)
     {
         nm_auto_nmpobj const NMPObject *obj = NULL;
         const NMPlatformRoutingRule     rr  = {
-            .addr_family = AF_INET,
-            .priority    = PROBE_PRORITY,
-            .uid_range =
+                 .addr_family = AF_INET,
+                 .priority    = PROBE_PRORITY,
+                 .uid_range =
                 {
-                    .start = 0,
-                    .end   = 0,
+                         .start = 0,
+                         .end   = 0,
                 },
-            .uid_range_has = TRUE,
+                 .uid_range_has = TRUE,
         };
 
         obj = _rule_check_kernel_support_one(platform, &rr);
@@ -1191,9 +1183,9 @@ _rule_check_kernel_support(NMPlatform *platform, int attribute)
     {
         nm_auto_nmpobj const NMPObject *obj = NULL;
         const NMPlatformRoutingRule     rr  = {
-            .addr_family = AF_INET,
-            .priority    = PROBE_PRORITY,
-            .protocol    = 30,
+                 .addr_family = AF_INET,
+                 .priority    = PROBE_PRORITY,
+                 .protocol    = 30,
         };
 
         obj = _rule_check_kernel_support_one(platform, &rr);
@@ -1205,9 +1197,9 @@ _rule_check_kernel_support(NMPlatform *platform, int attribute)
     {
         nm_auto_nmpobj const NMPObject *obj = NULL;
         const NMPlatformRoutingRule     rr  = {
-            .addr_family = AF_INET,
-            .priority    = PROBE_PRORITY,
-            .ip_proto    = 30,
+                 .addr_family = AF_INET,
+                 .priority    = PROBE_PRORITY,
+                 .ip_proto    = 30,
         };
 
         obj = _rule_check_kernel_support_one(platform, &rr);
@@ -1277,7 +1269,7 @@ _rr_rand_choose_u32(guint32 p)
 static const NMPObject *
 _rule_create_random(NMPlatform *platform)
 {
-    NMPObject *            obj;
+    NMPObject             *obj;
     NMPlatformRoutingRule *rr;
     guint32                p;
     int                    addr_size;
@@ -1320,7 +1312,7 @@ _rule_create_random(NMPlatform *platform)
 
     for (i = 0; i < 2; i++) {
         NMIPAddr *p_addr = i ? &rr->src : &rr->dst;
-        guint8 *  p_len  = i ? &rr->src_len : &rr->dst_len;
+        guint8   *p_len  = i ? &rr->src_len : &rr->dst_len;
 
         p = nmtst_get_rand_uint32();
         if ((p % 1000u) < 100) {
@@ -1543,11 +1535,11 @@ _rule_fuzzy_equal(const NMPObject *obj, const NMPObject *obj_comp, int op_type)
 static void
 test_rule(gconstpointer test_data)
 {
-    const int         TEST_IDX                = GPOINTER_TO_INT(test_data);
-    const gboolean    TEST_SYNC               = (TEST_IDX == 4);
+    const int                    TEST_IDX     = GPOINTER_TO_INT(test_data);
+    const gboolean               TEST_SYNC    = (TEST_IDX == 4);
     gs_unref_ptrarray GPtrArray *objs         = NULL;
     gs_unref_ptrarray GPtrArray *objs_initial = NULL;
-    NMPlatform *                 platform     = NM_PLATFORM_GET;
+    NMPlatform                  *platform     = NM_PLATFORM_GET;
     guint                        i, j, n;
     int                          r;
     gboolean                     had_an_issue_exist = FALSE;
@@ -1563,7 +1555,7 @@ test_rule(gconstpointer test_data)
 
     for (i = 6; i > 0; i--) {
         gs_unref_ptrarray GPtrArray *objs_extern = NULL;
-        const NMPObject *            obj;
+        const NMPObject             *obj;
 
         objs_extern = nmtstp_platform_routing_rules_get_all(platform, AF_UNSPEC);
 
@@ -1645,8 +1637,8 @@ again:
 
     if (TEST_SYNC) {
         gs_unref_hashtable GHashTable *unique_priorities = g_hash_table_new(NULL, NULL);
-        nm_auto_unref_rules_manager NMPRulesManager *rules_manager =
-            nmp_rules_manager_new(platform);
+        nm_auto_unref_route_manager NMPRouteManager *route_manager =
+            nmp_route_manager_new(platform);
         gs_unref_ptrarray GPtrArray *objs_sync  = NULL;
         gconstpointer                USER_TAG_1 = &platform;
         gconstpointer                USER_TAG_2 = &unique_priorities;
@@ -1668,29 +1660,29 @@ again:
         }
 
         for (i = 0; i < objs_sync->len; i++) {
-            nmp_rules_manager_track(rules_manager,
-                                    NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                    1,
-                                    USER_TAG_1,
-                                    NULL);
+            nmp_route_manager_track_rule(route_manager,
+                                         NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                         1,
+                                         USER_TAG_1,
+                                         NULL);
             if (nmtst_get_rand_bool()) {
                 /* this has no effect, because a negative priority (of same absolute value)
                  * has lower priority than the positive priority above. */
-                nmp_rules_manager_track(rules_manager,
-                                        NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                        -1,
-                                        USER_TAG_2,
-                                        NULL);
+                nmp_route_manager_track_rule(route_manager,
+                                             NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                             -1,
+                                             USER_TAG_2,
+                                             NULL);
             }
             if (nmtst_get_rand_uint32() % objs_sync->len == 0) {
-                nmp_rules_manager_sync(rules_manager, FALSE);
+                nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
                 g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
                                 ==,
                                 i + 1);
             }
         }
 
-        nmp_rules_manager_sync(rules_manager, FALSE);
+        nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
         g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
                         ==,
                         objs_sync->len);
@@ -1698,37 +1690,37 @@ again:
         for (i = 0; i < objs_sync->len; i++) {
             switch (nmtst_get_rand_uint32() % 3) {
             case 0:
-                nmp_rules_manager_untrack(rules_manager,
-                                          NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                          USER_TAG_1);
-                nmp_rules_manager_untrack(rules_manager,
-                                          NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                          USER_TAG_1);
+                nmp_route_manager_untrack_rule(route_manager,
+                                               NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                               USER_TAG_1);
+                nmp_route_manager_untrack_rule(route_manager,
+                                               NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                               USER_TAG_1);
                 break;
             case 1:
-                nmp_rules_manager_track(rules_manager,
-                                        NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                        -1,
-                                        USER_TAG_1,
-                                        NULL);
+                nmp_route_manager_track_rule(route_manager,
+                                             NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                             -1,
+                                             USER_TAG_1,
+                                             NULL);
                 break;
             case 2:
-                nmp_rules_manager_track(rules_manager,
-                                        NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                        -2,
-                                        USER_TAG_2,
-                                        NULL);
+                nmp_route_manager_track_rule(route_manager,
+                                             NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                             -2,
+                                             USER_TAG_2,
+                                             NULL);
                 break;
             }
             if (nmtst_get_rand_uint32() % objs_sync->len == 0) {
-                nmp_rules_manager_sync(rules_manager, FALSE);
+                nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
                 g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
                                 ==,
                                 objs_sync->len - i - 1);
             }
         }
 
-        nmp_rules_manager_sync(rules_manager, FALSE);
+        nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
 
     } else {
         for (i = 0; i < objs->len;) {
@@ -1767,7 +1759,7 @@ again:
                 NMPLookup                    lookup;
                 const NMDedupMultiHeadEntry *head_entry;
                 NMDedupMultiIter             iter;
-                const NMPObject *            o;
+                const NMPObject             *o;
 
                 g_print(">>> failing... errno=%d, rule=%s\n",
                         r,
@@ -1894,6 +1886,64 @@ again:
 
 /*****************************************************************************/
 
+static void
+test_blackhole(gconstpointer test_data)
+{
+    int                          TEST_IDX    = GPOINTER_TO_INT(test_data);
+    const int                    addr_family = (TEST_IDX == 1) ? AF_INET : AF_INET6;
+    const int                    IS_IPv4     = NM_IS_IPv4(addr_family);
+    const NMDedupMultiHeadEntry *head_entry;
+    NMDedupMultiIter             iter;
+    const NMPObject             *obj;
+    NMPObject                    obj_stack;
+    NMPlatformIPXRoute           rr = {};
+    int                          r  = -1;
+    int                          i;
+
+    if (IS_IPv4) {
+        rr.r4 = (const NMPlatformIP4Route){
+            .type_coerced = nmtst_rand_select(RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT),
+        };
+    } else {
+        rr.r6 = (const NMPlatformIP6Route){
+            .type_coerced = nmtst_rand_select(RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT),
+            .metric       = 1000,
+        };
+    }
+
+    nm_platform_ip_route_normalize(addr_family, &rr.rx);
+
+    if (IS_IPv4)
+        r = nm_platform_ip4_route_add(NM_PLATFORM_GET, NMP_NLM_FLAG_APPEND, &rr.r4);
+    else
+        r = nm_platform_ip6_route_add(NM_PLATFORM_GET, NMP_NLM_FLAG_APPEND, &rr.r6);
+
+    g_assert_cmpint(r, ==, 0);
+
+    nmp_object_stackinit(&obj_stack, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), &rr);
+
+    obj = nm_platform_lookup_obj(NM_PLATFORM_GET, NMP_CACHE_ID_TYPE_OBJECT_TYPE, &obj_stack);
+
+    _LOGT(">>> adding %s",
+          nmp_object_to_string(&obj_stack, NMP_OBJECT_TO_STRING_ALL, g_alloca(1000), 1000));
+    _LOGT(">>> found  %s",
+          nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_ALL, g_alloca(1000), 1000));
+
+    g_assert(obj);
+
+    head_entry = nm_platform_lookup_object(NM_PLATFORM_GET, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), 0);
+    g_assert(head_entry);
+    g_assert_cmpint(head_entry->len, ==, 1);
+    i = 0;
+    nm_dedup_multi_iter_for_each (&iter, head_entry) {
+        i++;
+        g_assert(iter.current->obj == obj);
+    }
+    g_assert_cmpint(i, ==, 1);
+}
+
+/*****************************************************************************/
+
 NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
 
 void
@@ -1931,4 +1981,8 @@ _nmtstp_setup_tests(void)
         add_test_func_data("/route/rule/3", test_rule, GINT_TO_POINTER(3));
         add_test_func_data("/route/rule/4", test_rule, GINT_TO_POINTER(4));
     }
+    if (nmtstp_is_root_test()) {
+        add_test_func_data("/route/blackhole/1", test_blackhole, GINT_TO_POINTER(1));
+        add_test_func_data("/route/blackhole/2", test_blackhole, GINT_TO_POINTER(2));
+    }
 }