about summary refs log tree commit diff
path: root/src/core/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/platform')
-rw-r--r--src/core/platform/tests/test-common.c63
-rw-r--r--src/core/platform/tests/test-common.h8
-rw-r--r--src/core/platform/tests/test-link.c64
-rw-r--r--src/core/platform/tests/test-route.c74
4 files changed, 198 insertions, 11 deletions
diff --git a/src/core/platform/tests/test-common.c b/src/core/platform/tests/test-common.c
index 91445b30..f1f7caee 100644
--- a/src/core/platform/tests/test-common.c
+++ b/src/core/platform/tests/test-common.c
@@ -1230,7 +1230,7 @@ out:
 }
 
 gboolean
-nmtstp_check_platform_full(NMPlatform *platform, guint32 obj_type_flags, gboolean do_assert)
+nmtstp_check_platform_full(NMPlatform *platform, guint64 obj_type_flags, gboolean do_assert)
 {
     static const NMPObjectType obj_types[] = {
         NMP_OBJECT_TYPE_IP4_ADDRESS,
@@ -1265,7 +1265,7 @@ nmtstp_check_platform_full(NMPlatform *platform, guint32 obj_type_flags, gboolea
 
     for (i_obj_types = 0; i_obj_types < (int) G_N_ELEMENTS(obj_types); i_obj_types++) {
         const NMPObjectType          obj_type         = obj_types[i_obj_types];
-        const guint32                i_obj_type_flags = nmp_object_type_to_flags(obj_type);
+        const guint64                i_obj_type_flags = nmp_object_type_to_flags(obj_type);
         gs_unref_ptrarray GPtrArray *arr1             = NULL;
         gs_unref_ptrarray GPtrArray *arr2             = NULL;
         NMPLookup                    lookup;
@@ -1408,7 +1408,7 @@ nmtstp_check_platform_full(NMPlatform *platform, guint32 obj_type_flags, gboolea
 }
 
 void
-nmtstp_check_platform(NMPlatform *platform, guint32 obj_type_flags)
+nmtstp_check_platform(NMPlatform *platform, guint64 obj_type_flags)
 {
     if (!nmtstp_check_platform_full(platform, obj_type_flags, FALSE)) {
         /* It's unclear why this failure sometimes happens. It happens
@@ -2394,6 +2394,61 @@ nmtstp_link_dummy_add(NMPlatform *platform, int external_command, const char *na
 }
 
 const NMPlatformLink *
+nmtstp_link_geneve_add(NMPlatform                *platform,
+                       int                        external_command,
+                       const char                *name,
+                       const NMPlatformLnkGeneve *lnk)
+{
+    const NMPlatformLink *pllink = NULL;
+    int                   success;
+
+    g_assert(nm_utils_ifname_valid_kernel(name, NULL));
+    g_assert(lnk->remote || !IN6_IS_ADDR_UNSPECIFIED(&lnk->remote6));
+
+    external_command = nmtstp_run_command_check_external(external_command);
+
+    _init_platform(&platform, external_command);
+
+    if (external_command) {
+        char remote[NM_INET_ADDRSTRLEN];
+        char remote6[NM_INET_ADDRSTRLEN];
+        char str_ttl[30];
+
+        if (lnk->remote)
+            nm_inet4_ntop(lnk->remote, remote);
+        else
+            remote[0] = '\0';
+
+        if (memcmp(&lnk->remote6, &in6addr_any, sizeof(in6addr_any)))
+            nm_inet6_ntop(&lnk->remote6, remote6);
+        else
+            remote6[0] = '\0';
+
+        success = !nmtstp_run_command(
+            "ip link add %s type geneve id %u remote %s %s tos %02x dstport %u%s",
+            name,
+            lnk->id,
+            remote[0] ? remote : remote6,
+            lnk->ttl > 0    ? nm_sprintf_buf(str_ttl, "ttl %u", lnk->ttl & 0xff)
+            : lnk->ttl == 0 ? "ttl auto"
+                            : "ttl inherit",
+            lnk->tos,
+            lnk->dst_port,
+            lnk->df == 1   ? " df set "
+            : lnk->df == 2 ? " df inherit "
+                           : "");
+
+        if (success)
+            pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_GENEVE, 100);
+    } else
+        success = NMTST_NM_ERR_SUCCESS(nm_platform_link_geneve_add(platform, name, lnk, &pllink));
+
+    _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_GENEVE);
+
+    return pllink;
+}
+
+const NMPlatformLink *
 nmtstp_link_gre_add(NMPlatform             *platform,
                     int                     external_command,
                     const char             *name,
@@ -3024,8 +3079,6 @@ nmtstp_link_vxlan_add(NMPlatform               *platform,
     return pllink;
 }
 
-/*****************************************************************************/
-
 const NMPlatformLink *
 nmtstp_link_get_typed(NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type)
 {
diff --git a/src/core/platform/tests/test-common.h b/src/core/platform/tests/test-common.h
index 85ed7961..251fa510 100644
--- a/src/core/platform/tests/test-common.h
+++ b/src/core/platform/tests/test-common.h
@@ -140,9 +140,9 @@ int nmtstp_run_command(const char *format, ...) _nm_printf(1, 2);
 /*****************************************************************************/
 
 gboolean
-nmtstp_check_platform_full(NMPlatform *platform, guint32 obj_type_flags, gboolean do_assert);
+nmtstp_check_platform_full(NMPlatform *platform, guint64 obj_type_flags, gboolean do_assert);
 
-void nmtstp_check_platform(NMPlatform *platform, guint32 obj_type_flags);
+void nmtstp_check_platform(NMPlatform *platform, guint64 obj_type_flags);
 
 /*****************************************************************************/
 
@@ -474,6 +474,10 @@ const NMPlatformLink *nmtstp_link_veth_add(NMPlatform *platform,
                                            const char *peer);
 const NMPlatformLink *
 nmtstp_link_dummy_add(NMPlatform *platform, int external_command, const char *name);
+const NMPlatformLink *nmtstp_link_geneve_add(NMPlatform                *platform,
+                                             int                        external_command,
+                                             const char                *name,
+                                             const NMPlatformLnkGeneve *lnk);
 const NMPlatformLink *nmtstp_link_gre_add(NMPlatform             *platform,
                                           int                     external_command,
                                           const char             *name,
diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c
index 77e7e641..5618308f 100644
--- a/src/core/platform/tests/test-link.c
+++ b/src/core/platform/tests/test-link.c
@@ -1388,10 +1388,11 @@ test_software_detect(gconstpointer user_data)
     const gboolean                   ext        = test_data->external_command;
     NMPlatformLnkBridge              lnk_bridge = {};
     NMPlatformLnkTun                 lnk_tun;
-    NMPlatformLnkGre                 lnk_gre  = {};
-    NMPlatformLnkVti                 lnk_vti  = {};
-    NMPlatformLnkVti6                lnk_vti6 = {};
-    nm_auto_close int                tun_fd   = -1;
+    NMPlatformLnkGeneve              lnk_geneve = {};
+    NMPlatformLnkGre                 lnk_gre    = {};
+    NMPlatformLnkVti                 lnk_vti    = {};
+    NMPlatformLnkVti6                lnk_vti6   = {};
+    nm_auto_close int                tun_fd     = -1;
     gboolean                         module_loaded;
 
     nmtstp_run_command_check("ip link add %s type dummy", PARENT_NAME);
@@ -1434,6 +1435,31 @@ test_software_detect(gconstpointer user_data)
             g_error("Failed adding Bridge interface");
         break;
 
+    case NM_LINK_TYPE_GENEVE:
+    {
+        switch (test_data->test_mode) {
+        case 0:
+            lnk_geneve.id       = 42;
+            lnk_geneve.remote   = nmtst_inet4_from_string("192.168.1.100");
+            lnk_geneve.ttl      = 64;
+            lnk_geneve.tos      = 0;
+            lnk_geneve.dst_port = 6081;
+            lnk_geneve.df       = 0;
+            break;
+        case 1:
+            lnk_geneve.id       = 12345;
+            lnk_geneve.remote6  = nmtst_inet6_from_string("2001:db8::1");
+            lnk_geneve.ttl      = 128;
+            lnk_geneve.tos      = 16;
+            lnk_geneve.dst_port = 6082;
+            lnk_geneve.df       = 1;
+            break;
+        }
+
+        g_assert(nmtstp_link_geneve_add(NULL, ext, DEVICE_NAME, &lnk_geneve));
+        break;
+    }
+
     case NM_LINK_TYPE_GRE:
         module_loaded = nmtstp_ensure_module("ip_gre");
 
@@ -2208,6 +2234,34 @@ test_software_detect(gconstpointer user_data)
             }
             break;
         }
+        case NM_LINK_TYPE_GENEVE:
+        {
+            const NMPlatformLnkGeneve *plnk = &lnk->lnk_geneve;
+
+            g_assert(plnk == nm_platform_link_get_lnk_geneve(NM_PLATFORM_GET, ifindex, NULL));
+
+            switch (test_data->test_mode) {
+            case 0:
+                g_assert_cmpint(plnk->id, ==, 42);
+                nmtst_assert_ip4_address(plnk->remote, "192.168.1.100");
+                nmtst_assert_ip6_address(&plnk->remote6, "::");
+                g_assert_cmpint(plnk->ttl, ==, 64);
+                g_assert_cmpint(plnk->tos, ==, 0);
+                g_assert_cmpint(plnk->dst_port, ==, 6081);
+                g_assert_cmpint(plnk->df, ==, 0);
+                break;
+            case 1:
+                g_assert_cmpint(plnk->id, ==, 12345);
+                nmtst_assert_ip4_address(plnk->remote, "0.0.0.0");
+                nmtst_assert_ip6_address(&plnk->remote6, "2001:db8::1");
+                g_assert_cmpint(plnk->ttl, ==, 128);
+                g_assert_cmpint(plnk->tos, ==, 16);
+                g_assert_cmpint(plnk->dst_port, ==, 6082);
+                g_assert_cmpint(plnk->df, ==, 1);
+                break;
+            }
+            break;
+        }
         case NM_LINK_TYPE_WIREGUARD:
         {
             const NMPlatformLnkWireGuard *plnk = &lnk->lnk_wireguard;
@@ -4143,6 +4197,8 @@ _nmtstp_setup_tests(void)
         g_test_add_func("/link/external", test_external);
 
         test_software_detect_add("/link/software/detect/bridge", NM_LINK_TYPE_BRIDGE, 0);
+        test_software_detect_add("/link/software/detect/geneve/0", NM_LINK_TYPE_GENEVE, 0);
+        test_software_detect_add("/link/software/detect/geneve/1", NM_LINK_TYPE_GENEVE, 1);
         test_software_detect_add("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0);
         test_software_detect_add("/link/software/detect/gretap", NM_LINK_TYPE_GRETAP, 0);
         test_software_detect_add("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0);
diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c
index fbad2447..27bb7431 100644
--- a/src/core/platform/tests/test-route.c
+++ b/src/core/platform/tests/test-route.c
@@ -2461,6 +2461,78 @@ done:
 }
 
 /*****************************************************************************/
+static void
+test_ip4_rtnh_onlink(void)
+{
+    /* Extra nexthops that differ only in rtnh_flags ONLINK should
+     * compare as different. */
+    NMPlatformIP4RtNextHop nh_a = {
+        .ifindex    = 2,
+        .gateway    = nmtst_inet4_from_string("10.10.10.10"),
+        .weight     = 1,
+        .rtnh_flags = 0,
+    };
+
+    NMPlatformIP4RtNextHop nh_b = nh_a;
+    nh_b.rtnh_flags             = RTNH_F_ONLINK;
+
+    g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, TRUE), !=, 0);
+    g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, FALSE), !=, 0);
+
+    nh_b.rtnh_flags = 0;
+    g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, TRUE), ==, 0);
+    g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, FALSE), ==, 0);
+}
+
+static void
+test_ip4_route_onlink_per_nexthop(void)
+{
+    NMPlatformIP4Route r_a = {};
+    NMPlatformIP4Route r_b;
+
+    /* Two single-hop routes that are identical, except for the onlink flag. */
+    r_a.ifindex      = 1;
+    r_a.rt_source    = NM_IP_CONFIG_SOURCE_USER;
+    r_a.network      = nmtst_inet4_from_string("10.10.10.10");
+    r_a.plen         = 24;
+    r_a.gateway      = nmtst_inet4_from_string("10.10.10.1");
+    r_a.metric       = 100;
+    r_a.n_nexthops   = 1;
+    r_a.type_coerced = nm_platform_route_type_coerce(RTN_UNICAST);
+    r_a.scope_inv    = nm_platform_route_scope_inv(RT_SCOPE_UNIVERSE);
+
+    r_b             = r_a;
+    r_b.r_rtm_flags = RTNH_F_ONLINK;
+
+    /* Onlink flag should result in the same ECMP_ID but different IDs. */
+    g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID),
+                    ==,
+                    0);
+
+    g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID), !=, 0);
+    g_assert_cmpint(
+        nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY),
+        !=,
+        0);
+    g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL),
+                    !=,
+                    0);
+
+    r_b.r_rtm_flags = 0;
+    g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID), ==, 0);
+    g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID),
+                    ==,
+                    0);
+    g_assert_cmpint(
+        nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY),
+        ==,
+        0);
+    g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL),
+                    ==,
+                    0);
+}
+
+/*****************************************************************************/
 
 NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
 
@@ -2480,6 +2552,8 @@ _nmtstp_setup_tests(void)
     nmtstp_env1_add_test_func_data(testpath, test_func, arg, 2, TRUE)
 
     add_test_func("/route/ip4", test_ip4_route);
+    add_test_func("/route/ip4_onlink_per_nexthop", test_ip4_route_onlink_per_nexthop);
+    add_test_func("/route/ip4_rtnh_onlink", test_ip4_rtnh_onlink);
     add_test_func("/route/ip6", test_ip6_route);
     add_test_func("/route/ip4_metric0", test_ip4_route_metric0);
     add_test_func_data("/route/ip4_options/1", test_ip4_route_options, GINT_TO_POINTER(1));