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 "vmlinux.h" |
9 | #include "net_shared.h" |
10 | #include <bpf/bpf_helpers.h> |
11 | |
12 | /* copy of 'struct ethhdr' without __packed */ |
13 | struct eth_hdr { |
14 | unsigned char h_dest[ETH_ALEN]; |
15 | unsigned char h_source[ETH_ALEN]; |
16 | unsigned short h_proto; |
17 | }; |
18 | |
19 | struct { |
20 | __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); |
21 | __type(key, u32); |
22 | __type(value, u32); |
23 | __uint(pinning, LIBBPF_PIN_BY_NAME); |
24 | __uint(max_entries, 1); |
25 | } test_cgrp2_array_pin SEC(".maps" ); |
26 | |
27 | SEC("filter" ) |
28 | int handle_egress(struct __sk_buff *skb) |
29 | { |
30 | void *data = (void *)(long)skb->data; |
31 | struct eth_hdr *eth = data; |
32 | struct ipv6hdr *ip6h = data + sizeof(*eth); |
33 | void *data_end = (void *)(long)skb->data_end; |
34 | char dont_care_msg[] = "dont care %04x %d\n" ; |
35 | char pass_msg[] = "pass\n" ; |
36 | char reject_msg[] = "reject\n" ; |
37 | |
38 | /* single length check */ |
39 | if (data + sizeof(*eth) + sizeof(*ip6h) > data_end) |
40 | return TC_ACT_OK; |
41 | |
42 | if (eth->h_proto != bpf_htons(ETH_P_IPV6) || |
43 | ip6h->nexthdr != IPPROTO_ICMPV6) { |
44 | bpf_trace_printk(dont_care_msg, sizeof(dont_care_msg), |
45 | eth->h_proto, ip6h->nexthdr); |
46 | return TC_ACT_OK; |
47 | } else if (bpf_skb_under_cgroup(skb, &test_cgrp2_array_pin, 0) != 1) { |
48 | bpf_trace_printk(pass_msg, sizeof(pass_msg)); |
49 | return TC_ACT_OK; |
50 | } else { |
51 | bpf_trace_printk(reject_msg, sizeof(reject_msg)); |
52 | return TC_ACT_SHOT; |
53 | } |
54 | } |
55 | |
56 | char _license[] SEC("license" ) = "GPL" ; |
57 | |