test_cgrp2_tc_kern.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /* Copyright (c) 2016 Facebook
  2. *
  3. * This program is free software; you can redistribute it and/or
  4. * modify it under the terms of version 2 of the GNU General Public
  5. * License as published by the Free Software Foundation.
  6. */
  7. #define KBUILD_MODNAME "foo"
  8. #include <uapi/linux/if_ether.h>
  9. #include <uapi/linux/in6.h>
  10. #include <uapi/linux/ipv6.h>
  11. #include <uapi/linux/pkt_cls.h>
  12. #include <uapi/linux/bpf.h>
  13. #include <bpf/bpf_helpers.h>
  14. /* copy of 'struct ethhdr' without __packed */
  15. struct eth_hdr {
  16. unsigned char h_dest[ETH_ALEN];
  17. unsigned char h_source[ETH_ALEN];
  18. unsigned short h_proto;
  19. };
  20. #define PIN_GLOBAL_NS 2
  21. struct bpf_elf_map {
  22. __u32 type;
  23. __u32 size_key;
  24. __u32 size_value;
  25. __u32 max_elem;
  26. __u32 flags;
  27. __u32 id;
  28. __u32 pinning;
  29. };
  30. struct bpf_elf_map SEC("maps") test_cgrp2_array_pin = {
  31. .type = BPF_MAP_TYPE_CGROUP_ARRAY,
  32. .size_key = sizeof(uint32_t),
  33. .size_value = sizeof(uint32_t),
  34. .pinning = PIN_GLOBAL_NS,
  35. .max_elem = 1,
  36. };
  37. SEC("filter")
  38. int handle_egress(struct __sk_buff *skb)
  39. {
  40. void *data = (void *)(long)skb->data;
  41. struct eth_hdr *eth = data;
  42. struct ipv6hdr *ip6h = data + sizeof(*eth);
  43. void *data_end = (void *)(long)skb->data_end;
  44. char dont_care_msg[] = "dont care %04x %d\n";
  45. char pass_msg[] = "pass\n";
  46. char reject_msg[] = "reject\n";
  47. /* single length check */
  48. if (data + sizeof(*eth) + sizeof(*ip6h) > data_end)
  49. return TC_ACT_OK;
  50. if (eth->h_proto != htons(ETH_P_IPV6) ||
  51. ip6h->nexthdr != IPPROTO_ICMPV6) {
  52. bpf_trace_printk(dont_care_msg, sizeof(dont_care_msg),
  53. eth->h_proto, ip6h->nexthdr);
  54. return TC_ACT_OK;
  55. } else if (bpf_skb_under_cgroup(skb, &test_cgrp2_array_pin, 0) != 1) {
  56. bpf_trace_printk(pass_msg, sizeof(pass_msg));
  57. return TC_ACT_OK;
  58. } else {
  59. bpf_trace_printk(reject_msg, sizeof(reject_msg));
  60. return TC_ACT_SHOT;
  61. }
  62. }
  63. char _license[] SEC("license") = "GPL";