0001
0002
0003
0004
0005
0006
0007 #define KBUILD_MODNAME "foo"
0008 #include <uapi/linux/if_ether.h>
0009 #include <uapi/linux/in6.h>
0010 #include <uapi/linux/ipv6.h>
0011 #include <uapi/linux/pkt_cls.h>
0012 #include <uapi/linux/bpf.h>
0013 #include <bpf/bpf_helpers.h>
0014
0015
0016 struct eth_hdr {
0017 unsigned char h_dest[ETH_ALEN];
0018 unsigned char h_source[ETH_ALEN];
0019 unsigned short h_proto;
0020 };
0021
0022 #define PIN_GLOBAL_NS 2
0023 struct bpf_elf_map {
0024 __u32 type;
0025 __u32 size_key;
0026 __u32 size_value;
0027 __u32 max_elem;
0028 __u32 flags;
0029 __u32 id;
0030 __u32 pinning;
0031 };
0032
0033 struct bpf_elf_map SEC("maps") test_cgrp2_array_pin = {
0034 .type = BPF_MAP_TYPE_CGROUP_ARRAY,
0035 .size_key = sizeof(uint32_t),
0036 .size_value = sizeof(uint32_t),
0037 .pinning = PIN_GLOBAL_NS,
0038 .max_elem = 1,
0039 };
0040
0041 SEC("filter")
0042 int handle_egress(struct __sk_buff *skb)
0043 {
0044 void *data = (void *)(long)skb->data;
0045 struct eth_hdr *eth = data;
0046 struct ipv6hdr *ip6h = data + sizeof(*eth);
0047 void *data_end = (void *)(long)skb->data_end;
0048 char dont_care_msg[] = "dont care %04x %d\n";
0049 char pass_msg[] = "pass\n";
0050 char reject_msg[] = "reject\n";
0051
0052
0053 if (data + sizeof(*eth) + sizeof(*ip6h) > data_end)
0054 return TC_ACT_OK;
0055
0056 if (eth->h_proto != htons(ETH_P_IPV6) ||
0057 ip6h->nexthdr != IPPROTO_ICMPV6) {
0058 bpf_trace_printk(dont_care_msg, sizeof(dont_care_msg),
0059 eth->h_proto, ip6h->nexthdr);
0060 return TC_ACT_OK;
0061 } else if (bpf_skb_under_cgroup(skb, &test_cgrp2_array_pin, 0) != 1) {
0062 bpf_trace_printk(pass_msg, sizeof(pass_msg));
0063 return TC_ACT_OK;
0064 } else {
0065 bpf_trace_printk(reject_msg, sizeof(reject_msg));
0066 return TC_ACT_SHOT;
0067 }
0068 }
0069
0070 char _license[] SEC("license") = "GPL";