diff options
author | John Fastabend <john.fastabend@gmail.com> | 2018-11-26 23:16:17 +0100 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-11-28 22:07:57 +0100 |
commit | 7246d8ed4dcce23f7509949a77be15fa9f0e3d28 (patch) | |
tree | 500458a8fb23f87db2411ad0849f06f05caedb48 /net/ipv4 | |
parent | Merge branch 'libbpf-versioning-doc' (diff) | |
download | linux-7246d8ed4dcce23f7509949a77be15fa9f0e3d28.tar.xz linux-7246d8ed4dcce23f7509949a77be15fa9f0e3d28.zip |
bpf: helper to pop data from messages
This adds a BPF SK_MSG program helper so that we can pop data from a
msg. We use this to pop metadata from a previous push data call.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp_bpf.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index 3b45fe530f91..a47c1cdf90fc 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -289,12 +289,23 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, { bool cork = false, enospc = msg->sg.start == msg->sg.end; struct sock *sk_redir; - u32 tosend; + u32 tosend, delta = 0; int ret; more_data: - if (psock->eval == __SK_NONE) + if (psock->eval == __SK_NONE) { + /* Track delta in msg size to add/subtract it on SK_DROP from + * returned to user copied size. This ensures user doesn't + * get a positive return code with msg_cut_data and SK_DROP + * verdict. + */ + delta = msg->sg.size; psock->eval = sk_psock_msg_verdict(sk, psock, msg); + if (msg->sg.size < delta) + delta -= msg->sg.size; + else + delta = 0; + } if (msg->cork_bytes && msg->cork_bytes > msg->sg.size && !enospc) { @@ -350,7 +361,7 @@ more_data: default: sk_msg_free_partial(sk, msg, tosend); sk_msg_apply_bytes(psock, tosend); - *copied -= tosend; + *copied -= (tosend + delta); return -EACCES; } |