1 #include <uapi/linux/bpf.h>
2 #include <linux/bpf.h>
3 #include <uapi/linux/ip.h>
4 #include <linux/socket.h>
5 #include <bpf/bpf_helpers.h>
6
7 #define MAXN 128
8 typedef unsigned int VNode[MAXN];
9
10 struct {
11 __uint(type, BPF_MAP_TYPE_HASH);
12 __uint(key_size, sizeof(unsigned int));
13 __uint(value_size, sizeof(VNode));
14 __uint(max_entries, 1024);
15 __uint(pinning, LIBBPF_PIN_BY_NAME);
16 } viprules SEC(".maps");
17
18 SEC("cgroup/connect4")
bpf_connectlb(struct bpf_sock_addr * sk)19 int bpf_connectlb(struct bpf_sock_addr *sk)
20 {
21 if (sk->family == AF_INET) {
22 unsigned int ip = sk->user_ip4, n, i;
23 VNode *value;
24
25 value = bpf_map_lookup_elem(&viprules, &ip);
26 if (!value) return 1; // let go
27 n = (*value)[0];
28 if (n == 0) return 0; // vip exist, but no real ip, reject this conn
29 i = 1+(bpf_get_prandom_u32()%n);
30 if (i<MAXN) {
31 ip =(*value)[i];
32 sk->user_ip4 = ip;
33 }
34 }
35 return 1;
36 }
37 char _license[] SEC("license") = "GPL";
38