1*0869e507SAlexei Starovoitov // SPDX-License-Identifier: GPL-2.0
2*0869e507SAlexei Starovoitov /* Copyright (c) 2021 Facebook */
3*0869e507SAlexei Starovoitov #include <linux/types.h>
4*0869e507SAlexei Starovoitov #include <bpf/bpf_helpers.h>
5*0869e507SAlexei Starovoitov #include <linux/bpf.h>
6*0869e507SAlexei Starovoitov #include <stdint.h>
7*0869e507SAlexei Starovoitov 
8*0869e507SAlexei Starovoitov #define TWFW_MAX_TIERS (64)
9*0869e507SAlexei Starovoitov /*
10*0869e507SAlexei Starovoitov  * load is successful
11*0869e507SAlexei Starovoitov  * #define TWFW_MAX_TIERS (64u)$
12*0869e507SAlexei Starovoitov  */
13*0869e507SAlexei Starovoitov 
14*0869e507SAlexei Starovoitov struct twfw_tier_value {
15*0869e507SAlexei Starovoitov 	unsigned long mask[1];
16*0869e507SAlexei Starovoitov };
17*0869e507SAlexei Starovoitov 
18*0869e507SAlexei Starovoitov struct rule {
19*0869e507SAlexei Starovoitov 	uint8_t seqnum;
20*0869e507SAlexei Starovoitov };
21*0869e507SAlexei Starovoitov 
22*0869e507SAlexei Starovoitov struct rules_map {
23*0869e507SAlexei Starovoitov 	__uint(type, BPF_MAP_TYPE_ARRAY);
24*0869e507SAlexei Starovoitov 	__type(key, __u32);
25*0869e507SAlexei Starovoitov 	__type(value, struct rule);
26*0869e507SAlexei Starovoitov 	__uint(max_entries, 1);
27*0869e507SAlexei Starovoitov };
28*0869e507SAlexei Starovoitov 
29*0869e507SAlexei Starovoitov struct tiers_map {
30*0869e507SAlexei Starovoitov 	__uint(type, BPF_MAP_TYPE_ARRAY);
31*0869e507SAlexei Starovoitov 	__type(key, __u32);
32*0869e507SAlexei Starovoitov 	__type(value, struct twfw_tier_value);
33*0869e507SAlexei Starovoitov 	__uint(max_entries, 1);
34*0869e507SAlexei Starovoitov };
35*0869e507SAlexei Starovoitov 
36*0869e507SAlexei Starovoitov struct rules_map rules SEC(".maps");
37*0869e507SAlexei Starovoitov struct tiers_map tiers SEC(".maps");
38*0869e507SAlexei Starovoitov 
39*0869e507SAlexei Starovoitov SEC("cgroup_skb/ingress")
twfw_verifier(struct __sk_buff * skb)40*0869e507SAlexei Starovoitov int twfw_verifier(struct __sk_buff* skb)
41*0869e507SAlexei Starovoitov {
42*0869e507SAlexei Starovoitov 	const uint32_t key = 0;
43*0869e507SAlexei Starovoitov 	const struct twfw_tier_value* tier = bpf_map_lookup_elem(&tiers, &key);
44*0869e507SAlexei Starovoitov 	if (!tier)
45*0869e507SAlexei Starovoitov 		return 1;
46*0869e507SAlexei Starovoitov 
47*0869e507SAlexei Starovoitov 	struct rule* rule = bpf_map_lookup_elem(&rules, &key);
48*0869e507SAlexei Starovoitov 	if (!rule)
49*0869e507SAlexei Starovoitov 		return 1;
50*0869e507SAlexei Starovoitov 
51*0869e507SAlexei Starovoitov 	if (rule && rule->seqnum < TWFW_MAX_TIERS) {
52*0869e507SAlexei Starovoitov 		/* rule->seqnum / 64 should always be 0 */
53*0869e507SAlexei Starovoitov 		unsigned long mask = tier->mask[rule->seqnum / 64];
54*0869e507SAlexei Starovoitov 		if (mask)
55*0869e507SAlexei Starovoitov 			return 0;
56*0869e507SAlexei Starovoitov 	}
57*0869e507SAlexei Starovoitov 	return 1;
58*0869e507SAlexei Starovoitov }
59