Skip to content

Commit b964921

Browse files
Geliang Tangmatttbe
authored andcommitted
selftests/bpf: Add bpf_first scheduler & test
This patch implements the simplest MPTCP scheduler, named bpf_first, which always picks the first subflow to send data. It's a sample of MPTCP BPF scheduler implementations. This patch defines MPTCP_SCHED_TEST macro, a template for all scheduler tests. Every scheduler is identified by argument name, and use sysctl to set net.mptcp.scheduler as "bpf_name" to use this sched. Add two veth net devices to simulate the multiple addresses case. Use 'ip mptcp endpoint' command to add the new endpoint ADDR2 to PM netlink. Arguments addr1/add2 means whether the data has been sent on the first/second subflow or not. Send data and check bytes_sent of 'ss' output after it using send_data_and_verify(). Using MPTCP_SCHED_TEST macro to add a new test for this bpf_first scheduler, the arguments "1 0" means data has been only sent on the first subflow ADDR1. Run this test by RUN_MPTCP_TEST macro. Signed-off-by: Geliang Tang <[email protected]> Acked-by: Paolo Abeni <[email protected]> Reviewed-by: Mat Martineau <[email protected]> Reviewed-by: Matthieu Baerts (NGI0) <[email protected]>
1 parent a5be59d commit b964921

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

tools/testing/selftests/bpf/prog_tests/mptcp.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "mptcpify.skel.h"
1313
#include "mptcp_subflow.skel.h"
1414
#include "mptcp_bpf_iters.skel.h"
15+
#include "mptcp_bpf_first.skel.h"
1516

1617
#define NS_TEST "mptcp_ns"
1718
#define ADDR_1 "10.0.1.1"
@@ -49,6 +50,7 @@
4950
#ifndef TCP_CA_NAME_MAX
5051
#define TCP_CA_NAME_MAX 16
5152
#endif
53+
#define MPTCP_SCHED_NAME_MAX 16
5254

5355
static const unsigned int total_bytes = 10 * 1024 * 1024;
5456
static int duration;
@@ -639,6 +641,49 @@ static void test_default(void)
639641
netns_free(netns);
640642
}
641643

644+
static void test_bpf_sched(struct bpf_map *map, char *sched,
645+
bool addr1, bool addr2)
646+
{
647+
char bpf_sched[MPTCP_SCHED_NAME_MAX] = "bpf_";
648+
struct netns_obj *netns;
649+
struct bpf_link *link;
650+
int err;
651+
652+
if (!ASSERT_LT(strlen(bpf_sched) + strlen(sched),
653+
MPTCP_SCHED_NAME_MAX, "Scheduler name too long"))
654+
return;
655+
656+
link = bpf_map__attach_struct_ops(map);
657+
if (!ASSERT_OK_PTR(link, "attach_struct_ops"))
658+
return;
659+
660+
netns = netns_new(NS_TEST, true);
661+
if (!netns)
662+
goto fail;
663+
664+
err = sched_init("subflow", strcat(bpf_sched, sched));
665+
if (!ASSERT_OK(err, "sched_init"))
666+
goto fail;
667+
668+
send_data_and_verify(sched, addr1, addr2);
669+
670+
fail:
671+
netns_free(netns);
672+
bpf_link__destroy(link);
673+
}
674+
675+
static void test_first(void)
676+
{
677+
struct mptcp_bpf_first *skel;
678+
679+
skel = mptcp_bpf_first__open_and_load();
680+
if (!ASSERT_OK_PTR(skel, "open_and_load: first"))
681+
return;
682+
683+
test_bpf_sched(skel->maps.first, "first", WITH_DATA, WITHOUT_DATA);
684+
mptcp_bpf_first__destroy(skel);
685+
}
686+
642687
void test_mptcp(void)
643688
{
644689
if (test__start_subtest("base"))
@@ -651,4 +696,6 @@ void test_mptcp(void)
651696
test_iters_subflow();
652697
if (test__start_subtest("default"))
653698
test_default();
699+
if (test__start_subtest("first"))
700+
test_first();
654701
}

tools/testing/selftests/bpf/progs/mptcp_bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,7 @@ mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
4343
extern struct mptcp_subflow_context *
4444
bpf_mptcp_subflow_ctx(const struct sock *sk) __ksym;
4545

46+
extern void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
47+
bool scheduled) __ksym;
48+
4649
#endif
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2022, SUSE. */
3+
4+
#include "mptcp_bpf.h"
5+
#include <bpf/bpf_tracing.h>
6+
7+
char _license[] SEC("license") = "GPL";
8+
9+
SEC("struct_ops")
10+
void BPF_PROG(mptcp_sched_first_init, struct mptcp_sock *msk)
11+
{
12+
}
13+
14+
SEC("struct_ops")
15+
void BPF_PROG(mptcp_sched_first_release, struct mptcp_sock *msk)
16+
{
17+
}
18+
19+
SEC("struct_ops")
20+
int BPF_PROG(bpf_first_get_send, struct mptcp_sock *msk)
21+
{
22+
struct mptcp_subflow_context *subflow;
23+
24+
subflow = bpf_mptcp_subflow_ctx(msk->first);
25+
if (!subflow)
26+
return -1;
27+
28+
mptcp_subflow_set_scheduled(subflow, true);
29+
return 0;
30+
}
31+
32+
SEC(".struct_ops.link")
33+
struct mptcp_sched_ops first = {
34+
.init = (void *)mptcp_sched_first_init,
35+
.release = (void *)mptcp_sched_first_release,
36+
.get_send = (void *)bpf_first_get_send,
37+
.name = "bpf_first",
38+
};

0 commit comments

Comments
 (0)