Skip to content

Commit

Permalink
Only set IP_ECN when IP_TOS isn't supported. Only set ECN or TOS when…
Browse files Browse the repository at this point in the history
… ECN and DSCP are non-default
  • Loading branch information
anrossi committed Feb 4, 2025
1 parent 7fc999b commit cc4d4f8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/platform/datapath_raw_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
52 changes: 27 additions & 25 deletions src/platform/datapath_winkernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
37 changes: 20 additions & 17 deletions src/platform/datapath_winuser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
];

Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit cc4d4f8

Please sign in to comment.