aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorLawrence Brakmo <brakmo@fb.com>2017-06-30 23:02:49 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-01 19:15:14 -0400
commit91b5b21c7c16899abb37f4a9e4388b4e9aae0b9d (patch)
treeff5989374783d9f11e822906a98e94d08a6f135a /net/ipv4/tcp_output.c
parentd9925368a641391f38cd281e67b948e6b6f3bcca (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.c8
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)
324static void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb) 325static 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}