Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new(libscap): save attached_progs + new libbpf stats -> complete scap_stats_v2 for modern bpf (new metrics 3a/n) #1044

Merged
merged 12 commits into from
May 12, 2023
Merged
173 changes: 173 additions & 0 deletions driver/modern_bpf/helpers/base/stats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
* Copyright (C) 2023 The Falco Authors.
*
* This file is dual licensed under either the MIT or GPL 2. See MIT.txt
* or GPL2.txt for full copies of the license.
*/

#pragma once

#include <helpers/base/common.h>
#include <shared_definitions/struct_definitions.h>
#include <driver/ppm_events_public.h>

/////////////////////////////////////////
// KERNEL SYSCALL CATEGORY DROP COUNTERS
/////////////////////////////////////////

static __always_inline void compute_event_types_stats(u16 event_type, struct counter_map *counter)
{
if(!counter)
{
return;
}
switch(event_type)
{
// enter
case PPME_SYSCALL_OPEN_E:
case PPME_SYSCALL_CREAT_E:
case PPME_SYSCALL_OPENAT_E:
case PPME_SYSCALL_OPENAT_2_E:
case PPME_SYSCALL_OPENAT2_E:
case PPME_SYSCALL_OPEN_BY_HANDLE_AT_E:
counter->n_drops_buffer_open_enter++;
break;
case PPME_SYSCALL_DUP_E:
case PPME_SYSCALL_CHMOD_E:
case PPME_SYSCALL_FCHMOD_E:
case PPME_SYSCALL_FCHMODAT_E:
case PPME_SYSCALL_CHOWN_E:
case PPME_SYSCALL_LCHOWN_E:
case PPME_SYSCALL_FCHOWN_E:
case PPME_SYSCALL_FCHOWNAT_E:
case PPME_SYSCALL_LINK_E:
case PPME_SYSCALL_LINK_2_E:
case PPME_SYSCALL_LINKAT_E:
case PPME_SYSCALL_LINKAT_2_E:
case PPME_SYSCALL_MKDIR_E:
case PPME_SYSCALL_MKDIR_2_E:
case PPME_SYSCALL_MKDIRAT_E:
case PPME_SYSCALL_MOUNT_E:
case PPME_SYSCALL_UMOUNT_E:
case PPME_SYSCALL_UMOUNT_1_E:
case PPME_SYSCALL_UMOUNT2_E:
case PPME_SYSCALL_RENAME_E:
case PPME_SYSCALL_RENAMEAT_E:
case PPME_SYSCALL_RENAMEAT2_E:
case PPME_SYSCALL_RMDIR_E:
case PPME_SYSCALL_RMDIR_2_E:
case PPME_SYSCALL_SYMLINK_E:
case PPME_SYSCALL_SYMLINKAT_E:
case PPME_SYSCALL_UNLINK_E:
case PPME_SYSCALL_UNLINK_2_E:
case PPME_SYSCALL_UNLINKAT_E:
case PPME_SYSCALL_UNLINKAT_2_E:
counter->n_drops_buffer_dir_file_enter++;
break;
case PPME_SYSCALL_CLONE_11_E:
case PPME_SYSCALL_CLONE_16_E:
case PPME_SYSCALL_CLONE_17_E:
case PPME_SYSCALL_CLONE_20_E:
case PPME_SYSCALL_CLONE3_E:
case PPME_SYSCALL_FORK_E:
case PPME_SYSCALL_FORK_20_E:
case PPME_SYSCALL_VFORK_E:
case PPME_SYSCALL_VFORK_20_E:
counter->n_drops_buffer_clone_fork_enter++;
break;
case PPME_SYSCALL_EXECVE_19_E:
case PPME_SYSCALL_EXECVEAT_E:
counter->n_drops_buffer_execve_enter++;
break;
case PPME_SOCKET_CONNECT_E:
counter->n_drops_buffer_connect_enter++;
break;
case PPME_SYSCALL_BPF_E:
case PPME_SYSCALL_BPF_2_E:
case PPME_SYSCALL_SETPGID_E:
case PPME_SYSCALL_PTRACE_E:
case PPME_SYSCALL_SECCOMP_E:
case PPME_SYSCALL_SETNS_E:
case PPME_SYSCALL_SETRESGID_E:
case PPME_SYSCALL_SETRESUID_E:
case PPME_SYSCALL_SETSID_E:
case PPME_SYSCALL_UNSHARE_E:
case PPME_SYSCALL_CAPSET_E:
counter->n_drops_buffer_other_interest_enter++;
break;
// exit
case PPME_SYSCALL_OPEN_X:
case PPME_SYSCALL_CREAT_X:
case PPME_SYSCALL_OPENAT_X:
case PPME_SYSCALL_OPENAT_2_X:
case PPME_SYSCALL_OPENAT2_X:
case PPME_SYSCALL_OPEN_BY_HANDLE_AT_X:
counter->n_drops_buffer_open_exit++;
break;
case PPME_SYSCALL_DUP_X:
case PPME_SYSCALL_CHMOD_X:
case PPME_SYSCALL_FCHMOD_X:
case PPME_SYSCALL_FCHMODAT_X:
case PPME_SYSCALL_CHOWN_X:
case PPME_SYSCALL_LCHOWN_X:
case PPME_SYSCALL_FCHOWN_X:
case PPME_SYSCALL_FCHOWNAT_X:
case PPME_SYSCALL_LINK_X:
case PPME_SYSCALL_LINK_2_X:
case PPME_SYSCALL_LINKAT_X:
case PPME_SYSCALL_LINKAT_2_X:
case PPME_SYSCALL_MKDIR_X:
case PPME_SYSCALL_MKDIR_2_X:
case PPME_SYSCALL_MKDIRAT_X:
case PPME_SYSCALL_MOUNT_X:
case PPME_SYSCALL_UMOUNT_X:
case PPME_SYSCALL_UMOUNT_1_X:
case PPME_SYSCALL_UMOUNT2_X:
case PPME_SYSCALL_RENAME_X:
case PPME_SYSCALL_RENAMEAT_X:
case PPME_SYSCALL_RENAMEAT2_X:
case PPME_SYSCALL_RMDIR_X:
case PPME_SYSCALL_RMDIR_2_X:
case PPME_SYSCALL_SYMLINK_X:
case PPME_SYSCALL_SYMLINKAT_X:
case PPME_SYSCALL_UNLINK_X:
case PPME_SYSCALL_UNLINK_2_X:
case PPME_SYSCALL_UNLINKAT_X:
case PPME_SYSCALL_UNLINKAT_2_X:
counter->n_drops_buffer_dir_file_exit++;
break;
case PPME_SYSCALL_CLONE_11_X:
case PPME_SYSCALL_CLONE_16_X:
case PPME_SYSCALL_CLONE_17_X:
case PPME_SYSCALL_CLONE_20_X:
case PPME_SYSCALL_CLONE3_X:
case PPME_SYSCALL_FORK_X:
case PPME_SYSCALL_FORK_20_X:
case PPME_SYSCALL_VFORK_X:
case PPME_SYSCALL_VFORK_20_X:
counter->n_drops_buffer_clone_fork_exit++;
break;
case PPME_SYSCALL_EXECVE_19_X:
case PPME_SYSCALL_EXECVEAT_X:
counter->n_drops_buffer_execve_exit++;
break;
case PPME_SOCKET_CONNECT_X:
counter->n_drops_buffer_connect_exit++;
break;
case PPME_SYSCALL_BPF_X:
case PPME_SYSCALL_BPF_2_X:
case PPME_SYSCALL_SETPGID_X:
case PPME_SYSCALL_PTRACE_X:
case PPME_SYSCALL_SECCOMP_X:
case PPME_SYSCALL_SETNS_X:
case PPME_SYSCALL_SETRESGID_X:
case PPME_SYSCALL_SETRESUID_X:
case PPME_SYSCALL_SETSID_X:
case PPME_SYSCALL_UNSHARE_X:
case PPME_SYSCALL_CAPSET_X:
counter->n_drops_buffer_other_interest_exit++;
break;
default:
break;
}
}
3 changes: 3 additions & 0 deletions driver/modern_bpf/helpers/store/auxmap_store_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <helpers/base/shared_size.h>
#include <helpers/base/push_data.h>
#include <helpers/extract/extract_from_kernel.h>
#include <helpers/base/stats.h>

/* Concept of auxamp (auxiliary map):
*
Expand Down Expand Up @@ -92,6 +93,7 @@ static __always_inline void auxmap__preload_event_header(struct auxiliary_map *a
hdr->nparams = nparams;
auxmap->payload_pos = sizeof(struct ppm_evt_hdr) + nparams * sizeof(u16);
auxmap->lengths_pos = sizeof(struct ppm_evt_hdr);
auxmap->event_type = event_type;
}

/**
Expand Down Expand Up @@ -149,6 +151,7 @@ static __always_inline void auxmap__submit_event(struct auxiliary_map *auxmap, v
if(err)
{
counter->n_drops_buffer++;
compute_event_types_stats(auxmap->event_type, counter);
}
}

Expand Down
14 changes: 8 additions & 6 deletions driver/modern_bpf/helpers/store/ringbuf_store_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <helpers/base/shared_size.h>
#include <helpers/base/push_data.h>
#include <helpers/extract/extract_from_kernel.h>
#include <helpers/base/stats.h>

/* `reserved_size - sizeof(u64)` free space is enough because this is the max dimension
* we put in the ring buffer in one atomic operation.
Expand Down Expand Up @@ -67,6 +68,7 @@ struct ringbuf_struct
u64 payload_pos; /* position of the first empty byte in the `data` buf.*/
u8 lengths_pos; /* position the first empty slot into the lengths array of the event. */
u16 reserved_event_size; /* reserved size in the ringbuf. */
u16 event_type; /* event type we want to send to userspace */
};

/////////////////////////////////
Expand All @@ -86,7 +88,7 @@ struct ringbuf_struct
* @param event_size exact size of the fixed-size event
* @return `1` in case of success, `0` in case of failure.
*/
static __always_inline u32 ringbuf__reserve_space(struct ringbuf_struct *ringbuf, void* ctx, u32 event_size)
static __always_inline u32 ringbuf__reserve_space(struct ringbuf_struct *ringbuf, void* ctx, u32 event_size, u16 event_type)
{
struct ringbuf_map *rb = maps__get_ringbuf_map();
if(!rb)
Expand All @@ -112,10 +114,12 @@ static __always_inline u32 ringbuf__reserve_space(struct ringbuf_struct *ringbuf
if(!space)
{
counter->n_drops_buffer++;
compute_event_types_stats(event_type, counter);
return 0;
}

ringbuf->data = space;
ringbuf->event_type = event_type;
ringbuf->reserved_event_size = event_size;
return 1;
}
Expand All @@ -128,16 +132,14 @@ static __always_inline u32 ringbuf__reserve_space(struct ringbuf_struct *ringbuf
* @brief Push the event header inside the ringbuf space.
*
* @param ringbuf pointer to the `ringbuf_struct`.
* @param event_type type of the event that we are storing into the ringbuf.
* @param event_size exact size of the fixed-size event.
*/
static __always_inline void ringbuf__store_event_header(struct ringbuf_struct *ringbuf, u32 event_type)
static __always_inline void ringbuf__store_event_header(struct ringbuf_struct *ringbuf)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this general refactor to include event_type in the structs throughout, much easier and cleaner :)

{
struct ppm_evt_hdr *hdr = (struct ppm_evt_hdr *)ringbuf->data;
u8 nparams = maps__get_event_num_params(event_type);
u8 nparams = maps__get_event_num_params(ringbuf->event_type);
hdr->ts = maps__get_boot_time() + bpf_ktime_get_boot_ns();
hdr->tid = bpf_get_current_pid_tgid() & 0xffffffff;
hdr->type = event_type;
hdr->type = ringbuf->event_type;
hdr->nparams = nparams;
hdr->len = ringbuf->reserved_event_size;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ int BPF_PROG(pf_kernel,
}

struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, PAGE_FAULT_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, PAGE_FAULT_SIZE, PPME_PAGE_FAULT_E))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am looking forward to fill the event size somewhere (event_table perhaps?) so that we can drop all the EVENT_SIZE defines :)
Now that we pass the event type too, it should be a quick change but would be even safer too! (ie: no typos allowed!)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep we definitely need to do that!

{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_PAGE_FAULT_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ int BPF_PROG(pf_user,
}

struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, PAGE_FAULT_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, PAGE_FAULT_SIZE, PPME_PAGE_FAULT_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_PAGE_FAULT_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ int BPF_PROG(sched_proc_exit,
}

struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, PROC_EXIT_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, PROC_EXIT_SIZE, PPME_PROCEXIT_1_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_PROCEXIT_1_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
4 changes: 2 additions & 2 deletions driver/modern_bpf/programs/attached/events/sched_switch.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ int BPF_PROG(sched_switch,
/// TODO: we could avoid switches from kernel threads to kernel threads (?).

struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, SCHED_SWITCH_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, SCHED_SWITCH_SIZE, PPME_SCHEDSWITCH_6_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_SCHEDSWITCH_6_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ int BPF_PROG(signal_deliver,
}

struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, SIGNAL_DELIVER_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, SIGNAL_DELIVER_SIZE, PPME_SIGNALDELIVER_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_SIGNALDELIVER_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ SEC("tp_btf/sys_enter")
int BPF_PROG(t1_drop_e)
{
struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, DROP_E_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, DROP_E_SIZE, PPME_DROP_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_DROP_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand All @@ -38,12 +38,12 @@ SEC("tp_btf/sys_exit")
int BPF_PROG(t1_drop_x)
{
struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, DROP_X_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, DROP_X_SIZE, PPME_DROP_X))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_DROP_X);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ int BPF_PROG(t1_hotplug_e)
*/
struct ringbuf_struct ringbuf;
ringbuf.reserved_event_size = HOTPLUG_E_SIZE;
ringbuf.event_type = PPME_CPU_HOTPLUG_E;
ringbuf.data = bpf_ringbuf_reserve(rb, HOTPLUG_E_SIZE, 0);
if(!ringbuf.data)
{
counter->n_drops_buffer++;
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_CPU_HOTPLUG_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ int BPF_PROG(accept_e,
long id)
{
struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, ctx, ACCEPT_E_SIZE))
if(!ringbuf__reserve_space(&ringbuf, ctx, ACCEPT_E_SIZE, PPME_SOCKET_ACCEPT_5_E))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_SOCKET_ACCEPT_5_E);
ringbuf__store_event_header(&ringbuf);

/*=============================== COLLECT PARAMETERS ===========================*/

Expand Down
Loading