aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Scheffenegger <rscheff@FreeBSD.org>2021-05-26 17:45:06 +0000
committerRichard Scheffenegger <rscheff@FreeBSD.org>2021-05-31 06:56:34 +0000
commit9eed9e5c2dd1c59ef28b9abaa076959562a91a04 (patch)
tree79f32e87e271b44a68d69b6705e99ab52f1bc7fe
parent4a4a174959ce4ab35ecdf282b84f608fbf6d609e (diff)
downloadsrc-9eed9e5c2dd1c59ef28b9abaa076959562a91a04.tar.gz
src-9eed9e5c2dd1c59ef28b9abaa076959562a91a04.zip
tcp: Use local CC data only in the correct context
Most CC algos do use local data, and when calling newreno_cong_signal from there, the latter misinterprets the data as its own struct, leading to incorrect behavior. Reported by: chengc_netapp.com Reviewed By: chengc_netapp.com, tuexen, #transport MFC after: 3 days Sponsored By: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D30470 (cherry picked from commit c358f1857f0c749ad166fb9e9bef04f4033f3a72)
-rw-r--r--sys/netinet/cc/cc_newreno.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c
index 84f8b6a5eb1a..a924acb0b8d6 100644
--- a/sys/netinet/cc/cc_newreno.c
+++ b/sys/netinet/cc/cc_newreno.c
@@ -238,7 +238,12 @@ newreno_cong_signal(struct cc_var *ccv, uint32_t type)
cwin = CCV(ccv, snd_cwnd);
mss = tcp_maxseg(ccv->ccvc.tcp);
- nreno = ccv->cc_data;
+ /*
+ * Other TCP congestion controls use newreno_cong_signal(), but
+ * with their own private cc_data. Make sure the cc_data is used
+ * correctly.
+ */
+ nreno = (CC_ALGO(ccv->ccvc.tcp) == &newreno_cc_algo) ? ccv->cc_data : NULL;
beta = (nreno == NULL) ? V_newreno_beta : nreno->beta;
beta_ecn = (nreno == NULL) ? V_newreno_beta_ecn : nreno->beta_ecn;
if (V_cc_do_abe && type == CC_ECN)
@@ -328,6 +333,9 @@ newreno_ctl_output(struct cc_var *ccv, struct sockopt *sopt, void *buf)
if (sopt->sopt_valsize != sizeof(struct cc_newreno_opts))
return (EMSGSIZE);
+ if (CC_ALGO(ccv->ccvc.tcp) != &newreno_cc_algo)
+ return (ENOPROTOOPT);
+
nreno = ccv->cc_data;
opt = buf;