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