|
| 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"; |
0 commit comments