120 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2018 Facebook3 4#include <linux/stddef.h>5#include <linux/bpf.h>6#include <sys/socket.h>7 8#include <bpf/bpf_helpers.h>9#include <bpf/bpf_endian.h>10 11#include <bpf_sockopt_helpers.h>12 13#define SRC_REWRITE_IP6_0 014#define SRC_REWRITE_IP6_1 015#define SRC_REWRITE_IP6_2 016#define SRC_REWRITE_IP6_3 617 18#define DST_REWRITE_IP6_0 019#define DST_REWRITE_IP6_1 020#define DST_REWRITE_IP6_2 021#define DST_REWRITE_IP6_3 122 23#define DST_REWRITE_IP6_V4_MAPPED_0 024#define DST_REWRITE_IP6_V4_MAPPED_1 025#define DST_REWRITE_IP6_V4_MAPPED_2 0x0000FFFF26#define DST_REWRITE_IP6_V4_MAPPED_3 0xc0a80004 // 192.168.0.427 28#define DST_REWRITE_PORT6 666629 30SEC("cgroup/sendmsg6")31int sendmsg_v6_prog(struct bpf_sock_addr *ctx)32{33 if (ctx->type != SOCK_DGRAM)34 return 0;35 36 if (!get_set_sk_priority(ctx))37 return 0;38 39 /* Rewrite source. */40 if (ctx->msg_src_ip6[3] == bpf_htonl(1) ||41 ctx->msg_src_ip6[3] == bpf_htonl(0)) {42 ctx->msg_src_ip6[0] = bpf_htonl(SRC_REWRITE_IP6_0);43 ctx->msg_src_ip6[1] = bpf_htonl(SRC_REWRITE_IP6_1);44 ctx->msg_src_ip6[2] = bpf_htonl(SRC_REWRITE_IP6_2);45 ctx->msg_src_ip6[3] = bpf_htonl(SRC_REWRITE_IP6_3);46 } else {47 /* Unexpected source. Reject sendmsg. */48 return 0;49 }50 51 /* Rewrite destination. */52 if (ctx->user_ip6[0] == bpf_htonl(0xFACEB00C)) {53 ctx->user_ip6[0] = bpf_htonl(DST_REWRITE_IP6_0);54 ctx->user_ip6[1] = bpf_htonl(DST_REWRITE_IP6_1);55 ctx->user_ip6[2] = bpf_htonl(DST_REWRITE_IP6_2);56 ctx->user_ip6[3] = bpf_htonl(DST_REWRITE_IP6_3);57 58 ctx->user_port = bpf_htons(DST_REWRITE_PORT6);59 } else {60 /* Unexpected destination. Reject sendmsg. */61 return 0;62 }63 64 return 1;65}66 67SEC("cgroup/sendmsg6")68int sendmsg_v6_v4mapped_prog(struct bpf_sock_addr *ctx)69{70 /* Rewrite source. */71 ctx->msg_src_ip6[0] = bpf_htonl(SRC_REWRITE_IP6_0);72 ctx->msg_src_ip6[1] = bpf_htonl(SRC_REWRITE_IP6_1);73 ctx->msg_src_ip6[2] = bpf_htonl(SRC_REWRITE_IP6_2);74 ctx->msg_src_ip6[3] = bpf_htonl(SRC_REWRITE_IP6_3);75 76 /* Rewrite destination. */77 ctx->user_ip6[0] = bpf_htonl(DST_REWRITE_IP6_V4_MAPPED_0);78 ctx->user_ip6[1] = bpf_htonl(DST_REWRITE_IP6_V4_MAPPED_1);79 ctx->user_ip6[2] = bpf_htonl(DST_REWRITE_IP6_V4_MAPPED_2);80 ctx->user_ip6[3] = bpf_htonl(DST_REWRITE_IP6_V4_MAPPED_3);81 82 ctx->user_port = bpf_htons(DST_REWRITE_PORT6);83 84 return 1;85}86 87SEC("cgroup/sendmsg6")88int sendmsg_v6_wildcard_prog(struct bpf_sock_addr *ctx)89{90 /* Rewrite source. */91 ctx->msg_src_ip6[0] = bpf_htonl(SRC_REWRITE_IP6_0);92 ctx->msg_src_ip6[1] = bpf_htonl(SRC_REWRITE_IP6_1);93 ctx->msg_src_ip6[2] = bpf_htonl(SRC_REWRITE_IP6_2);94 ctx->msg_src_ip6[3] = bpf_htonl(SRC_REWRITE_IP6_3);95 96 /* Rewrite destination. */97 ctx->user_ip6[0] = bpf_htonl(0);98 ctx->user_ip6[1] = bpf_htonl(0);99 ctx->user_ip6[2] = bpf_htonl(0);100 ctx->user_ip6[3] = bpf_htonl(0);101 102 ctx->user_port = bpf_htons(DST_REWRITE_PORT6);103 104 return 1;105}106 107SEC("cgroup/sendmsg6")108int sendmsg_v6_preserve_dst_prog(struct bpf_sock_addr *ctx)109{110 return 1;111}112 113SEC("cgroup/sendmsg6")114int sendmsg_v6_deny_prog(struct bpf_sock_addr *ctx)115{116 return 0;117}118 119char _license[] SEC("license") = "GPL";120