0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <uapi/linux/bpf.h>
0011 #include <uapi/linux/tcp.h>
0012 #include <uapi/linux/if_ether.h>
0013 #include <uapi/linux/if_packet.h>
0014 #include <uapi/linux/ip.h>
0015 #include <uapi/linux/ipv6.h>
0016 #include <uapi/linux/in.h>
0017 #include <linux/socket.h>
0018 #include <bpf/bpf_helpers.h>
0019 #include <bpf/bpf_endian.h>
0020
0021 #define DEBUG 1
0022
0023 SEC("sockops")
0024 int bpf_basertt(struct bpf_sock_ops *skops)
0025 {
0026 char header[sizeof(struct ipv6hdr)];
0027 struct ipv6hdr *hdr6;
0028 struct iphdr *hdr;
0029 int hdr_size = 0;
0030 int save_syn = 1;
0031 int tos = 0;
0032 int rv = 0;
0033 int op;
0034
0035 op = (int) skops->op;
0036
0037 #ifdef DEBUG
0038 bpf_printk("BPF command: %d\n", op);
0039 #endif
0040 switch (op) {
0041 case BPF_SOCK_OPS_TCP_LISTEN_CB:
0042 rv = bpf_setsockopt(skops, SOL_TCP, TCP_SAVE_SYN,
0043 &save_syn, sizeof(save_syn));
0044 break;
0045 case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
0046 if (skops->family == AF_INET)
0047 hdr_size = sizeof(struct iphdr);
0048 else
0049 hdr_size = sizeof(struct ipv6hdr);
0050 rv = bpf_getsockopt(skops, SOL_TCP, TCP_SAVED_SYN,
0051 header, hdr_size);
0052 if (!rv) {
0053 if (skops->family == AF_INET) {
0054 hdr = (struct iphdr *) header;
0055 tos = hdr->tos;
0056 if (tos != 0)
0057 bpf_setsockopt(skops, SOL_IP, IP_TOS,
0058 &tos, sizeof(tos));
0059 } else {
0060 hdr6 = (struct ipv6hdr *) header;
0061 tos = ((hdr6->priority) << 4 |
0062 (hdr6->flow_lbl[0]) >> 4);
0063 if (tos)
0064 bpf_setsockopt(skops, SOL_IPV6,
0065 IPV6_TCLASS,
0066 &tos, sizeof(tos));
0067 }
0068 rv = 0;
0069 }
0070 break;
0071 default:
0072 rv = -1;
0073 }
0074 #ifdef DEBUG
0075 bpf_printk("Returning %d\n", rv);
0076 #endif
0077 skops->reply = rv;
0078 return 1;
0079 }
0080 char _license[] SEC("license") = "GPL";