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
This commit is contained in:
Richard Scheffenegger 2021-05-26 19:45:06 +02:00
parent fef99da69f
commit c358f1857f

View File

@ -239,7 +239,12 @@ newreno_cong_signal(struct cc_var *ccv, uint32_t type)
cwin = CCV(ccv, snd_cwnd); cwin = CCV(ccv, snd_cwnd);
mss = tcp_fixed_maxseg(ccv->ccvc.tcp); mss = tcp_fixed_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 = (nreno == NULL) ? V_newreno_beta : nreno->beta;
beta_ecn = (nreno == NULL) ? V_newreno_beta_ecn : nreno->beta_ecn; beta_ecn = (nreno == NULL) ? V_newreno_beta_ecn : nreno->beta_ecn;
@ -336,6 +341,9 @@ newreno_ctl_output(struct cc_var *ccv, struct sockopt *sopt, void *buf)
if (sopt->sopt_valsize != sizeof(struct cc_newreno_opts)) if (sopt->sopt_valsize != sizeof(struct cc_newreno_opts))
return (EMSGSIZE); return (EMSGSIZE);
if (CC_ALGO(ccv->ccvc.tcp) != &newreno_cc_algo)
return (ENOPROTOOPT);
nreno = ccv->cc_data; nreno = ccv->cc_data;
opt = buf; opt = buf;