bpf: allow clearing all sock_ops callback flags
authorViet Hoang Tran <hoang.tran@uclouvain.be>
Mon, 15 Apr 2019 09:54:55 +0000 (09:54 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 17 Apr 2019 02:24:20 +0000 (19:24 -0700)
The helper function bpf_sock_ops_cb_flags_set() can be used to both
set and clear the sock_ops callback flags. However, its current
behavior is not consistent. BPF program may clear a flag if more than
one were set, or replace a flag with another one, but cannot clear all
flags.

This patch also updates the documentation to clarify the ability to
clear flags of this helper function.

Signed-off-by: Hoang Tran <hoang.tran@uclouvain.be>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
net/core/filter.c

index 704bb69514a20318adc1188e440cd18e0e1c5e0d..eaf2d328424883ff525c22a9476ad3956cddbdd2 100644 (file)
@@ -1737,12 +1737,19 @@ union bpf_attr {
  *             error if an eBPF program tries to set a callback that is not
  *             supported in the current kernel.
  *
- *             The supported callback values that *argval* can combine are:
+ *             *argval* is a flag array which can combine these flags:
  *
  *             * **BPF_SOCK_OPS_RTO_CB_FLAG** (retransmission time out)
  *             * **BPF_SOCK_OPS_RETRANS_CB_FLAG** (retransmission)
  *             * **BPF_SOCK_OPS_STATE_CB_FLAG** (TCP state change)
  *
+ *             Therefore, this function can be used to clear a callback flag by
+ *             setting the appropriate bit to zero. e.g. to disable the RTO
+ *             callback:
+ *
+ *             **bpf_sock_ops_cb_flags_set(bpf_sock,**
+ *                     **bpf_sock->bpf_sock_ops_cb_flags & ~BPF_SOCK_OPS_RTO_CB_FLAG)**
+ *
  *             Here are some examples of where one could call such eBPF
  *             program:
  *
index bd1f51907b83bc82f4f4d415054d1cea4591efa1..1833926a63fc16da4c5685abc3676c17911b2c83 100644 (file)
@@ -4437,8 +4437,7 @@ BPF_CALL_2(bpf_sock_ops_cb_flags_set, struct bpf_sock_ops_kern *, bpf_sock,
        if (!IS_ENABLED(CONFIG_INET) || !sk_fullsock(sk))
                return -EINVAL;
 
-       if (val)
-               tcp_sk(sk)->bpf_sock_ops_cb_flags = val;
+       tcp_sk(sk)->bpf_sock_ops_cb_flags = val;
 
        return argval & (~BPF_SOCK_OPS_ALL_CB_FLAGS);
 }