Skip to content

Commit 85bdeeb

Browse files
author
Alexei Starovoitov
committed
Merge branch 'selftests-bpf-convert-test_tc_edt-sh-into-test_progs'
Alexis Lothoré says: ==================== selftests/bpf: convert test_tc_edt.sh into test_progs Hello, this is a (late) v2 to my first attempt to convert the test_tc_edt script to test_progs. This new version is way simpler, thanks to Martin's suggestion about properly using the existing network_helpers rather than reinventing the wheel. It also fixes a small bug in the measured effective rate. The converted test roughly follows the original script logic, with two veths in two namespaces, a TCP connection between a client and a server, and the client pushing a specific amount of data. Time is recorded before and after the transmission to compute the effective rate. There are two knobs driving the robustness of the test in CI: - the amount of pushed data (the higher, the more precise is the effective rate) - the tolerated error margin The original test was configured with a 20s duration and a 1% error margin. The new test is configured with 1MB of data being pushed and a 2% error margin, to: - make the duration tolerable in CI - while keeping enough margin for rate measure fluctuations depending on the CI machines load This has been run multiple times locally to ensure that those values are sane, and once in CI before sending the series, but I suggest to let it live a few days in CI to see how it really behaves. Signed-off-by: Alexis Lothoré (eBPF Foundation) <[email protected]> Changes in v2: - drop custom client/server management - update bpf program now that server pushes data - fix effective rate computation - Link to v1: https://lore.kernel.org/r/[email protected] --- Alexis Lothoré (eBPF Foundation) (4): selftests/bpf: rename test_tc_edt.bpf.c section to expose program type selftests/bpf: integrate test_tc_edt into test_progs selftests/bpf: remove test_tc_edt.sh selftests/bpf: do not hardcode target rate in test_tc_edt BPF program tools/testing/selftests/bpf/Makefile | 2 - .../testing/selftests/bpf/prog_tests/test_tc_edt.c | 145 +++++++++++++++++++++ tools/testing/selftests/bpf/progs/test_tc_edt.c | 11 +- tools/testing/selftests/bpf/test_tc_edt.sh | 100 -------------- 4 files changed, 151 insertions(+), 107 deletions(-) --- base-commit: 233a075a1b27070af76d64541cf001340ecff917 change-id: 20251030-tc_edt-3ea8e8d3d14e Best regards, ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 34235a3 + 1d17bcc commit 85bdeeb

File tree

4 files changed

+151
-107
lines changed

4 files changed

+151
-107
lines changed

tools/testing/selftests/bpf/Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,11 @@ TEST_GEN_PROGS += test_progs-cpuv4
9999
TEST_INST_SUBDIRS += cpuv4
100100
endif
101101

102-
TEST_GEN_FILES = test_tc_edt.bpf.o
103102
TEST_FILES = xsk_prereqs.sh $(wildcard progs/btf_dump_test_case_*.c)
104103

105104
# Order correspond to 'make run_tests' order
106105
TEST_PROGS := test_kmod.sh \
107106
test_lirc_mode2.sh \
108-
test_tc_edt.sh \
109107
test_xdping.sh \
110108
test_bpftool_build.sh \
111109
test_bpftool.sh \
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
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+
36+
struct connection {
37+
int server_listen_fd;
38+
int server_conn_fd;
39+
int client_conn_fd;
40+
};
41+
42+
static 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+
75+
fail_close_server_ns:
76+
close_netns(nstoken_server);
77+
fail_close_client_ns:
78+
close_netns(nstoken_client);
79+
fail_delete_server_ns:
80+
remove_netns(SERVER_NS);
81+
fail_delete_client_ns:
82+
remove_netns(CLIENT_NS);
83+
fail:
84+
return -1;
85+
}
86+
87+
static void cleanup(void)
88+
{
89+
remove_netns(CLIENT_NS);
90+
remove_netns(SERVER_NS);
91+
}
92+
93+
static 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+
130+
void 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+
}

tools/testing/selftests/bpf/progs/test_tc_edt.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#define TIME_HORIZON_NS (2000 * 1000 * 1000)
1515
#define NS_PER_SEC 1000000000
1616
#define ECN_HORIZON_NS 5000000
17-
#define THROTTLE_RATE_BPS (5 * 1000 * 1000)
1817

1918
/* flow_key => last_tstamp timestamp used */
2019
struct {
@@ -24,12 +23,13 @@ struct {
2423
__uint(max_entries, 1);
2524
} flow_map SEC(".maps");
2625

26+
__uint64_t target_rate;
27+
2728
static inline int throttle_flow(struct __sk_buff *skb)
2829
{
2930
int key = 0;
3031
uint64_t *last_tstamp = bpf_map_lookup_elem(&flow_map, &key);
31-
uint64_t delay_ns = ((uint64_t)skb->len) * NS_PER_SEC /
32-
THROTTLE_RATE_BPS;
32+
uint64_t delay_ns = ((uint64_t)skb->len) * NS_PER_SEC / target_rate;
3333
uint64_t now = bpf_ktime_get_ns();
3434
uint64_t tstamp, next_tstamp = 0;
3535

@@ -70,7 +70,7 @@ static inline int handle_tcp(struct __sk_buff *skb, struct tcphdr *tcp)
7070
if ((void *)(tcp + 1) > data_end)
7171
return TC_ACT_SHOT;
7272

73-
if (tcp->dest == bpf_htons(9000))
73+
if (tcp->source == bpf_htons(9000))
7474
return throttle_flow(skb);
7575

7676
return TC_ACT_OK;
@@ -99,7 +99,8 @@ static inline int handle_ipv4(struct __sk_buff *skb)
9999
return TC_ACT_OK;
100100
}
101101

102-
SEC("cls_test") int tc_prog(struct __sk_buff *skb)
102+
SEC("tc")
103+
int tc_prog(struct __sk_buff *skb)
103104
{
104105
if (skb->protocol == bpf_htons(ETH_P_IP))
105106
return handle_ipv4(skb);

tools/testing/selftests/bpf/test_tc_edt.sh

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)