Back to home page

OSCL-LXR

 
 

    


0001 /* Copyright (c) 2017 Facebook
0002  *
0003  * This program is free software; you can redistribute it and/or
0004  * modify it under the terms of version 2 of the GNU General Public
0005  * License as published by the Free Software Foundation.
0006  *
0007  * BPF program to set initial congestion window and initial receive
0008  * window to 40 packets and send and receive buffers to 1.5MB. This
0009  * would usually be done after doing appropriate checks that indicate
0010  * the hosts are far enough away (i.e. large RTT).
0011  *
0012  * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
0013  */
0014 
0015 #include <uapi/linux/bpf.h>
0016 #include <uapi/linux/if_ether.h>
0017 #include <uapi/linux/if_packet.h>
0018 #include <uapi/linux/ip.h>
0019 #include <linux/socket.h>
0020 #include <bpf/bpf_helpers.h>
0021 #include <bpf/bpf_endian.h>
0022 
0023 #define DEBUG 1
0024 
0025 SEC("sockops")
0026 int bpf_iw(struct bpf_sock_ops *skops)
0027 {
0028     int bufsize = 1500000;
0029     int rwnd_init = 40;
0030     int iw = 40;
0031     int rv = 0;
0032     int op;
0033 
0034     /* For testing purposes, only execute rest of BPF program
0035      * if neither port numberis 55601
0036      */
0037     if (bpf_ntohl(skops->remote_port) != 55601 &&
0038         skops->local_port != 55601) {
0039         skops->reply = -1;
0040         return 1;
0041     }
0042 
0043     op = (int) skops->op;
0044 
0045 #ifdef DEBUG
0046     bpf_printk("BPF command: %d\n", op);
0047 #endif
0048 
0049     /* Usually there would be a check to insure the hosts are far
0050      * from each other so it makes sense to increase buffer sizes
0051      */
0052     switch (op) {
0053     case BPF_SOCK_OPS_RWND_INIT:
0054         rv = rwnd_init;
0055         break;
0056     case BPF_SOCK_OPS_TCP_CONNECT_CB:
0057         /* Set sndbuf and rcvbuf of active connections */
0058         rv = bpf_setsockopt(skops, SOL_SOCKET, SO_SNDBUF, &bufsize,
0059                     sizeof(bufsize));
0060         rv += bpf_setsockopt(skops, SOL_SOCKET, SO_RCVBUF,
0061                      &bufsize, sizeof(bufsize));
0062         break;
0063     case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
0064         rv = bpf_setsockopt(skops, SOL_TCP, TCP_BPF_IW, &iw,
0065                     sizeof(iw));
0066         break;
0067     case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
0068         /* Set sndbuf and rcvbuf of passive connections */
0069         rv = bpf_setsockopt(skops, SOL_SOCKET, SO_SNDBUF, &bufsize,
0070                     sizeof(bufsize));
0071         rv +=  bpf_setsockopt(skops, SOL_SOCKET, SO_RCVBUF,
0072                       &bufsize, sizeof(bufsize));
0073         break;
0074     default:
0075         rv = -1;
0076     }
0077 #ifdef DEBUG
0078     bpf_printk("Returning %d\n", rv);
0079 #endif
0080     skops->reply = rv;
0081     return 1;
0082 }
0083 char _license[] SEC("license") = "GPL";