Handle ECN handshake in simultaneous open

While testing simultaneous open TCP with ECN, found that
negotiation fails to arrive at the expected final state.

Reviewed by:	tuexen (mentor)
Approved by:	tuexen (mentor), rgrimes (mentor)
MFC after:	2 weeks
Sponsored by:	NetApp, Inc.
Differential Revision:	https://reviews.freebsd.org/D23373
This commit is contained in:
Richard Scheffenegger 2020-05-21 21:15:25 +00:00
parent 091e9e469b
commit 6e16d87751
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=361345
3 changed files with 28 additions and 0 deletions

View File

@ -1611,6 +1611,14 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* XXX this is traditional behavior, may need to be cleaned up.
*/
if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) {
/* Handle parallel SYN for ECN */
if (!(thflags & TH_ACK) &&
((thflags & (TH_CWR | TH_ECE)) == (TH_CWR | TH_ECE)) &&
((V_tcp_do_ecn == 1) || (V_tcp_do_ecn == 2))) {
tp->t_flags2 |= TF2_ECN_PERMIT;
tp->t_flags2 |= TF2_ECN_SND_ECE;
TCPSTAT_INC(tcps_ecn_shs);
}
if ((to.to_flags & TOF_SCALE) &&
(tp->t_flags & TF_REQ_SCALE)) {
tp->t_flags |= TF_RCVD_SCALE;

View File

@ -1154,6 +1154,12 @@ tcp_output(struct tcpcb *tp)
} else
flags |= TH_ECE|TH_CWR;
}
/* Handle parallel SYN for ECN */
if ((tp->t_state == TCPS_SYN_RECEIVED) &&
(tp->t_flags2 & TF2_ECN_SND_ECE)) {
flags |= TH_ECE;
tp->t_flags2 &= ~TF2_ECN_SND_ECE;
}
if (tp->t_state == TCPS_ESTABLISHED &&
(tp->t_flags2 & TF2_ECN_PERMIT)) {

View File

@ -11070,6 +11070,14 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so,
* this is traditional behavior, may need to be cleaned up.
*/
if (tp->t_state == TCPS_SYN_SENT && (thflags & TH_SYN)) {
/* Handle parallel SYN for ECN */
if (!(thflags & TH_ACK) &&
((thflags & (TH_CWR | TH_ECE)) == (TH_CWR | TH_ECE)) &&
((V_tcp_do_ecn == 1) || (V_tcp_do_ecn == 2))) {
tp->t_flags2 |= TF2_ECN_PERMIT;
tp->t_flags2 |= TF2_ECN_SND_ECE;
TCPSTAT_INC(tcps_ecn_shs);
}
if ((to.to_flags & TOF_SCALE) &&
(tp->t_flags & TF_REQ_SCALE)) {
tp->t_flags |= TF_RCVD_SCALE;
@ -13523,6 +13531,12 @@ rack_output(struct tcpcb *tp)
} else
flags |= TH_ECE | TH_CWR;
}
/* Handle parallel SYN for ECN */
if ((tp->t_state == TCPS_SYN_RECEIVED) &&
(tp->t_flags2 & TF2_ECN_SND_ECE)) {
flags |= TH_ECE;
tp->t_flags2 &= ~TF2_ECN_SND_ECE;
}
if (tp->t_state == TCPS_ESTABLISHED &&
(tp->t_flags2 & TF2_ECN_PERMIT)) {
/*