1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/bpf.h> 4 #include <bpf/bpf_helpers.h> 5 #include "bpf_misc.h" 6 7 SEC(".maps") struct { 8 __uint(type, BPF_MAP_TYPE_SOCKMAP); 9 __uint(max_entries, 1); 10 __type(key, __u32); 11 __type(value, __u64); 12 } nop_map, sock_map; 13 14 SEC(".maps") struct { 15 __uint(type, BPF_MAP_TYPE_SOCKHASH); 16 __uint(max_entries, 1); 17 __type(key, __u32); 18 __type(value, __u64); 19 } nop_hash, sock_hash; 20 21 SEC(".maps") struct { 22 __uint(type, BPF_MAP_TYPE_ARRAY); 23 __uint(max_entries, 2); 24 __type(key, int); 25 __type(value, unsigned int); 26 } verdict_map; 27 28 /* Set by user space */ 29 int redirect_type; 30 int redirect_flags; 31 32 #define redirect_map(__data) \ 33 _Generic((__data), \ 34 struct __sk_buff * : bpf_sk_redirect_map, \ 35 struct sk_msg_md * : bpf_msg_redirect_map \ 36 )((__data), &sock_map, (__u32){0}, redirect_flags) 37 38 #define redirect_hash(__data) \ 39 _Generic((__data), \ 40 struct __sk_buff * : bpf_sk_redirect_hash, \ 41 struct sk_msg_md * : bpf_msg_redirect_hash \ 42 )((__data), &sock_hash, &(__u32){0}, redirect_flags) 43 44 #define DEFINE_PROG(__type, __param) \ 45 SEC("sk_" XSTR(__type)) \ 46 int prog_ ## __type ## _verdict(__param data) \ 47 { \ 48 unsigned int *count; \ 49 int verdict; \ 50 \ 51 if (redirect_type == BPF_MAP_TYPE_SOCKMAP) \ 52 verdict = redirect_map(data); \ 53 else if (redirect_type == BPF_MAP_TYPE_SOCKHASH) \ 54 verdict = redirect_hash(data); \ 55 else \ 56 verdict = redirect_type - __MAX_BPF_MAP_TYPE; \ 57 \ 58 count = bpf_map_lookup_elem(&verdict_map, &verdict); \ 59 if (count) \ 60 (*count)++; \ 61 \ 62 return verdict; \ 63 } 64 65 DEFINE_PROG(skb, struct __sk_buff *); 66 DEFINE_PROG(msg, struct sk_msg_md *); 67 68 char _license[] SEC("license") = "GPL"; 69