-
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf:examples: update mptcp_set_mark_kern.c
This example is extented to illustrate more advanced usage of subflows handling : - use bpf_mptcp_sock to identify the parent MPTCP connection. - set tcp cc vegas algorithm only on the first subflow of a MPTCP connection. The mark is still updated to allow further filtering (e.g. at firewall level). The file is also renamed to describe more precisely its new content. This patch also adds a bash script launching all the approriate commands to run the example. Signed-off-by: Nicolas Rybowski <[email protected]>
- Loading branch information
Showing
5 changed files
with
215 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#include <asm/socket.h> // SOL_SOCKET, SO_MARK, ... | ||
#include <linux/tcp.h> // TCP_CONGESTION | ||
#include <linux/bpf.h> | ||
#include <bpf/bpf_helpers.h> | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
#ifndef SOL_TCP | ||
#define SOL_TCP 6 | ||
#endif | ||
|
||
#ifndef TCP_CA_NAME_MAX | ||
#define TCP_CA_NAME_MAX 16 | ||
#endif | ||
|
||
char cc [TCP_CA_NAME_MAX] = "vegas"; | ||
|
||
/* Associate a subflow counter to each token */ | ||
struct bpf_map_def SEC("maps") mptcp_sf = { | ||
.type = BPF_MAP_TYPE_HASH, | ||
.key_size = sizeof(__u32), | ||
.value_size = sizeof(__u32), | ||
.max_entries = 100 | ||
}; | ||
|
||
#define DEBUG 1 | ||
|
||
#ifdef DEBUG | ||
char fmt1[] = "Mark <%u> : return code <%i>\n"; | ||
char fmt2[] = "Failed to get bpf_sock\n"; | ||
char fmt3[] = "Failed to get bpf_mptcp_sock\n"; | ||
char fmt4[] = "Failed to update sockopt\n"; | ||
|
||
#define pr_debug(msg, ...) bpf_trace_printk(msg, sizeof(msg), ##__VA_ARGS__); | ||
|
||
#else | ||
|
||
#define pr_debug(msg, ...) | ||
|
||
#endif | ||
|
||
SEC("sockops") | ||
int mark_mptcp_sf(struct bpf_sock_ops *skops) | ||
{ | ||
__u32 init = 1, key, mark, *cnt; | ||
int err; | ||
|
||
if (skops->op != BPF_SOCK_OPS_TCP_CONNECT_CB) | ||
goto out; | ||
|
||
struct bpf_sock *sk = skops->sk; | ||
if (!sk) { | ||
pr_debug(fmt2); | ||
goto out; | ||
} | ||
|
||
struct bpf_mptcp_sock *msk = bpf_mptcp_sock(sk); | ||
if (!msk) { | ||
pr_debug(fmt3); | ||
goto out; | ||
} | ||
|
||
key = msk->token; | ||
cnt = bpf_map_lookup_elem(&mptcp_sf, &key); | ||
|
||
if (cnt) { | ||
/* A new subflow is added to an existing MPTCP connection */ | ||
__sync_fetch_and_add(cnt, 1); | ||
mark = *cnt; | ||
} else { | ||
/* A new MPTCP connection is just initiated and this is its primary | ||
* subflow | ||
*/ | ||
bpf_map_update_elem(&mptcp_sf, &key, &init, BPF_ANY); | ||
mark = init; | ||
} | ||
|
||
/* Set the mark of the subflow's socket to its apparition order */ | ||
err = bpf_setsockopt(skops, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)); | ||
pr_debug(fmt1, mark, err); | ||
|
||
if (mark == 1) | ||
err = err ?: bpf_setsockopt(skops, SOL_TCP, TCP_CONGESTION, cc, | ||
TCP_CA_NAME_MAX); | ||
|
||
if (err < 0) | ||
pr_debug(fmt4); | ||
|
||
out: | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#! /bin/bash | ||
|
||
TRACEFS="/sys/kernel/debug/tracing" | ||
BPF_OBJECT="mptcp_set_sf_sockopt_kern.o" | ||
USE_MPTCP="mptcp-tools/use_mptcp/use_mptcp.sh" | ||
NS_EXEC="ip netns exec" | ||
NS_CLIENT_EXEC="${NS_EXEC} ns_client" | ||
CLIENT_PROCS="/tmp/cgroup2/client/cgroup.procs" | ||
TCPDUMP_DUMP="/tmp/tcpdump.log" | ||
|
||
info () { | ||
echo -e "\n[INFO] ${*}" | ||
} | ||
|
||
show () { | ||
while [ 1 ] | ||
do | ||
${NS_EXEC} $1 ss -bit --cgroup | ||
sleep 0.25 | ||
done | ||
} | ||
|
||
# clean previous trace | ||
echo > "${TRACEFS}/trace" | ||
|
||
# setup testing env and load BPF program on client side | ||
./env.sh --clean -c -m -B "${BPF_OBJECT}" | ||
|
||
# wait for end of setup | ||
sleep 5 | ||
|
||
# load output filtering rules on client side | ||
${NS_CLIENT_EXEC} nft -f client.rules | ||
|
||
# show server socket status | ||
show ns_server & | ||
SPID="${!}" | ||
|
||
# register current process to the client cgroup | ||
echo $$ >> "${CLIENT_PROCS}" | ||
|
||
# show client socket status | ||
show ns_client & | ||
CPID="${!}" | ||
|
||
# launch tcpdump on client side | ||
${NS_CLIENT_EXEC} tcpdump -Uni any -w "${TCPDUMP_DUMP}" tcp & | ||
TPID="${!}" | ||
|
||
# wait for tcpdump launch | ||
sleep 5 | ||
|
||
# querying server | ||
${NS_CLIENT_EXEC} "${USE_MPTCP}" curl 10.0.1.2:8000 -o /dev/null &> /dev/null | ||
|
||
# unregister current process from the client cgroup | ||
echo 0 >> "${CLIENT_PROCS}" | ||
|
||
# kill ss wrappers and tcpdump | ||
kill "${CPID}" "${SPID}" &> /dev/null | ||
sleep 5 | ||
kill "${TPID}" &> /dev/null | ||
|
||
info "Client-side tcpdump log :" | ||
tcpdump -r "${TCPDUMP_DUMP}" | ||
|
||
# show output filtering result | ||
info "Client-side output filters :" | ||
${NS_CLIENT_EXEC} nft list ruleset | ||
|
||
# show current trace | ||
info "Client-side bpf trace :" | ||
cat "${TRACEFS}/trace" |