Skip to content

Commit 6510e2f

Browse files
committed
feature(modern_bpf): add dynamic snaplen handling for recvmmsg/sendmmsg
A new argument had to be added to the apply_dynamic_snaplen function, I opted for using an auxiliar struct and pass a single pointer to it to the function. I think this is a bit cleaner, since removing or adding other arguments can be done by simply adding it to the struct, keeping the function signature unchanged. Signed-off-by: Mauro Ezequiel Moltrasio <[email protected]>
1 parent b94a5e3 commit 6510e2f

19 files changed

+129
-22
lines changed

Diff for: driver/modern_bpf/helpers/store/auxmap_store_params.h

+37-4
Original file line numberDiff line numberDiff line change
@@ -1499,10 +1499,15 @@ static __always_inline void auxmap__store_fdlist_param(struct auxiliary_map *aux
14991499
sizeof(uint16_t) + (num_pairs * (sizeof(int64_t) + sizeof(int16_t))));
15001500
}
15011501

1502+
typedef struct {
1503+
bool only_port_range;
1504+
ppm_event_code evt_type;
1505+
long mmsg_index;
1506+
} dynamic_snaplen_args;
1507+
15021508
static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs,
15031509
uint16_t *snaplen,
1504-
bool only_port_range,
1505-
ppm_event_code evt_type) {
1510+
const dynamic_snaplen_args *input_args) {
15061511
if(!maps__get_do_dynamic_snaplen()) {
15071512
return;
15081513
}
@@ -1519,7 +1524,9 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs,
15191524
* - writev
15201525
* - pwritev
15211526
* - recvmsg
1527+
* - recvmmsg
15221528
* - sendmsg
1529+
* - sendmmsg
15231530
* - send
15241531
* - recv
15251532
* - recvfrom
@@ -1539,12 +1546,14 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs,
15391546
* - writev
15401547
* - pwritev
15411548
* - recvmsg
1549+
* - recvmmsg
15421550
* - sendmsg
1551+
* - sendmmsg
15431552
*/
15441553
unsigned long args[5] = {0};
15451554
struct sockaddr *sockaddr = NULL;
15461555

1547-
switch(evt_type) {
1556+
switch(input_args->evt_type) {
15481557
case PPME_SOCKET_SENDTO_X:
15491558
case PPME_SOCKET_RECVFROM_X:
15501559
extract__network_args(args, 5, regs);
@@ -1571,6 +1580,30 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs,
15711580
}
15721581
} break;
15731582

1583+
case PPME_SOCKET_RECVMMSG_X:
1584+
case PPME_SOCKET_SENDMMSG_X: {
1585+
extract__network_args(args, 3, regs);
1586+
if(bpf_in_ia32_syscall()) {
1587+
struct compat_mmsghdr compat_mmh = {};
1588+
struct compat_mmsghdr *mmh_ptr = (struct compat_mmsghdr *)args[1];
1589+
if(likely(bpf_probe_read_user(&compat_mmh,
1590+
bpf_core_type_size(struct compat_mmsghdr),
1591+
(void *)(mmh_ptr + input_args->mmsg_index)) == 0)) {
1592+
sockaddr = (struct sockaddr *)(unsigned long)(compat_mmh.msg_hdr.msg_name);
1593+
}
1594+
// in any case we break the switch.
1595+
break;
1596+
}
1597+
1598+
struct mmsghdr mmh = {};
1599+
struct mmsghdr *mmh_ptr = (struct mmsghdr *)args[1];
1600+
if(bpf_probe_read_user(&mmh,
1601+
bpf_core_type_size(struct mmsghdr),
1602+
(void *)(mmh_ptr + input_args->mmsg_index)) == 0) {
1603+
sockaddr = (struct sockaddr *)mmh.msg_hdr.msg_name;
1604+
}
1605+
} break;
1606+
15741607
default:
15751608
extract__network_args(args, 3, regs);
15761609
break;
@@ -1639,7 +1672,7 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs,
16391672
}
16401673

16411674
/* If we check only port range without reading syscall data we can stop here */
1642-
if(only_port_range) {
1675+
if(input_args->only_port_range) {
16431676
return;
16441677
}
16451678

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/pread64.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ int BPF_PROG(pread64_x, struct pt_regs *regs, long ret) {
6363
/* We read the minimum between `snaplen` and what we really
6464
* have in the buffer.
6565
*/
66+
dynamic_snaplen_args snaplen_args = {
67+
.only_port_range = false,
68+
.evt_type = PPME_SYSCALL_PREAD_X,
69+
};
6670
uint16_t snaplen = maps__get_snaplen();
67-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SYSCALL_PREAD_X);
71+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6872
if(snaplen > ret) {
6973
snaplen = ret;
7074
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/preadv.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,12 @@ int BPF_PROG(preadv_x, struct pt_regs *regs, long ret) {
6262
/* We read the minimum between `snaplen` and what we really
6363
* have in the buffer.
6464
*/
65+
dynamic_snaplen_args snaplen_args = {
66+
.only_port_range = true,
67+
.evt_type = PPME_SYSCALL_PREADV_X,
68+
};
6569
uint16_t snaplen = maps__get_snaplen();
66-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SYSCALL_PREADV_X);
70+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6771
if(snaplen > ret) {
6872
snaplen = ret;
6973
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/process_vm_readv.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ int BPF_PROG(process_vm_readv_x, struct pt_regs *regs, long ret) {
5959
/* We read the minimum between `snaplen` and what we really
6060
* have in the buffer.
6161
*/
62+
dynamic_snaplen_args snaplen_args = {
63+
.only_port_range = true,
64+
.evt_type = PPME_SYSCALL_PROCESS_VM_READV_X,
65+
};
6266
uint16_t snaplen = maps__get_snaplen();
63-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SYSCALL_PROCESS_VM_READV_X);
67+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6468
if(snaplen > ret) {
6569
snaplen = ret;
6670
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/process_vm_writev.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ int BPF_PROG(process_vm_writev_x, struct pt_regs *regs, long ret) {
5959
/* We read the minimum between `snaplen` and what we really
6060
* have in the buffer.
6161
*/
62+
dynamic_snaplen_args snaplen_args = {
63+
.only_port_range = true,
64+
.evt_type = PPME_SYSCALL_PROCESS_VM_WRITEV_X,
65+
};
6266
uint16_t snaplen = maps__get_snaplen();
63-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SYSCALL_PROCESS_VM_WRITEV_X);
67+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6468
if(snaplen > ret) {
6569
snaplen = ret;
6670
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/pwrite64.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,13 @@ int BPF_PROG(pwrite64_x, struct pt_regs *regs, long ret) {
6262
/* If the syscall doesn't fail we use the return value as `size`
6363
* otherwise we need to rely on the syscall parameter provided by the user.
6464
*/
65+
dynamic_snaplen_args snaplen_args = {
66+
.only_port_range = false,
67+
.evt_type = PPME_SYSCALL_PWRITE_X,
68+
};
6569
int64_t bytes_to_read = ret > 0 ? ret : extract__syscall_argument(regs, 2);
6670
uint16_t snaplen = maps__get_snaplen();
67-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SYSCALL_PWRITE_X);
71+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6872
if((int64_t)snaplen > bytes_to_read) {
6973
snaplen = bytes_to_read;
7074
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/pwritev.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,12 @@ int BPF_PROG(pwritev_x, struct pt_regs *regs, long ret) {
6666
* otherwise we need to extract it now and it has a cost. Here we check just
6767
* the return value if the syscall is successful.
6868
*/
69+
dynamic_snaplen_args snaplen_args = {
70+
.only_port_range = true,
71+
.evt_type = PPME_SYSCALL_PWRITEV_X,
72+
};
6973
uint16_t snaplen = maps__get_snaplen();
70-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SYSCALL_PWRITEV_X);
74+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
7175
if(ret > 0 && snaplen > ret) {
7276
snaplen = ret;
7377
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/read.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ int BPF_PROG(read_x, struct pt_regs *regs, long ret) {
5959
/* We read the minimum between `snaplen` and what we really
6060
* have in the buffer.
6161
*/
62+
dynamic_snaplen_args snaplen_args = {
63+
.only_port_range = false,
64+
.evt_type = PPME_SYSCALL_READ_X,
65+
};
6266
uint16_t snaplen = maps__get_snaplen();
63-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SYSCALL_READ_X);
67+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6468
if(snaplen > ret) {
6569
snaplen = ret;
6670
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/readv.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,12 @@ int BPF_PROG(readv_x, struct pt_regs *regs, long ret) {
5858
/* We read the minimum between `snaplen` and what we really
5959
* have in the buffer.
6060
*/
61+
dynamic_snaplen_args snaplen_args = {
62+
.only_port_range = true,
63+
.evt_type = PPME_SYSCALL_READV_X,
64+
};
6165
uint16_t snaplen = maps__get_snaplen();
62-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SYSCALL_READV_X);
66+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6367
if(snaplen > ret) {
6468
snaplen = ret;
6569
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recv.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ int BPF_PROG(recv_x, struct pt_regs *regs, long ret) {
6464
unsigned long args[2] = {0};
6565
extract__network_args(args, 2, regs);
6666

67+
dynamic_snaplen_args snaplen_args = {
68+
.only_port_range = false,
69+
.evt_type = PPME_SOCKET_RECV_X,
70+
};
6771
uint16_t snaplen = maps__get_snaplen();
68-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SOCKET_RECV_X);
72+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6973
if(snaplen > ret) {
7074
snaplen = ret;
7175
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvfrom.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ int BPF_PROG(recvfrom_x, struct pt_regs *regs, long ret) {
6363
/* We read the minimum between `snaplen` and what we really
6464
* have in the buffer.
6565
*/
66+
dynamic_snaplen_args snaplen_args = {
67+
.only_port_range = false,
68+
.evt_type = PPME_SOCKET_RECVFROM_X,
69+
};
6670
uint16_t snaplen = maps__get_snaplen();
67-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SOCKET_RECVFROM_X);
71+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6872
if(snaplen > ret) {
6973
snaplen = ret;
7074
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,13 @@ static long handle_exit(uint32_t index, void *ctx) {
7272
/* We read the minimum between `snaplen` and what we really
7373
* have in the buffer.
7474
*/
75+
dynamic_snaplen_args snaplen_args = {
76+
.only_port_range = true,
77+
.evt_type = PPME_SOCKET_RECVMMSG_X,
78+
.mmsg_index = index,
79+
};
7580
uint16_t snaplen = maps__get_snaplen();
76-
apply_dynamic_snaplen(data->regs, &snaplen, true, PPME_SOCKET_RECVMMSG_X);
81+
apply_dynamic_snaplen(data->regs, &snaplen, &snaplen_args);
7782
if(snaplen > mmh.msg_len) {
7883
snaplen = mmh.msg_len;
7984
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmsg.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@ int BPF_PROG(recvmsg_x, struct pt_regs *regs, long ret) {
6161
/* We read the minimum between `snaplen` and what we really
6262
* have in the buffer.
6363
*/
64+
dynamic_snaplen_args snaplen_args = {
65+
.only_port_range = true,
66+
.evt_type = PPME_SOCKET_RECVMSG_X,
67+
};
6468
uint16_t snaplen = maps__get_snaplen();
65-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SOCKET_RECVMSG_X);
69+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6670
if(snaplen > ret) {
6771
snaplen = ret;
6872
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/send.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,13 @@ int BPF_PROG(send_x, struct pt_regs *regs, long ret) {
6363
unsigned long args[3] = {0};
6464
extract__network_args(args, 3, regs);
6565

66+
dynamic_snaplen_args snaplen_args = {
67+
.only_port_range = false,
68+
.evt_type = PPME_SOCKET_SEND_X,
69+
};
6670
int64_t bytes_to_read = ret > 0 ? ret : args[2];
6771
uint16_t snaplen = maps__get_snaplen();
68-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SOCKET_SEND_X);
72+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6973
if((int64_t)snaplen > bytes_to_read) {
7074
snaplen = bytes_to_read;
7175
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,13 @@ static long handle_exit(uint32_t index, void *ctx) {
7777
* otherwise we need to extract it now and it has a cost. Here we check just
7878
* the return value if the syscall is successful.
7979
*/
80+
dynamic_snaplen_args snaplen_args = {
81+
.only_port_range = true,
82+
.evt_type = PPME_SOCKET_SENDMMSG_X,
83+
.mmsg_index = index,
84+
};
8085
uint16_t snaplen = maps__get_snaplen();
81-
apply_dynamic_snaplen(data->regs, &snaplen, true, PPME_SOCKET_SENDMMSG_X);
86+
apply_dynamic_snaplen(data->regs, &snaplen, &snaplen_args);
8287
if(mmh.msg_len > 0 && snaplen > mmh.msg_len) {
8388
snaplen = mmh.msg_len;
8489
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmsg.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ int BPF_PROG(sendmsg_x, struct pt_regs *regs, long ret) {
8585
* the return value if the syscall is successful.
8686
*/
8787
uint16_t snaplen = maps__get_snaplen();
88-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SOCKET_SENDMSG_X);
88+
dynamic_snaplen_args snaplen_args = {
89+
.only_port_range = true,
90+
.evt_type = PPME_SOCKET_SENDMSG_X,
91+
};
92+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
8993
if(ret > 0 && snaplen > ret) {
9094
snaplen = ret;
9195
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendto.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ int BPF_PROG(sendto_x, struct pt_regs *regs, long ret) {
8080
/* If the syscall doesn't fail we use the return value as `size`
8181
* otherwise we need to rely on the syscall parameter provided by the user.
8282
*/
83+
dynamic_snaplen_args snaplen_args = {
84+
.only_port_range = false,
85+
.evt_type = PPME_SOCKET_SENDTO_X,
86+
};
8387
int64_t bytes_to_read = ret > 0 ? ret : args[2];
8488
uint16_t snaplen = maps__get_snaplen();
85-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SOCKET_SENDTO_X);
89+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
8690
if((int64_t)snaplen > bytes_to_read) {
8791
snaplen = bytes_to_read;
8892
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/write.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,13 @@ int BPF_PROG(write_x, struct pt_regs *regs, long ret) {
5858
/* If the syscall doesn't fail we use the return value as `size`
5959
* otherwise we need to rely on the syscall parameter provided by the user.
6060
*/
61+
dynamic_snaplen_args snaplen_args = {
62+
.only_port_range = false,
63+
.evt_type = PPME_SYSCALL_WRITE_X,
64+
};
6165
int64_t bytes_to_read = ret > 0 ? ret : extract__syscall_argument(regs, 2);
6266
uint16_t snaplen = maps__get_snaplen();
63-
apply_dynamic_snaplen(regs, &snaplen, false, PPME_SYSCALL_WRITE_X);
67+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6468
if((int64_t)snaplen > bytes_to_read) {
6569
snaplen = bytes_to_read;
6670
}

Diff for: driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/writev.bpf.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,12 @@ int BPF_PROG(writev_x, struct pt_regs *regs, long ret) {
6262
* otherwise we need to extract it now and it has a cost. Here we check just
6363
* the return value if the syscall is successful.
6464
*/
65+
dynamic_snaplen_args snaplen_args = {
66+
.only_port_range = true,
67+
.evt_type = PPME_SYSCALL_WRITEV_X,
68+
};
6569
uint16_t snaplen = maps__get_snaplen();
66-
apply_dynamic_snaplen(regs, &snaplen, true, PPME_SYSCALL_WRITEV_X);
70+
apply_dynamic_snaplen(regs, &snaplen, &snaplen_args);
6771
if(ret > 0 && snaplen > ret) {
6872
snaplen = ret;
6973
}

0 commit comments

Comments
 (0)