sockopt_inherit.c (2305B)
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/bpf.h> 3#include <bpf/bpf_helpers.h> 4 5char _license[] SEC("license") = "GPL"; 6 7#define SOL_CUSTOM 0xdeadbeef 8#define CUSTOM_INHERIT1 0 9#define CUSTOM_INHERIT2 1 10#define CUSTOM_LISTENER 2 11 12struct sockopt_inherit { 13 __u8 val; 14}; 15 16struct { 17 __uint(type, BPF_MAP_TYPE_SK_STORAGE); 18 __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE); 19 __type(key, int); 20 __type(value, struct sockopt_inherit); 21} cloned1_map SEC(".maps"); 22 23struct { 24 __uint(type, BPF_MAP_TYPE_SK_STORAGE); 25 __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE); 26 __type(key, int); 27 __type(value, struct sockopt_inherit); 28} cloned2_map SEC(".maps"); 29 30struct { 31 __uint(type, BPF_MAP_TYPE_SK_STORAGE); 32 __uint(map_flags, BPF_F_NO_PREALLOC); 33 __type(key, int); 34 __type(value, struct sockopt_inherit); 35} listener_only_map SEC(".maps"); 36 37static __inline struct sockopt_inherit *get_storage(struct bpf_sockopt *ctx) 38{ 39 if (ctx->optname == CUSTOM_INHERIT1) 40 return bpf_sk_storage_get(&cloned1_map, ctx->sk, 0, 41 BPF_SK_STORAGE_GET_F_CREATE); 42 else if (ctx->optname == CUSTOM_INHERIT2) 43 return bpf_sk_storage_get(&cloned2_map, ctx->sk, 0, 44 BPF_SK_STORAGE_GET_F_CREATE); 45 else 46 return bpf_sk_storage_get(&listener_only_map, ctx->sk, 0, 47 BPF_SK_STORAGE_GET_F_CREATE); 48} 49 50SEC("cgroup/getsockopt") 51int _getsockopt(struct bpf_sockopt *ctx) 52{ 53 __u8 *optval_end = ctx->optval_end; 54 struct sockopt_inherit *storage; 55 __u8 *optval = ctx->optval; 56 57 if (ctx->level != SOL_CUSTOM) 58 return 1; /* only interested in SOL_CUSTOM */ 59 60 if (optval + 1 > optval_end) 61 return 0; /* EPERM, bounds check */ 62 63 storage = get_storage(ctx); 64 if (!storage) 65 return 0; /* EPERM, couldn't get sk storage */ 66 67 ctx->retval = 0; /* Reset system call return value to zero */ 68 69 optval[0] = storage->val; 70 ctx->optlen = 1; 71 72 return 1; 73} 74 75SEC("cgroup/setsockopt") 76int _setsockopt(struct bpf_sockopt *ctx) 77{ 78 __u8 *optval_end = ctx->optval_end; 79 struct sockopt_inherit *storage; 80 __u8 *optval = ctx->optval; 81 82 if (ctx->level != SOL_CUSTOM) 83 return 1; /* only interested in SOL_CUSTOM */ 84 85 if (optval + 1 > optval_end) 86 return 0; /* EPERM, bounds check */ 87 88 storage = get_storage(ctx); 89 if (!storage) 90 return 0; /* EPERM, couldn't get sk storage */ 91 92 storage->val = optval[0]; 93 ctx->optlen = -1; 94 95 return 1; 96}