91 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <string.h>3#include <stdbool.h>4 5#include <linux/bpf.h>6#include <linux/in.h>7#include <linux/in6.h>8#include <sys/socket.h>9 10#include <bpf/bpf_helpers.h>11#include <bpf/bpf_endian.h>12 13#include <bpf_sockopt_helpers.h>14 15char _license[] SEC("license") = "GPL";16 17struct svc_addr {18 __be32 addr;19 __be16 port;20};21 22struct {23 __uint(type, BPF_MAP_TYPE_SK_STORAGE);24 __uint(map_flags, BPF_F_NO_PREALLOC);25 __type(key, int);26 __type(value, struct svc_addr);27} service_mapping SEC(".maps");28 29SEC("cgroup/connect4")30int connect4(struct bpf_sock_addr *ctx)31{32 struct sockaddr_in sa = {};33 struct svc_addr *orig;34 35 /* Force local address to 127.0.0.1:22222. */36 sa.sin_family = AF_INET;37 sa.sin_port = bpf_htons(22222);38 sa.sin_addr.s_addr = bpf_htonl(0x7f000001);39 40 if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)41 return 0;42 43 /* Rewire service 1.2.3.4:60000 to backend 127.0.0.1:60123. */44 if (ctx->user_port == bpf_htons(60000)) {45 orig = bpf_sk_storage_get(&service_mapping, ctx->sk, 0,46 BPF_SK_STORAGE_GET_F_CREATE);47 if (!orig)48 return 0;49 50 orig->addr = ctx->user_ip4;51 orig->port = ctx->user_port;52 53 ctx->user_ip4 = bpf_htonl(0x7f000001);54 ctx->user_port = bpf_htons(60123);55 }56 return 1;57}58 59SEC("cgroup/getsockname4")60int getsockname4(struct bpf_sock_addr *ctx)61{62 if (!get_set_sk_priority(ctx))63 return 1;64 65 /* Expose local server as 1.2.3.4:60000 to client. */66 if (ctx->user_port == bpf_htons(60123)) {67 ctx->user_ip4 = bpf_htonl(0x01020304);68 ctx->user_port = bpf_htons(60000);69 }70 return 1;71}72 73SEC("cgroup/getpeername4")74int getpeername4(struct bpf_sock_addr *ctx)75{76 struct svc_addr *orig;77 78 if (!get_set_sk_priority(ctx))79 return 1;80 81 /* Expose service 1.2.3.4:60000 as peer instead of backend. */82 if (ctx->user_port == bpf_htons(60123)) {83 orig = bpf_sk_storage_get(&service_mapping, ctx->sk, 0, 0);84 if (orig) {85 ctx->user_ip4 = orig->addr;86 ctx->user_port = orig->port;87 }88 }89 return 1;90}91