root/samples/bpf/tcp_tos_reflect_kern.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SEC

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (c) 2018 Facebook
   4  *
   5  * BPF program to automatically reflect TOS option from received syn packet
   6  *
   7  * Use "bpftool cgroup attach $cg sock_ops $prog" to load this BPF program.
   8  */
   9 
  10 #include <uapi/linux/bpf.h>
  11 #include <uapi/linux/tcp.h>
  12 #include <uapi/linux/if_ether.h>
  13 #include <uapi/linux/if_packet.h>
  14 #include <uapi/linux/ip.h>
  15 #include <uapi/linux/ipv6.h>
  16 #include <uapi/linux/in.h>
  17 #include <linux/socket.h>
  18 #include "bpf_helpers.h"
  19 #include "bpf_endian.h"
  20 
  21 #define DEBUG 1
  22 
  23 SEC("sockops")
  24 int bpf_basertt(struct bpf_sock_ops *skops)
  25 {
  26         char header[sizeof(struct ipv6hdr)];
  27         struct ipv6hdr *hdr6;
  28         struct iphdr *hdr;
  29         int hdr_size = 0;
  30         int save_syn = 1;
  31         int tos = 0;
  32         int rv = 0;
  33         int op;
  34 
  35         op = (int) skops->op;
  36 
  37 #ifdef DEBUG
  38         bpf_printk("BPF command: %d\n", op);
  39 #endif
  40         switch (op) {
  41         case BPF_SOCK_OPS_TCP_LISTEN_CB:
  42                 rv = bpf_setsockopt(skops, SOL_TCP, TCP_SAVE_SYN,
  43                                    &save_syn, sizeof(save_syn));
  44                 break;
  45         case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
  46                 if (skops->family == AF_INET)
  47                         hdr_size = sizeof(struct iphdr);
  48                 else
  49                         hdr_size = sizeof(struct ipv6hdr);
  50                 rv = bpf_getsockopt(skops, SOL_TCP, TCP_SAVED_SYN,
  51                                     header, hdr_size);
  52                 if (!rv) {
  53                         if (skops->family == AF_INET) {
  54                                 hdr = (struct iphdr *) header;
  55                                 tos = hdr->tos;
  56                                 if (tos != 0)
  57                                         bpf_setsockopt(skops, SOL_IP, IP_TOS,
  58                                                        &tos, sizeof(tos));
  59                         } else {
  60                                 hdr6 = (struct ipv6hdr *) header;
  61                                 tos = ((hdr6->priority) << 4 |
  62                                        (hdr6->flow_lbl[0]) >>  4);
  63                                 if (tos)
  64                                         bpf_setsockopt(skops, SOL_IPV6,
  65                                                        IPV6_TCLASS,
  66                                                        &tos, sizeof(tos));
  67                         }
  68                         rv = 0;
  69                 }
  70                 break;
  71         default:
  72                 rv = -1;
  73         }
  74 #ifdef DEBUG
  75         bpf_printk("Returning %d\n", rv);
  76 #endif
  77         skops->reply = rv;
  78         return 1;
  79 }
  80 char _license[] SEC("license") = "GPL";

/* [<][>][^][v][top][bottom][index][help] */