summary refs log tree commit diff
path: root/src/core/platform/tests/test-route.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2022-08-16 18:24:19 +0200
committerMichael Biebl <biebl@debian.org>2022-08-16 18:24:19 +0200
commit0018d1f3cf71d680d7b6bceda55a5717244d8b26 (patch)
treea058f1d106d172d3354179437ef034c9355cdf9c /src/core/platform/tests/test-route.c
parent6accbd3ec0e42d8633bbde4d47ed7bfe854e7e0b (diff)
New upstream version 1.39.90 upstream/1.39.90
Diffstat (limited to 'src/core/platform/tests/test-route.c')
-rw-r--r--src/core/platform/tests/test-route.c275
1 files changed, 239 insertions, 36 deletions
diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c
index 85838267..148ed792 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-route-manager.h"
+#include "libnm-platform/nmp-global-tracker.h"
 
 #include "test-common.h"
 
@@ -35,8 +35,9 @@ _wait_for_ipv4_addr_device_route(NMPlatform *platform,
 
         nmp_cache_iter_for_each (
             &iter,
-            nm_platform_lookup(platform,
-                               nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex)),
+            nm_platform_lookup(
+                platform,
+                nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex)),
             &o) {
             const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE(o);
 
@@ -646,6 +647,9 @@ test_ip4_route_options(gconstpointer test_data)
             .initrwnd  = 50,
             .mtu       = 1350,
             .lock_cwnd = TRUE,
+            .mss       = 1300,
+            .quickack  = TRUE,
+            .rto_min   = 1000,
         });
         break;
     case 2:
@@ -1167,7 +1171,7 @@ _rule_check_kernel_support(NMPlatform *platform, int attribute)
                  .addr_family = AF_INET,
                  .priority    = PROBE_PRORITY,
                  .uid_range =
-                {
+                     {
                          .start = 0,
                          .end   = 0,
                 },
@@ -1643,8 +1647,8 @@ again:
 
     if (TEST_SYNC) {
         gs_unref_hashtable GHashTable *unique_priorities = g_hash_table_new(NULL, NULL);
-        nm_auto_unref_route_manager NMPRouteManager *route_manager =
-            nmp_route_manager_new(platform);
+        nm_auto_unref_global_tracker NMPGlobalTracker *global_tracker =
+            nmp_global_tracker_new(platform);
         gs_unref_ptrarray GPtrArray *objs_sync  = NULL;
         gconstpointer                USER_TAG_1 = &platform;
         gconstpointer                USER_TAG_2 = &unique_priorities;
@@ -1666,29 +1670,29 @@ again:
         }
 
         for (i = 0; i < objs_sync->len; i++) {
-            nmp_route_manager_track_rule(route_manager,
-                                         NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                         1,
-                                         USER_TAG_1,
-                                         NULL);
+            nmp_global_tracker_track_rule(global_tracker,
+                                          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_route_manager_track_rule(route_manager,
-                                             NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                             -1,
-                                             USER_TAG_2,
-                                             NULL);
+                nmp_global_tracker_track_rule(global_tracker,
+                                              NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                              -1,
+                                              USER_TAG_2,
+                                              NULL);
             }
             if (nmtst_get_rand_uint32() % objs_sync->len == 0) {
-                nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
+                nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
                 g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
                                 ==,
                                 i + 1);
             }
         }
 
-        nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
+        nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
         g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
                         ==,
                         objs_sync->len);
@@ -1696,37 +1700,37 @@ again:
         for (i = 0; i < objs_sync->len; i++) {
             switch (nmtst_get_rand_uint32() % 3) {
             case 0:
-                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);
+                nmp_global_tracker_untrack_rule(global_tracker,
+                                                NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                                USER_TAG_1);
+                nmp_global_tracker_untrack_rule(global_tracker,
+                                                NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                                USER_TAG_1);
                 break;
             case 1:
-                nmp_route_manager_track_rule(route_manager,
-                                             NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                             -1,
-                                             USER_TAG_1,
-                                             NULL);
+                nmp_global_tracker_track_rule(global_tracker,
+                                              NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
+                                              -1,
+                                              USER_TAG_1,
+                                              NULL);
                 break;
             case 2:
-                nmp_route_manager_track_rule(route_manager,
-                                             NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]),
-                                             -2,
-                                             USER_TAG_2,
-                                             NULL);
+                nmp_global_tracker_track_rule(global_tracker,
+                                              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_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
+                nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
                 g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC),
                                 ==,
                                 objs_sync->len - i - 1);
             }
         }
 
-        nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
+        nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE);
 
     } else {
         for (i = 0; i < objs->len;) {
@@ -1957,6 +1961,200 @@ test_blackhole(gconstpointer test_data)
 
 /*****************************************************************************/
 
+static gboolean
+_mptcp_has_permissions(void)
+{
+    static int has_permissions = -1;
+    int        p;
+
+    /* We create a new netns for testing, where we also have CAP_NET_ADMIN.
+     * However, that is not enough for configuring MPTCP endpoints. Probably
+     * you can only create them, by running the test as root. Detect the
+     * inability, to skip the test.
+     *
+     * See https://lore.kernel.org/mptcp/20220805115020.525181-1-thaller@redhat.com/T/#u */
+
+again:
+    p = g_atomic_int_get(&has_permissions);
+
+    if (p == -1) {
+        static gsize              lock;
+        const NMPlatformMptcpAddr mptcp_addr = (NMPlatformMptcpAddr){
+            .id          = 1,
+            .addr_family = AF_INET,
+            .addr.addr4  = nmtst_inet4_from_string("1.2.3.4"),
+        };
+        int r;
+
+        if (!g_once_init_enter(&lock))
+            goto again;
+
+        if (nmtst_get_rand_one_case_in(3)) {
+            gs_unref_ptrarray GPtrArray *arr = NULL;
+
+            arr = nm_platform_mptcp_addrs_dump(NM_PLATFORM_GET);
+            g_assert_cmpint(nm_g_ptr_array_len(arr), ==, 0);
+        }
+
+        r = nm_platform_mptcp_addr_update(NM_PLATFORM_GET, TRUE, &mptcp_addr);
+        if (r == 0)
+            p = TRUE;
+        else if (r == -EPERM)
+            p = FALSE;
+        else
+            g_assert_cmpint(r, ==, 0);
+
+        if (p) {
+            if (nmtst_get_rand_one_case_in(3)) {
+                gs_unref_ptrarray GPtrArray *arr = NULL;
+
+                arr = nm_platform_mptcp_addrs_dump(NM_PLATFORM_GET);
+                g_assert_cmpint(nm_g_ptr_array_len(arr), ==, 1);
+            }
+
+            r = nm_platform_mptcp_addr_update(NM_PLATFORM_GET, FALSE, &mptcp_addr);
+            g_assert_cmpint(r, ==, 0);
+        }
+
+        if (nmtst_get_rand_one_case_in(3)) {
+            gs_unref_ptrarray GPtrArray *arr = NULL;
+
+            arr = nm_platform_mptcp_addrs_dump(NM_PLATFORM_GET);
+            g_assert_cmpint(nm_g_ptr_array_len(arr), ==, 0);
+        }
+
+        g_atomic_int_set(&has_permissions, p);
+        g_once_init_leave(&lock, 1);
+    }
+
+    return p;
+}
+
+static gboolean
+_mptcp_skip_test(void)
+{
+    if (nm_platform_genl_get_family_id(NM_PLATFORM_GET, NMP_GENL_FAMILY_TYPE_MPTCP_PM) == 0) {
+        g_test_skip("mptcp not available");
+        return TRUE;
+    }
+
+    if (!_mptcp_has_permissions()) {
+        g_test_skip("No permissions to create MPTCP endpoints");
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static void
+test_mptcp(gconstpointer test_data)
+{
+    const int                                      TEST_IDX = GPOINTER_TO_INT(test_data);
+    gs_unref_object NMPlatform                    *platform = g_object_ref(NM_PLATFORM_GET);
+    nm_auto_unref_global_tracker NMPGlobalTracker *global_tracker =
+        nmp_global_tracker_new(platform);
+    gconstpointer const          USER_TAG = &TEST_IDX;
+    const int                    IFINDEX  = nm_platform_link_get_ifindex(platform, DEVICE_NAME);
+    guint                        i;
+    guint                        j;
+    int                          r;
+    gs_unref_ptrarray GPtrArray *arr_external =
+        g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
+    gs_unref_ptrarray GPtrArray *arr_tracked =
+        g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
+    const NMPObject *obj;
+    gboolean         delete_extra;
+
+    g_assert_cmpint(IFINDEX, >, 0);
+
+    if (_mptcp_skip_test())
+        return;
+
+    j = nmtst_get_rand_uint32() % 5;
+    for (i = 0; i < j; i++) {
+        obj = nmtst_object_new_mptcp_addr(.id          = i + 1,
+                                          .ifindex     = IFINDEX,
+                                          .addr_family = AF_INET,
+                                          .addr.addr4  = htonl(0xC0A80001u + i));
+        g_ptr_array_add(arr_external, (gpointer) obj);
+        r = nm_platform_mptcp_addr_update(platform, TRUE, NMP_OBJECT_CAST_MPTCP_ADDR(obj));
+        g_assert_cmpint(r, ==, 0);
+    }
+
+    j = nmtst_get_rand_uint32() % 10;
+    for (i = 0; i < j; i++) {
+        obj = nmtst_object_new_mptcp_addr(.ifindex     = IFINDEX,
+                                          .addr_family = AF_INET,
+                                          .addr.addr4  = htonl(0xC0A80001u + i));
+        g_ptr_array_add(arr_tracked, (gpointer) obj);
+        nmp_global_tracker_track(global_tracker,
+                                 NMP_OBJECT_TYPE_MPTCP_ADDR,
+                                 NMP_OBJECT_CAST_MPTCP_ADDR(obj),
+                                 20 - i,
+                                 USER_TAG,
+                                 NULL);
+    }
+    for (i = 0; i < arr_tracked->len;) {
+        if (nmtst_get_rand_bool()) {
+            nmp_global_tracker_untrack(global_tracker,
+                                       NMP_OBJECT_TYPE_MPTCP_ADDR,
+                                       NMP_OBJECT_CAST_MPTCP_ADDR(arr_tracked->pdata[i]),
+                                       USER_TAG);
+            g_ptr_array_remove_index(arr_tracked, i);
+        } else
+            i++;
+    }
+
+    if (arr_tracked->len == 0 || nmtst_get_rand_bool()) {
+        NMPlatformMptcpAddr a;
+
+        /* Track a dummy object that marks the ifindex as managed. */
+        nmp_global_tracker_track(global_tracker,
+                                 NMP_OBJECT_TYPE_MPTCP_ADDR,
+                                 nmp_global_tracker_mptcp_addr_init_for_ifindex(&a, IFINDEX),
+                                 10,
+                                 USER_TAG,
+                                 NULL);
+    }
+
+    nmp_global_tracker_sync_mptcp_addrs(global_tracker, FALSE);
+
+    if (nmtst_get_rand_bool()) {
+        gboolean reapply;
+
+        nmp_global_tracker_untrack_all(global_tracker, USER_TAG, TRUE, FALSE);
+        reapply = nmtst_get_rand_bool();
+        nmp_global_tracker_sync_mptcp_addrs(global_tracker, reapply);
+
+        delete_extra = !reapply;
+    } else
+        delete_extra = TRUE;
+
+    if (delete_extra) {
+        gs_unref_ptrarray GPtrArray *arr = NULL;
+
+        /* We need to delete all MPTCP address again, because the next test uses the
+         * same netns (this test setup doesn't create a netns per test). */
+        arr = nm_platform_mptcp_addrs_dump(platform);
+        for (i = 0; i < nm_g_ptr_array_len(arr); i++) {
+            r = nm_platform_mptcp_addr_update(platform,
+                                              FALSE,
+                                              NMP_OBJECT_CAST_MPTCP_ADDR(arr->pdata[i]));
+            g_assert(NMTST_NM_ERR_SUCCESS(r));
+        }
+    }
+
+    {
+        gs_unref_ptrarray GPtrArray *arr = NULL;
+
+        arr = nm_platform_mptcp_addrs_dump(platform);
+        g_assert(arr);
+        g_assert_cmpint(arr->len, ==, 0);
+    }
+}
+
+/*****************************************************************************/
+
 NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
 
 void
@@ -1971,6 +2169,7 @@ _nmtstp_setup_tests(void)
 #define add_test_func(testpath, test_func) nmtstp_env1_add_test_func(testpath, test_func, TRUE)
 #define add_test_func_data(testpath, test_func, arg) \
     nmtstp_env1_add_test_func_data(testpath, test_func, arg, TRUE)
+
     add_test_func("/route/ip4", test_ip4_route);
     add_test_func("/route/ip6", test_ip6_route);
     add_test_func("/route/ip4_metric0", test_ip4_route_metric0);
@@ -1998,4 +2197,8 @@ _nmtstp_setup_tests(void)
         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));
     }
+    if (nmtstp_is_root_test()) {
+        add_test_func_data("/route/mptcp/1", test_mptcp, GINT_TO_POINTER(1));
+        add_test_func_data("/route/mptcp/2", test_mptcp, GINT_TO_POINTER(2));
+    }
 }