aboutsummaryrefslogtreecommitdiffstats
path: root/samples/bpf
diff options
context:
space:
mode:
authorLawrence Brakmo <brakmo@fb.com>2017-06-30 23:02:50 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-01 19:15:14 -0400
commitbb56d4449d8b8de1f22a07f007bb91cb30fcc7cc (patch)
treef267b7163aa103e842705e765a2cf726b0a7f6a4 /samples/bpf
parent91b5b21c7c16899abb37f4a9e4388b4e9aae0b9d (diff)
bpf: Sample BPF program to set congestion control
Sample BPF program that sets congestion control to dctcp when both hosts are within the same datacenter. In this example that is assumed to be when they have the first 5.5 bytes of their IPv6 address are the same. Signed-off-by: Lawrence Brakmo <brakmo@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples/bpf')
-rw-r--r--samples/bpf/Makefile1
-rw-r--r--samples/bpf/tcp_cong_kern.c83
2 files changed, 84 insertions, 0 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 3b300db3d74d..6fdf32dffa92 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -116,6 +116,7 @@ always += cookie_uid_helper_example.o
116always += tcp_synrto_kern.o 116always += tcp_synrto_kern.o
117always += tcp_rwnd_kern.o 117always += tcp_rwnd_kern.o
118always += tcp_bufs_kern.o 118always += tcp_bufs_kern.o
119always += tcp_cong_kern.o
119 120
120HOSTCFLAGS += -I$(objtree)/usr/include 121HOSTCFLAGS += -I$(objtree)/usr/include
121HOSTCFLAGS += -I$(srctree)/tools/lib/ 122HOSTCFLAGS += -I$(srctree)/tools/lib/
diff --git a/samples/bpf/tcp_cong_kern.c b/samples/bpf/tcp_cong_kern.c
new file mode 100644
index 000000000000..dac15bce1fa9
--- /dev/null
+++ b/samples/bpf/tcp_cong_kern.c
@@ -0,0 +1,83 @@
1/* Copyright (c) 2017 Facebook
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
6 *
7 * BPF program to set congestion control to dctcp when both hosts are
8 * in the same datacenter (as deteremined by IPv6 prefix).
9 *
10 * Use load_sock_ops to load this BPF program.
11 */
12
13#include <uapi/linux/bpf.h>
14#include <uapi/linux/tcp.h>
15#include <uapi/linux/if_ether.h>
16#include <uapi/linux/if_packet.h>
17#include <uapi/linux/ip.h>
18#include <linux/socket.h>
19#include "bpf_helpers.h"
20#include "bpf_endian.h"
21
22#define DEBUG 1
23
24#define bpf_printk(fmt, ...) \
25({ \
26 char ____fmt[] = fmt; \
27 bpf_trace_printk(____fmt, sizeof(____fmt), \
28 ##__VA_ARGS__); \
29})
30
31SEC("sockops")
32int bpf_cong(struct bpf_sock_ops *skops)
33{
34 char cong[] = "dctcp";
35 int rv = 0;
36 int op;
37
38 /* For testing purposes, only execute rest of BPF program
39 * if neither port numberis 55601
40 */
41 if (bpf_ntohl(skops->remote_port) != 55601 &&
42 skops->local_port != 55601)
43 return -1;
44
45 op = (int) skops->op;
46
47#ifdef DEBUG
48 bpf_printk("BPF command: %d\n", op);
49#endif
50
51 /* Check if both hosts are in the same datacenter. For this
52 * example they are if the 1st 5.5 bytes in the IPv6 address
53 * are the same.
54 */
55 if (skops->family == AF_INET6 &&
56 skops->local_ip6[0] == skops->remote_ip6[0] &&
57 (bpf_ntohl(skops->local_ip6[1]) & 0xfff00000) ==
58 (bpf_ntohl(skops->remote_ip6[1]) & 0xfff00000)) {
59 switch (op) {
60 case BPF_SOCK_OPS_NEEDS_ECN:
61 rv = 1;
62 break;
63 case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
64 rv = bpf_setsockopt(skops, SOL_TCP, TCP_CONGESTION,
65 cong, sizeof(cong));
66 break;
67 case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
68 rv = bpf_setsockopt(skops, SOL_TCP, TCP_CONGESTION,
69 cong, sizeof(cong));
70 break;
71 default:
72 rv = -1;
73 }
74 } else {
75 rv = -1;
76 }
77#ifdef DEBUG
78 bpf_printk("Returning %d\n", rv);
79#endif
80 skops->reply = rv;
81 return 1;
82}
83char _license[] SEC("license") = "GPL";