Re: [PATCH bpf-next v6 11/11] bpf: add selftest for tcpbpf

2018-01-19 Thread Alexei Starovoitov
On Fri, Jan 19, 2018 at 05:45:48PM -0800, Lawrence Brakmo wrote:
> Added a selftest for tcpbpf (sock_ops) that checks that the appropriate
> callbacks occured and that it can access tcp_sock fields and that their
> values are correct.
> 
> Run with command: ./test_tcpbpf_user
> 
> Signed-off-by: Lawrence Brakmo 
...
> + __u32 key = 0;
> + struct tcpbpf_globals g, *gp;
> +
> + gp = bpf_map_lookup_elem(&global_map, &key);
> + if (gp == NULL) {
> + struct tcpbpf_globals g = {0, 0, 0, 0, 0, 0, 0, 0};
> +
> + g.event_map |= (1 << event);
> + bpf_map_update_elem(&global_map, &key, &g,
> + BPF_ANY);
> + } else {
> + g = *gp;
> + g.event_map |= (1 << event);
> + bpf_map_update_elem(&global_map, &key, &g,
> + BPF_ANY);
...
> + __u32 key = 0;
> + struct tcpbpf_globals g, *gp;
> +
> + gp = bpf_map_lookup_elem(&global_map, &key);
> + if (!gp)
> + break;
> + g = *gp;
> + g.bad_cb_test_rv = bad_call_rv;
> + g.good_cb_test_rv = good_call_rv;
> + bpf_map_update_elem(&global_map, &key, &g,
> + BPF_ANY);

since 'g' is an array of one element and the tests designed
for single flow anyway, there is no need to use map_update_elem.
the program can directly assign into fields like:
gp->bad_cb_test_rv = bad_call_rv;
gp->good_cb_test_rv = good_call_rv;
probably not worth respining just for that. Mainly fyi.
Acked-by: Alexei Starovoitov 



[PATCH bpf-next v6 11/11] bpf: add selftest for tcpbpf

2018-01-19 Thread Lawrence Brakmo
Added a selftest for tcpbpf (sock_ops) that checks that the appropriate
callbacks occured and that it can access tcp_sock fields and that their
values are correct.

Run with command: ./test_tcpbpf_user

Signed-off-by: Lawrence Brakmo 
---
 tools/include/uapi/linux/bpf.h |  74 +-
 tools/testing/selftests/bpf/Makefile   |   4 +-
 tools/testing/selftests/bpf/bpf_helpers.h  |   2 +
 tools/testing/selftests/bpf/tcp_client.py  |  52 ++
 tools/testing/selftests/bpf/tcp_server.py  |  79 +++
 tools/testing/selftests/bpf/test_tcpbpf.h  |  16 +++
 tools/testing/selftests/bpf/test_tcpbpf_kern.c | 131 +
 tools/testing/selftests/bpf/test_tcpbpf_user.c | 126 
 8 files changed, 478 insertions(+), 6 deletions(-)
 create mode 100755 tools/testing/selftests/bpf/tcp_client.py
 create mode 100755 tools/testing/selftests/bpf/tcp_server.py
 create mode 100644 tools/testing/selftests/bpf/test_tcpbpf.h
 create mode 100644 tools/testing/selftests/bpf/test_tcpbpf_kern.c
 create mode 100644 tools/testing/selftests/bpf/test_tcpbpf_user.c

diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index af1f49a..0e336cf8 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -17,7 +17,7 @@
 #define BPF_ALU64  0x07/* alu mode in double word width */
 
 /* ld/ldx fields */
-#define BPF_DW 0x18/* double word */
+#define BPF_DW 0x18/* double word (64-bit) */
 #define BPF_XADD   0xc0/* exclusive add */
 
 /* alu/jmp fields */
@@ -642,6 +642,14 @@ union bpf_attr {
  * @optlen: length of optval in bytes
  * Return: 0 or negative error
  *
+ * int bpf_sock_ops_cb_flags_set(bpf_sock_ops, flags)
+ * Set callback flags for sock_ops
+ * @bpf_sock_ops: pointer to bpf_sock_ops_kern struct
+ * @flags: flags value
+ * Return: 0 for no error
+ * -EINVAL if there is no full tcp socket
+ * bits in flags that are not supported by current kernel
+ *
  * int bpf_skb_adjust_room(skb, len_diff, mode, flags)
  * Grow or shrink room in sk_buff.
  * @skb: pointer to skb
@@ -748,7 +756,8 @@ union bpf_attr {
FN(perf_event_read_value),  \
FN(perf_prog_read_value),   \
FN(getsockopt), \
-   FN(override_return),
+   FN(override_return),\
+   FN(sock_ops_cb_flags_set),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
@@ -952,8 +961,9 @@ struct bpf_map_info {
 struct bpf_sock_ops {
__u32 op;
union {
-   __u32 reply;
-   __u32 replylong[4];
+   __u32 args[4];  /* Optionally passed to bpf program */
+   __u32 reply;/* Returned by bpf program  */
+   __u32 replylong[4]; /* Optionally returned by bpf prog  */
};
__u32 family;
__u32 remote_ip4;   /* Stored in network byte order */
@@ -968,6 +978,27 @@ 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;
+   __u64 bytes_received;
+   __u64 bytes_acked;
+   __u32 sk_txhash;
 };
 
 /* List of known BPF sock_ops operators.
@@ -1003,6 +1034,41 @@ enum {
 * a congestion threshold. RTTs above
 * this indicate congestion
 */
+   BPF_SOCK_OPS_RTO_CB,/* Called when an RTO has triggered.
+* Arg1: value of icsk_retransmits
+* Arg2: value of icsk_rto
+* Arg3: whether RTO has expired
+*/
+   BPF_SOCK_OPS_RETRANS_CB,/* Called when skb is retransmitted.
+* Arg1: sequence number of 1st byte
+* Arg2: # segments
+*/
+   BPF_SOCK_OPS_STATE_CB,  /* Called when TCP changes state.
+* Arg1: old_state
+* Arg2: new_state
+*/
+};
+
+/* List of TCP states. T