Linux Audio

Check our new training course

Loading...
v6.13.7
 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 * Sample BPF program to set send and receive buffers to 150KB, sndcwnd clamp
 8 * to 100 packets and SYN and SYN_ACK RTOs to 10ms when both hosts are within
 9 * the same datacenter. For his example, we assume they are within the same
10 * datacenter when the first 5.5 bytes of their IPv6 addresses are the same.
11 *
12 * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
13 */
14
15#include <uapi/linux/bpf.h>
16#include <uapi/linux/if_ether.h>
17#include <uapi/linux/if_packet.h>
18#include <uapi/linux/ip.h>
19#include <linux/socket.h>
20#include <bpf/bpf_helpers.h>
21#include <bpf/bpf_endian.h>
22
23#define DEBUG 1
 
 
 
 
 
 
 
24
25SEC("sockops")
26int bpf_clamp(struct bpf_sock_ops *skops)
27{
28	int bufsize = 150000;
29	int to_init = 10;
30	int clamp = 100;
31	int rv = 0;
32	int op;
33
34	/* For testing purposes, only execute rest of BPF program
35	 * if neither port numberis 55601
36	 */
37	if (bpf_ntohl(skops->remote_port) != 55601 && skops->local_port != 55601) {
38		skops->reply = -1;
39		return 0;
40	}
41
42	op = (int) skops->op;
43
44#ifdef DEBUG
45	bpf_printk("BPF command: %d\n", op);
46#endif
47
48	/* Check that both hosts are within same datacenter. For this example
49	 * it is the case when the first 5.5 bytes of their IPv6 addresses are
50	 * the same.
51	 */
52	if (skops->family == AF_INET6 &&
53	    skops->local_ip6[0] == skops->remote_ip6[0] &&
54	    (bpf_ntohl(skops->local_ip6[1]) & 0xfff00000) ==
55	    (bpf_ntohl(skops->remote_ip6[1]) & 0xfff00000)) {
56		switch (op) {
57		case BPF_SOCK_OPS_TIMEOUT_INIT:
58			rv = to_init;
59			break;
60		case BPF_SOCK_OPS_TCP_CONNECT_CB:
61			/* Set sndbuf and rcvbuf of active connections */
62			rv = bpf_setsockopt(skops, SOL_SOCKET, SO_SNDBUF,
63					    &bufsize, sizeof(bufsize));
64			rv += bpf_setsockopt(skops, SOL_SOCKET,
65					     SO_RCVBUF, &bufsize,
66					     sizeof(bufsize));
67			break;
68		case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
69			rv = bpf_setsockopt(skops, SOL_TCP,
70					    TCP_BPF_SNDCWND_CLAMP,
71					    &clamp, sizeof(clamp));
72			break;
73		case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
74			/* Set sndbuf and rcvbuf of passive connections */
75			rv = bpf_setsockopt(skops, SOL_TCP,
76					    TCP_BPF_SNDCWND_CLAMP,
77					    &clamp, sizeof(clamp));
78			rv += bpf_setsockopt(skops, SOL_SOCKET,
79					     SO_SNDBUF, &bufsize,
80					     sizeof(bufsize));
81			rv += bpf_setsockopt(skops, SOL_SOCKET,
82					     SO_RCVBUF, &bufsize,
83					     sizeof(bufsize));
84			break;
85		default:
86			rv = -1;
87		}
88	} else {
89		rv = -1;
90	}
91#ifdef DEBUG
92	bpf_printk("Returning %d\n", rv);
93#endif
94	skops->reply = rv;
95	return 1;
96}
97char _license[] SEC("license") = "GPL";
v4.17
  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 * Sample BPF program to set send and receive buffers to 150KB, sndcwnd clamp
  8 * to 100 packets and SYN and SYN_ACK RTOs to 10ms when both hosts are within
  9 * the same datacenter. For his example, we assume they are within the same
 10 * datacenter when the first 5.5 bytes of their IPv6 addresses are the same.
 11 *
 12 * Use load_sock_ops to load this BPF program.
 13 */
 14
 15#include <uapi/linux/bpf.h>
 16#include <uapi/linux/if_ether.h>
 17#include <uapi/linux/if_packet.h>
 18#include <uapi/linux/ip.h>
 19#include <linux/socket.h>
 20#include "bpf_helpers.h"
 21#include "bpf_endian.h"
 22
 23#define DEBUG 1
 24
 25#define bpf_printk(fmt, ...)					\
 26({								\
 27	       char ____fmt[] = fmt;				\
 28	       bpf_trace_printk(____fmt, sizeof(____fmt),	\
 29				##__VA_ARGS__);			\
 30})
 31
 32SEC("sockops")
 33int bpf_clamp(struct bpf_sock_ops *skops)
 34{
 35	int bufsize = 150000;
 36	int to_init = 10;
 37	int clamp = 100;
 38	int rv = 0;
 39	int op;
 40
 41	/* For testing purposes, only execute rest of BPF program
 42	 * if neither port numberis 55601
 43	 */
 44	if (bpf_ntohl(skops->remote_port) != 55601 && skops->local_port != 55601) {
 45		skops->reply = -1;
 46		return 0;
 47	}
 48
 49	op = (int) skops->op;
 50
 51#ifdef DEBUG
 52	bpf_printk("BPF command: %d\n", op);
 53#endif
 54
 55	/* Check that both hosts are within same datacenter. For this example
 56	 * it is the case when the first 5.5 bytes of their IPv6 addresses are
 57	 * the same.
 58	 */
 59	if (skops->family == AF_INET6 &&
 60	    skops->local_ip6[0] == skops->remote_ip6[0] &&
 61	    (bpf_ntohl(skops->local_ip6[1]) & 0xfff00000) ==
 62	    (bpf_ntohl(skops->remote_ip6[1]) & 0xfff00000)) {
 63		switch (op) {
 64		case BPF_SOCK_OPS_TIMEOUT_INIT:
 65			rv = to_init;
 66			break;
 67		case BPF_SOCK_OPS_TCP_CONNECT_CB:
 68			/* Set sndbuf and rcvbuf of active connections */
 69			rv = bpf_setsockopt(skops, SOL_SOCKET, SO_SNDBUF,
 70					    &bufsize, sizeof(bufsize));
 71			rv += bpf_setsockopt(skops, SOL_SOCKET,
 72					     SO_RCVBUF, &bufsize,
 73					     sizeof(bufsize));
 74			break;
 75		case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
 76			rv = bpf_setsockopt(skops, SOL_TCP,
 77					    TCP_BPF_SNDCWND_CLAMP,
 78					    &clamp, sizeof(clamp));
 79			break;
 80		case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
 81			/* Set sndbuf and rcvbuf of passive connections */
 82			rv = bpf_setsockopt(skops, SOL_TCP,
 83					    TCP_BPF_SNDCWND_CLAMP,
 84					    &clamp, sizeof(clamp));
 85			rv += bpf_setsockopt(skops, SOL_SOCKET,
 86					     SO_SNDBUF, &bufsize,
 87					     sizeof(bufsize));
 88			rv += bpf_setsockopt(skops, SOL_SOCKET,
 89					     SO_RCVBUF, &bufsize,
 90					     sizeof(bufsize));
 91			break;
 92		default:
 93			rv = -1;
 94		}
 95	} else {
 96		rv = -1;
 97	}
 98#ifdef DEBUG
 99	bpf_printk("Returning %d\n", rv);
100#endif
101	skops->reply = rv;
102	return 1;
103}
104char _license[] SEC("license") = "GPL";