Re: [PATCH bpf-next v8 08/12] bpf: Add support for reading sk_state and more
On 1/24/18, 12:07 PM, "netdev-ow...@vger.kernel.org on behalf of Yuchung Cheng" wrote: On Tue, Jan 23, 2018 at 11:57 PM, Lawrence Brakmo wrote: > Add support for reading many more tcp_sock fields > > state,same as sk->sk_state > rtt_min same as sk->rtt_min.s[0].v (current rtt_min) > snd_ssthresh > rcv_nxt > snd_nxt > snd_una > mss_cache > ecn_flags > rate_delivered > rate_interval_us > packets_out > retrans_out Might as well get ca_state, sacked_out and lost_out to estimate CA states and the packets in flight? Will try to add in updated patchset. If not, I will add as a new patch. > total_retrans > segs_in > data_segs_in > segs_out > data_segs_out > sk_txhash > bytes_received (__u64) > bytes_acked(__u64) > > Signed-off-by: Lawrence Brakmo > --- > include/uapi/linux/bpf.h | 20 +++ > net/core/filter.c| 135 +++ > 2 files changed, 144 insertions(+), 11 deletions(-) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 2a8c40a..6998032 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -979,6 +979,26 @@ struct bpf_sock_ops { > __u32 snd_cwnd; > __u32 srtt_us; /* Averaged RTT << 3 in usecs */ > __u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */ > + __u32 state; > + __u32 rtt_min; > + __u32 snd_ssthresh; > + __u32 rcv_nxt; > + __u32 snd_nxt; > + __u32 snd_una; > + __u32 mss_cache; > + __u32 ecn_flags; > + __u32 rate_delivered; > + __u32 rate_interval_us; > + __u32 packets_out; > + __u32 retrans_out; > + __u32 total_retrans; > + __u32 segs_in; > + __u32 data_segs_in; > + __u32 segs_out; > + __u32 data_segs_out; > + __u32 sk_txhash; > + __u64 bytes_received; > + __u64 bytes_acked; > }; > > /* List of known BPF sock_ops operators. > diff --git a/net/core/filter.c b/net/core/filter.c > index 6936d19..ffe9b60 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -3855,33 +3855,43 @@ void bpf_warn_invalid_xdp_action(u32 act) > } > EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); > > -static bool __is_valid_sock_ops_access(int off, int size) > +static bool sock_ops_is_valid_access(int off, int size, > +enum bpf_access_type type, > +struct bpf_insn_access_aux *info) > { > + const int size_default = sizeof(__u32); > + > if (off < 0 || off >= sizeof(struct bpf_sock_ops)) > return false; > + > /* The verifier guarantees that size > 0. */ > if (off % size != 0) > return false; > - if (size != sizeof(__u32)) > - return false; > - > - return true; > -} > > -static bool sock_ops_is_valid_access(int off, int size, > -enum bpf_access_type type, > -struct bpf_insn_access_aux *info) > -{ > if (type == BPF_WRITE) { > switch (off) { > case offsetof(struct bpf_sock_ops, reply): > + if (size != size_default) > + return false; > break; > default: > return false; > } > + } else { > + switch (off) { > + case bpf_ctx_range_till(struct bpf_sock_ops, bytes_received, > + bytes_acked): > + if (size != sizeof(__u64)) > + return false; > + break; > + default: > + if (size != size_default) > + return false; > + break; > + } > } > > - return __is_valid_sock_ops_access(off, size); > + return true; > } > > static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write, > @@ -4498,6 +4508,32 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, >is_fullsock)); > break; > > + case offsetof(struct bpf_sock_ops, state): > + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_state) != 1); > + > + *insn+
Re: [PATCH bpf-next v8 08/12] bpf: Add support for reading sk_state and more
On Tue, Jan 23, 2018 at 11:57 PM, Lawrence Brakmo wrote: > Add support for reading many more tcp_sock fields > > state,same as sk->sk_state > rtt_min same as sk->rtt_min.s[0].v (current rtt_min) > snd_ssthresh > rcv_nxt > snd_nxt > snd_una > mss_cache > ecn_flags > rate_delivered > rate_interval_us > packets_out > retrans_out Might as well get ca_state, sacked_out and lost_out to estimate CA states and the packets in flight? > total_retrans > segs_in > data_segs_in > segs_out > data_segs_out > sk_txhash > bytes_received (__u64) > bytes_acked(__u64) > > Signed-off-by: Lawrence Brakmo > --- > include/uapi/linux/bpf.h | 20 +++ > net/core/filter.c| 135 > +++ > 2 files changed, 144 insertions(+), 11 deletions(-) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 2a8c40a..6998032 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -979,6 +979,26 @@ struct bpf_sock_ops { > __u32 snd_cwnd; > __u32 srtt_us; /* Averaged RTT << 3 in usecs */ > __u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */ > + __u32 state; > + __u32 rtt_min; > + __u32 snd_ssthresh; > + __u32 rcv_nxt; > + __u32 snd_nxt; > + __u32 snd_una; > + __u32 mss_cache; > + __u32 ecn_flags; > + __u32 rate_delivered; > + __u32 rate_interval_us; > + __u32 packets_out; > + __u32 retrans_out; > + __u32 total_retrans; > + __u32 segs_in; > + __u32 data_segs_in; > + __u32 segs_out; > + __u32 data_segs_out; > + __u32 sk_txhash; > + __u64 bytes_received; > + __u64 bytes_acked; > }; > > /* List of known BPF sock_ops operators. > diff --git a/net/core/filter.c b/net/core/filter.c > index 6936d19..ffe9b60 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -3855,33 +3855,43 @@ void bpf_warn_invalid_xdp_action(u32 act) > } > EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); > > -static bool __is_valid_sock_ops_access(int off, int size) > +static bool sock_ops_is_valid_access(int off, int size, > +enum bpf_access_type type, > +struct bpf_insn_access_aux *info) > { > + const int size_default = sizeof(__u32); > + > if (off < 0 || off >= sizeof(struct bpf_sock_ops)) > return false; > + > /* The verifier guarantees that size > 0. */ > if (off % size != 0) > return false; > - if (size != sizeof(__u32)) > - return false; > - > - return true; > -} > > -static bool sock_ops_is_valid_access(int off, int size, > -enum bpf_access_type type, > -struct bpf_insn_access_aux *info) > -{ > if (type == BPF_WRITE) { > switch (off) { > case offsetof(struct bpf_sock_ops, reply): > + if (size != size_default) > + return false; > break; > default: > return false; > } > + } else { > + switch (off) { > + case bpf_ctx_range_till(struct bpf_sock_ops, bytes_received, > + bytes_acked): > + if (size != sizeof(__u64)) > + return false; > + break; > + default: > + if (size != size_default) > + return false; > + break; > + } > } > > - return __is_valid_sock_ops_access(off, size); > + return true; > } > > static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write, > @@ -4498,6 +4508,32 @@ static u32 sock_ops_convert_ctx_access(enum > bpf_access_type type, >is_fullsock)); > break; > > + case offsetof(struct bpf_sock_ops, state): > + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_state) != > 1); > + > + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( > + struct bpf_sock_ops_kern, sk), > + si->dst_reg, si->src_reg, > + offsetof(struct bpf_sock_ops_kern, sk)); > + *insn++ = BPF_LDX_MEM(BPF_B, si->dst_reg, si->dst_reg, > + offsetof(struct sock_common, > skc_state)); > + break; > + > + case offsetof(struct bpf_sock_ops, rtt_min): > + BUILD_BUG_ON(FIELD_SIZEOF(struct tcp_sock, rtt_min) != > +sizeof(struct minmax)); > + BUILD_BUG_ON(sizeof(struct minmax
[PATCH bpf-next v8 08/12] bpf: Add support for reading sk_state and more
Add support for reading many more tcp_sock fields state,same as sk->sk_state rtt_min same as sk->rtt_min.s[0].v (current rtt_min) snd_ssthresh rcv_nxt snd_nxt snd_una mss_cache ecn_flags rate_delivered rate_interval_us packets_out retrans_out total_retrans segs_in data_segs_in segs_out data_segs_out sk_txhash bytes_received (__u64) bytes_acked(__u64) Signed-off-by: Lawrence Brakmo --- include/uapi/linux/bpf.h | 20 +++ net/core/filter.c| 135 +++ 2 files changed, 144 insertions(+), 11 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 2a8c40a..6998032 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -979,6 +979,26 @@ struct bpf_sock_ops { __u32 snd_cwnd; __u32 srtt_us; /* Averaged RTT << 3 in usecs */ __u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */ + __u32 state; + __u32 rtt_min; + __u32 snd_ssthresh; + __u32 rcv_nxt; + __u32 snd_nxt; + __u32 snd_una; + __u32 mss_cache; + __u32 ecn_flags; + __u32 rate_delivered; + __u32 rate_interval_us; + __u32 packets_out; + __u32 retrans_out; + __u32 total_retrans; + __u32 segs_in; + __u32 data_segs_in; + __u32 segs_out; + __u32 data_segs_out; + __u32 sk_txhash; + __u64 bytes_received; + __u64 bytes_acked; }; /* List of known BPF sock_ops operators. diff --git a/net/core/filter.c b/net/core/filter.c index 6936d19..ffe9b60 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3855,33 +3855,43 @@ void bpf_warn_invalid_xdp_action(u32 act) } EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); -static bool __is_valid_sock_ops_access(int off, int size) +static bool sock_ops_is_valid_access(int off, int size, +enum bpf_access_type type, +struct bpf_insn_access_aux *info) { + const int size_default = sizeof(__u32); + if (off < 0 || off >= sizeof(struct bpf_sock_ops)) return false; + /* The verifier guarantees that size > 0. */ if (off % size != 0) return false; - if (size != sizeof(__u32)) - return false; - - return true; -} -static bool sock_ops_is_valid_access(int off, int size, -enum bpf_access_type type, -struct bpf_insn_access_aux *info) -{ if (type == BPF_WRITE) { switch (off) { case offsetof(struct bpf_sock_ops, reply): + if (size != size_default) + return false; break; default: return false; } + } else { + switch (off) { + case bpf_ctx_range_till(struct bpf_sock_ops, bytes_received, + bytes_acked): + if (size != sizeof(__u64)) + return false; + break; + default: + if (size != size_default) + return false; + break; + } } - return __is_valid_sock_ops_access(off, size); + return true; } static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write, @@ -4498,6 +4508,32 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, is_fullsock)); break; + case offsetof(struct bpf_sock_ops, state): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_state) != 1); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( + struct bpf_sock_ops_kern, sk), + si->dst_reg, si->src_reg, + offsetof(struct bpf_sock_ops_kern, sk)); + *insn++ = BPF_LDX_MEM(BPF_B, si->dst_reg, si->dst_reg, + offsetof(struct sock_common, skc_state)); + break; + + case offsetof(struct bpf_sock_ops, rtt_min): + BUILD_BUG_ON(FIELD_SIZEOF(struct tcp_sock, rtt_min) != +sizeof(struct minmax)); + BUILD_BUG_ON(sizeof(struct minmax) < +sizeof(struct minmax_sample)); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( + struct bpf_sock_ops_kern, sk), + si->dst_reg, si->src_reg, + offsetof(struct bpf_sock_ops_kern, sk)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, +