|
2 | 2 | // Copyright (c) 2020 Cloudflare
|
3 | 3 | #include <error.h>
|
4 | 4 | #include <netinet/tcp.h>
|
| 5 | +#include <sys/epoll.h> |
5 | 6 |
|
6 | 7 | #include "test_progs.h"
|
7 | 8 | #include "test_skmsg_load_helpers.skel.h"
|
8 | 9 | #include "test_sockmap_update.skel.h"
|
9 | 10 | #include "test_sockmap_invalid_update.skel.h"
|
10 | 11 | #include "test_sockmap_skb_verdict_attach.skel.h"
|
11 | 12 | #include "test_sockmap_progs_query.skel.h"
|
| 13 | +#include "test_sockmap_pass_prog.skel.h" |
12 | 14 | #include "bpf_iter_sockmap.skel.h"
|
13 | 15 |
|
| 16 | +#include "sockmap_helpers.h" |
| 17 | + |
14 | 18 | #define TCP_REPAIR 19 /* TCP sock is under repair right now */
|
15 | 19 |
|
16 | 20 | #define TCP_REPAIR_ON 1
|
@@ -350,6 +354,62 @@ static void test_sockmap_progs_query(enum bpf_attach_type attach_type)
|
350 | 354 | test_sockmap_progs_query__destroy(skel);
|
351 | 355 | }
|
352 | 356 |
|
| 357 | +#define MAX_EVENTS 10 |
| 358 | +static void test_sockmap_skb_verdict_shutdown(void) |
| 359 | +{ |
| 360 | + struct epoll_event ev, events[MAX_EVENTS]; |
| 361 | + int n, err, map, verdict, s, c1, p1; |
| 362 | + struct test_sockmap_pass_prog *skel; |
| 363 | + int epollfd; |
| 364 | + int zero = 0; |
| 365 | + char b; |
| 366 | + |
| 367 | + skel = test_sockmap_pass_prog__open_and_load(); |
| 368 | + if (!ASSERT_OK_PTR(skel, "open_and_load")) |
| 369 | + return; |
| 370 | + |
| 371 | + verdict = bpf_program__fd(skel->progs.prog_skb_verdict); |
| 372 | + map = bpf_map__fd(skel->maps.sock_map_rx); |
| 373 | + |
| 374 | + err = bpf_prog_attach(verdict, map, BPF_SK_SKB_STREAM_VERDICT, 0); |
| 375 | + if (!ASSERT_OK(err, "bpf_prog_attach")) |
| 376 | + goto out; |
| 377 | + |
| 378 | + s = socket_loopback(AF_INET, SOCK_STREAM); |
| 379 | + if (s < 0) |
| 380 | + goto out; |
| 381 | + err = create_pair(s, AF_INET, SOCK_STREAM, &c1, &p1); |
| 382 | + if (err < 0) |
| 383 | + goto out; |
| 384 | + |
| 385 | + err = bpf_map_update_elem(map, &zero, &c1, BPF_NOEXIST); |
| 386 | + if (err < 0) |
| 387 | + goto out_close; |
| 388 | + |
| 389 | + shutdown(p1, SHUT_WR); |
| 390 | + |
| 391 | + ev.events = EPOLLIN; |
| 392 | + ev.data.fd = c1; |
| 393 | + |
| 394 | + epollfd = epoll_create1(0); |
| 395 | + if (!ASSERT_GT(epollfd, -1, "epoll_create(0)")) |
| 396 | + goto out_close; |
| 397 | + err = epoll_ctl(epollfd, EPOLL_CTL_ADD, c1, &ev); |
| 398 | + if (!ASSERT_OK(err, "epoll_ctl(EPOLL_CTL_ADD)")) |
| 399 | + goto out_close; |
| 400 | + err = epoll_wait(epollfd, events, MAX_EVENTS, -1); |
| 401 | + if (!ASSERT_EQ(err, 1, "epoll_wait(fd)")) |
| 402 | + goto out_close; |
| 403 | + |
| 404 | + n = recv(c1, &b, 1, SOCK_NONBLOCK); |
| 405 | + ASSERT_EQ(n, 0, "recv_timeout(fin)"); |
| 406 | +out_close: |
| 407 | + close(c1); |
| 408 | + close(p1); |
| 409 | +out: |
| 410 | + test_sockmap_pass_prog__destroy(skel); |
| 411 | +} |
| 412 | + |
353 | 413 | void test_sockmap_basic(void)
|
354 | 414 | {
|
355 | 415 | if (test__start_subtest("sockmap create_update_free"))
|
@@ -384,4 +444,6 @@ void test_sockmap_basic(void)
|
384 | 444 | test_sockmap_progs_query(BPF_SK_SKB_STREAM_VERDICT);
|
385 | 445 | if (test__start_subtest("sockmap skb_verdict progs query"))
|
386 | 446 | test_sockmap_progs_query(BPF_SK_SKB_VERDICT);
|
| 447 | + if (test__start_subtest("sockmap skb_verdict shutdown")) |
| 448 | + test_sockmap_skb_verdict_shutdown(); |
387 | 449 | }
|
0 commit comments