0001
0002 #include <linux/bpf.h>
0003 #include <bpf/bpf_helpers.h>
0004
0005 char _license[] SEC("license") = "GPL";
0006
0007 #define SOL_CUSTOM 0xdeadbeef
0008 #define CUSTOM_INHERIT1 0
0009 #define CUSTOM_INHERIT2 1
0010 #define CUSTOM_LISTENER 2
0011
0012 struct sockopt_inherit {
0013 __u8 val;
0014 };
0015
0016 struct {
0017 __uint(type, BPF_MAP_TYPE_SK_STORAGE);
0018 __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE);
0019 __type(key, int);
0020 __type(value, struct sockopt_inherit);
0021 } cloned1_map SEC(".maps");
0022
0023 struct {
0024 __uint(type, BPF_MAP_TYPE_SK_STORAGE);
0025 __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE);
0026 __type(key, int);
0027 __type(value, struct sockopt_inherit);
0028 } cloned2_map SEC(".maps");
0029
0030 struct {
0031 __uint(type, BPF_MAP_TYPE_SK_STORAGE);
0032 __uint(map_flags, BPF_F_NO_PREALLOC);
0033 __type(key, int);
0034 __type(value, struct sockopt_inherit);
0035 } listener_only_map SEC(".maps");
0036
0037 static __inline struct sockopt_inherit *get_storage(struct bpf_sockopt *ctx)
0038 {
0039 if (ctx->optname == CUSTOM_INHERIT1)
0040 return bpf_sk_storage_get(&cloned1_map, ctx->sk, 0,
0041 BPF_SK_STORAGE_GET_F_CREATE);
0042 else if (ctx->optname == CUSTOM_INHERIT2)
0043 return bpf_sk_storage_get(&cloned2_map, ctx->sk, 0,
0044 BPF_SK_STORAGE_GET_F_CREATE);
0045 else
0046 return bpf_sk_storage_get(&listener_only_map, ctx->sk, 0,
0047 BPF_SK_STORAGE_GET_F_CREATE);
0048 }
0049
0050 SEC("cgroup/getsockopt")
0051 int _getsockopt(struct bpf_sockopt *ctx)
0052 {
0053 __u8 *optval_end = ctx->optval_end;
0054 struct sockopt_inherit *storage;
0055 __u8 *optval = ctx->optval;
0056
0057 if (ctx->level != SOL_CUSTOM)
0058 return 1;
0059
0060 if (optval + 1 > optval_end)
0061 return 0;
0062
0063 storage = get_storage(ctx);
0064 if (!storage)
0065 return 0;
0066
0067 ctx->retval = 0;
0068
0069 optval[0] = storage->val;
0070 ctx->optlen = 1;
0071
0072 return 1;
0073 }
0074
0075 SEC("cgroup/setsockopt")
0076 int _setsockopt(struct bpf_sockopt *ctx)
0077 {
0078 __u8 *optval_end = ctx->optval_end;
0079 struct sockopt_inherit *storage;
0080 __u8 *optval = ctx->optval;
0081
0082 if (ctx->level != SOL_CUSTOM)
0083 return 1;
0084
0085 if (optval + 1 > optval_end)
0086 return 0;
0087
0088 storage = get_storage(ctx);
0089 if (!storage)
0090 return 0;
0091
0092 storage->val = optval[0];
0093 ctx->optlen = -1;
0094
0095 return 1;
0096 }