Skip to content

Commit 0f761c4

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 fba27c2 commit 0f761c4

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

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

Lines changed: 44 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;
@@ -659,6 +661,46 @@ static void test_default(void)
659661
cleanup_netns(nstoken);
660662
}
661663

664+
static void test_bpf_sched(struct bpf_object *obj, char *sched,
665+
bool addr1, bool addr2)
666+
{
667+
char bpf_sched[MPTCP_SCHED_NAME_MAX] = "bpf_";
668+
struct nstoken *nstoken;
669+
struct bpf_link *link;
670+
struct bpf_map *map;
671+
672+
if (!ASSERT_LT(strlen(bpf_sched) + strlen(sched),
673+
MPTCP_SCHED_NAME_MAX, "Scheduler name too long"))
674+
return;
675+
676+
map = bpf_object__find_map_by_name(obj, sched);
677+
link = bpf_map__attach_struct_ops(map);
678+
if (CHECK(!link, sched, "attach_struct_ops: %d\n", errno))
679+
return;
680+
681+
nstoken = sched_init("subflow", strcat(bpf_sched, sched));
682+
if (!nstoken)
683+
goto fail;
684+
685+
send_data_and_verify(sched, addr1, addr2);
686+
687+
fail:
688+
cleanup_netns(nstoken);
689+
bpf_link__destroy(link);
690+
}
691+
692+
static void test_first(void)
693+
{
694+
struct mptcp_bpf_first *skel;
695+
696+
skel = mptcp_bpf_first__open_and_load();
697+
if (!ASSERT_OK_PTR(skel, "open_and_load: first"))
698+
return;
699+
700+
test_bpf_sched(skel->obj, "first", WITH_DATA, WITHOUT_DATA);
701+
mptcp_bpf_first__destroy(skel);
702+
}
703+
662704
void test_mptcp(void)
663705
{
664706
if (test__start_subtest("base"))
@@ -671,4 +713,6 @@ void test_mptcp(void)
671713
test_iters_subflow();
672714
if (test__start_subtest("default"))
673715
test_default();
716+
if (test__start_subtest("first"))
717+
test_first();
674718
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,10 @@ bpf_mptcp_subflow_ctx(const struct sock *sk) __ksym;
4949
extern struct sock *
5050
bpf_mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow) __ksym;
5151

52+
extern void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
53+
bool scheduled) __ksym;
54+
55+
extern struct mptcp_subflow_context *
56+
bpf_mptcp_subflow_ctx_by_pos(const struct mptcp_sched_data *data, unsigned int pos) __ksym;
57+
5258
#endif
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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_subflow, struct mptcp_sock *msk,
21+
struct mptcp_sched_data *data)
22+
{
23+
mptcp_subflow_set_scheduled(bpf_mptcp_subflow_ctx_by_pos(data, 0), true);
24+
return 0;
25+
}
26+
27+
SEC(".struct_ops")
28+
struct mptcp_sched_ops first = {
29+
.init = (void *)mptcp_sched_first_init,
30+
.release = (void *)mptcp_sched_first_release,
31+
.get_subflow = (void *)bpf_first_get_subflow,
32+
.name = "bpf_first",
33+
};

0 commit comments

Comments
 (0)