Ingest XDP v0.16.7 and use TCP CIBIR rules when needed (#3462)

Ingest XDP v0.16.7 and use TCP CIBIR rules when needed.

Changes to our tests:
1. 0-RTT tests are disabled. QTIP caches only one packet before handshake completes. So, if multiple 0-RTT packets are sent, only one of them will make it.
2. NAT rebind doesn't apply to TCP.  So, they are disabled.
3. Due to implementation limitations, sharing bindings isn't supported. Some tests are tweaked to always create a new binding per connection. For simplicity, the implementation assumes client side sockets have a 1:1 mapping to QUIC connection.
This commit is contained in:
Yi Huang 2023-02-28 17:32:50 -08:00 коммит произвёл GitHub
Родитель fe2fc5944a
Коммит 1edd42421a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 403 добавлений и 103 удалений

10
.github/workflows/build.yml поставляемый
Просмотреть файл

@ -69,6 +69,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 0
- name: Prepare Machine
shell: pwsh
run: scripts/prepare-machine.ps1 -ForBuild -Tls ${{ matrix.tls }}
@ -104,7 +106,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 2
fetch-depth: 0
submodules: 'recursive'
- name: Set ownership
run: |
@ -139,6 +141,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 0
- name: Prepare Machine
shell: pwsh
run: scripts/prepare-machine.ps1 -ForBuild -Tls ${{ matrix.tls }}
@ -187,6 +191,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 0
- name: Install Perl
uses: shogo82148/actions-setup-perl@e0737ade83f9863f9f5c00d8470b6d7bec207fee
with:
@ -217,6 +223,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 0
- name: Prepare Machine
shell: pwsh
run: scripts/prepare-machine.ps1 -ForBuild -ForKernel

13
.github/workflows/bvt.yml поставляемый
Просмотреть файл

@ -30,6 +30,7 @@ jobs:
tls: [schannel, openssl, openssl3]
systemcrypto: ['', '-UseSystemOpenSSLCrypto']
xdp: ['', '-UseXdp']
qtip: ['', '-UseQtip']
sanitize: ['', '-Sanitize']
exclude:
# Schannel only supported on windows-2022
@ -85,10 +86,14 @@ jobs:
xdp: '-UseXdp'
- os: windows-2019
xdp: '-UseXdp'
# QTIP only works with XDP
- xdp: ''
qtip: '-UseQtip'
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 0
- name: Install Perl
if: runner.os == 'Windows'
uses: shogo82148/actions-setup-perl@e0737ade83f9863f9f5c00d8470b6d7bec207fee
@ -114,12 +119,12 @@ jobs:
- name: Test
shell: pwsh
timeout-minutes: 120
run: scripts/test.ps1 -Config Debug -Arch ${{ matrix.arch }} -Tls ${{ matrix.tls }} -OsRunner ${{ matrix.os }} -GHA -LogProfile Basic.Light -GenerateXmlResults ${{ matrix.xdp }}
run: scripts/test.ps1 -Config Debug -Arch ${{ matrix.arch }} -Tls ${{ matrix.tls }} -OsRunner ${{ matrix.os }} -GHA -LogProfile Basic.Light -GenerateXmlResults ${{ matrix.xdp }} ${{ matrix.qtip }}
- name: Upload on Failure
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
if: failure()
with:
name: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.tls }}${{ matrix.systemcrypto }}${{ matrix.xdp }}${{ matrix.sanitize }}
name: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.tls }}${{ matrix.systemcrypto }}${{ matrix.xdp }}${{ matrix.qtip }}${{ matrix.sanitize }}
path: artifacts
# TODO: Get this working

2
.github/workflows/stress.yml поставляемый
Просмотреть файл

@ -74,6 +74,8 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 0
- name: Install Perl
if: runner.os == 'Windows'
uses: shogo82148/actions-setup-perl@e0737ade83f9863f9f5c00d8470b6d7bec207fee

2
.github/workflows/test-down-level.yml поставляемый
Просмотреть файл

@ -51,6 +51,8 @@ jobs:
rubygems.org:443
- name: Checkout repository
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
with:
fetch-depth: 0
- name: Prepare Machine
run: scripts/prepare-machine.ps1 -Tls ${{ matrix.tls }} -DisableTest
shell: pwsh

Просмотреть файл

@ -134,7 +134,10 @@ param (
[switch]$DuoNic = $false,
[Parameter(Mandatory = $false)]
[string]$OsRunner = ""
[string]$OsRunner = "",
[Parameter(Mandatory = $false)]
[switch]$UseQtip = $false
)
Set-StrictMode -Version 'Latest'
@ -382,6 +385,9 @@ function Start-TestCase([String]$Name) {
if ($DuoNic) {
$Arguments += " --duoNic"
}
if ($UseQtip) {
$Arguments += " --useQTIP"
}
if ("" -ne $OsRunner) {
$Arguments += " --osRunner=$OsRunner"
}
@ -425,6 +431,9 @@ function Start-AllTestCases {
if ($DuoNic) {
$Arguments += " --duoNic"
}
if ($UseQtip) {
$Arguments += " --useQTIP"
}
if ("" -ne $OsRunner) {
$Arguments += " --osRunner=$OsRunner"
}

Просмотреть файл

@ -168,6 +168,9 @@ param (
[Parameter(Mandatory = $false)]
[switch]$UseXdp = $false,
[Parameter(Mandatory = $false)]
[switch]$UseQtip = $false,
[Parameter(Mandatory = $false)]
[string]$OsRunner = ""
)
@ -333,6 +336,9 @@ if ($ErrorsAsWarnings) {
if ("" -ne $OsRunner) {
$TestArguments += " -OsRunner $OsRunner"
}
if ($UseQtip) {
$TestArguments += " -UseQtip"
}
if (![string]::IsNullOrWhiteSpace($ExtraArtifactDir)) {
$TestArguments += " -ExtraArtifactDir $ExtraArtifactDir"

Просмотреть файл

@ -1,3 +1,3 @@
{
"path" : "https://github.com/microsoft/xdp-for-windows/releases/download/v0.16.5/xdp-devkit-x64-0.16.5-prerelease.zip"
"path" : "https://github.com/microsoft/xdp-for-windows/releases/download/v0.16.7/xdp-devkit-x64-0.16.7-prerelease.zip"
}

Просмотреть файл

@ -203,18 +203,44 @@ tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, AllocFailure , arg2, arg3);\
/*----------------------------------------------------------
// Decoder Ring for DatapathSendTcpControl
// [data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!
// QuicTraceEvent(
DatapathSendTcpControl,
"[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
(uint8_t)(TH_FIN | TH_ACK),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = SendData->Buffer.Length = arg3
// arg4 = arg4 = (uint8_t)(TH_FIN | TH_ACK) = arg4
// arg5 = arg5 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg5
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg6
----------------------------------------------------------*/
#ifndef _clog_9_ARGS_TRACE_DatapathSendTcpControl
#define _clog_9_ARGS_TRACE_DatapathSendTcpControl(uniqueId, encoded_arg_string, arg2, arg3, arg4, arg5, arg5_len, arg6, arg6_len)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, DatapathSendTcpControl , arg2, arg3, arg4, arg5_len, arg5, arg6_len, arg6);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathSend
// [data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!
// QuicTraceEvent(
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = SendData->Buffer.Length = arg3
// arg4 = arg4 = 1 = arg4

Просмотреть файл

@ -227,18 +227,57 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, AllocFailure,
/*----------------------------------------------------------
// Decoder Ring for DatapathSendTcpControl
// [data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!
// QuicTraceEvent(
DatapathSendTcpControl,
"[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
(uint8_t)(TH_FIN | TH_ACK),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = SendData->Buffer.Length = arg3
// arg4 = arg4 = (uint8_t)(TH_FIN | TH_ACK) = arg4
// arg5 = arg5 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg5
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg6
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, DatapathSendTcpControl,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,
unsigned char, arg4,
unsigned int, arg5_len,
const void *, arg5,
unsigned int, arg6_len,
const void *, arg6),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3, arg3)
ctf_integer(unsigned char, arg4, arg4)
ctf_integer(unsigned int, arg5_len, arg5_len)
ctf_sequence(char, arg5, arg5, unsigned int, arg5_len)
ctf_integer(unsigned int, arg6_len, arg6_len)
ctf_sequence(char, arg6, arg6, unsigned int, arg6_len)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathSend
// [data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!
// QuicTraceEvent(
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = SendData->Buffer.Length = arg3
// arg4 = arg4 = 1 = arg4

Просмотреть файл

@ -1863,6 +1863,41 @@
outType="win:SocketAddress"
/>
</template>
<template tid="tid_DATA_SEND_TCP_CONTROL">
<data
inType="win:Pointer"
name="UdpBinding"
/>
<data
inType="win:UInt32"
name="SegmentSize"
/>
<data
inType="win:UInt8"
name="TcpFlags"
outType="win:HexInt8"
/>
<data
inType="win:UInt8"
name="RemoteAddrLength"
/>
<data
inType="win:Binary"
length="RemoteAddrLength"
name="RemoteAddr"
outType="win:SocketAddress"
/>
<data
inType="win:UInt8"
name="LocalAddrLength"
/>
<data
inType="win:Binary"
length="LocalAddrLength"
name="LocalAddr"
outType="win:SocketAddress"
/>
</template>
<template tid="tid_DATA_SEND_RECV">
<data
inType="win:Pointer"
@ -3592,6 +3627,15 @@
template="tid_UDP_ADDRESS"
value="9224"
/>
<event
keywords="ut:UDP ut:LowVolume"
level="win:Informational"
message="$(string.Etw.DatapathSendTcpControl)"
opcode="Datapath"
symbol="QuicDatapathSendTcpControl"
template="tid_DATA_SEND_TCP_CONTROL"
value="9225"
/>
<!-- 10240 - 11263 | Logs (not events) -->
<event
keywords="ut:Log"
@ -4765,6 +4809,10 @@
id="Etw.ConnStatsV2"
value="[conn][%1] STATS: SRtt=%2 CongestionCount=%3 PersistentCongestionCount=%4 SendTotalBytes=%5 RecvTotalBytes=%6 CongestionWindow=%7 Cc=%8 EcnCongestionCount=%8"
/>
<string
id="Etw.DatapathSendTcpControl"
value="[data][%1] Send %2 bytes TCP control packet Flags=%3 Dst=%5 Src=%7"
/>
</stringTable>
</resources>
</localization>

Просмотреть файл

@ -2931,6 +2931,34 @@
],
"macroName": "QuicTraceEvent"
},
"DatapathSendTcpControl": {
"ModuleProperites": {},
"TraceString": "[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!",
"UniqueId": "DatapathSendTcpControl",
"splitArgs": [
{
"DefinationEncoding": "p",
"MacroVariableName": "arg2"
},
{
"DefinationEncoding": "u",
"MacroVariableName": "arg3"
},
{
"DefinationEncoding": "hhu",
"MacroVariableName": "arg4"
},
{
"DefinationEncoding": "!ADDR!",
"MacroVariableName": "arg5"
},
{
"DefinationEncoding": "!ADDR!",
"MacroVariableName": "arg6"
}
],
"macroName": "QuicTraceEvent"
},
"DatapathShutDownComplete": {
"ModuleProperites": {},
"TraceString": "[data][%p] Shut down (complete)",
@ -13197,6 +13225,11 @@
"TraceID": "DatapathSend",
"EncodingString": "[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!"
},
{
"UniquenessHash": "798b4c99-cb62-f6d9-178d-daf707dc6c10",
"TraceID": "DatapathSendTcpControl",
"EncodingString": "[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!"
},
{
"UniquenessHash": "4f1e0892-0852-480e-71db-5b9bb377aabc",
"TraceID": "DatapathShutDownComplete",

Просмотреть файл

@ -1156,12 +1156,11 @@ CxPlatDpRawSocketAckFin(
}
QuicTraceEvent(
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
DatapathSendTcpControl,
"[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
(uint8_t)(TH_FIN | TH_ACK),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
CXPLAT_DBG_ASSERT(Route->State == RouteResolved);
@ -1195,39 +1194,39 @@ CxPlatDpRawSocketAckSyn(
return;
}
QuicTraceEvent(
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
uint8_t TcpFlags = Packet->Reserved == L4_TYPE_TCP_SYN ? (TH_SYN | TH_ACK) : TH_ACK;
CXPLAT_DBG_ASSERT(Route->State == RouteResolved);
CXPLAT_DBG_ASSERT(Route->Queue != NULL);
const CXPLAT_INTERFACE* Interface = CxPlatDpRawGetInterfaceFromQueue(Route->Queue);
TCP_HEADER* ReceivedTcpHeader = (TCP_HEADER*)(Packet->Buffer - Packet->ReservedEx);
QuicTraceEvent(
DatapathSendTcpControl,
"[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
TcpFlags,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
CxPlatFramingWriteHeaders(
Socket, Route, &SendData->Buffer, SendData->ECN,
Interface->OffloadStatus.Transmit.NetworkLayerXsum,
Interface->OffloadStatus.Transmit.TransportLayerXsum,
ReceivedTcpHeader->AckNumber,
CxPlatByteSwapUint32(CxPlatByteSwapUint32(ReceivedTcpHeader->SequenceNumber) + 1),
Packet->Reserved == L4_TYPE_TCP_SYN ? (TH_SYN | TH_ACK) : TH_ACK);
TcpFlags);
CxPlatDpRawTxEnqueue(SendData);
SendData = InterlockedFetchAndClearPointer(&Socket->PausedTcpSend);
if (SendData) {
CXPLAT_DBG_ASSERT(Socket->Connected);
QuicTraceEvent(
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
DatapathSendTcpControl,
"[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
TH_ACK,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
CxPlatFramingWriteHeaders(
@ -1280,12 +1279,11 @@ CxPlatDpRawSocketSyn(
}
QuicTraceEvent(
DatapathSend,
"[data][%p] Send %u bytes in %hhu buffers (segment=%hu) Dst=%!ADDR!, Src=%!ADDR!",
DatapathSendTcpControl,
"[data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!",
Socket,
SendData->Buffer.Length,
1,
(uint16_t)SendData->Buffer.Length,
TH_SYN,
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress));
CXPLAT_DBG_ASSERT(Route->State == RouteResolved);

Просмотреть файл

@ -857,8 +857,6 @@ CxPlatDpRawInterfaceUpdateRules(
.SubLayer = XDP_HOOK_INSPECT,
};
const UINT32 Flags = XDP_CREATE_PROGRAM_FLAG_SHARE; // TODO: support native/generic forced flags.
for (uint32_t i = 0; i < Interface->QueueCount; i++) {
XDP_QUEUE* Queue = &Interface->Queues[i];
@ -872,7 +870,7 @@ CxPlatDpRawInterfaceUpdateRules(
Interface->IfIndex,
&RxHook,
i,
Flags,
0,
Interface->Rules,
Interface->RuleCount,
&NewRxProgram);
@ -972,11 +970,12 @@ CxPlatDpRawInterfaceRemoveRules(
continue;
}
if (Rules[j].Match == XDP_MATCH_UDP_DST) {
if (Rules[j].Match == XDP_MATCH_UDP_DST || Rules[j].Match == XDP_MATCH_TCP_CONTROL_DST || Rules[j].Match == XDP_MATCH_TCP_DST) {
if (Rules[j].Pattern.Port != Interface->Rules[i].Pattern.Port) {
continue;
}
} else if (Rules[j].Match == XDP_MATCH_QUIC_FLOW_SRC_CID || Rules[j].Match == XDP_MATCH_QUIC_FLOW_DST_CID) {
} else if (Rules[j].Match == XDP_MATCH_QUIC_FLOW_SRC_CID || Rules[j].Match == XDP_MATCH_QUIC_FLOW_DST_CID ||
Rules[j].Match == XDP_MATCH_TCP_QUIC_FLOW_SRC_CID || Rules[j].Match == XDP_MATCH_TCP_QUIC_FLOW_DST_CID) {
if (Rules[j].Pattern.QuicFlow.UdpPort != Interface->Rules[i].Pattern.QuicFlow.UdpPort ||
Rules[j].Pattern.QuicFlow.CidLength != Interface->Rules[i].Pattern.QuicFlow.CidLength ||
Rules[j].Pattern.QuicFlow.CidOffset != Interface->Rules[i].Pattern.QuicFlow.CidOffset ||
@ -1309,62 +1308,57 @@ CxPlatDpRawPlumbRulesOnSocket(
{
XDP_DATAPATH* Xdp = (XDP_DATAPATH*)Socket->Datapath;
if (Socket->Wildcard) {
XDP_RULE Rules[3] = {0};
uint8_t RulesSize = 0;
if (Socket->CibirIdLength) {
//
// TODO: Add support for TCP based CIBIR rules.
//
XDP_RULE Rules[] = {
{
.Match = XDP_MATCH_QUIC_FLOW_SRC_CID,
.Pattern.QuicFlow.UdpPort = Socket->LocalAddress.Ipv4.sin_port,
.Pattern.QuicFlow.CidLength = Socket->CibirIdLength,
.Pattern.QuicFlow.CidOffset = Socket->CibirIdOffsetSrc,
.Action = XDP_PROGRAM_ACTION_REDIRECT,
.Redirect.TargetType = XDP_REDIRECT_TARGET_TYPE_XSK,
.Redirect.Target = NULL,
},
{
.Match = XDP_MATCH_QUIC_FLOW_DST_CID,
.Pattern.QuicFlow.UdpPort = Socket->LocalAddress.Ipv4.sin_port,
.Pattern.QuicFlow.CidLength = Socket->CibirIdLength,
.Pattern.QuicFlow.CidOffset = Socket->CibirIdOffsetDst,
.Action = XDP_PROGRAM_ACTION_REDIRECT,
.Redirect.TargetType = XDP_REDIRECT_TARGET_TYPE_XSK,
.Redirect.Target = NULL,
}
};
Rules[0].Match = Socket->UseTcp ? XDP_MATCH_TCP_QUIC_FLOW_SRC_CID : XDP_MATCH_QUIC_FLOW_SRC_CID;
Rules[0].Pattern.QuicFlow.UdpPort = Socket->LocalAddress.Ipv4.sin_port;
Rules[0].Pattern.QuicFlow.CidLength = Socket->CibirIdLength;
Rules[0].Pattern.QuicFlow.CidOffset = Socket->CibirIdOffsetSrc;
Rules[0].Action = XDP_PROGRAM_ACTION_REDIRECT;
Rules[0].Redirect.TargetType = XDP_REDIRECT_TARGET_TYPE_XSK;
Rules[0].Redirect.Target = NULL;
Rules[1].Match = Socket->UseTcp ? XDP_MATCH_TCP_QUIC_FLOW_DST_CID : XDP_MATCH_QUIC_FLOW_DST_CID;
Rules[1].Pattern.QuicFlow.UdpPort = Socket->LocalAddress.Ipv4.sin_port;
Rules[1].Pattern.QuicFlow.CidLength = Socket->CibirIdLength;
Rules[1].Pattern.QuicFlow.CidOffset = Socket->CibirIdOffsetDst;
Rules[1].Action = XDP_PROGRAM_ACTION_REDIRECT;
Rules[1].Redirect.TargetType = XDP_REDIRECT_TARGET_TYPE_XSK;
Rules[1].Redirect.Target = NULL;
memcpy(Rules[0].Pattern.QuicFlow.CidData, Socket->CibirId, Socket->CibirIdLength);
memcpy(Rules[1].Pattern.QuicFlow.CidData, Socket->CibirId, Socket->CibirIdLength);
CXPLAT_LIST_ENTRY* Entry;
for (Entry = Xdp->Interfaces.Flink; Entry != &Xdp->Interfaces; Entry = Entry->Flink) {
XDP_INTERFACE* Interface = CONTAINING_RECORD(Entry, XDP_INTERFACE, Link);
if (IsCreated) {
CxPlatDpRawInterfaceAddRules(Interface, Rules, 2);
} else {
CxPlatDpRawInterfaceRemoveRules(Interface, Rules, 2);
}
RulesSize = 2;
if (Socket->UseTcp) {
Rules[2].Match = XDP_MATCH_TCP_CONTROL_DST;
Rules[2].Pattern.Port = Socket->LocalAddress.Ipv4.sin_port;
Rules[2].Action = XDP_PROGRAM_ACTION_REDIRECT;
Rules[2].Redirect.TargetType = XDP_REDIRECT_TARGET_TYPE_XSK;
Rules[2].Redirect.Target = NULL;
++RulesSize;
}
CXPLAT_DBG_ASSERT(RulesSize <= RTL_NUMBER_OF(Rules));
} else {
const XDP_RULE Rule = {
.Match = Socket->UseTcp ? XDP_MATCH_TCP_DST : XDP_MATCH_UDP_DST,
.Pattern.Port = Socket->LocalAddress.Ipv4.sin_port,
.Action = XDP_PROGRAM_ACTION_REDIRECT,
.Redirect.TargetType = XDP_REDIRECT_TARGET_TYPE_XSK,
.Redirect.Target = NULL,
};
Rules[0].Match = Socket->UseTcp ? XDP_MATCH_TCP_DST : XDP_MATCH_UDP_DST;
Rules[0].Pattern.Port = Socket->LocalAddress.Ipv4.sin_port;
Rules[0].Action = XDP_PROGRAM_ACTION_REDIRECT;
Rules[0].Redirect.TargetType = XDP_REDIRECT_TARGET_TYPE_XSK;
Rules[0].Redirect.Target = NULL;
CXPLAT_LIST_ENTRY* Entry;
for (Entry = Xdp->Interfaces.Flink; Entry != &Xdp->Interfaces; Entry = Entry->Flink) {
XDP_INTERFACE* Interface = CONTAINING_RECORD(Entry, XDP_INTERFACE, Link);
if (IsCreated) {
CxPlatDpRawInterfaceAddRules(Interface, &Rule, 1);
} else {
CxPlatDpRawInterfaceRemoveRules(Interface, &Rule, 1);
}
}
RulesSize = 1;
}
CXPLAT_LIST_ENTRY* Entry;
for (Entry = Xdp->Interfaces.Flink; Entry != &Xdp->Interfaces; Entry = Entry->Flink) {
XDP_INTERFACE* Interface = CONTAINING_RECORD(Entry, XDP_INTERFACE, Link);
if (IsCreated) {
CxPlatDpRawInterfaceAddRules(Interface, Rules, RulesSize);
} else {
CxPlatDpRawInterfaceRemoveRules(Interface, Rules, RulesSize);
}
}
} else {
//

Просмотреть файл

@ -13,6 +13,9 @@
bool TestingKernelMode = false;
bool PrivateTestLibrary = false;
bool UseDuoNic = false;
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
bool UseQTIP = false;
#endif
const MsQuicApi* MsQuic;
const char* OsRunner = nullptr;
QUIC_CREDENTIAL_CONFIG ServerSelfSignedCredConfig;
@ -75,6 +78,17 @@ public:
printf("Initializing for User Mode tests\n");
MsQuic = new(std::nothrow) MsQuicApi();
ASSERT_TRUE(QUIC_SUCCEEDED(MsQuic->GetInitStatus()));
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP) {
QUIC_EXECUTION_CONFIG Config = {QUIC_EXECUTION_CONFIG_FLAG_QTIP, 10000, 0};
ASSERT_TRUE(QUIC_SUCCEEDED(
MsQuic->SetParam(
nullptr,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
sizeof(Config),
&Config)));
}
#endif // QUIC_API_ENABLE_PREVIEW_FEATURES
memcpy(&ServerSelfSignedCredConfig, SelfSignedCertParams, sizeof(QUIC_CREDENTIAL_CONFIG));
memcpy(&ServerSelfSignedCredConfigClientAuth, SelfSignedCertParams, sizeof(QUIC_CREDENTIAL_CONFIG));
ServerSelfSignedCredConfigClientAuth.Flags |=
@ -1440,6 +1454,14 @@ TEST_P(WithFamilyArgs, ClientBlockedSourcePort) {
#if QUIC_TEST_DATAPATH_HOOKS_ENABLED
TEST_P(WithFamilyArgs, RebindPort) {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP) {
//
// NAT rebind doesn't make sense for TCP and QTIP.
//
return;
}
#endif
TestLoggerT<ParamType> Logger("QuicTestNatPortRebind", GetParam());
if (TestingKernelMode) {
QUIC_RUN_REBIND_PARAMS Params = {
@ -1453,6 +1475,14 @@ TEST_P(WithFamilyArgs, RebindPort) {
}
TEST_P(WithRebindPaddingArgs, RebindPortPadded) {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP) {
//
// NAT rebind doesn't make sense for TCP and QTIP.
//
return;
}
#endif
TestLoggerT<ParamType> Logger("QuicTestNatPortRebind(pad)", GetParam());
if (TestingKernelMode) {
QUIC_RUN_REBIND_PARAMS Params = {
@ -1466,6 +1496,14 @@ TEST_P(WithRebindPaddingArgs, RebindPortPadded) {
}
TEST_P(WithFamilyArgs, RebindAddr) {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP) {
//
// NAT rebind doesn't make sense for TCP and QTIP.
//
return;
}
#endif
TestLoggerT<ParamType> Logger("QuicTestNatAddrRebind", GetParam());
if (TestingKernelMode) {
QUIC_RUN_REBIND_PARAMS Params = {
@ -1479,6 +1517,14 @@ TEST_P(WithFamilyArgs, RebindAddr) {
}
TEST_P(WithRebindPaddingArgs, RebindAddrPadded) {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP) {
//
// NAT rebind doesn't make sense for TCP and QTIP.
//
return;
}
#endif
TestLoggerT<ParamType> Logger("QuicTestNatAddrRebind(pad)", GetParam());
if (TestingKernelMode) {
QUIC_RUN_REBIND_PARAMS Params = {
@ -1655,6 +1701,16 @@ TEST_P(WithSendArgs3, SendIntermittently) {
#ifndef QUIC_DISABLE_0RTT_TESTS
TEST_P(WithSend0RttArgs1, Send0Rtt) {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP) {
//
// QTIP doesn't work with 0-RTT. QTIP only pauses and caches 1 packet during
// TCP handshake.
//
return;
}
#endif
TestLoggerT<ParamType> Logger("Send0Rtt", GetParam());
if (TestingKernelMode) {
QUIC_RUN_CONNECT_AND_PING_PARAMS Params = {
@ -1694,6 +1750,15 @@ TEST_P(WithSend0RttArgs1, Send0Rtt) {
}
TEST_P(WithSend0RttArgs2, Reject0Rtt) {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP) {
//
// QTIP doesn't work with 0-RTT. QTIP only pauses and caches 1 packet during
// TCP handshake.
//
return;
}
#endif
TestLoggerT<ParamType> Logger("Reject0Rtt", GetParam());
if (TestingKernelMode) {
QUIC_RUN_CONNECT_AND_PING_PARAMS Params = {
@ -2305,6 +2370,13 @@ int main(int argc, char** argv) {
}
} else if (strcmp("--duoNic", argv[i]) == 0) {
UseDuoNic = true;
} else if (strcmp("--useQTIP", argv[i]) == 0) {
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
UseQTIP = true;
#else
printf("QTIP is not supported in this build.\n");
return -1;
#endif
} else if (strstr(argv[i], "--osRunner")) {
OsRunner = argv[i] + sizeof("--osRunner");
}

Просмотреть файл

@ -20,6 +20,9 @@
#endif
extern bool TestingKernelMode;
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
extern bool UseQTIP;
#endif
class WithBool : public testing::Test,
public testing::WithParamInterface<bool> {
@ -341,8 +344,15 @@ struct SendArgs2 {
for (bool UseZeroRtt : { false, true })
#else
for (bool UseZeroRtt : { false })
#endif
{
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
if (UseQTIP && UseZeroRtt) {
continue;
}
#endif
list.push_back({ Family, UseSendBuffer, UseZeroRtt });
}
return list;
}
};

Просмотреть файл

@ -16,6 +16,10 @@ Abstract:
#pragma warning(disable:6387) // '_Param_(1)' could be '0': this does not adhere to the specification for the function
#ifdef QUIC_USE_RAW_DATAPATH
extern bool UseQTIP;
#endif
void QuicTestValidateApi()
{
TEST_QUIC_STATUS(
@ -2131,7 +2135,6 @@ void QuicTestStatefulGlobalSetParam()
//
{
TestScopeLogger LogScope1("Set QUIC_PARAM_GLOBAL_EXECUTION_CONFIG when MsQuicLib.Datapath != NULL");
GlobalSettingScope ParamScope(QUIC_PARAM_GLOBAL_EXECUTION_CONFIG);
uint16_t Data[QUIC_EXECUTION_CONFIG_MIN_SIZE] = {};
TEST_QUIC_STATUS(
QUIC_STATUS_INVALID_STATE,
@ -2511,6 +2514,20 @@ void QuicTestGlobalParam()
SimpleGetParamTest(nullptr, QUIC_PARAM_GLOBAL_EXECUTION_CONFIG, DataLength, Data);
}
#ifdef QUIC_USE_RAW_DATAPATH
if (!UseQTIP) {
//
// Good GetParam with length == 0 when QTIP is not in use.
//
uint32_t BufferLength = 0;
TEST_QUIC_SUCCEEDED(
MsQuic->GetParam(
nullptr,
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
&BufferLength,
nullptr));
}
#else
//
// Good GetParam with length == 0
//
@ -2521,6 +2538,7 @@ void QuicTestGlobalParam()
QUIC_PARAM_GLOBAL_EXECUTION_CONFIG,
&BufferLength,
nullptr));
#endif
}
#endif

Просмотреть файл

@ -14,6 +14,10 @@ Abstract:
#include "DataTest.cpp.clog.h"
#endif
#ifdef QUIC_USE_RAW_DATAPATH
extern bool UseQTIP;
#endif
/*
Helper function to estimate a maximum timeout for a test with a
particular payload length.
@ -471,18 +475,30 @@ QuicTestConnectAndPing(
}
TEST_QUIC_SUCCEEDED(Connections.get()[i]->SetRemoteAddr(RemoteAddr));
#ifdef QUIC_USE_RAW_DATAPATH
if (!UseQTIP && i != 0) {
Connections.get()[i]->SetLocalAddr(LocalAddr);
}
#else
if (i != 0) {
Connections.get()[i]->SetLocalAddr(LocalAddr);
}
#endif
TEST_QUIC_SUCCEEDED(
Connections.get()[i]->Start(
ClientConfiguration,
QuicAddrFamily,
ClientZeroRtt ? QUIC_LOCALHOST_FOR_AF(QuicAddrFamily) : nullptr,
ServerLocalAddr.GetPort()));
#ifdef QUIC_USE_RAW_DATAPATH
if (!UseQTIP && i == 0) {
Connections.get()[i]->GetLocalAddr(LocalAddr);
}
#else
if (i == 0) {
Connections.get()[i]->GetLocalAddr(LocalAddr);
}
#endif
}
}
}

Просмотреть файл

@ -14,6 +14,10 @@ Abstract:
#include "MtuTest.cpp.clog.h"
#endif
#ifdef QUIC_USE_RAW_DATAPATH
extern bool UseQTIP;
#endif
static QUIC_STATUS MtuStreamCallback(_In_ MsQuicStream*, _In_opt_ void*, _Inout_ QUIC_STREAM_EVENT*) {
return QUIC_STATUS_SUCCESS;
}
@ -45,6 +49,12 @@ struct ResetSettings {
void
QuicTestMtuSettings()
{
#ifdef QUIC_USE_RAW_DATAPATH
const uint16_t DefaultMaximumMtu = UseQTIP ? 1488 : 1500; // reserve 12B for TCP header
#else
const uint16_t DefaultMaximumMtu = 1500;
#endif
{
//
// Test setting on library works
@ -210,7 +220,7 @@ QuicTestMtuSettings()
{
MsQuicSettings ServerSettings;
ServerSettings.
SetMaximumMtu(1500).
SetMaximumMtu(DefaultMaximumMtu).
SetMinimumMtu(1280).
SetPeerUnidiStreamCount(1).
SetIdleTimeoutMs(30000).
@ -227,7 +237,7 @@ QuicTestMtuSettings()
{
MsQuicSettings Settings;
Settings.
SetMaximumMtu(1500).
SetMaximumMtu(DefaultMaximumMtu).
SetMinimumMtu(1280).
SetMtuDiscoveryMissingProbeCount(1).
SetPeerUnidiStreamCount(1).
@ -244,7 +254,7 @@ QuicTestMtuSettings()
MtuDropHelper ServerDropper(
0,
ServerLocalAddr.GetPort(),
1499);
DefaultMaximumMtu - 1);
TEST_QUIC_SUCCEEDED(Connection.Start(ClientConfiguration, ServerLocalAddr.GetFamily(), QUIC_TEST_LOOPBACK_FOR_AF(ServerLocalAddr.GetFamily()), ServerLocalAddr.GetPort()));
MsQuicStream Stream(Connection, QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL);
TEST_QUIC_SUCCEEDED(Stream.GetInitStatus());
@ -266,7 +276,7 @@ QuicTestMtuSettings()
//
QUIC_STATISTICS_V2 Stats;
TEST_QUIC_SUCCEEDED(Connection.GetStatistics(&Stats));
TEST_NOT_EQUAL(1500, Stats.SendPathMtu);
TEST_NOT_EQUAL(DefaultMaximumMtu, Stats.SendPathMtu);
TEST_NOT_EQUAL(1280, Stats.SendPathMtu);
ServerDropper.ClientDropPacketSize = 0xFFFF;
@ -283,7 +293,7 @@ QuicTestMtuSettings()
// Ensure our MTU is in the max
//
TEST_QUIC_SUCCEEDED(Connection.GetStatistics(&Stats));
TEST_EQUAL(1500, Stats.SendPathMtu);
TEST_EQUAL(DefaultMaximumMtu, Stats.SendPathMtu);
TEST_QUIC_SUCCEEDED(Stream.Send(&Buffer, 1, QUIC_SEND_FLAG_FIN));
@ -305,7 +315,11 @@ QuicTestMtuDiscovery(
TEST_QUIC_SUCCEEDED(Registration.GetInitStatus());
const uint16_t MinimumMtu = RaiseMinimumMtu ? 1360 : 1248;
#ifdef QUIC_USE_RAW_DATAPATH
const uint16_t MaximumMtu = UseQTIP ? 1488 : 1500; // reserve 12B for TCP header
#else
const uint16_t MaximumMtu = 1500;
#endif
MsQuicAlpn Alpn("MsQuicTest");
MsQuicSettings Settings;