summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/testing/selftests/bpf/prog_tests/sockopt_sk.c17
-rw-r--r--tools/testing/selftests/bpf/progs/sockopt_sk.c16
2 files changed, 32 insertions, 1 deletions
diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
index 53637431ec5d..3a41c517b918 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
@@ -190,7 +190,7 @@ static int getsetsockopt(void)
fd = socket(AF_NETLINK, SOCK_RAW, 0);
if (fd < 0) {
log_err("Failed to create AF_NETLINK socket");
- return -1;
+ goto err;
}
buf.u32 = 1;
@@ -211,6 +211,21 @@ static int getsetsockopt(void)
}
ASSERT_EQ(optlen, 8, "Unexpected NETLINK_LIST_MEMBERSHIPS value");
+ /* Trick bpf_tcp_sock() with IPPROTO_TCP */
+ close(fd);
+ fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
+ if (!ASSERT_OK_FD(fd, "socket"))
+ goto err;
+
+ /* The BPF prog intercepts this before the kernel sees it, any
+ * optlen works. Go with 4 bytes for simplicity.
+ */
+ buf.u32 = 1;
+ optlen = sizeof(buf.u32);
+ err = setsockopt(fd, SOL_TCP, TCP_SAVED_SYN, &buf, optlen);
+ if (!ASSERT_ERR(err, "setsockopt(TCP_SAVED_SYN)"))
+ goto err;
+
free(big_buf);
close(fd);
return 0;
diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c
index cb990a7d3d45..5e0b27e7855c 100644
--- a/tools/testing/selftests/bpf/progs/sockopt_sk.c
+++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c
@@ -149,6 +149,20 @@ int _setsockopt(struct bpf_sockopt *ctx)
if (sk && sk->family == AF_NETLINK)
goto out;
+ if (sk && sk->family == AF_INET && sk->type == SOCK_RAW) {
+ struct bpf_tcp_sock *tp = bpf_tcp_sock(sk);
+
+ if (tp) {
+ char saved_syn[60];
+
+ bpf_getsockopt(sk, SOL_TCP, TCP_SAVED_SYN,
+ &saved_syn, sizeof(saved_syn));
+ goto consumed;
+ }
+
+ goto out;
+ }
+
/* Make sure bpf_get_netns_cookie is callable.
*/
if (bpf_get_netns_cookie(NULL) == 0)
@@ -224,6 +238,8 @@ int _setsockopt(struct bpf_sockopt *ctx)
return 0; /* couldn't get sk storage */
storage->val = optval[0];
+
+consumed:
ctx->optlen = -1; /* BPF has consumed this option, don't call kernel
* setsockopt handler.
*/