Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 145 lines 3.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 3/* 4 * BPF-based flow shaping 5 * 6 * The test brings up two veth in two isolated namespaces, attach some flow 7 * shaping program onto it, and ensures that a manual speedtest maximum 8 * value matches the rate set in the BPF shapers. 9 */ 10 11#include <asm-generic/socket.h> 12#include <stdio.h> 13#include <unistd.h> 14#include <fcntl.h> 15#include <math.h> 16#include <sys/time.h> 17#include <sys/socket.h> 18#include <bpf/libbpf.h> 19#include <pthread.h> 20#include "test_progs.h" 21#include "network_helpers.h" 22#include "test_tc_edt.skel.h" 23 24#define SERVER_NS "tc-edt-server-ns" 25#define CLIENT_NS "tc-edt-client-ns" 26#define IP4_ADDR_VETH1 "192.168.1.1" 27#define IP4_ADDR_VETH2 "192.168.1.2" 28#define IP4_ADDR_VETH2_HEX 0xC0A80102 29 30#define TIMEOUT_MS 2000 31#define TEST_PORT 9000 32#define TARGET_RATE_MBPS 5.0 33#define TX_BYTES_COUNT (1 * 1000 * 1000) 34#define RATE_ERROR_PERCENT 2.0 35 36struct connection { 37 int server_listen_fd; 38 int server_conn_fd; 39 int client_conn_fd; 40}; 41 42static int setup(struct test_tc_edt *skel) 43{ 44 struct nstoken *nstoken_client, *nstoken_server; 45 int ret; 46 47 if (!ASSERT_OK(make_netns(CLIENT_NS), "create client ns")) 48 goto fail; 49 if (!ASSERT_OK(make_netns(SERVER_NS), "create server ns")) 50 goto fail_delete_client_ns; 51 52 nstoken_client = open_netns(CLIENT_NS); 53 if (!ASSERT_OK_PTR(nstoken_client, "open client ns")) 54 goto fail_delete_server_ns; 55 SYS(fail_close_client_ns, "ip link add veth1 type veth peer name %s", 56 "veth2 netns " SERVER_NS); 57 SYS(fail_close_client_ns, "ip -4 addr add " IP4_ADDR_VETH1 "/24 dev veth1"); 58 SYS(fail_close_client_ns, "ip link set veth1 up"); 59 60 nstoken_server = open_netns(SERVER_NS); 61 if (!ASSERT_OK_PTR(nstoken_server, "enter server ns")) 62 goto fail_close_client_ns; 63 SYS(fail_close_server_ns, "ip -4 addr add " IP4_ADDR_VETH2 "/24 dev veth2"); 64 SYS(fail_close_server_ns, "ip link set veth2 up"); 65 SYS(fail_close_server_ns, "tc qdisc add dev veth2 root fq"); 66 ret = tc_prog_attach("veth2", -1, bpf_program__fd(skel->progs.tc_prog)); 67 if (!ASSERT_OK(ret, "attach bpf prog")) 68 goto fail_close_server_ns; 69 skel->bss->target_rate = TARGET_RATE_MBPS * 1000 * 1000; 70 close_netns(nstoken_server); 71 close_netns(nstoken_client); 72 73 return 0; 74 75fail_close_server_ns: 76 close_netns(nstoken_server); 77fail_close_client_ns: 78 close_netns(nstoken_client); 79fail_delete_server_ns: 80 remove_netns(SERVER_NS); 81fail_delete_client_ns: 82 remove_netns(CLIENT_NS); 83fail: 84 return -1; 85} 86 87static void cleanup(void) 88{ 89 remove_netns(CLIENT_NS); 90 remove_netns(SERVER_NS); 91} 92 93static void run_test(void) 94{ 95 int server_fd, client_fd, err; 96 double rate_mbps, rate_error; 97 struct nstoken *nstoken; 98 __u64 ts_start, ts_end; 99 100 nstoken = open_netns(SERVER_NS); 101 if (!ASSERT_OK_PTR(nstoken, "open server ns")) 102 return; 103 server_fd = start_server(AF_INET, SOCK_STREAM, IP4_ADDR_VETH2, 104 TEST_PORT, TIMEOUT_MS); 105 if (!ASSERT_OK_FD(server_fd, "start server")) 106 return; 107 108 close_netns(nstoken); 109 nstoken = open_netns(CLIENT_NS); 110 if (!ASSERT_OK_PTR(nstoken, "open client ns")) 111 return; 112 client_fd = connect_to_fd(server_fd, 0); 113 if (!ASSERT_OK_FD(client_fd, "connect client")) 114 return; 115 116 ts_start = get_time_ns(); 117 err = send_recv_data(server_fd, client_fd, TX_BYTES_COUNT); 118 ts_end = get_time_ns(); 119 close_netns(nstoken); 120 ASSERT_OK(err, "send_recv_data"); 121 122 rate_mbps = TX_BYTES_COUNT / ((ts_end - ts_start) / 1000.0); 123 rate_error = 124 fabs((rate_mbps - TARGET_RATE_MBPS) * 100.0 / TARGET_RATE_MBPS); 125 126 ASSERT_LE(rate_error, RATE_ERROR_PERCENT, 127 "rate error is lower than threshold"); 128} 129 130void test_tc_edt(void) 131{ 132 struct test_tc_edt *skel; 133 134 skel = test_tc_edt__open_and_load(); 135 if (!ASSERT_OK_PTR(skel, "skel open and load")) 136 return; 137 138 if (!ASSERT_OK(setup(skel), "global setup")) 139 return; 140 141 run_test(); 142 143 cleanup(); 144 test_tc_edt__destroy(skel); 145}