Skip to content

Commit 0854a8d

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 b3983da commit 0854a8d

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-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
@@ -11,6 +11,7 @@
1111
#include "mptcp_sock.skel.h"
1212
#include "mptcpify.skel.h"
1313
#include "mptcp_subflow.skel.h"
14+
#include "mptcp_bpf_first.skel.h"
1415

1516
#define NS_TEST "mptcp_ns"
1617
#define ADDR_1 "10.0.1.1"
@@ -45,6 +46,7 @@
4546
#ifndef TCP_CA_NAME_MAX
4647
#define TCP_CA_NAME_MAX 16
4748
#endif
49+
#define MPTCP_SCHED_NAME_MAX 16
4850

4951
static const unsigned int total_bytes = 10 * 1024 * 1024;
5052
static int duration;
@@ -568,6 +570,49 @@ static void test_default(void)
568570
netns_free(netns);
569571
}
570572

573+
static void test_bpf_sched(struct bpf_map *map, char *sched,
574+
bool addr1, bool addr2)
575+
{
576+
char bpf_sched[MPTCP_SCHED_NAME_MAX] = "bpf_";
577+
struct netns_obj *netns;
578+
struct bpf_link *link;
579+
int err;
580+
581+
if (!ASSERT_LT(strlen(bpf_sched) + strlen(sched),
582+
MPTCP_SCHED_NAME_MAX, "Scheduler name too long"))
583+
return;
584+
585+
link = bpf_map__attach_struct_ops(map);
586+
if (!ASSERT_OK_PTR(link, "attach_struct_ops"))
587+
return;
588+
589+
netns = netns_new(NS_TEST, true);
590+
if (!netns)
591+
goto fail;
592+
593+
err = sched_init("subflow", strcat(bpf_sched, sched));
594+
if (!ASSERT_OK(err, "sched_init"))
595+
goto fail;
596+
597+
send_data_and_verify(sched, addr1, addr2);
598+
599+
fail:
600+
netns_free(netns);
601+
bpf_link__destroy(link);
602+
}
603+
604+
static void test_first(void)
605+
{
606+
struct mptcp_bpf_first *skel;
607+
608+
skel = mptcp_bpf_first__open_and_load();
609+
if (!ASSERT_OK_PTR(skel, "open_and_load: first"))
610+
return;
611+
612+
test_bpf_sched(skel->maps.first, "first", WITH_DATA, WITHOUT_DATA);
613+
mptcp_bpf_first__destroy(skel);
614+
}
615+
571616
void test_mptcp(void)
572617
{
573618
if (test__start_subtest("base"))
@@ -578,4 +623,6 @@ void test_mptcp(void)
578623
test_subflow();
579624
if (test__start_subtest("default"))
580625
test_default();
626+
if (test__start_subtest("first"))
627+
test_first();
581628
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,11 @@ mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
3939
return subflow->tcp_sock;
4040
}
4141

42+
/* ksym */
43+
extern struct mptcp_subflow_context *
44+
bpf_mptcp_subflow_ctx(const struct sock *sk) __ksym;
45+
46+
extern void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
47+
bool scheduled) __ksym;
48+
4249
#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)