diff options
author | John Fastabend <john.fastabend@gmail.com> | 2017-08-28 07:12:01 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-28 11:13:22 -0700 |
commit | 78aeaaef997db7096a17d0d3572a7940ffa5c9a0 (patch) | |
tree | 5dda1f129368bc28ab93f4f98e7d22947203ba6f /kernel/bpf/sockmap.c | |
parent | 81374aaa2693f8d3cd6cf3656a02ac8cf5c7ebea (diff) | |
download | linux-78aeaaef997db7096a17d0d3572a7940ffa5c9a0.tar.gz linux-78aeaaef997db7096a17d0d3572a7940ffa5c9a0.tar.bz2 linux-78aeaaef997db7096a17d0d3572a7940ffa5c9a0.zip |
bpf: sockmap indicate sock events to listeners
After userspace pushes sockets into a sockmap it may not be receiving
data (assuming stream_{parser|verdict} programs are attached). But, it
may still want to manage the socks. A common pattern is to poll/select
for a POLLRDHUP event so we can close the sock.
This patch adds the logic to wake up these listeners.
Also add TCP_SYN_SENT to the list of events to handle. We don't want
to break the connection just because we happen to be in this state.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/sockmap.c')
-rw-r--r-- | kernel/bpf/sockmap.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c index 38bf4e4ae2fd..bcc326a2e5ce 100644 --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c @@ -162,6 +162,7 @@ static void smap_state_change(struct sock *sk) { struct smap_psock_map_entry *e, *tmp; struct smap_psock *psock; + struct socket_wq *wq; struct sock *osk; rcu_read_lock(); @@ -171,6 +172,7 @@ static void smap_state_change(struct sock *sk) * is established. */ switch (sk->sk_state) { + case TCP_SYN_SENT: case TCP_SYN_RECV: case TCP_ESTABLISHED: break; @@ -208,6 +210,10 @@ static void smap_state_change(struct sock *sk) smap_report_sk_error(psock, EPIPE); break; } + + wq = rcu_dereference(sk->sk_wq); + if (skwq_has_sleeper(wq)) + wake_up_interruptible_all(&wq->wait); rcu_read_unlock(); } |