Skip to content

Commit 2a10031

Browse files
jrfastabborkmann
authored andcommitted
bpf: sockmap, add bpf_msg_apply_bytes() helper
A single sendmsg or sendfile system call can contain multiple logical messages that a BPF program may want to read and apply a verdict. But, without an apply_bytes helper any verdict on the data applies to all bytes in the sendmsg/sendfile. Alternatively, a BPF program may only care to read the first N bytes of a msg. If the payload is large say MB or even GB setting up and calling the BPF program repeatedly for all bytes, even though the verdict is already known, creates unnecessary overhead. To allow BPF programs to control how many bytes a given verdict applies to we implement a bpf_msg_apply_bytes() helper. When called from within a BPF program this sets a counter, internal to the BPF infrastructure, that applies the last verdict to the next N bytes. If the N is smaller than the current data being processed from a sendmsg/sendfile call, the first N bytes will be sent and the BPF program will be re-run with start_data pointing to the N+1 byte. If N is larger than the current data being processed the BPF verdict will be applied to multiple sendmsg/sendfile calls until N bytes are consumed. Note1 if a socket closes with apply_bytes counter non-zero this is not a problem because data is not being buffered for N bytes and is sent as its received. Signed-off-by: John Fastabend <[email protected]> Acked-by: David S. Miller <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 4f738ad commit 2a10031

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

Diff for: include/uapi/linux/bpf.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,8 @@ union bpf_attr {
791791
FN(getsockopt), \
792792
FN(override_return), \
793793
FN(sock_ops_cb_flags_set), \
794-
FN(msg_redirect_map),
794+
FN(msg_redirect_map), \
795+
FN(msg_apply_bytes),
795796

796797
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
797798
* function eBPF program intends to call

Diff for: net/core/filter.c

+16
Original file line numberDiff line numberDiff line change
@@ -1928,6 +1928,20 @@ static const struct bpf_func_proto bpf_msg_redirect_map_proto = {
19281928
.arg4_type = ARG_ANYTHING,
19291929
};
19301930

1931+
BPF_CALL_2(bpf_msg_apply_bytes, struct sk_msg_buff *, msg, u32, bytes)
1932+
{
1933+
msg->apply_bytes = bytes;
1934+
return 0;
1935+
}
1936+
1937+
static const struct bpf_func_proto bpf_msg_apply_bytes_proto = {
1938+
.func = bpf_msg_apply_bytes,
1939+
.gpl_only = false,
1940+
.ret_type = RET_INTEGER,
1941+
.arg1_type = ARG_PTR_TO_CTX,
1942+
.arg2_type = ARG_ANYTHING,
1943+
};
1944+
19311945
BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb)
19321946
{
19331947
return task_get_classid(skb);
@@ -3634,6 +3648,8 @@ static const struct bpf_func_proto *sk_msg_func_proto(enum bpf_func_id func_id)
36343648
switch (func_id) {
36353649
case BPF_FUNC_msg_redirect_map:
36363650
return &bpf_msg_redirect_map_proto;
3651+
case BPF_FUNC_msg_apply_bytes:
3652+
return &bpf_msg_apply_bytes_proto;
36373653
default:
36383654
return bpf_base_func_proto(func_id);
36393655
}

0 commit comments

Comments
 (0)