diff options
| author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-08-07 17:14:42 -0400 | 
|---|---|---|
| committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-08-07 17:14:42 -0400 | 
| commit | 2612e3bbc0386368a850140a6c9b990cd496a5ec (patch) | |
| tree | 5d332c873fdb6b6b3d951afabe15548d5d09fc62 /tools/testing/selftests/bpf/prog_tests/sockmap_basic.c | |
| parent | 0701760ec0e910ab3c399b607e55346d6c57d244 (diff) | |
| parent | d9aa1da9a8cfb0387eb5703c15bd1f54421460ac (diff) | |
Merge drm/drm-next into drm-intel-next
Catching-up with drm-next and drm-intel-gt-next.
It will unblock a code refactor around the platform
definitions (names vs acronyms).
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'tools/testing/selftests/bpf/prog_tests/sockmap_basic.c')
| -rw-r--r-- | tools/testing/selftests/bpf/prog_tests/sockmap_basic.c | 131 | 
1 files changed, 131 insertions, 0 deletions
| diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c index 0ce25a967481..064cc5e8d9ad 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c @@ -2,6 +2,7 @@  // Copyright (c) 2020 Cloudflare  #include <error.h>  #include <netinet/tcp.h> +#include <sys/epoll.h>  #include "test_progs.h"  #include "test_skmsg_load_helpers.skel.h" @@ -9,8 +10,12 @@  #include "test_sockmap_invalid_update.skel.h"  #include "test_sockmap_skb_verdict_attach.skel.h"  #include "test_sockmap_progs_query.skel.h" +#include "test_sockmap_pass_prog.skel.h" +#include "test_sockmap_drop_prog.skel.h"  #include "bpf_iter_sockmap.skel.h" +#include "sockmap_helpers.h" +  #define TCP_REPAIR		19	/* TCP sock is under repair right now */  #define TCP_REPAIR_ON		1 @@ -350,6 +355,126 @@ out:  	test_sockmap_progs_query__destroy(skel);  } +#define MAX_EVENTS 10 +static void test_sockmap_skb_verdict_shutdown(void) +{ +	struct epoll_event ev, events[MAX_EVENTS]; +	int n, err, map, verdict, s, c1, p1; +	struct test_sockmap_pass_prog *skel; +	int epollfd; +	int zero = 0; +	char b; + +	skel = test_sockmap_pass_prog__open_and_load(); +	if (!ASSERT_OK_PTR(skel, "open_and_load")) +		return; + +	verdict = bpf_program__fd(skel->progs.prog_skb_verdict); +	map = bpf_map__fd(skel->maps.sock_map_rx); + +	err = bpf_prog_attach(verdict, map, BPF_SK_SKB_STREAM_VERDICT, 0); +	if (!ASSERT_OK(err, "bpf_prog_attach")) +		goto out; + +	s = socket_loopback(AF_INET, SOCK_STREAM); +	if (s < 0) +		goto out; +	err = create_pair(s, AF_INET, SOCK_STREAM, &c1, &p1); +	if (err < 0) +		goto out; + +	err = bpf_map_update_elem(map, &zero, &c1, BPF_NOEXIST); +	if (err < 0) +		goto out_close; + +	shutdown(p1, SHUT_WR); + +	ev.events = EPOLLIN; +	ev.data.fd = c1; + +	epollfd = epoll_create1(0); +	if (!ASSERT_GT(epollfd, -1, "epoll_create(0)")) +		goto out_close; +	err = epoll_ctl(epollfd, EPOLL_CTL_ADD, c1, &ev); +	if (!ASSERT_OK(err, "epoll_ctl(EPOLL_CTL_ADD)")) +		goto out_close; +	err = epoll_wait(epollfd, events, MAX_EVENTS, -1); +	if (!ASSERT_EQ(err, 1, "epoll_wait(fd)")) +		goto out_close; + +	n = recv(c1, &b, 1, SOCK_NONBLOCK); +	ASSERT_EQ(n, 0, "recv_timeout(fin)"); +out_close: +	close(c1); +	close(p1); +out: +	test_sockmap_pass_prog__destroy(skel); +} + +static void test_sockmap_skb_verdict_fionread(bool pass_prog) +{ +	int expected, zero = 0, sent, recvd, avail; +	int err, map, verdict, s, c0, c1, p0, p1; +	struct test_sockmap_pass_prog *pass; +	struct test_sockmap_drop_prog *drop; +	char buf[256] = "0123456789"; + +	if (pass_prog) { +		pass = test_sockmap_pass_prog__open_and_load(); +		if (!ASSERT_OK_PTR(pass, "open_and_load")) +			return; +		verdict = bpf_program__fd(pass->progs.prog_skb_verdict); +		map = bpf_map__fd(pass->maps.sock_map_rx); +		expected = sizeof(buf); +	} else { +		drop = test_sockmap_drop_prog__open_and_load(); +		if (!ASSERT_OK_PTR(drop, "open_and_load")) +			return; +		verdict = bpf_program__fd(drop->progs.prog_skb_verdict); +		map = bpf_map__fd(drop->maps.sock_map_rx); +		/* On drop data is consumed immediately and copied_seq inc'd */ +		expected = 0; +	} + + +	err = bpf_prog_attach(verdict, map, BPF_SK_SKB_STREAM_VERDICT, 0); +	if (!ASSERT_OK(err, "bpf_prog_attach")) +		goto out; + +	s = socket_loopback(AF_INET, SOCK_STREAM); +	if (!ASSERT_GT(s, -1, "socket_loopback(s)")) +		goto out; +	err = create_socket_pairs(s, AF_INET, SOCK_STREAM, &c0, &c1, &p0, &p1); +	if (!ASSERT_OK(err, "create_socket_pairs(s)")) +		goto out; + +	err = bpf_map_update_elem(map, &zero, &c1, BPF_NOEXIST); +	if (!ASSERT_OK(err, "bpf_map_update_elem(c1)")) +		goto out_close; + +	sent = xsend(p1, &buf, sizeof(buf), 0); +	ASSERT_EQ(sent, sizeof(buf), "xsend(p0)"); +	err = ioctl(c1, FIONREAD, &avail); +	ASSERT_OK(err, "ioctl(FIONREAD) error"); +	ASSERT_EQ(avail, expected, "ioctl(FIONREAD)"); +	/* On DROP test there will be no data to read */ +	if (pass_prog) { +		recvd = recv_timeout(c1, &buf, sizeof(buf), SOCK_NONBLOCK, IO_TIMEOUT_SEC); +		ASSERT_EQ(recvd, sizeof(buf), "recv_timeout(c0)"); +	} + +out_close: +	close(c0); +	close(p0); +	close(c1); +	close(p1); +out: +	if (pass_prog) +		test_sockmap_pass_prog__destroy(pass); +	else +		test_sockmap_drop_prog__destroy(drop); +} +  void test_sockmap_basic(void)  {  	if (test__start_subtest("sockmap create_update_free")) @@ -384,4 +509,10 @@ void test_sockmap_basic(void)  		test_sockmap_progs_query(BPF_SK_SKB_STREAM_VERDICT);  	if (test__start_subtest("sockmap skb_verdict progs query"))  		test_sockmap_progs_query(BPF_SK_SKB_VERDICT); +	if (test__start_subtest("sockmap skb_verdict shutdown")) +		test_sockmap_skb_verdict_shutdown(); +	if (test__start_subtest("sockmap skb_verdict fionread")) +		test_sockmap_skb_verdict_fionread(true); +	if (test__start_subtest("sockmap skb_verdict fionread on drop")) +		test_sockmap_skb_verdict_fionread(false);  } | 
