Adds field bpf_sock_ops_flags to tcp_sock and bpf_sock_ops. Its primary
use is to determine if there should be calls to sock_ops bpf program at
various points in the TCP code. The field is initialized to zero,
disabling the calls. A sock_ops BPF program can set, per connection and
as necessary, when the connection is established.

It also adds support for reading and writting the field within a
sock_ops BPF program.

Examples of where to call the bpf program:

1) When RTO fires
2) When a packet is retransmitted
3) When the connection terminates
4) When a packet is sent
5) When a packet is received

Signed-off-by: Lawrence Brakmo <bra...@fb.com>
---
 include/linux/tcp.h      | 8 ++++++++
 include/uapi/linux/bpf.h | 1 +
 net/core/filter.c        | 7 +++++++
 3 files changed, 16 insertions(+)

diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 4f93f095..62f4388 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -373,6 +373,14 @@ struct tcp_sock {
         */
        struct request_sock *fastopen_rsk;
        u32     *saved_syn;
+
+/* Sock_ops bpf program related variables */
+#ifdef CONFIG_BPF
+       u32     bpf_sock_ops_flags;     /* values defined in uapi/linux/tcp.h */
+#define BPF_SOCK_OPS_TEST_FLAG(TP, ARG) (TP->bpf_sock_ops_flags & ARG)
+#else
+#define BPF_SOCK_OPS_TEST_FLAG(TP, ARG) 0
+#endif
 };
 
 enum tsq_enum {
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 1fea987..62b2c89 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -959,6 +959,7 @@ struct bpf_sock_ops {
                                 */
        __u32 snd_cwnd;
        __u32 srtt_us;          /* Averaged RTT << 3 in usecs */
+       __u32 bpf_sock_ops_flags; /* flags defined in uapi/linux/tcp.h */
 };
 
 /* List of known BPF sock_ops operators.
diff --git a/net/core/filter.c b/net/core/filter.c
index 978ac78..76fd6e9 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3843,6 +3843,7 @@ static bool sock_ops_is_valid_access(int off, int size,
                switch (off) {
                case offsetof(struct bpf_sock_ops, op) ...
                     offsetof(struct bpf_sock_ops, replylong[3]):
+               case offsetof(struct bpf_sock_ops, bpf_sock_ops_flags):
                        break;
                default:
                        return false;
@@ -4525,6 +4526,12 @@ static u32 sock_ops_convert_ctx_access(enum 
bpf_access_type type,
        case offsetof(struct bpf_sock_ops, srtt_us):
                SOCK_OPS_GET_FIELD(srtt_us, srtt_us, struct tcp_sock);
                break;
+
+       case offsetof(struct bpf_sock_ops, bpf_sock_ops_flags):
+               SOCK_OPS_GET_OR_SET_FIELD(bpf_sock_ops_flags,
+                                         bpf_sock_ops_flags,
+                                         struct tcp_sock, type);
+               break;
        }
        return insn - insn_buf;
 }
-- 
2.9.5

Reply via email to