diff options
author | glebius <glebius@FreeBSD.org> | 2016-01-22 02:07:48 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2016-01-22 02:07:48 +0000 |
commit | 40ba1ae95a65027a63267d57c7b0fee6e030bbd2 (patch) | |
tree | dddc38b9e03f3559cc94d54c711282c48c319bd8 /sys/netinet | |
parent | 0840cf26409ce91dd72208f7439fe1b11f4204c8 (diff) | |
download | FreeBSD-src-40ba1ae95a65027a63267d57c7b0fee6e030bbd2.zip FreeBSD-src-40ba1ae95a65027a63267d57c7b0fee6e030bbd2.tar.gz |
Provide new socket option TCP_CCALGOOPT, which stands for TCP congestion
control algorithm options. The argument is variable length and is opaque
to TCP, forwarded directly to the algorithm's ctl_output method.
Provide new includes directory netinet/cc, where algorithm specific
headers can be installed.
The new API doesn't yet have any in tree consumers.
The original code written by lstewart.
Reviewed by: rrs, emax
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D711
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/tcp.h | 1 | ||||
-rw-r--r-- | sys/netinet/tcp_cc.h | 3 | ||||
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 28 |
3 files changed, 31 insertions, 1 deletions
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h index bfc8073..4703810 100644 --- a/sys/netinet/tcp.h +++ b/sys/netinet/tcp.h @@ -165,6 +165,7 @@ struct tcphdr { #define TCP_MD5SIG 16 /* use MD5 digests (RFC2385) */ #define TCP_INFO 32 /* retrieve tcp_info structure */ #define TCP_CONGESTION 64 /* get/set congestion control algorithm */ +#define TCP_CCALGOOPT 65 /* get/set cc algorithm specific options */ #define TCP_KEEPINIT 128 /* N, time to establish connection */ #define TCP_KEEPIDLE 256 /* L,N,X start keeplives after this period */ #define TCP_KEEPINTVL 512 /* L,N interval between keepalives */ diff --git a/sys/netinet/tcp_cc.h b/sys/netinet/tcp_cc.h index 4a2b0c8..d90cd19 100644 --- a/sys/netinet/tcp_cc.h +++ b/sys/netinet/tcp_cc.h @@ -151,6 +151,9 @@ struct cc_algo { /* Called for an additional ECN processing apart from RFC3168. */ void (*ecnpkt_handler)(struct cc_var *ccv); + /* Called for {get|set}sockopt() on a TCP socket with TCP_CCALGOOPT. */ + int (*ctl_output)(struct cc_var *, struct sockopt *, void *); + STAILQ_ENTRY (cc_algo) entries; }; diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 29e92b2..4b3150b 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1480,7 +1480,33 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp struct tcp_info ti; struct cc_algo *algo; char *buf; - + + /* + * For TCP_CCALGOOPT forward the control to CC module, for both + * SOPT_SET and SOPT_GET. + */ + switch (sopt->sopt_name) { + case TCP_CCALGOOPT: + INP_WUNLOCK(inp); + buf = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK | M_ZERO); + error = sooptcopyin(sopt, buf, sopt->sopt_valsize, + sopt->sopt_valsize); + if (error) { + free(buf, M_TEMP); + return (error); + } + INP_WLOCK_RECHECK(inp); + if (CC_ALGO(tp)->ctl_output != NULL) + error = CC_ALGO(tp)->ctl_output(tp->ccv, sopt, buf); + else + error = ENOENT; + INP_WUNLOCK(inp); + if (error == 0 && sopt->sopt_dir == SOPT_GET) + error = sooptcopyout(sopt, buf, sopt->sopt_valsize); + free(buf, M_TEMP); + return (error); + } + switch (sopt->sopt_dir) { case SOPT_SET: switch (sopt->sopt_name) { |