selftests/bpf: Check -EBUSY for the recurred bpf_setsockopt(TCP_CONGESTION)
authorMartin KaFai Lau <martin.lau@kernel.org>
Thu, 29 Sep 2022 07:04:07 +0000 (00:04 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 29 Sep 2022 16:25:47 +0000 (09:25 -0700)
This patch changes the bpf_dctcp test to ensure the recurred
bpf_setsockopt(TCP_CONGESTION) returns -EBUSY.

Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20220929070407.965581-6-martin.lau@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
tools/testing/selftests/bpf/progs/bpf_dctcp.c

index 2959a52..e980188 100644 (file)
@@ -290,6 +290,10 @@ static void test_dctcp_fallback(void)
                goto done;
        ASSERT_STREQ(dctcp_skel->bss->cc_res, "cubic", "cc_res");
        ASSERT_EQ(dctcp_skel->bss->tcp_cdg_res, -ENOTSUPP, "tcp_cdg_res");
+       /* All setsockopt(TCP_CONGESTION) in the recurred
+        * bpf_dctcp->init() should fail with -EBUSY.
+        */
+       ASSERT_EQ(dctcp_skel->bss->ebusy_cnt, 3, "ebusy_cnt");
 
        err = getsockopt(srv_fd, SOL_TCP, TCP_CONGESTION, srv_cc, &cc_len);
        if (!ASSERT_OK(err, "getsockopt(srv_fd, TCP_CONGESTION)"))
index 9573be6..4606827 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/tcp.h>
+#include <errno.h>
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include "bpf_tcp_helpers.h"
@@ -23,6 +24,7 @@ const char tcp_cdg[] = "cdg";
 char cc_res[TCP_CA_NAME_MAX];
 int tcp_cdg_res = 0;
 int stg_result = 0;
+int ebusy_cnt = 0;
 
 struct {
        __uint(type, BPF_MAP_TYPE_SK_STORAGE);
@@ -64,16 +66,23 @@ void BPF_PROG(dctcp_init, struct sock *sk)
 
        if (!(tp->ecn_flags & TCP_ECN_OK) && fallback[0]) {
                /* Switch to fallback */
-               bpf_setsockopt(sk, SOL_TCP, TCP_CONGESTION,
-                              (void *)fallback, sizeof(fallback));
-               /* Switch back to myself which the bpf trampoline
-                * stopped calling dctcp_init recursively.
+               if (bpf_setsockopt(sk, SOL_TCP, TCP_CONGESTION,
+                                  (void *)fallback, sizeof(fallback)) == -EBUSY)
+                       ebusy_cnt++;
+
+               /* Switch back to myself and the recurred dctcp_init()
+                * will get -EBUSY for all bpf_setsockopt(TCP_CONGESTION),
+                * except the last "cdg" one.
                 */
-               bpf_setsockopt(sk, SOL_TCP, TCP_CONGESTION,
-                              (void *)bpf_dctcp, sizeof(bpf_dctcp));
+               if (bpf_setsockopt(sk, SOL_TCP, TCP_CONGESTION,
+                                  (void *)bpf_dctcp, sizeof(bpf_dctcp)) == -EBUSY)
+                       ebusy_cnt++;
+
                /* Switch back to fallback */
-               bpf_setsockopt(sk, SOL_TCP, TCP_CONGESTION,
-                              (void *)fallback, sizeof(fallback));
+               if (bpf_setsockopt(sk, SOL_TCP, TCP_CONGESTION,
+                                  (void *)fallback, sizeof(fallback)) == -EBUSY)
+                       ebusy_cnt++;
+
                /* Expecting -ENOTSUPP for tcp_cdg_res */
                tcp_cdg_res = bpf_setsockopt(sk, SOL_TCP, TCP_CONGESTION,
                                             (void *)tcp_cdg, sizeof(tcp_cdg));