summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorLawrence Brakmo <brakmo@fb.com>2017-07-01 06:02:49 +0300
committerDavid S. Miller <davem@davemloft.net>2017-07-02 02:15:14 +0300
commit91b5b21c7c16899abb37f4a9e4388b4e9aae0b9d (patch)
treeff5989374783d9f11e822906a98e94d08a6f135a /net/core
parentd9925368a641391f38cd281e67b948e6b6f3bcca (diff)
downloadlinux-91b5b21c7c16899abb37f4a9e4388b4e9aae0b9d.tar.xz
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/core')
-rw-r--r--net/core/filter.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index ca033e15d35e..12df52711fe8 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2719,8 +2719,24 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
}
} else if (level == SOL_TCP &&
sk->sk_prot->setsockopt == tcp_setsockopt) {
- /* Place holder */
+#ifdef CONFIG_INET
+ if (optname == TCP_CONGESTION) {
+ char name[TCP_CA_NAME_MAX];
+
+ strncpy(name, optval, min_t(long, optlen,
+ TCP_CA_NAME_MAX-1));
+ name[TCP_CA_NAME_MAX-1] = 0;
+ ret = tcp_set_congestion_control(sk, name, false);
+ if (!ret && bpf_sock->op > BPF_SOCK_OPS_NEEDS_ECN)
+ /* replacing an existing ca */
+ tcp_reinit_congestion_control(sk,
+ inet_csk(sk)->icsk_ca_ops);
+ } else {
+ ret = -EINVAL;
+ }
+#else
ret = -EINVAL;
+#endif
} else {
ret = -EINVAL;
}