Skip to content

Commit c890063

Browse files
Lawrence Brakmodavem330
authored andcommitted
bpf: sample BPF_SOCKET_OPS_BASE_RTT program
Sample socket_ops BPF program to test the BPF helper function bpf_getsocketops and the new socket_ops op BPF_SOCKET_OPS_BASE_RTT. The program provides a base RTT of 80us when the calling flow is within a DC (as determined by the IPV6 prefix) and the congestion algorithm is "nv". Signed-off-by: Lawrence Brakmo <brakmo@fb.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Acked_by: Alexei Starovoitov <ast@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 85cce21 commit c890063

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

samples/bpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ always += tcp_bufs_kern.o
129129
always += tcp_cong_kern.o
130130
always += tcp_iw_kern.o
131131
always += tcp_clamp_kern.o
132+
always += tcp_basertt_kern.o
132133
always += xdp_redirect_kern.o
133134
always += xdp_redirect_map_kern.o
134135
always += xdp_redirect_cpu_kern.o

samples/bpf/tcp_basertt_kern.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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 base_rtt to 80us when host is running TCP-NV and
8+
* both hosts are in the same datacenter (as determined 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+
31+
SEC("sockops")
32+
int bpf_basertt(struct bpf_sock_ops *skops)
33+
{
34+
char cong[20];
35+
char nv[] = "nv";
36+
int rv = 0, n;
37+
int op;
38+
39+
op = (int) skops->op;
40+
41+
#ifdef DEBUG
42+
bpf_printk("BPF command: %d\n", op);
43+
#endif
44+
45+
/* Check if both hosts are in the same datacenter. For this
46+
* example they are if the 1st 5.5 bytes in the IPv6 address
47+
* are the same.
48+
*/
49+
if (skops->family == AF_INET6 &&
50+
skops->local_ip6[0] == skops->remote_ip6[0] &&
51+
(bpf_ntohl(skops->local_ip6[1]) & 0xfff00000) ==
52+
(bpf_ntohl(skops->remote_ip6[1]) & 0xfff00000)) {
53+
switch (op) {
54+
case BPF_SOCK_OPS_BASE_RTT:
55+
n = bpf_getsockopt(skops, SOL_TCP, TCP_CONGESTION,
56+
cong, sizeof(cong));
57+
if (!n && !__builtin_memcmp(cong, nv, sizeof(nv)+1)) {
58+
/* Set base_rtt to 80us */
59+
rv = 80;
60+
} else if (n) {
61+
rv = n;
62+
} else {
63+
rv = -1;
64+
}
65+
break;
66+
default:
67+
rv = -1;
68+
}
69+
} else {
70+
rv = -1;
71+
}
72+
#ifdef DEBUG
73+
bpf_printk("Returning %d\n", rv);
74+
#endif
75+
skops->reply = rv;
76+
return 1;
77+
}
78+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)