FILE
tcp_custom_syncookie.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/bpf/prog_tests/tcp_custom_syncookie.c
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright Amazon.com Inc. or its affiliates. */ 3 4#define _GNU_SOURCE 5#include <sched.h> 6#include <stdlib.h> 7#include <net/if.h> 8 9#include "test_progs.h" 10#include "cgroup_helpers.h" 11#include "network_helpers.h" 12#include "test_tcp_custom_syncookie.skel.h" 13 14static struct test_tcp_custom_syncookie_case { 15 int family, type; 16 char addr[16]; 17 char name[10]; 18} test_cases[] = { 19 { 20 .name = "IPv4 TCP", 21 .family = AF_INET, 22 .type = SOCK_STREAM, 23 .addr = "127.0.0.1", 24 }, 25 { 26 .name = "IPv6 TCP", 27 .family = AF_INET6, 28 .type = SOCK_STREAM, 29 .addr = "::1", 30 }, 31}; 32 33static int setup_netns(void) 34{ 35 if (!ASSERT_OK(unshare(CLONE_NEWNET), "create netns")) 36 return -1; 37 38 if (!ASSERT_OK(system("ip link set dev lo up"), "ip")) 39 goto err; 40 41 if (!ASSERT_OK(write_sysctl("/proc/sys/net/ipv4/tcp_ecn", "1"), 42 "write_sysctl")) 43 goto err; 44 45 return 0; 46err: 47 return -1; 48} 49 50static int setup_tc(struct test_tcp_custom_syncookie *skel) 51{ 52 LIBBPF_OPTS(bpf_tc_hook, qdisc_lo, .attach_point = BPF_TC_INGRESS); 53 LIBBPF_OPTS(bpf_tc_opts, tc_attach, 54 .prog_fd = bpf_program__fd(skel->progs.tcp_custom_syncookie)); 55 56 qdisc_lo.ifindex = if_nametoindex("lo"); 57 if (!ASSERT_OK(bpf_tc_hook_create(&qdisc_lo), "qdisc add dev lo clsact")) 58 goto err; 59 60 if (!ASSERT_OK(bpf_tc_attach(&qdisc_lo, &tc_attach), 61 "filter add dev lo ingress")) 62 goto err; 63 64 return 0; 65err: 66 return -1; 67} 68 69#define msg "Hello World" 70#define msglen 11 71 72static void transfer_message(int sender, int receiver) 73{ 74 char buf[msglen]; 75 int ret; 76 77 ret = send(sender, msg, msglen, 0); 78 if (!ASSERT_EQ(ret, msglen, "send")) 79 return; 80 81 memset(buf, 0, sizeof(buf)); 82 83 ret = recv(receiver, buf, msglen, 0); 84 if (!ASSERT_EQ(ret, msglen, "recv")) 85 return; 86 87 ret = strncmp(buf, msg, msglen); 88 if (!ASSERT_EQ(ret, 0, "strncmp")) 89 return; 90} 91 92static void create_connection(struct test_tcp_custom_syncookie_case *test_case) 93{ 94 int server, client, child; 95 96 server = start_server(test_case->family, test_case->type, test_case->addr, 0, 0); 97 if (!ASSERT_NEQ(server, -1, "start_server")) 98 return; 99 100 client = connect_to_fd(server, 0); 101 if (!ASSERT_NEQ(client, -1, "connect_to_fd")) 102 goto close_server; 103 104 child = accept(server, NULL, 0); 105 if (!ASSERT_NEQ(child, -1, "accept")) 106 goto close_client; 107 108 transfer_message(client, child); 109 transfer_message(child, client); 110 111 close(child); 112close_client: 113 close(client); 114close_server: 115 close(server); 116} 117 118void test_tcp_custom_syncookie(void) 119{ 120 struct test_tcp_custom_syncookie *skel; 121 int i; 122 123 if (setup_netns()) 124 return; 125 126 skel = test_tcp_custom_syncookie__open_and_load(); 127 if (!ASSERT_OK_PTR(skel, "open_and_load")) 128 return; 129 130 if (setup_tc(skel)) 131 goto destroy_skel; 132 133 for (i = 0; i < ARRAY_SIZE(test_cases); i++) { 134 if (!test__start_subtest(test_cases[i].name)) 135 continue; 136 137 skel->bss->handled_syn = false; 138 skel->bss->handled_ack = false; 139 140 create_connection(&test_cases[i]); 141 142 ASSERT_EQ(skel->bss->handled_syn, true, "SYN is not handled at tc."); 143 ASSERT_EQ(skel->bss->handled_ack, true, "ACK is not handled at tc"); 144 } 145 146destroy_skel: 147 system("tc qdisc del dev lo clsact"); 148 149 test_tcp_custom_syncookie__destroy(skel); 150}
~/
Read-only file preview.