bpf: add icsk_retransmits to bpf_tcp_sock
authorStanislav Fomichev <sdf@google.com>
Tue, 2 Jul 2019 16:13:59 +0000 (09:13 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Wed, 3 Jul 2019 14:52:02 +0000 (16:52 +0200)
Add some inet_connection_sock fields to bpf_tcp_sock that might be useful
for debugging congestion control issues.

Cc: Eric Dumazet <edumazet@google.com>
Cc: Priyaranjan Jha <priyarjha@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Acked-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
include/uapi/linux/bpf.h
net/core/filter.c

index bfb0b1a..ead27ae 100644 (file)
@@ -3078,6 +3078,7 @@ struct bpf_tcp_sock {
                                 */
        __u32 delivered;        /* Total data packets delivered incl. rexmits */
        __u32 delivered_ce;     /* Like the above but only ECE marked packets */
+       __u32 icsk_retransmits; /* Number of unrecovered [RTO] timeouts */
 };
 
 struct bpf_sock_tuple {
index 3da4b6c..089aaea 100644 (file)
@@ -5544,7 +5544,8 @@ static const struct bpf_func_proto bpf_sock_addr_sk_lookup_udp_proto = {
 bool bpf_tcp_sock_is_valid_access(int off, int size, enum bpf_access_type type,
                                  struct bpf_insn_access_aux *info)
 {
-       if (off < 0 || off >= offsetofend(struct bpf_tcp_sock, delivered_ce))
+       if (off < 0 || off >= offsetofend(struct bpf_tcp_sock,
+                                         icsk_retransmits))
                return false;
 
        if (off % size != 0)
@@ -5575,6 +5576,20 @@ u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
                                      offsetof(struct tcp_sock, FIELD)); \
        } while (0)
 
+#define BPF_INET_SOCK_GET_COMMON(FIELD)                                        \
+       do {                                                            \
+               BUILD_BUG_ON(FIELD_SIZEOF(struct inet_connection_sock,  \
+                                         FIELD) >                      \
+                            FIELD_SIZEOF(struct bpf_tcp_sock, FIELD)); \
+               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(                 \
+                                       struct inet_connection_sock,    \
+                                       FIELD),                         \
+                                     si->dst_reg, si->src_reg,         \
+                                     offsetof(                         \
+                                       struct inet_connection_sock,    \
+                                       FIELD));                        \
+       } while (0)
+
        if (insn > insn_buf)
                return insn - insn_buf;
 
@@ -5661,6 +5676,9 @@ u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
        case offsetof(struct bpf_tcp_sock, delivered_ce):
                BPF_TCP_SOCK_GET_COMMON(delivered_ce);
                break;
+       case offsetof(struct bpf_tcp_sock, icsk_retransmits):
+               BPF_INET_SOCK_GET_COMMON(icsk_retransmits);
+               break;
        }
 
        return insn - insn_buf;