Skip to content

Commit f8f321b

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 5464e28 commit f8f321b

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;
@@ -641,6 +643,46 @@ static void test_default(void)
641643
netns_free(netns);
642644
}
643645

646+
static void test_bpf_sched(struct bpf_object *obj, char *sched,
647+
bool addr1, bool addr2)
648+
{
649+
char bpf_sched[MPTCP_SCHED_NAME_MAX] = "bpf_";
650+
struct netns_obj *netns;
651+
struct bpf_link *link;
652+
struct bpf_map *map;
653+
654+
if (!ASSERT_LT(strlen(bpf_sched) + strlen(sched),
655+
MPTCP_SCHED_NAME_MAX, "Scheduler name too long"))
656+
return;
657+
658+
map = bpf_object__find_map_by_name(obj, sched);
659+
link = bpf_map__attach_struct_ops(map);
660+
if (CHECK(!link, sched, "attach_struct_ops: %d\n", errno))
661+
return;
662+
663+
netns = sched_init("subflow", strcat(bpf_sched, sched));
664+
if (!netns)
665+
goto fail;
666+
667+
send_data_and_verify(sched, addr1, addr2);
668+
669+
fail:
670+
netns_free(netns);
671+
bpf_link__destroy(link);
672+
}
673+
674+
static void test_first(void)
675+
{
676+
struct mptcp_bpf_first *skel;
677+
678+
skel = mptcp_bpf_first__open_and_load();
679+
if (!ASSERT_OK_PTR(skel, "open_and_load: first"))
680+
return;
681+
682+
test_bpf_sched(skel->obj, "first", WITH_DATA, WITHOUT_DATA);
683+
mptcp_bpf_first__destroy(skel);
684+
}
685+
644686
void test_mptcp(void)
645687
{
646688
if (test__start_subtest("base"))
@@ -653,4 +695,6 @@ void test_mptcp(void)
653695
test_iters_subflow();
654696
if (test__start_subtest("default"))
655697
test_default();
698+
if (test__start_subtest("first"))
699+
test_first();
656700
}

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

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

51+
extern void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
52+
bool scheduled) __ksym;
53+
54+
extern struct mptcp_subflow_context *
55+
bpf_mptcp_subflow_ctx_by_pos(const struct mptcp_sched_data *data, unsigned int pos) __ksym;
56+
5157
#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_send, 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_send = (void *)bpf_first_get_send,
32+
.name = "bpf_first",
33+
};

0 commit comments

Comments
 (0)