xref: /linux-tools/ebpf/kernel-samples-bpf/sockconn4lb_kern.c (revision 74ce4ce33d5b8318cee71b38976a25818e666ff3)
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")
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