Commit 2b8ee4f0 authored by Martin KaFai Lau's avatar Martin KaFai Lau Committed by Alexei Starovoitov

tcp: bpf: Add TCP_BPF_DELACK_MAX setsockopt

This change is mostly from an internal patch and adapts it from sysctl
config to the bpf_setsockopt setup.

The bpf_prog can set the max delay ack by using
bpf_setsockopt(TCP_BPF_DELACK_MAX).  This max delay ack can be communicated
to its peer through bpf header option.  The receiving peer can then use
this max delay ack and set a potentially lower rto by using
bpf_setsockopt(TCP_BPF_RTO_MIN) which will be introduced
in the next patch.

Another later selftest patch will also use it like the above to show
how to write and parse bpf tcp header option.
Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200820190021.2884000-1-kafai@fb.com
parent 70a217f1
...@@ -86,6 +86,7 @@ struct inet_connection_sock { ...@@ -86,6 +86,7 @@ struct inet_connection_sock {
struct timer_list icsk_retransmit_timer; struct timer_list icsk_retransmit_timer;
struct timer_list icsk_delack_timer; struct timer_list icsk_delack_timer;
__u32 icsk_rto; __u32 icsk_rto;
__u32 icsk_delack_max;
__u32 icsk_pmtu_cookie; __u32 icsk_pmtu_cookie;
const struct tcp_congestion_ops *icsk_ca_ops; const struct tcp_congestion_ops *icsk_ca_ops;
const struct inet_connection_sock_af_ops *icsk_af_ops; const struct inet_connection_sock_af_ops *icsk_af_ops;
......
...@@ -4257,6 +4257,7 @@ enum { ...@@ -4257,6 +4257,7 @@ enum {
enum { enum {
TCP_BPF_IW = 1001, /* Set TCP initial congestion window */ TCP_BPF_IW = 1001, /* Set TCP initial congestion window */
TCP_BPF_SNDCWND_CLAMP = 1002, /* Set sndcwnd_clamp */ TCP_BPF_SNDCWND_CLAMP = 1002, /* Set sndcwnd_clamp */
TCP_BPF_DELACK_MAX = 1003, /* Max delay ack in usecs */
}; };
struct bpf_perf_event_value { struct bpf_perf_event_value {
......
...@@ -4459,6 +4459,7 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname, ...@@ -4459,6 +4459,7 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
} else { } else {
struct inet_connection_sock *icsk = inet_csk(sk); struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
unsigned long timeout;
if (optlen != sizeof(int)) if (optlen != sizeof(int))
return -EINVAL; return -EINVAL;
...@@ -4480,6 +4481,13 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname, ...@@ -4480,6 +4481,13 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
tp->snd_ssthresh = val; tp->snd_ssthresh = val;
} }
break; break;
case TCP_BPF_DELACK_MAX:
timeout = usecs_to_jiffies(val);
if (timeout > TCP_DELACK_MAX ||
timeout < TCP_TIMEOUT_MIN)
return -EINVAL;
inet_csk(sk)->icsk_delack_max = timeout;
break;
case TCP_SAVE_SYN: case TCP_SAVE_SYN:
if (val < 0 || val > 1) if (val < 0 || val > 1)
ret = -EINVAL; ret = -EINVAL;
......
...@@ -418,6 +418,7 @@ void tcp_init_sock(struct sock *sk) ...@@ -418,6 +418,7 @@ void tcp_init_sock(struct sock *sk)
INIT_LIST_HEAD(&tp->tsorted_sent_queue); INIT_LIST_HEAD(&tp->tsorted_sent_queue);
icsk->icsk_rto = TCP_TIMEOUT_INIT; icsk->icsk_rto = TCP_TIMEOUT_INIT;
icsk->icsk_delack_max = TCP_DELACK_MAX;
tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT); tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT);
minmax_reset(&tp->rtt_min, tcp_jiffies32, ~0U); minmax_reset(&tp->rtt_min, tcp_jiffies32, ~0U);
...@@ -2685,6 +2686,7 @@ int tcp_disconnect(struct sock *sk, int flags) ...@@ -2685,6 +2686,7 @@ int tcp_disconnect(struct sock *sk, int flags)
icsk->icsk_backoff = 0; icsk->icsk_backoff = 0;
icsk->icsk_probes_out = 0; icsk->icsk_probes_out = 0;
icsk->icsk_rto = TCP_TIMEOUT_INIT; icsk->icsk_rto = TCP_TIMEOUT_INIT;
icsk->icsk_delack_max = TCP_DELACK_MAX;
tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
tp->snd_cwnd = TCP_INIT_CWND; tp->snd_cwnd = TCP_INIT_CWND;
tp->snd_cwnd_cnt = 0; tp->snd_cwnd_cnt = 0;
......
...@@ -3741,6 +3741,8 @@ void tcp_send_delayed_ack(struct sock *sk) ...@@ -3741,6 +3741,8 @@ void tcp_send_delayed_ack(struct sock *sk)
ato = min(ato, max_ato); ato = min(ato, max_ato);
} }
ato = min_t(u32, ato, inet_csk(sk)->icsk_delack_max);
/* Stay within the limit we were given */ /* Stay within the limit we were given */
timeout = jiffies + ato; timeout = jiffies + ato;
......
...@@ -4257,6 +4257,7 @@ enum { ...@@ -4257,6 +4257,7 @@ enum {
enum { enum {
TCP_BPF_IW = 1001, /* Set TCP initial congestion window */ TCP_BPF_IW = 1001, /* Set TCP initial congestion window */
TCP_BPF_SNDCWND_CLAMP = 1002, /* Set sndcwnd_clamp */ TCP_BPF_SNDCWND_CLAMP = 1002, /* Set sndcwnd_clamp */
TCP_BPF_DELACK_MAX = 1003, /* Max delay ack in usecs */
}; };
struct bpf_perf_event_value { struct bpf_perf_event_value {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment