selftests/bpf: Test case for BPF_SOCK_OPS_TCP_LISTEN_CB
authorAndrey Ignatov <rdna@fb.com>
Thu, 12 Jul 2018 00:33:37 +0000 (17:33 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Sat, 14 Jul 2018 22:08:41 +0000 (00:08 +0200)
Cover new TCP-BPF callback in test_tcpbpf: when listen() is called on
socket, set BPF_SOCK_OPS_STATE_CB_FLAG so that BPF_SOCK_OPS_STATE_CB
callback can be called on future state transition, and when such a
transition happens (TCP_LISTEN -> TCP_CLOSE), track it in the map and
verify it in user space later.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
tools/testing/selftests/bpf/test_tcpbpf.h
tools/testing/selftests/bpf/test_tcpbpf_kern.c
tools/testing/selftests/bpf/test_tcpbpf_user.c

index 2fe43289943c7fcf2fc5715c5abb4b4d10d06b1f..7bcfa62070056e0a07d6d8c03e25ccfa37e2bb0b 100644 (file)
@@ -12,5 +12,6 @@ struct tcpbpf_globals {
        __u32 good_cb_test_rv;
        __u64 bytes_received;
        __u64 bytes_acked;
+       __u32 num_listen;
 };
 #endif
index 3e645ee41ed5fcc033266645b8e893c143fb79fc..4b7fd540cea9dd89d506bfe693be0414e79b6d90 100644 (file)
@@ -96,15 +96,22 @@ int bpf_testcb(struct bpf_sock_ops *skops)
                        if (!gp)
                                break;
                        g = *gp;
-                       g.total_retrans = skops->total_retrans;
-                       g.data_segs_in = skops->data_segs_in;
-                       g.data_segs_out = skops->data_segs_out;
-                       g.bytes_received = skops->bytes_received;
-                       g.bytes_acked = skops->bytes_acked;
+                       if (skops->args[0] == BPF_TCP_LISTEN) {
+                               g.num_listen++;
+                       } else {
+                               g.total_retrans = skops->total_retrans;
+                               g.data_segs_in = skops->data_segs_in;
+                               g.data_segs_out = skops->data_segs_out;
+                               g.bytes_received = skops->bytes_received;
+                               g.bytes_acked = skops->bytes_acked;
+                       }
                        bpf_map_update_elem(&global_map, &key, &g,
                                            BPF_ANY);
                }
                break;
+       case BPF_SOCK_OPS_TCP_LISTEN_CB:
+               bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG);
+               break;
        default:
                rv = -1;
        }
index 971f1644b9c7ad3b1e03444f566d2e1e7f8ae00f..a275c29713760b79a2e74700d14fd78931947976 100644 (file)
@@ -37,7 +37,8 @@ int verify_result(const struct tcpbpf_globals *result)
                           (1 << BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB) |
                           (1 << BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) |
                           (1 << BPF_SOCK_OPS_NEEDS_ECN) |
-                          (1 << BPF_SOCK_OPS_STATE_CB));
+                          (1 << BPF_SOCK_OPS_STATE_CB) |
+                          (1 << BPF_SOCK_OPS_TCP_LISTEN_CB));
 
        EXPECT_EQ(expected_events, result->event_map, "#" PRIx32);
        EXPECT_EQ(501ULL, result->bytes_received, "llu");
@@ -46,6 +47,7 @@ int verify_result(const struct tcpbpf_globals *result)
        EXPECT_EQ(1, result->data_segs_out, PRIu32);
        EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32);
        EXPECT_EQ(0, result->good_cb_test_rv, PRIu32);
+       EXPECT_EQ(1, result->num_listen, PRIu32);
 
        return 0;
 err: