diff options
author | Lawrence Brakmo <brakmo@fb.com> | 2018-01-25 19:14:14 -0500 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-01-25 19:41:14 -0500 |
commit | a31ad29e6a30cb0b9084a9425b819cdcd97273ce (patch) | |
tree | 33ed37e633027ebf8b53a289eaddc687b1756368 | |
parent | 6f9bd3d731aac0d2ac21dd78a642af5df38fb5c5 (diff) |
bpf: Add BPF_SOCK_OPS_RETRANS_CB
Adds support for calling sock_ops BPF program when there is a
retransmission. Three arguments are used; one for the sequence number,
another for the number of segments retransmitted, and the last one for
the return value of tcp_transmit_skb (0 => success).
Does not include syn-ack retransmissions.
New op: BPF_SOCK_OPS_RETRANS_CB.
Signed-off-by: Lawrence Brakmo <brakmo@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r-- | include/uapi/linux/bpf.h | 9 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 4 |
2 files changed, 12 insertions, 1 deletions
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 46520eae37fa..31c93a0bdbc2 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h | |||
@@ -1005,7 +1005,8 @@ struct bpf_sock_ops { | |||
1005 | 1005 | ||
1006 | /* Definitions for bpf_sock_ops_cb_flags */ | 1006 | /* Definitions for bpf_sock_ops_cb_flags */ |
1007 | #define BPF_SOCK_OPS_RTO_CB_FLAG (1<<0) | 1007 | #define BPF_SOCK_OPS_RTO_CB_FLAG (1<<0) |
1008 | #define BPF_SOCK_OPS_ALL_CB_FLAGS 0x1 /* Mask of all currently | 1008 | #define BPF_SOCK_OPS_RETRANS_CB_FLAG (1<<1) |
1009 | #define BPF_SOCK_OPS_ALL_CB_FLAGS 0x3 /* Mask of all currently | ||
1009 | * supported cb flags | 1010 | * supported cb flags |
1010 | */ | 1011 | */ |
1011 | 1012 | ||
@@ -1047,6 +1048,12 @@ enum { | |||
1047 | * Arg2: value of icsk_rto | 1048 | * Arg2: value of icsk_rto |
1048 | * Arg3: whether RTO has expired | 1049 | * Arg3: whether RTO has expired |
1049 | */ | 1050 | */ |
1051 | BPF_SOCK_OPS_RETRANS_CB, /* Called when skb is retransmitted. | ||
1052 | * Arg1: sequence number of 1st byte | ||
1053 | * Arg2: # segments | ||
1054 | * Arg3: return value of | ||
1055 | * tcp_transmit_skb (0 => success) | ||
1056 | */ | ||
1050 | }; | 1057 | }; |
1051 | 1058 | ||
1052 | #define TCP_BPF_IW 1001 /* Set TCP initial congestion window */ | 1059 | #define TCP_BPF_IW 1001 /* Set TCP initial congestion window */ |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index d12f7f71c1c4..e9f985e42405 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2905,6 +2905,10 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) | |||
2905 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); | 2905 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); |
2906 | } | 2906 | } |
2907 | 2907 | ||
2908 | if (BPF_SOCK_OPS_TEST_FLAG(tp, BPF_SOCK_OPS_RETRANS_CB_FLAG)) | ||
2909 | tcp_call_bpf_3arg(sk, BPF_SOCK_OPS_RETRANS_CB, | ||
2910 | TCP_SKB_CB(skb)->seq, segs, err); | ||
2911 | |||
2908 | if (likely(!err)) { | 2912 | if (likely(!err)) { |
2909 | TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; | 2913 | TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; |
2910 | trace_tcp_retransmit_skb(sk, skb); | 2914 | trace_tcp_retransmit_skb(sk, skb); |