tcp: set IP ECN header codepoint properly

TCP RACK can cache the IP header while preparing
a new TCP packet for transmission. Thus all the
IP ECN codepoint bits need to be assigned, without
assuming a clear field beforehand.

Reviewed By: tuexen, kbowling, #transport
MFC after:   3 days
Sponsored by:        NetApp, Inc.
Differential Revision: https://reviews.freebsd.org/D34148
This commit is contained in:
Richard Scheffenegger 2022-02-03 16:47:50 +01:00
parent 1ebf460758
commit f026275e26
2 changed files with 18 additions and 3 deletions

View File

@ -1223,11 +1223,16 @@ tcp_default_output(struct tcpcb *tp)
!((tp->t_flags & TF_FORCEDATA) && len == 1 &&
SEQ_LT(tp->snd_una, tp->snd_max))) {
#ifdef INET6
if (isipv6)
if (isipv6) {
ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
}
else
#endif
{
ip->ip_tos &= ~IPTOS_ECN_MASK;
ip->ip_tos |= IPTOS_ECN_ECT0;
}
TCPSTAT_INC(tcps_ecn_ect0);
/*
* Reply with proper ECN notifications.

View File

@ -16537,11 +16537,16 @@ rack_fast_output(struct tcpcb *tp, struct tcp_rack *rack, uint64_t ts_val,
*/
if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max)) {
#ifdef INET6
if (rack->r_is_v6)
if (rack->r_is_v6) {
ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
}
else
#endif
{
ip->ip_tos &= ~IPTOS_ECN_MASK;
ip->ip_tos |= IPTOS_ECN_ECT0;
}
KMOD_TCPSTAT_INC(tcps_ecn_ect0);
/*
* Reply with proper ECN notifications.
@ -18614,11 +18619,16 @@ rack_output(struct tcpcb *tp)
if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) &&
(sack_rxmit == 0)) {
#ifdef INET6
if (isipv6)
if (isipv6) {
ip6->ip6_flow &= ~htonl(IPTOS_ECN_MASK << 20);
ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20);
}
else
#endif
{
ip->ip_tos &= IPTOS_ECN_MASK;
ip->ip_tos |= IPTOS_ECN_ECT0;
}
KMOD_TCPSTAT_INC(tcps_ecn_ect0);
/*
* Reply with proper ECN notifications.