bpf: add selftest for bpf's (set|get)_sockopt for SAVE_SYN
adding selftest for feature, introduced in commit 9452048c79404 ("bpf: add TCP_SAVE_SYN/TCP_SAVED_SYN options for bpf_(set|get)sockopt"). Signed-off-by: Nikita V. Shirokov <tehnerd@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
parent
11c3f51136
commit
9746b1ee2e
|
@ -5,6 +5,7 @@
|
|||
#include <linux/if_ether.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/tcp.h>
|
||||
|
@ -17,6 +18,13 @@ struct bpf_map_def SEC("maps") global_map = {
|
|||
.type = BPF_MAP_TYPE_ARRAY,
|
||||
.key_size = sizeof(__u32),
|
||||
.value_size = sizeof(struct tcpbpf_globals),
|
||||
.max_entries = 4,
|
||||
};
|
||||
|
||||
struct bpf_map_def SEC("maps") sockopt_results = {
|
||||
.type = BPF_MAP_TYPE_ARRAY,
|
||||
.key_size = sizeof(__u32),
|
||||
.value_size = sizeof(int),
|
||||
.max_entries = 2,
|
||||
};
|
||||
|
||||
|
@ -45,11 +53,14 @@ int _version SEC("version") = 1;
|
|||
SEC("sockops")
|
||||
int bpf_testcb(struct bpf_sock_ops *skops)
|
||||
{
|
||||
int rv = -1;
|
||||
int bad_call_rv = 0;
|
||||
char header[sizeof(struct ipv6hdr) + sizeof(struct tcphdr)];
|
||||
struct tcphdr *thdr;
|
||||
int good_call_rv = 0;
|
||||
int op;
|
||||
int bad_call_rv = 0;
|
||||
int save_syn = 1;
|
||||
int rv = -1;
|
||||
int v = 0;
|
||||
int op;
|
||||
|
||||
op = (int) skops->op;
|
||||
|
||||
|
@ -82,6 +93,21 @@ int bpf_testcb(struct bpf_sock_ops *skops)
|
|||
v = 0xff;
|
||||
rv = bpf_setsockopt(skops, SOL_IPV6, IPV6_TCLASS, &v,
|
||||
sizeof(v));
|
||||
if (skops->family == AF_INET6) {
|
||||
v = bpf_getsockopt(skops, IPPROTO_TCP, TCP_SAVED_SYN,
|
||||
header, (sizeof(struct ipv6hdr) +
|
||||
sizeof(struct tcphdr)));
|
||||
if (!v) {
|
||||
int offset = sizeof(struct ipv6hdr);
|
||||
|
||||
thdr = (struct tcphdr *)(header + offset);
|
||||
v = thdr->syn;
|
||||
__u32 key = 1;
|
||||
|
||||
bpf_map_update_elem(&sockopt_results, &key, &v,
|
||||
BPF_ANY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BPF_SOCK_OPS_RTO_CB:
|
||||
break;
|
||||
|
@ -111,6 +137,12 @@ int bpf_testcb(struct bpf_sock_ops *skops)
|
|||
break;
|
||||
case BPF_SOCK_OPS_TCP_LISTEN_CB:
|
||||
bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG);
|
||||
v = bpf_setsockopt(skops, IPPROTO_TCP, TCP_SAVE_SYN,
|
||||
&save_syn, sizeof(save_syn));
|
||||
/* Update global map w/ result of setsock opt */
|
||||
__u32 key = 0;
|
||||
|
||||
bpf_map_update_elem(&sockopt_results, &key, &v, BPF_ANY);
|
||||
break;
|
||||
default:
|
||||
rv = -1;
|
||||
|
|
|
@ -54,6 +54,26 @@ err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
int verify_sockopt_result(int sock_map_fd)
|
||||
{
|
||||
__u32 key = 0;
|
||||
int res;
|
||||
int rv;
|
||||
|
||||
/* check setsockopt for SAVE_SYN */
|
||||
rv = bpf_map_lookup_elem(sock_map_fd, &key, &res);
|
||||
EXPECT_EQ(0, rv, "d");
|
||||
EXPECT_EQ(0, res, "d");
|
||||
key = 1;
|
||||
/* check getsockopt for SAVED_SYN */
|
||||
rv = bpf_map_lookup_elem(sock_map_fd, &key, &res);
|
||||
EXPECT_EQ(0, rv, "d");
|
||||
EXPECT_EQ(1, res, "d");
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int bpf_find_map(const char *test, struct bpf_object *obj,
|
||||
const char *name)
|
||||
{
|
||||
|
@ -70,11 +90,11 @@ static int bpf_find_map(const char *test, struct bpf_object *obj,
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *file = "test_tcpbpf_kern.o";
|
||||
int prog_fd, map_fd, sock_map_fd;
|
||||
struct tcpbpf_globals g = {0};
|
||||
const char *cg_path = "/foo";
|
||||
int error = EXIT_FAILURE;
|
||||
struct bpf_object *obj;
|
||||
int prog_fd, map_fd;
|
||||
int cg_fd = -1;
|
||||
__u32 key = 0;
|
||||
int rv;
|
||||
|
@ -110,6 +130,10 @@ int main(int argc, char **argv)
|
|||
if (map_fd < 0)
|
||||
goto err;
|
||||
|
||||
sock_map_fd = bpf_find_map(__func__, obj, "sockopt_results");
|
||||
if (sock_map_fd < 0)
|
||||
goto err;
|
||||
|
||||
rv = bpf_map_lookup_elem(map_fd, &key, &g);
|
||||
if (rv != 0) {
|
||||
printf("FAILED: bpf_map_lookup_elem returns %d\n", rv);
|
||||
|
@ -121,6 +145,11 @@ int main(int argc, char **argv)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (verify_sockopt_result(sock_map_fd)) {
|
||||
printf("FAILED: Wrong sockopt stats\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
printf("PASSED!\n");
|
||||
error = 0;
|
||||
err:
|
||||
|
|
Loading…
Reference in New Issue