bpf: Add BPF_FUNC_tcp_send_ack helper
authorMartin KaFai Lau <kafai@fb.com>
Thu, 9 Jan 2020 00:45:51 +0000 (16:45 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 9 Jan 2020 16:46:18 +0000 (08:46 -0800)
Add a helper to send out a tcp-ack.  It will be used in the later
bpf_dctcp implementation that requires to send out an ack
when the CE state changed.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20200109004551.3900448-1-kafai@fb.com
include/uapi/linux/bpf.h
net/ipv4/bpf_tcp_ca.c

index 38059880963ea387afe00ae29f224bc26d13f174..2d6a2e572f561ba8f0b7cb1969cb344e0ae10430 100644 (file)
@@ -2837,6 +2837,14 @@ union bpf_attr {
  *     Return
  *             On success, the strictly positive length of the string, including
  *             the trailing NUL character. On error, a negative value.
+ *
+ * int bpf_tcp_send_ack(void *tp, u32 rcv_nxt)
+ *     Description
+ *             Send out a tcp-ack. *tp* is the in-kernel struct tcp_sock.
+ *             *rcv_nxt* is the ack_seq to be sent out.
+ *     Return
+ *             0 on success, or a negative error in case of failure.
+ *
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
@@ -2954,7 +2962,8 @@ union bpf_attr {
        FN(probe_read_user),            \
        FN(probe_read_kernel),          \
        FN(probe_read_user_str),        \
-       FN(probe_read_kernel_str),
+       FN(probe_read_kernel_str),      \
+       FN(tcp_send_ack),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
index 9c7745b958d705f210085a55f8c3eec497ba6a56..574972bc72995d3a78253a6521d67f813be935b3 100644 (file)
@@ -143,11 +143,33 @@ static int bpf_tcp_ca_btf_struct_access(struct bpf_verifier_log *log,
        return NOT_INIT;
 }
 
+BPF_CALL_2(bpf_tcp_send_ack, struct tcp_sock *, tp, u32, rcv_nxt)
+{
+       /* bpf_tcp_ca prog cannot have NULL tp */
+       __tcp_send_ack((struct sock *)tp, rcv_nxt);
+       return 0;
+}
+
+static const struct bpf_func_proto bpf_tcp_send_ack_proto = {
+       .func           = bpf_tcp_send_ack,
+       .gpl_only       = false,
+       /* In case we want to report error later */
+       .ret_type       = RET_INTEGER,
+       .arg1_type      = ARG_PTR_TO_BTF_ID,
+       .arg2_type      = ARG_ANYTHING,
+       .btf_id         = &tcp_sock_id,
+};
+
 static const struct bpf_func_proto *
 bpf_tcp_ca_get_func_proto(enum bpf_func_id func_id,
                          const struct bpf_prog *prog)
 {
-       return bpf_base_func_proto(func_id);
+       switch (func_id) {
+       case BPF_FUNC_tcp_send_ack:
+               return &bpf_tcp_send_ack_proto;
+       default:
+               return bpf_base_func_proto(func_id);
+       }
 }
 
 static const struct bpf_verifier_ops bpf_tcp_ca_verifier_ops = {