Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: sockmap, add msg_cork_bytes() helper

In the case where we need a specific number of bytes before a
verdict can be assigned, even if the data spans multiple sendmsg
or sendfile calls. The BPF program may use msg_cork_bytes().

The extreme case is a user can call sendmsg repeatedly with
1-byte msg segments. Obviously, this is bad for performance but
is still valid. If the BPF program needs N bytes to validate
a header it can use msg_cork_bytes to specify N bytes and the
BPF program will not be called again until N bytes have been
accumulated. The infrastructure will attempt to coalesce data
if possible so in many cases (most my use cases at least) the
data will be in a single scatterlist element with data pointers
pointing to start/end of the element. However, this is dependent
on available memory so is not guaranteed. So BPF programs must
validate data pointer ranges, but this is the case anyways to
convince the verifier the accesses are valid.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>

authored by

John Fastabend and committed by
Daniel Borkmann
91843d54 2a100317

+18 -1
+2 -1
include/uapi/linux/bpf.h
··· 792 792 FN(override_return), \ 793 793 FN(sock_ops_cb_flags_set), \ 794 794 FN(msg_redirect_map), \ 795 - FN(msg_apply_bytes), 795 + FN(msg_apply_bytes), \ 796 + FN(msg_cork_bytes), 796 797 797 798 /* integer value in 'imm' field of BPF_CALL instruction selects which helper 798 799 * function eBPF program intends to call
+16
net/core/filter.c
··· 1942 1942 .arg2_type = ARG_ANYTHING, 1943 1943 }; 1944 1944 1945 + BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg_buff *, msg, u32, bytes) 1946 + { 1947 + msg->cork_bytes = bytes; 1948 + return 0; 1949 + } 1950 + 1951 + static const struct bpf_func_proto bpf_msg_cork_bytes_proto = { 1952 + .func = bpf_msg_cork_bytes, 1953 + .gpl_only = false, 1954 + .ret_type = RET_INTEGER, 1955 + .arg1_type = ARG_PTR_TO_CTX, 1956 + .arg2_type = ARG_ANYTHING, 1957 + }; 1958 + 1945 1959 BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb) 1946 1960 { 1947 1961 return task_get_classid(skb); ··· 3664 3650 return &bpf_msg_redirect_map_proto; 3665 3651 case BPF_FUNC_msg_apply_bytes: 3666 3652 return &bpf_msg_apply_bytes_proto; 3653 + case BPF_FUNC_msg_cork_bytes: 3654 + return &bpf_msg_cork_bytes_proto; 3667 3655 default: 3668 3656 return bpf_base_func_proto(func_id); 3669 3657 }