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(driver/modern_bpf,userspace/libpman): support multiple programs for each event #2255

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/drivers_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,9 @@ jobs:
cd src && make install
cd ../../
git clone https://github.com/libbpf/libbpf.git --branch v1.3.0 --single-branch
cd libbpf/src && BUILD_STATIC_ONLY=y DESTDIR=/ make install
cd libbpf/src && BUILD_STATIC_ONLY=y DESTDIR=/ make install install_uapi_headers
ln -s /usr/lib64/libbpf.a /usr/lib/s390x-linux-gnu/
ln -s /usr/include/bpf /usr/include/s390x-linux-gnu/
# Please note: we cannot inject the BPF probe inside QEMU, so right now, we only build it
run: |
git config --global --add safe.directory $GITHUB_WORKSPACE
Expand Down
3 changes: 0 additions & 3 deletions driver/modern_bpf/helpers/base/shared_size.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
/* Maximum number of `iovec` structures that we can analyze. */
#define MAX_IOVCNT 32

/* Maximum number of supported sendmmsg/recvmmsg messages */
#define MAX_SENDMMSG_RECVMMSG_SIZE 8

/* Maximum number of `pollfd` structures that we can analyze. */
#define MAX_POLLFD 16

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,60 @@ int BPF_PROG(recvmmsg_x, struct pt_regs *regs, long ret) {
.ctx = ctx,
};

// We can't use bpf_loop() helper since the below check triggers a verifier failure:
// see
// https://lore.kernel.org/bpf/CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com/T/#u
/*if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) {
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);
} else {*/
for(int i = 0; i < ret && i < MAX_SENDMMSG_RECVMMSG_SIZE; i++) {
handle_exit(i, &data);
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);

return 0;
}

SEC("tp_btf/sys_exit")
int BPF_PROG(recvmmsg_old_x, struct pt_regs *regs, long ret) {
if(ret <= 0) {
unsigned long fd = 0;
struct auxiliary_map *auxmap = auxmap__get();
if(!auxmap) {
return 0;
}

auxmap__preload_event_header(auxmap, PPME_SOCKET_RECVMMSG_X);

/* Parameter 1: res (type: PT_ERRNO) */
auxmap__store_s64_param(auxmap, ret);

/* Parameter 2: fd (type: PT_FD) */
extract__network_args(&fd, 1, regs);
auxmap__store_s64_param(auxmap, (int64_t)(int32_t)fd);

/* Parameter 3: size (type: PT_UINT32) */
auxmap__store_u32_param(auxmap, 0);

/* Parameter 4: data (type: PT_BYTEBUF) */
auxmap__store_empty_param(auxmap);

/* Parameter 5: tuple (type: PT_SOCKTUPLE) */
auxmap__store_empty_param(auxmap);

/* Parameter 6: msg_control (type: PT_BYTEBUF) */
auxmap__store_empty_param(auxmap);

auxmap__finalize_event_header(auxmap);

auxmap__submit_event(auxmap);
return 0;
}
//}

/* Collect parameters at the beginning to manage socketcalls */
unsigned long args[2];
extract__network_args(args, 2, regs);
recvmmsg_data_t data = {
.fd = args[0],
.mmh = (struct mmsghdr *)args[1],
.regs = regs,
.ctx = ctx,
};

// Send only first message
handle_exit(0, &data);

return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,57 @@ int BPF_PROG(sendmmsg_x, struct pt_regs *regs, long ret) {
.ctx = ctx,
};

// We can't use bpf_loop() helper since the below check triggers a verifier failure:
// see
// https://lore.kernel.org/bpf/CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com/T/#u
/*if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) {
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);
} else {*/
for(int i = 0; i < ret && i < MAX_SENDMMSG_RECVMMSG_SIZE; i++) {
handle_exit(i, &data);
uint32_t nr_loops = ret < 1024 ? ret : 1024;
bpf_loop(nr_loops, handle_exit, &data, 0);

return 0;
}

SEC("tp_btf/sys_exit")
int BPF_PROG(sendmmsg_old_x, struct pt_regs *regs, long ret) {
if(ret <= 0) {
unsigned long fd = 0;
struct auxiliary_map *auxmap = auxmap__get();
if(!auxmap) {
return 0;
}

auxmap__preload_event_header(auxmap, PPME_SOCKET_SENDMMSG_X);

/* Parameter 1: res (type: PT_ERRNO) */
auxmap__store_s64_param(auxmap, ret);

/* Parameter 2: fd (type: PT_FD) */
extract__network_args(&fd, 1, regs);
auxmap__store_s64_param(auxmap, (int64_t)(int32_t)fd);

/* Parameter 3: size (type: PT_UINT32) */
auxmap__store_u32_param(auxmap, 0);

/* Parameter 4: data (type: PT_BYTEBUF) */
auxmap__store_empty_param(auxmap);

/* Parameter 5: tuple (type: PT_SOCKTUPLE) */
auxmap__store_empty_param(auxmap);

auxmap__finalize_event_header(auxmap);

auxmap__submit_event(auxmap);
return 0;
}
//}

/* Collect parameters at the beginning to manage socketcalls */
unsigned long args[2];
extract__network_args(args, 2, regs);
sendmmsg_exit_t data = {
.fd = args[0],
.mmh = (struct mmsghdr *)args[1],
.regs = regs,
.ctx = ctx,
};

// Only first message
handle_exit(0, &data);

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions userspace/libpman/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ add_library(
src/configuration.c
src/state.c
src/sc_set.c
src/events_prog_table.c
)

target_include_directories(
Expand Down
8 changes: 8 additions & 0 deletions userspace/libpman/include/libpman.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ bool pman_check_support();
*/
int pman_open_probe(void);

/**
* @brief Prepares the bpf skeleton object checking if
* it satisfies each events_prog_name feature requirements for each prog.
*
* @return `0` on success, `errno` in case of error.
*/
int pman_prepare_progs_before_loading(void);

/**
* @brief Load into the kernel all the programs and maps
* contained into the skeleton.
Expand Down
Loading
Loading