summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorJohn Fastabend <john.fastabend@gmail.com>2018-12-20 22:35:32 +0300
committerDaniel Borkmann <daniel@iogearbox.net>2018-12-21 01:47:09 +0300
commit51199405f967207de372d9b60989eb87d7ae8809 (patch)
tree741ba99a4d0a7d867ce0cfae70af1d1a83d1adb3 /net/core
parent7a69c0f250568e6ab72f401b2c69aa0e666c94f2 (diff)
downloadlinux-51199405f967207de372d9b60989eb87d7ae8809.tar.xz
bpf: skb_verdict, support SK_PASS on RX BPF path
Add SK_PASS verdict support to SK_SKB_VERDICT programs. Now that support for redirects exists we can implement SK_PASS as a redirect to the same socket. This simplifies the BPF programs and avoids an extra map lookup on RX path for simple visibility cases. Further, reduces user (BPF programmer in this context) confusion when their program drops skb due to lack of support. Signed-off-by: John Fastabend <john.fastabend@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skmsg.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 56a99d0c9aa0..8a91a460de8f 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -669,6 +669,22 @@ static void sk_psock_verdict_apply(struct sk_psock *psock,
bool ingress;
switch (verdict) {
+ case __SK_PASS:
+ sk_other = psock->sk;
+ if (sock_flag(sk_other, SOCK_DEAD) ||
+ !sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
+ goto out_free;
+ }
+ if (atomic_read(&sk_other->sk_rmem_alloc) <=
+ sk_other->sk_rcvbuf) {
+ struct tcp_skb_cb *tcp = TCP_SKB_CB(skb);
+
+ tcp->bpf.flags |= BPF_F_INGRESS;
+ skb_queue_tail(&psock->ingress_skb, skb);
+ schedule_work(&psock->work);
+ break;
+ }
+ goto out_free;
case __SK_REDIRECT:
sk_other = tcp_skb_bpf_redirect_fetch(skb);
if (unlikely(!sk_other))