1 // SPDX-License-Identifier: GPL-2.0
8 #include <sys/socket.h>
10 #include <bpf/bpf_helpers.h>
11 #include <bpf/bpf_endian.h>
13 char _license
[] SEC("license") = "GPL";
14 int _version
SEC("version") = 1;
22 __uint(type
, BPF_MAP_TYPE_SK_STORAGE
);
23 __uint(map_flags
, BPF_F_NO_PREALLOC
);
25 __type(value
, struct svc_addr
);
26 } service_mapping
SEC(".maps");
28 SEC("cgroup/connect4")
29 int connect4(struct bpf_sock_addr
*ctx
)
31 struct sockaddr_in sa
= {};
32 struct svc_addr
*orig
;
34 /* Force local address to 127.0.0.1:22222. */
35 sa
.sin_family
= AF_INET
;
36 sa
.sin_port
= bpf_htons(22222);
37 sa
.sin_addr
.s_addr
= bpf_htonl(0x7f000001);
39 if (bpf_bind(ctx
, (struct sockaddr
*)&sa
, sizeof(sa
)) != 0)
42 /* Rewire service 1.2.3.4:60000 to backend 127.0.0.1:60123. */
43 if (ctx
->user_port
== bpf_htons(60000)) {
44 orig
= bpf_sk_storage_get(&service_mapping
, ctx
->sk
, 0,
45 BPF_SK_STORAGE_GET_F_CREATE
);
49 orig
->addr
= ctx
->user_ip4
;
50 orig
->port
= ctx
->user_port
;
52 ctx
->user_ip4
= bpf_htonl(0x7f000001);
53 ctx
->user_port
= bpf_htons(60123);
58 SEC("cgroup/getsockname4")
59 int getsockname4(struct bpf_sock_addr
*ctx
)
61 /* Expose local server as 1.2.3.4:60000 to client. */
62 if (ctx
->user_port
== bpf_htons(60123)) {
63 ctx
->user_ip4
= bpf_htonl(0x01020304);
64 ctx
->user_port
= bpf_htons(60000);
69 SEC("cgroup/getpeername4")
70 int getpeername4(struct bpf_sock_addr
*ctx
)
72 struct svc_addr
*orig
;
74 /* Expose service 1.2.3.4:60000 as peer instead of backend. */
75 if (ctx
->user_port
== bpf_htons(60123)) {
76 orig
= bpf_sk_storage_get(&service_mapping
, ctx
->sk
, 0, 0);
78 ctx
->user_ip4
= orig
->addr
;
79 ctx
->user_port
= orig
->port
;