diff options
author | Lawrence Brakmo <brakmo@fb.com> | 2017-06-30 23:02:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-07-01 19:15:14 -0400 |
commit | 91b5b21c7c16899abb37f4a9e4388b4e9aae0b9d (patch) | |
tree | ff5989374783d9f11e822906a98e94d08a6f135a /net/ipv4/tcp_output.c | |
parent | d9925368a641391f38cd281e67b948e6b6f3bcca (diff) |
bpf: Add support for changing congestion control
Added support for changing congestion control for SOCK_OPS bpf
programs through the setsockopt bpf helper function. It also adds
a new SOCK_OPS op, BPF_SOCK_OPS_NEEDS_ECN, that is needed for
congestion controls, like dctcp, that need to enable ECN in the
SYN packets.
Signed-off-by: Lawrence Brakmo <brakmo@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 33b3e401e812..4d36f0b093e6 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -316,7 +316,8 @@ static void tcp_ecn_send_synack(struct sock *sk, struct sk_buff *skb) | |||
316 | TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_CWR; | 316 | TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_CWR; |
317 | if (!(tp->ecn_flags & TCP_ECN_OK)) | 317 | if (!(tp->ecn_flags & TCP_ECN_OK)) |
318 | TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ECE; | 318 | TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ECE; |
319 | else if (tcp_ca_needs_ecn(sk)) | 319 | else if (tcp_ca_needs_ecn(sk) || |
320 | tcp_bpf_ca_needs_ecn(sk)) | ||
320 | INET_ECN_xmit(sk); | 321 | INET_ECN_xmit(sk); |
321 | } | 322 | } |
322 | 323 | ||
@@ -324,8 +325,9 @@ static void tcp_ecn_send_synack(struct sock *sk, struct sk_buff *skb) | |||
324 | static void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb) | 325 | static void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb) |
325 | { | 326 | { |
326 | struct tcp_sock *tp = tcp_sk(sk); | 327 | struct tcp_sock *tp = tcp_sk(sk); |
328 | bool bpf_needs_ecn = tcp_bpf_ca_needs_ecn(sk); | ||
327 | bool use_ecn = sock_net(sk)->ipv4.sysctl_tcp_ecn == 1 || | 329 | bool use_ecn = sock_net(sk)->ipv4.sysctl_tcp_ecn == 1 || |
328 | tcp_ca_needs_ecn(sk); | 330 | tcp_ca_needs_ecn(sk) || bpf_needs_ecn; |
329 | 331 | ||
330 | if (!use_ecn) { | 332 | if (!use_ecn) { |
331 | const struct dst_entry *dst = __sk_dst_get(sk); | 333 | const struct dst_entry *dst = __sk_dst_get(sk); |
@@ -339,7 +341,7 @@ static void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb) | |||
339 | if (use_ecn) { | 341 | if (use_ecn) { |
340 | TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; | 342 | TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; |
341 | tp->ecn_flags = TCP_ECN_OK; | 343 | tp->ecn_flags = TCP_ECN_OK; |
342 | if (tcp_ca_needs_ecn(sk)) | 344 | if (tcp_ca_needs_ecn(sk) || bpf_needs_ecn) |
343 | INET_ECN_xmit(sk); | 345 | INET_ECN_xmit(sk); |
344 | } | 346 | } |
345 | } | 347 | } |