Simple Proof-Of-Concept test program for BPF_TCP_INFO_NOTIFY (will move this to testing/selftests/net later)
Signed-off-by: Sowmini Varadhan <sowmini.varad...@oracle.com> --- samples/bpf/Makefile | 1 + samples/bpf/tcp_notify_kern.c | 73 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 0 deletions(-) create mode 100644 samples/bpf/tcp_notify_kern.c diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index be0a961..d937bd2 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -152,6 +152,7 @@ always += tcp_bufs_kern.o always += tcp_cong_kern.o always += tcp_iw_kern.o always += tcp_clamp_kern.o +always += tcp_notify_kern.o always += tcp_basertt_kern.o always += tcp_tos_reflect_kern.o always += xdp_redirect_kern.o diff --git a/samples/bpf/tcp_notify_kern.c b/samples/bpf/tcp_notify_kern.c new file mode 100644 index 0000000..bc4efd8 --- /dev/null +++ b/samples/bpf/tcp_notify_kern.c @@ -0,0 +1,73 @@ +/* Sample BPF program to demonstrate how to triger async tcp_info + * notification based on thresholds determeined in the filter. + * The example here will trigger notification if skops->total_retrans > 16 + * + * Use load_sock_ops to load this BPF program. + */ + +#include <uapi/linux/bpf.h> +#include <uapi/linux/if_ether.h> +#include <uapi/linux/if_packet.h> +#include <uapi/linux/ip.h> +#include <linux/socket.h> +#include "bpf_helpers.h" +#include "bpf_endian.h" + +#define DEBUG 0 + +#define bpf_printk(fmt, ...) \ +({ \ + char ____fmt[] = fmt; \ + bpf_trace_printk(____fmt, sizeof(____fmt), \ + ##__VA_ARGS__); \ +}) + +SEC("sockops") +int bpf_tcp_info_notify(struct bpf_sock_ops *skops) +{ + int bufsize = 150000; + int to_init = 10; + int clamp = 100; + int rv = 0; + int op; + + /* For testing purposes, only execute rest of BPF program + * if neither port numberis 5001 (default iperf port) + */ + if (bpf_ntohl(skops->remote_port) != 5001 && + skops->local_port != 5001) { + skops->reply = -1; + return 0; + } + + op = (int) skops->op; + +#ifdef DEBUG + bpf_printk("BPF command: %d\n", op); +#endif + + switch (op) { + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + bpf_sock_ops_cb_flags_set(skops, + (BPF_SOCK_OPS_RETRANS_CB_FLAG| + BPF_SOCK_OPS_RTO_CB_FLAG)); + rv = 1; + break; + case BPF_SOCK_OPS_RETRANS_CB: + case BPF_SOCK_OPS_RTO_CB: + if (skops->total_retrans < 16) + rv = 1; /* skip */ + else + rv = BPF_TCP_INFO_NOTIFY; + break; + default: + rv = -1; + } +#ifdef DEBUG + bpf_printk("Returning %d\n", rv); +#endif + skops->reply = rv; + return 1; +} +char _license[] SEC("license") = "GPL"; -- 1.7.1