diff --git a/src/platform/datapath_raw_socket.c b/src/platform/datapath_raw_socket.c index 1e82cc38af..9641ea9109 100644 --- a/src/platform/datapath_raw_socket.c +++ b/src/platform/datapath_raw_socket.c @@ -366,7 +366,7 @@ CxPlatDpRawParseIPv6( } VersionClassEcnFlow; VersionClassEcnFlow.Value = CxPlatByteSwapUint32(IP->VersionClassEcnFlow); - Packet->TypeOfService = ((uint8_t)VersionClassEcnFlow.EcnField) | (uint8_t)(VersionClassEcnFlow.Class << 2); + Packet->TypeOfService = (uint8_t)(VersionClassEcnFlow.EcnField | (VersionClassEcnFlow.Class << 2)); Packet->HopLimitTTL = IP->HopLimit; Packet->Route->RemoteAddress.Ipv6.sin6_family = AF_INET6; CxPlatCopyMemory(&Packet->Route->RemoteAddress.Ipv6.sin6_addr, IP->Source, sizeof(IP->Source)); diff --git a/src/platform/datapath_winkernel.c b/src/platform/datapath_winkernel.c index 5dfa34ca8a..6f0ef59759 100644 --- a/src/platform/datapath_winkernel.c +++ b/src/platform/datapath_winkernel.c @@ -2929,8 +2929,7 @@ SocketSend( // BYTE CMsgBuffer[ WSA_CMSG_SPACE(sizeof(IN6_PKTINFO)) + // IP_PKTINFO - WSA_CMSG_SPACE(sizeof(INT)) + // IP_ECN - WSA_CMSG_SPACE(sizeof(INT)) + // IP_TOS/IPV6_TCLASS + WSA_CMSG_SPACE(sizeof(INT)) + // IP_ECN or IP_TOS WSA_CMSG_SPACE(sizeof(*SegmentSize)) // UDP_SEND_MSG_SIZE ]; PWSACMSGHDR CMsg = (PWSACMSGHDR)CMsgBuffer; @@ -2961,30 +2960,33 @@ SocketSend( } } - if (SendData->ECN != CXPLAT_ECN_NON_ECT) { - CMsg = (PWSACMSGHDR)&CMsgBuffer[CMsgLen]; - CMsgLen += WSA_CMSG_SPACE(sizeof(INT)); - CMsg->cmsg_level = - Route->LocalAddress.si_family == QUIC_ADDRESS_FAMILY_INET ? - IPPROTO_IP : IPPROTO_IPV6; - CMsg->cmsg_type = IP_ECN; // == IPV6_ECN - CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); - - *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN; - } - if (Binding->Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_DSCP) { - CMsg = (PWSACMSGHDR)&CMsgBuffer[CMsgLen]; - CMsgLen += WSA_CMSG_SPACE(sizeof(INT)); - CMsg->cmsg_level = - Route->LocalAddress.si_family == QUIC_ADDRESS_FAMILY_INET ? - IPPROTO_IP : IPPROTO_IPV6; - CMsg->cmsg_type = - Route->LocalAddress.si_family == QUIC_ADDRESS_FAMILY_INET ? - IP_TOS : IPV6_TCLASS; - CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); - - *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN | (SendData->DSCP << 2); + if (SendData->ECN != CXPLAT_ECN_NON_ECT || SendData->DSCP != CXPLAT_DSCP_CS0) { + CMsg = (PWSACMSGHDR)&CMsgBuffer[CMsgLen]; + CMsgLen += WSA_CMSG_SPACE(sizeof(INT)); + if (Route->LocalAddress.si_family == QUIC_ADDRESS_FAMILY_INET) { + CMsg->cmsg_level = IPPROTO_IP; + CMsg->cmsg_type = IP_TOS; + } else { + CMsg->cmsg_level = IPPROTO_IPV6; + CMsg->cmsg_type = IPV6_TCLASS; + } + CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); + + *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN | (SendData->DSCP << 2); + } + } else { + if (SendData->ECN != CXPLAT_ECN_NON_ECT) { + CMsg = (PWSACMSGHDR)&CMsgBuffer[CMsgLen]; + CMsgLen += WSA_CMSG_SPACE(sizeof(INT)); + CMsg->cmsg_level = + Route->LocalAddress.si_family == QUIC_ADDRESS_FAMILY_INET ? + IPPROTO_IP : IPPROTO_IPV6; + CMsg->cmsg_type = IP_ECN; // == IPV6_ECN + CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); + + *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN; + } } if (SendData->SegmentSize > 0) { diff --git a/src/platform/datapath_winuser.c b/src/platform/datapath_winuser.c index 60595b5405..8a292a6c96 100644 --- a/src/platform/datapath_winuser.c +++ b/src/platform/datapath_winuser.c @@ -273,8 +273,7 @@ typedef struct CXPLAT_SEND_DATA { char CtrlBuf[ RIO_CMSG_BASE_SIZE + WSA_CMSG_SPACE(sizeof(IN6_PKTINFO)) + // IP_PKTINFO - WSA_CMSG_SPACE(sizeof(INT)) + // IP_ECN - WSA_CMSG_SPACE(sizeof(INT)) + // IP_TOS + WSA_CMSG_SPACE(sizeof(INT)) + // IP_ECN or IP_TOS WSA_CMSG_SPACE(sizeof(DWORD)) // UDP_SEND_MSG_SIZE ]; @@ -4520,22 +4519,26 @@ CxPlatSocketSendInline( PktInfo->ipi_addr = LocalAddress->Ipv4.sin_addr; } - WSAMhdr.Control.len += WSA_CMSG_SPACE(sizeof(INT)); - CMsg = WSA_CMSG_NXTHDR(&WSAMhdr, CMsg); - CXPLAT_DBG_ASSERT(CMsg != NULL); - CMsg->cmsg_level = IPPROTO_IP; - CMsg->cmsg_type = IP_ECN; - CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); - *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN; - if (Socket->Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_DSCP) { - WSAMhdr.Control.len += WSA_CMSG_SPACE(sizeof(INT)); - CMsg = WSA_CMSG_NXTHDR(&WSAMhdr, CMsg); - CXPLAT_DBG_ASSERT(CMsg != NULL); - CMsg->cmsg_level = IPPROTO_IP; - CMsg->cmsg_type = IP_TOS; - CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); - *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN | (SendData->DSCP << 2); + if (SendData->ECN != CXPLAT_ECN_NON_ECT || SendData->DSCP != CXPLAT_DSCP_CS0) { + WSAMhdr.Control.len += WSA_CMSG_SPACE(sizeof(INT)); + CMsg = WSA_CMSG_NXTHDR(&WSAMhdr, CMsg); + CXPLAT_DBG_ASSERT(CMsg != NULL); + CMsg->cmsg_level = IPPROTO_IP; + CMsg->cmsg_type = IP_TOS; + CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); + *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN | (SendData->DSCP << 2); + } + } else { + if (SendData->ECN != CXPLAT_ECN_NON_ECT) { + WSAMhdr.Control.len += WSA_CMSG_SPACE(sizeof(INT)); + CMsg = WSA_CMSG_NXTHDR(&WSAMhdr, CMsg); + CXPLAT_DBG_ASSERT(CMsg != NULL); + CMsg->cmsg_level = IPPROTO_IP; + CMsg->cmsg_type = IP_ECN; + CMsg->cmsg_len = WSA_CMSG_LEN(sizeof(INT)); + *(PINT)WSA_CMSG_DATA(CMsg) = SendData->ECN; + } } } else {