#include "bpf_tracing_net.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <errno.h>
#include "err.h"
extern int tcp_memory_per_cpu_fw_alloc __ksym;
extern int udp_memory_per_cpu_fw_alloc __ksym;
int nr_cpus;
bool tcp_activated, udp_activated;
long tcp_memory_allocated, udp_memory_allocated;
struct sk_prot {
long *memory_allocated;
int *memory_per_cpu_fw_alloc;
};
static int drain_memory_per_cpu_fw_alloc(__u32 i, struct sk_prot *sk_prot_ctx)
{
int *memory_per_cpu_fw_alloc;
memory_per_cpu_fw_alloc = bpf_per_cpu_ptr(sk_prot_ctx->memory_per_cpu_fw_alloc, i);
if (memory_per_cpu_fw_alloc)
*sk_prot_ctx->memory_allocated += *memory_per_cpu_fw_alloc;
return 0;
}
static long get_memory_allocated(struct sock *_sk, int *memory_per_cpu_fw_alloc)
{
struct sock *sk = bpf_core_cast(_sk, struct sock);
struct sk_prot sk_prot_ctx;
long memory_allocated;
memory_allocated = sk->__sk_common.skc_prot->memory_allocated->counter;
sk_prot_ctx.memory_allocated = &memory_allocated;
sk_prot_ctx.memory_per_cpu_fw_alloc = memory_per_cpu_fw_alloc;
bpf_loop(nr_cpus, drain_memory_per_cpu_fw_alloc, &sk_prot_ctx, 0);
return memory_allocated;
}
static void fentry_init_sock(struct sock *sk, bool *activated,
long *memory_allocated, int *memory_per_cpu_fw_alloc)
{
if (!*activated)
return;
*memory_allocated = get_memory_allocated(sk, memory_per_cpu_fw_alloc);
*activated = false;
}
SEC("fentry/tcp_init_sock")
int BPF_PROG(fentry_tcp_init_sock, struct sock *sk)
{
fentry_init_sock(sk, &tcp_activated,
&tcp_memory_allocated, &tcp_memory_per_cpu_fw_alloc);
return 0;
}
SEC("fentry/udp_init_sock")
int BPF_PROG(fentry_udp_init_sock, struct sock *sk)
{
fentry_init_sock(sk, &udp_activated,
&udp_memory_allocated, &udp_memory_per_cpu_fw_alloc);
return 0;
}
SEC("cgroup/sock_create")
int sock_create(struct bpf_sock *ctx)
{
int err, val = 1;
err = bpf_setsockopt(ctx, SOL_SOCKET, SK_BPF_BYPASS_PROT_MEM,
&val, sizeof(val));
if (err)
goto err;
val = 0;
err = bpf_getsockopt(ctx, SOL_SOCKET, SK_BPF_BYPASS_PROT_MEM,
&val, sizeof(val));
if (err)
goto err;
if (val != 1) {
err = -EINVAL;
goto err;
}
return 1;
err:
set_if_not_errno_or_zero(err, -EFAULT);
bpf_set_retval(err);
return 0;
}
char LICENSE[] SEC("license") = "GPL";