tcp_tos_reflect_kern.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #include <uapi/linux/bpf.h>
  10. #include <uapi/linux/tcp.h>
  11. #include <uapi/linux/if_ether.h>
  12. #include <uapi/linux/if_packet.h>
  13. #include <uapi/linux/ip.h>
  14. #include <uapi/linux/ipv6.h>
  15. #include <uapi/linux/in.h>
  16. #include <linux/socket.h>
  17. #include <bpf/bpf_helpers.h>
  18. #include <bpf/bpf_endian.h>
  19. #define DEBUG 1
  20. SEC("sockops")
  21. int bpf_basertt(struct bpf_sock_ops *skops)
  22. {
  23. char header[sizeof(struct ipv6hdr)];
  24. struct ipv6hdr *hdr6;
  25. struct iphdr *hdr;
  26. int hdr_size = 0;
  27. int save_syn = 1;
  28. int tos = 0;
  29. int rv = 0;
  30. int op;
  31. op = (int) skops->op;
  32. #ifdef DEBUG
  33. bpf_printk("BPF command: %d\n", op);
  34. #endif
  35. switch (op) {
  36. case BPF_SOCK_OPS_TCP_LISTEN_CB:
  37. rv = bpf_setsockopt(skops, SOL_TCP, TCP_SAVE_SYN,
  38. &save_syn, sizeof(save_syn));
  39. break;
  40. case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
  41. if (skops->family == AF_INET)
  42. hdr_size = sizeof(struct iphdr);
  43. else
  44. hdr_size = sizeof(struct ipv6hdr);
  45. rv = bpf_getsockopt(skops, SOL_TCP, TCP_SAVED_SYN,
  46. header, hdr_size);
  47. if (!rv) {
  48. if (skops->family == AF_INET) {
  49. hdr = (struct iphdr *) header;
  50. tos = hdr->tos;
  51. if (tos != 0)
  52. bpf_setsockopt(skops, SOL_IP, IP_TOS,
  53. &tos, sizeof(tos));
  54. } else {
  55. hdr6 = (struct ipv6hdr *) header;
  56. tos = ((hdr6->priority) << 4 |
  57. (hdr6->flow_lbl[0]) >> 4);
  58. if (tos)
  59. bpf_setsockopt(skops, SOL_IPV6,
  60. IPV6_TCLASS,
  61. &tos, sizeof(tos));
  62. }
  63. rv = 0;
  64. }
  65. break;
  66. default:
  67. rv = -1;
  68. }
  69. #ifdef DEBUG
  70. bpf_printk("Returning %d\n", rv);
  71. #endif
  72. skops->reply = rv;
  73. return 1;
  74. }
  75. char _license[] SEC("license") = "GPL";