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 receive window to 40 packets when using IPv6
0008  * and the first 5.5 bytes of the IPv6 addresses are not the same (in this
0009  * example that means both hosts are not the same datacenter).
0010  *
0011  * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
0012  */
0013 
0014 #include <uapi/linux/bpf.h>
0015 #include <uapi/linux/if_ether.h>
0016 #include <uapi/linux/if_packet.h>
0017 #include <uapi/linux/ip.h>
0018 #include <linux/socket.h>
0019 #include <bpf/bpf_helpers.h>
0020 #include <bpf/bpf_endian.h>
0021 
0022 #define DEBUG 1
0023 
0024 SEC("sockops")
0025 int bpf_rwnd(struct bpf_sock_ops *skops)
0026 {
0027     int rv = -1;
0028     int op;
0029 
0030     /* For testing purposes, only execute rest of BPF program
0031      * if neither port numberis 55601
0032      */
0033     if (bpf_ntohl(skops->remote_port) !=
0034         55601 && skops->local_port != 55601) {
0035         skops->reply = -1;
0036         return 1;
0037     }
0038 
0039     op = (int) skops->op;
0040 
0041 #ifdef DEBUG
0042     bpf_printk("BPF command: %d\n", op);
0043 #endif
0044 
0045     /* Check for RWND_INIT operation and IPv6 addresses */
0046     if (op == BPF_SOCK_OPS_RWND_INIT &&
0047         skops->family == AF_INET6) {
0048 
0049         /* If the first 5.5 bytes of the IPv6 address are not the same
0050          * then both hosts are not in the same datacenter
0051          * so use a larger initial advertized window (40 packets)
0052          */
0053         if (skops->local_ip6[0] != skops->remote_ip6[0] ||
0054             (bpf_ntohl(skops->local_ip6[1]) & 0xfffff000) !=
0055             (bpf_ntohl(skops->remote_ip6[1]) & 0xfffff000))
0056             rv = 40;
0057     }
0058 #ifdef DEBUG
0059     bpf_printk("Returning %d\n", rv);
0060 #endif
0061     skops->reply = rv;
0062     return 1;
0063 }
0064 char _license[] SEC("license") = "GPL";