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:
parent
fef99da69f
commit
c358f1857f
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user