0001
0002
0003 #include <sys/socket.h>
0004 #include <linux/bpf.h>
0005 #include <bpf/bpf_helpers.h>
0006
0007 int invocations = 0, in_use = 0;
0008
0009 struct {
0010 __uint(type, BPF_MAP_TYPE_SK_STORAGE);
0011 __uint(map_flags, BPF_F_NO_PREALLOC);
0012 __type(key, int);
0013 __type(value, int);
0014 } sk_map SEC(".maps");
0015
0016 SEC("cgroup/sock_create")
0017 int sock(struct bpf_sock *ctx)
0018 {
0019 int *sk_storage;
0020 __u32 key;
0021
0022 if (ctx->type != SOCK_DGRAM)
0023 return 1;
0024
0025 sk_storage = bpf_sk_storage_get(&sk_map, ctx, 0,
0026 BPF_SK_STORAGE_GET_F_CREATE);
0027 if (!sk_storage)
0028 return 0;
0029 *sk_storage = 0xdeadbeef;
0030
0031 __sync_fetch_and_add(&invocations, 1);
0032
0033 if (in_use > 0) {
0034
0035
0036
0037
0038 return 0;
0039 }
0040
0041 __sync_fetch_and_add(&in_use, 1);
0042 return 1;
0043 }
0044
0045 SEC("cgroup/sock_release")
0046 int sock_release(struct bpf_sock *ctx)
0047 {
0048 int *sk_storage;
0049 __u32 key;
0050
0051 if (ctx->type != SOCK_DGRAM)
0052 return 1;
0053
0054 sk_storage = bpf_sk_storage_get(&sk_map, ctx, 0, 0);
0055 if (!sk_storage || *sk_storage != 0xdeadbeef)
0056 return 0;
0057
0058 __sync_fetch_and_add(&invocations, 1);
0059 __sync_fetch_and_add(&in_use, -1);
0060 return 1;
0061 }