Skip to content

Commit a5a3a82

Browse files
sowminivborkmann
authored andcommitted
bpf: add perf event notificaton support for sock_ops
This patch allows eBPF programs that use sock_ops to send perf based event notifications using bpf_perf_event_output(). Our main use case for this is the following: We would like to monitor some subset of TCP sockets in user-space, (the monitoring application would define 4-tuples it wants to monitor) using TCP_INFO stats to analyze reported problems. The idea is to use those stats to see where the bottlenecks are likely to be ("is it application-limited?" or "is there evidence of BufferBloat in the path?" etc). Today we can do this by periodically polling for tcp_info, but this could be made more efficient if the kernel would asynchronously notify the application via tcp_info when some "interesting" thresholds (e.g., "RTT variance > X", or "total_retrans > Y" etc) are reached. And to make this effective, it is better if we could apply the threshold check *before* constructing the tcp_info netlink notification, so that we don't waste resources constructing notifications that will be discarded by the filter. This work solves the problem by adding perf event based notification support for sock_ops. The eBPF program can thus be designed to apply any desired filters to the bpf_sock_ops and trigger a perf event notification based on the evaluation from the filter. The user space component can use these perf event notifications to either read any state managed by the eBPF program, or issue a TCP_INFO netlink call if desired. Signed-off-by: Sowmini Varadhan <[email protected]> Co-developed-by: Daniel Borkmann <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 185067a commit a5a3a82

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

net/core/filter.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3908,6 +3908,26 @@ static const struct bpf_func_proto bpf_get_socket_uid_proto = {
39083908
.arg1_type = ARG_PTR_TO_CTX,
39093909
};
39103910

3911+
BPF_CALL_5(bpf_sockopt_event_output, struct bpf_sock_ops_kern *, bpf_sock,
3912+
struct bpf_map *, map, u64, flags, void *, data, u64, size)
3913+
{
3914+
if (unlikely(flags & ~(BPF_F_INDEX_MASK)))
3915+
return -EINVAL;
3916+
3917+
return bpf_event_output(map, flags, data, size, NULL, 0, NULL);
3918+
}
3919+
3920+
static const struct bpf_func_proto bpf_sockopt_event_output_proto = {
3921+
.func = bpf_sockopt_event_output,
3922+
.gpl_only = true,
3923+
.ret_type = RET_INTEGER,
3924+
.arg1_type = ARG_PTR_TO_CTX,
3925+
.arg2_type = ARG_CONST_MAP_PTR,
3926+
.arg3_type = ARG_ANYTHING,
3927+
.arg4_type = ARG_PTR_TO_MEM,
3928+
.arg5_type = ARG_CONST_SIZE_OR_ZERO,
3929+
};
3930+
39113931
BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
39123932
int, level, int, optname, char *, optval, int, optlen)
39133933
{
@@ -5240,6 +5260,8 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
52405260
return &bpf_get_socket_cookie_sock_ops_proto;
52415261
case BPF_FUNC_get_local_storage:
52425262
return &bpf_get_local_storage_proto;
5263+
case BPF_FUNC_perf_event_output:
5264+
return &bpf_sockopt_event_output_proto;
52435265
default:
52445266
return bpf_base_func_proto(func_id);
52455267
}

0 commit comments

Comments
 (0)