// SPDX-License-Identifier: GPL-2.0 #include #include #include "bpf_misc.h" SEC(".maps") struct { __uint(type, BPF_MAP_TYPE_SOCKMAP); __uint(max_entries, 1); __type(key, __u32); __type(value, __u64); } nop_map, sock_map; SEC(".maps") struct { __uint(type, BPF_MAP_TYPE_SOCKHASH); __uint(max_entries, 1); __type(key, __u32); __type(value, __u64); } nop_hash, sock_hash; SEC(".maps") struct { __uint(type, BPF_MAP_TYPE_ARRAY); __uint(max_entries, 2); __type(key, int); __type(value, unsigned int); } verdict_map; /* Set by user space */ int redirect_type; int redirect_flags; #define redirect_map(__data) \ _Generic((__data), \ struct __sk_buff * : bpf_sk_redirect_map, \ struct sk_msg_md * : bpf_msg_redirect_map \ )((__data), &sock_map, (__u32){0}, redirect_flags) #define redirect_hash(__data) \ _Generic((__data), \ struct __sk_buff * : bpf_sk_redirect_hash, \ struct sk_msg_md * : bpf_msg_redirect_hash \ )((__data), &sock_hash, &(__u32){0}, redirect_flags) #define DEFINE_PROG(__type, __param) \ SEC("sk_" XSTR(__type)) \ int prog_ ## __type ## _verdict(__param data) \ { \ unsigned int *count; \ int verdict; \ \ if (redirect_type == BPF_MAP_TYPE_SOCKMAP) \ verdict = redirect_map(data); \ else if (redirect_type == BPF_MAP_TYPE_SOCKHASH) \ verdict = redirect_hash(data); \ else \ verdict = redirect_type - __MAX_BPF_MAP_TYPE; \ \ count = bpf_map_lookup_elem(&verdict_map, &verdict); \ if (count) \ (*count)++; \ \ return verdict; \ } DEFINE_PROG(skb, struct __sk_buff *); DEFINE_PROG(msg, struct sk_msg_md *); char _license[] SEC("license") = "GPL";