Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  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";