Refactoring for cross-platform xdp placeholder (#3628)

This commit is contained in:
Daiki AMINAKA 2023-07-08 06:50:36 -07:00 коммит произвёл GitHub
Родитель dc64ccb47a
Коммит f596ae5313
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
34 изменённых файлов: 2699 добавлений и 1125 удалений

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

@ -15,8 +15,12 @@
../src/platform/datapath_winuser.c
../src/platform/datapath_raw_dpdk.c
../src/platform/datapath_raw_socket.c
../src/platform/datapath_raw_xdp.c
../src/platform/datapath_raw.c
../src/platform/datapath_raw_socket_win.c
../src/platform/datapath_raw_socket_linux.c
../src/platform/datapath_raw_xdp_win.c
../src/platform/datapath_raw_xdp_linux.c
../src/platform/datapath_raw_win.c
../src/platform/datapath_raw_linux.c
../src/platform/crypt_bcrypt.c
../src/platform/platform_winuser.c
../src/platform/toeplitz.c

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

@ -3307,7 +3307,7 @@ _IRQL_requires_max_(DISPATCH_LEVEL)
_Function_class_(CXPLAT_ROUTE_RESOLUTION_CALLBACK)
void
QuicConnQueueRouteCompletion(
_Inout_ QUIC_CONNECTION* Connection,
_Inout_ void* Context,
_When_(Succeeded == FALSE, _Reserved_)
_When_(Succeeded == TRUE, _In_reads_bytes_(6))
const uint8_t* PhysicalAddress,
@ -3315,6 +3315,7 @@ QuicConnQueueRouteCompletion(
_In_ BOOLEAN Succeeded
)
{
QUIC_CONNECTION* Connection = (QUIC_CONNECTION*)Context;
QUIC_OPERATION* ConnOper =
QuicOperationAlloc(Connection->Worker, QUIC_OPER_TYPE_ROUTE_COMPLETION);
if (ConnOper != NULL) {

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

@ -1522,7 +1522,7 @@ _IRQL_requires_max_(DISPATCH_LEVEL)
_Function_class_(CXPLAT_ROUTE_RESOLUTION_CALLBACK)
void
QuicConnQueueRouteCompletion(
_Inout_ QUIC_CONNECTION* Connection,
_Inout_ void* Context,
_When_(Succeeded == FALSE, _Reserved_)
_When_(Succeeded == TRUE, _In_reads_bytes_(6))
const uint8_t* PhysicalAddress,

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

@ -0,0 +1,145 @@
#ifndef CLOG_DO_NOT_INCLUDE_HEADER
#include <clog.h>
#endif
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER CLOG_DATAPATH_RAW_LINUX_C
#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "datapath_raw_linux.c.clog.h.lttng.h"
#if !defined(DEF_CLOG_DATAPATH_RAW_LINUX_C) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define DEF_CLOG_DATAPATH_RAW_LINUX_C
#include <lttng/tracepoint.h>
#define __int64 __int64_t
#include "datapath_raw_linux.c.clog.h.lttng.h"
#endif
#include <lttng/tracepoint-event.h>
#ifndef _clog_MACRO_QuicTraceEvent
#define _clog_MACRO_QuicTraceEvent 1
#define QuicTraceEvent(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
// QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_WORKER));
// arg2 = arg2 = "CXPLAT_DATAPATH" = arg2
// arg3 = arg3 = sizeof(CXPLAT_ROUTE_RESOLUTION_WORKER) = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_AllocFailure
#define _clog_4_ARGS_TRACE_AllocFailure(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_LINUX_C, AllocFailure , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
"CxPlatThreadCreate");
// arg2 = arg2 = Status = arg2
// arg3 = arg3 = "CxPlatThreadCreate" = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_LINUX_C, LibraryErrorStatus , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathCreated
// [data][%p] Created, local=%!ADDR!, remote=%!ADDR!
// QuicTraceEvent(
DatapathCreated,
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
*NewSocket,
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
// arg2 = arg2 = *NewSocket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress) = arg3
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress) = arg4
----------------------------------------------------------*/
#ifndef _clog_7_ARGS_TRACE_DatapathCreated
#define _clog_7_ARGS_TRACE_DatapathCreated(uniqueId, encoded_arg_string, arg2, arg3, arg3_len, arg4, arg4_len)\
tracepoint(CLOG_DATAPATH_RAW_LINUX_C, DatapathCreated , arg2, arg3_len, arg3, arg4_len, arg4);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathRecv
// [data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!
// QuicTraceEvent(
DatapathRecv,
"[data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!",
Socket,
Packets[i]->BufferLength,
Packets[i]->BufferLength,
CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->LocalAddress), &Packets[i]->Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->RemoteAddress), &Packets[i]->Route->RemoteAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = Packets[i]->BufferLength = arg3
// arg4 = arg4 = Packets[i]->BufferLength = arg4
// arg5 = arg5 = CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->LocalAddress), &Packets[i]->Route->LocalAddress) = arg5
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->RemoteAddress), &Packets[i]->Route->RemoteAddress) = arg6
----------------------------------------------------------*/
#ifndef _clog_9_ARGS_TRACE_DatapathRecv
#define _clog_9_ARGS_TRACE_DatapathRecv(uniqueId, encoded_arg_string, arg2, arg3, arg4, arg5, arg5_len, arg6, arg6_len)\
tracepoint(CLOG_DATAPATH_RAW_LINUX_C, DatapathRecv , 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));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = SendData->Buffer.Length = arg3
// arg4 = arg4 = 1 = arg4
// arg5 = arg5 = (uint16_t)SendData->Buffer.Length = arg5
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg6
// arg7 = arg7 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg7
----------------------------------------------------------*/
#ifndef _clog_10_ARGS_TRACE_DatapathSend
#define _clog_10_ARGS_TRACE_DatapathSend(uniqueId, encoded_arg_string, arg2, arg3, arg4, arg5, arg6, arg6_len, arg7, arg7_len)\
tracepoint(CLOG_DATAPATH_RAW_LINUX_C, DatapathSend , arg2, arg3, arg4, arg5, arg6_len, arg6, arg7_len, arg7);\
#endif
#ifdef __cplusplus
}
#endif
#ifdef CLOG_INLINE_IMPLEMENTATION
#include "quic.clog_datapath_raw_linux.c.clog.h.c"
#endif

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

@ -0,0 +1,159 @@
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
// QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_WORKER));
// arg2 = arg2 = "CXPLAT_DATAPATH" = arg2
// arg3 = arg3 = sizeof(CXPLAT_ROUTE_RESOLUTION_WORKER) = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_LINUX_C, AllocFailure,
TP_ARGS(
const char *, arg2,
unsigned long long, arg3),
TP_FIELDS(
ctf_string(arg2, arg2)
ctf_integer(uint64_t, arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
"CxPlatThreadCreate");
// arg2 = arg2 = Status = arg2
// arg3 = arg3 = "CxPlatThreadCreate" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_LINUX_C, LibraryErrorStatus,
TP_ARGS(
unsigned int, arg2,
const char *, arg3),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
ctf_string(arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathCreated
// [data][%p] Created, local=%!ADDR!, remote=%!ADDR!
// QuicTraceEvent(
DatapathCreated,
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
*NewSocket,
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
// arg2 = arg2 = *NewSocket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress) = arg3
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress) = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_LINUX_C, DatapathCreated,
TP_ARGS(
const void *, arg2,
unsigned int, arg3_len,
const void *, arg3,
unsigned int, arg4_len,
const void *, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3_len, arg3_len)
ctf_sequence(char, arg3, arg3, unsigned int, arg3_len)
ctf_integer(unsigned int, arg4_len, arg4_len)
ctf_sequence(char, arg4, arg4, unsigned int, arg4_len)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathRecv
// [data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!
// QuicTraceEvent(
DatapathRecv,
"[data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!",
Socket,
Packets[i]->BufferLength,
Packets[i]->BufferLength,
CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->LocalAddress), &Packets[i]->Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->RemoteAddress), &Packets[i]->Route->RemoteAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = Packets[i]->BufferLength = arg3
// arg4 = arg4 = Packets[i]->BufferLength = arg4
// arg5 = arg5 = CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->LocalAddress), &Packets[i]->Route->LocalAddress) = arg5
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->RemoteAddress), &Packets[i]->Route->RemoteAddress) = arg6
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_LINUX_C, DatapathRecv,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,
unsigned short, 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 short, 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));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = SendData->Buffer.Length = arg3
// arg4 = arg4 = 1 = arg4
// arg5 = arg5 = (uint16_t)SendData->Buffer.Length = arg5
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg6
// arg7 = arg7 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg7
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_LINUX_C, DatapathSend,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,
unsigned char, arg4,
unsigned short, arg5,
unsigned int, arg6_len,
const void *, arg6,
unsigned int, arg7_len,
const void *, arg7),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3, arg3)
ctf_integer(unsigned char, arg4, arg4)
ctf_integer(unsigned short, arg5, arg5)
ctf_integer(unsigned int, arg6_len, arg6_len)
ctf_sequence(char, arg6, arg6, unsigned int, arg6_len)
ctf_integer(unsigned int, arg7_len, arg7_len)
ctf_sequence(char, arg7, arg7, unsigned int, arg7_len)
)
)

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

@ -57,60 +57,18 @@ tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, RouteResolutionEnd , arg1, arg3, arg4, ar
/*----------------------------------------------------------
// Decoder Ring for RouteResolutionStart
// [conn][%p] Starting to look up neighbor on Path[%hhu] with status %u
// QuicTraceLogConnInfo(
RouteResolutionStart,
Context,
"Starting to look up neighbor on Path[%hhu] with status %u",
PathId,
Status);
// arg1 = arg1 = Context = arg1
// arg3 = arg3 = PathId = arg3
// arg4 = arg4 = Status = arg4
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_RouteResolutionStart
#define _clog_5_ARGS_TRACE_RouteResolutionStart(uniqueId, arg1, encoded_arg_string, arg3, arg4)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, RouteResolutionStart , arg1, arg3, arg4);\
#endif
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
WsaError,
"WSAStartup");
// arg2 = arg2 = WsaError = arg2
// arg3 = arg3 = "WSAStartup" = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, LibraryErrorStatus , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathErrorStatus
// [data][%p] ERROR, %u, %s.
// QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"socket");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = WsaError = arg3
// arg4 = arg4 = "socket" = arg4
Datapath,
Length,
"packet is too small for a UDP header");
// arg2 = arg2 = Datapath = arg2
// arg3 = arg3 = Length = arg3
// arg4 = arg4 = "packet is too small for a UDP header" = arg4
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_DatapathErrorStatus
#define _clog_5_ARGS_TRACE_DatapathErrorStatus(uniqueId, encoded_arg_string, arg2, arg3, arg4)\
@ -121,88 +79,6 @@ tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, DatapathErrorStatus , arg2, arg3, arg4);\
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteStart
// [data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!
// QuicTraceEvent(
DatapathGetRouteStart,
"[data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg3
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg4
----------------------------------------------------------*/
#ifndef _clog_7_ARGS_TRACE_DatapathGetRouteStart
#define _clog_7_ARGS_TRACE_DatapathGetRouteStart(uniqueId, encoded_arg_string, arg2, arg3, arg3_len, arg4, arg4_len)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, DatapathGetRouteStart , arg2, arg3_len, arg3, arg4_len, arg4);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteComplete
// [data][%p] Query route result: %!ADDR!
// QuicTraceEvent(
DatapathGetRouteComplete,
"[data][%p] Query route result: %!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress) = arg3
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_DatapathGetRouteComplete
#define _clog_5_ARGS_TRACE_DatapathGetRouteComplete(uniqueId, encoded_arg_string, arg2, arg3, arg3_len)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, DatapathGetRouteComplete , arg2, arg3_len, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathError
// [data][%p] ERROR, %s.
// QuicTraceEvent(
DatapathError,
"[data][%p] ERROR, %s.",
Socket,
"no matching interface/queue");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = "no matching interface/queue" = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_DatapathError
#define _clog_4_ARGS_TRACE_DatapathError(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, DatapathError , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
// QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION));
// arg2 = arg2 = "CXPLAT_DATAPATH" = arg2
// arg3 = arg3 = sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION) = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_AllocFailure
#define _clog_4_ARGS_TRACE_AllocFailure(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_C, AllocFailure , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathSendTcpControl
// [data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!

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

@ -48,68 +48,18 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, RouteResolutionEnd,
/*----------------------------------------------------------
// Decoder Ring for RouteResolutionStart
// [conn][%p] Starting to look up neighbor on Path[%hhu] with status %u
// QuicTraceLogConnInfo(
RouteResolutionStart,
Context,
"Starting to look up neighbor on Path[%hhu] with status %u",
PathId,
Status);
// arg1 = arg1 = Context = arg1
// arg3 = arg3 = PathId = arg3
// arg4 = arg4 = Status = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, RouteResolutionStart,
TP_ARGS(
const void *, arg1,
unsigned char, arg3,
unsigned int, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg1, arg1)
ctf_integer(unsigned char, arg3, arg3)
ctf_integer(unsigned int, arg4, arg4)
)
)
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
WsaError,
"WSAStartup");
// arg2 = arg2 = WsaError = arg2
// arg3 = arg3 = "WSAStartup" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, LibraryErrorStatus,
TP_ARGS(
unsigned int, arg2,
const char *, arg3),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
ctf_string(arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathErrorStatus
// [data][%p] ERROR, %u, %s.
// QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"socket");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = WsaError = arg3
// arg4 = arg4 = "socket" = arg4
Datapath,
Length,
"packet is too small for a UDP header");
// arg2 = arg2 = Datapath = arg2
// arg3 = arg3 = Length = arg3
// arg4 = arg4 = "packet is too small for a UDP header" = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, DatapathErrorStatus,
TP_ARGS(
@ -125,108 +75,6 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, DatapathErrorStatus,
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteStart
// [data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!
// QuicTraceEvent(
DatapathGetRouteStart,
"[data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg3
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, DatapathGetRouteStart,
TP_ARGS(
const void *, arg2,
unsigned int, arg3_len,
const void *, arg3,
unsigned int, arg4_len,
const void *, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3_len, arg3_len)
ctf_sequence(char, arg3, arg3, unsigned int, arg3_len)
ctf_integer(unsigned int, arg4_len, arg4_len)
ctf_sequence(char, arg4, arg4, unsigned int, arg4_len)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteComplete
// [data][%p] Query route result: %!ADDR!
// QuicTraceEvent(
DatapathGetRouteComplete,
"[data][%p] Query route result: %!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress) = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, DatapathGetRouteComplete,
TP_ARGS(
const void *, arg2,
unsigned int, arg3_len,
const void *, arg3),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3_len, arg3_len)
ctf_sequence(char, arg3, arg3, unsigned int, arg3_len)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathError
// [data][%p] ERROR, %s.
// QuicTraceEvent(
DatapathError,
"[data][%p] ERROR, %s.",
Socket,
"no matching interface/queue");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = "no matching interface/queue" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, DatapathError,
TP_ARGS(
const void *, arg2,
const char *, arg3),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_string(arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
// QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION));
// arg2 = arg2 = "CXPLAT_DATAPATH" = arg2
// arg3 = arg3 = sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION) = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_C, AllocFailure,
TP_ARGS(
const char *, arg2,
unsigned long long, arg3),
TP_FIELDS(
ctf_string(arg2, arg2)
ctf_integer(uint64_t, arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathSendTcpControl
// [data][%p] Send %u bytes TCP control packet Flags=%hhu Dst=%!ADDR!, Src=%!ADDR!

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

@ -0,0 +1,12 @@
#ifndef CLOG_DO_NOT_INCLUDE_HEADER
#include <clog.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#ifdef CLOG_INLINE_IMPLEMENTATION
#include "quic.clog_datapath_raw_socket_linux.c.clog.h.c"
#endif

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

@ -0,0 +1,179 @@
#ifndef CLOG_DO_NOT_INCLUDE_HEADER
#include <clog.h>
#endif
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER CLOG_DATAPATH_RAW_SOCKET_WIN_C
#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "datapath_raw_socket_win.c.clog.h.lttng.h"
#if !defined(DEF_CLOG_DATAPATH_RAW_SOCKET_WIN_C) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define DEF_CLOG_DATAPATH_RAW_SOCKET_WIN_C
#include <lttng/tracepoint.h>
#define __int64 __int64_t
#include "datapath_raw_socket_win.c.clog.h.lttng.h"
#endif
#include <lttng/tracepoint-event.h>
#ifndef _clog_MACRO_QuicTraceLogConnInfo
#define _clog_MACRO_QuicTraceLogConnInfo 1
#define QuicTraceLogConnInfo(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
#endif
#ifndef _clog_MACRO_QuicTraceEvent
#define _clog_MACRO_QuicTraceEvent 1
#define QuicTraceEvent(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------
// Decoder Ring for RouteResolutionStart
// [conn][%p] Starting to look up neighbor on Path[%hhu] with status %u
// QuicTraceLogConnInfo(
RouteResolutionStart,
Context,
"Starting to look up neighbor on Path[%hhu] with status %u",
PathId,
Status);
// arg1 = arg1 = Context = arg1
// arg3 = arg3 = PathId = arg3
// arg4 = arg4 = Status = arg4
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_RouteResolutionStart
#define _clog_5_ARGS_TRACE_RouteResolutionStart(uniqueId, arg1, encoded_arg_string, arg3, arg4)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, RouteResolutionStart , arg1, arg3, arg4);\
#endif
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
WsaError,
"WSAStartup");
// arg2 = arg2 = WsaError = arg2
// arg3 = arg3 = "WSAStartup" = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, LibraryErrorStatus , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathErrorStatus
// [data][%p] ERROR, %u, %s.
// QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Error,
"closesocket");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = Error = arg3
// arg4 = arg4 = "closesocket" = arg4
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_DatapathErrorStatus
#define _clog_5_ARGS_TRACE_DatapathErrorStatus(uniqueId, encoded_arg_string, arg2, arg3, arg4)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathErrorStatus , arg2, arg3, arg4);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteStart
// [data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!
// QuicTraceEvent(
DatapathGetRouteStart,
"[data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg3
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg4
----------------------------------------------------------*/
#ifndef _clog_7_ARGS_TRACE_DatapathGetRouteStart
#define _clog_7_ARGS_TRACE_DatapathGetRouteStart(uniqueId, encoded_arg_string, arg2, arg3, arg3_len, arg4, arg4_len)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathGetRouteStart , arg2, arg3_len, arg3, arg4_len, arg4);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteComplete
// [data][%p] Query route result: %!ADDR!
// QuicTraceEvent(
DatapathGetRouteComplete,
"[data][%p] Query route result: %!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress) = arg3
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_DatapathGetRouteComplete
#define _clog_5_ARGS_TRACE_DatapathGetRouteComplete(uniqueId, encoded_arg_string, arg2, arg3, arg3_len)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathGetRouteComplete , arg2, arg3_len, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for DatapathError
// [data][%p] ERROR, %s.
// QuicTraceEvent(
DatapathError,
"[data][%p] ERROR, %s.",
Socket,
"no matching interface/queue");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = "no matching interface/queue" = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_DatapathError
#define _clog_4_ARGS_TRACE_DatapathError(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathError , arg2, arg3);\
#endif
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
// QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION));
// arg2 = arg2 = "CXPLAT_DATAPATH" = arg2
// arg3 = arg3 = sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION) = arg3
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_AllocFailure
#define _clog_4_ARGS_TRACE_AllocFailure(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_SOCKET_WIN_C, AllocFailure , arg2, arg3);\
#endif
#ifdef __cplusplus
}
#endif
#ifdef CLOG_INLINE_IMPLEMENTATION
#include "quic.clog_datapath_raw_socket_win.c.clog.h.c"
#endif

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

@ -0,0 +1,179 @@
/*----------------------------------------------------------
// Decoder Ring for RouteResolutionStart
// [conn][%p] Starting to look up neighbor on Path[%hhu] with status %u
// QuicTraceLogConnInfo(
RouteResolutionStart,
Context,
"Starting to look up neighbor on Path[%hhu] with status %u",
PathId,
Status);
// arg1 = arg1 = Context = arg1
// arg3 = arg3 = PathId = arg3
// arg4 = arg4 = Status = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, RouteResolutionStart,
TP_ARGS(
const void *, arg1,
unsigned char, arg3,
unsigned int, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg1, arg1)
ctf_integer(unsigned char, arg3, arg3)
ctf_integer(unsigned int, arg4, arg4)
)
)
/*----------------------------------------------------------
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
WsaError,
"WSAStartup");
// arg2 = arg2 = WsaError = arg2
// arg3 = arg3 = "WSAStartup" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, LibraryErrorStatus,
TP_ARGS(
unsigned int, arg2,
const char *, arg3),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
ctf_string(arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathErrorStatus
// [data][%p] ERROR, %u, %s.
// QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Error,
"closesocket");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = Error = arg3
// arg4 = arg4 = "closesocket" = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathErrorStatus,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,
const char *, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3, arg3)
ctf_string(arg4, arg4)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteStart
// [data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!
// QuicTraceEvent(
DatapathGetRouteStart,
"[data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg3
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathGetRouteStart,
TP_ARGS(
const void *, arg2,
unsigned int, arg3_len,
const void *, arg3,
unsigned int, arg4_len,
const void *, arg4),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3_len, arg3_len)
ctf_sequence(char, arg3, arg3, unsigned int, arg3_len)
ctf_integer(unsigned int, arg4_len, arg4_len)
ctf_sequence(char, arg4, arg4, unsigned int, arg4_len)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathGetRouteComplete
// [data][%p] Query route result: %!ADDR!
// QuicTraceEvent(
DatapathGetRouteComplete,
"[data][%p] Query route result: %!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress));
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress) = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathGetRouteComplete,
TP_ARGS(
const void *, arg2,
unsigned int, arg3_len,
const void *, arg3),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_integer(unsigned int, arg3_len, arg3_len)
ctf_sequence(char, arg3, arg3, unsigned int, arg3_len)
)
)
/*----------------------------------------------------------
// Decoder Ring for DatapathError
// [data][%p] ERROR, %s.
// QuicTraceEvent(
DatapathError,
"[data][%p] ERROR, %s.",
Socket,
"no matching interface/queue");
// arg2 = arg2 = Socket = arg2
// arg3 = arg3 = "no matching interface/queue" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, DatapathError,
TP_ARGS(
const void *, arg2,
const char *, arg3),
TP_FIELDS(
ctf_integer_hex(uint64_t, arg2, arg2)
ctf_string(arg3, arg3)
)
)
/*----------------------------------------------------------
// Decoder Ring for AllocFailure
// Allocation of '%s' failed. (%llu bytes)
// QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION));
// arg2 = arg2 = "CXPLAT_DATAPATH" = arg2
// arg3 = arg3 = sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION) = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_SOCKET_WIN_C, AllocFailure,
TP_ARGS(
const char *, arg2,
unsigned long long, arg3),
TP_FIELDS(
ctf_string(arg2, arg2)
ctf_integer(uint64_t, arg3, arg3)
)
)

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

@ -2,16 +2,16 @@
#include <clog.h>
#endif
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER CLOG_DATAPATH_RAW_C
#define TRACEPOINT_PROVIDER CLOG_DATAPATH_RAW_WIN_C
#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "datapath_raw.c.clog.h.lttng.h"
#if !defined(DEF_CLOG_DATAPATH_RAW_C) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define DEF_CLOG_DATAPATH_RAW_C
#define TRACEPOINT_INCLUDE "datapath_raw_win.c.clog.h.lttng.h"
#if !defined(DEF_CLOG_DATAPATH_RAW_WIN_C) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define DEF_CLOG_DATAPATH_RAW_WIN_C
#include <lttng/tracepoint.h>
#define __int64 __int64_t
#include "datapath_raw.c.clog.h.lttng.h"
#include "datapath_raw_win.c.clog.h.lttng.h"
#endif
#include <lttng/tracepoint-event.h>
#ifndef _clog_MACRO_QuicTraceLogError
@ -38,7 +38,7 @@ extern "C" {
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed
#define _clog_4_ARGS_TRACE_DatapathResolveHostNameFailed(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_C, DatapathResolveHostNameFailed , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, DatapathResolveHostNameFailed , arg2, arg3);\
#endif
@ -58,7 +58,7 @@ tracepoint(CLOG_DATAPATH_RAW_C, DatapathResolveHostNameFailed , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_AllocFailure
#define _clog_4_ARGS_TRACE_AllocFailure(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_C, AllocFailure , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, AllocFailure , arg2, arg3);\
#endif
@ -78,7 +78,7 @@ tracepoint(CLOG_DATAPATH_RAW_C, AllocFailure , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_C, LibraryErrorStatus , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, LibraryErrorStatus , arg2, arg3);\
#endif
@ -96,7 +96,7 @@ tracepoint(CLOG_DATAPATH_RAW_C, LibraryErrorStatus , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_LibraryError
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_C, LibraryError , arg2);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, LibraryError , arg2);\
#endif
@ -118,7 +118,7 @@ tracepoint(CLOG_DATAPATH_RAW_C, LibraryError , arg2);\
----------------------------------------------------------*/
#ifndef _clog_7_ARGS_TRACE_DatapathCreated
#define _clog_7_ARGS_TRACE_DatapathCreated(uniqueId, encoded_arg_string, arg2, arg3, arg3_len, arg4, arg4_len)\
tracepoint(CLOG_DATAPATH_RAW_C, DatapathCreated , arg2, arg3_len, arg3, arg4_len, arg4);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, DatapathCreated , arg2, arg3_len, arg3, arg4_len, arg4);\
#endif
@ -144,7 +144,7 @@ tracepoint(CLOG_DATAPATH_RAW_C, DatapathCreated , arg2, arg3_len, arg3, arg4_len
----------------------------------------------------------*/
#ifndef _clog_9_ARGS_TRACE_DatapathRecv
#define _clog_9_ARGS_TRACE_DatapathRecv(uniqueId, encoded_arg_string, arg2, arg3, arg4, arg5, arg5_len, arg6, arg6_len)\
tracepoint(CLOG_DATAPATH_RAW_C, DatapathRecv , arg2, arg3, arg4, arg5_len, arg5, arg6_len, arg6);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, DatapathRecv , arg2, arg3, arg4, arg5_len, arg5, arg6_len, arg6);\
#endif
@ -172,7 +172,7 @@ tracepoint(CLOG_DATAPATH_RAW_C, DatapathRecv , arg2, arg3, arg4, arg5_len, arg5,
----------------------------------------------------------*/
#ifndef _clog_10_ARGS_TRACE_DatapathSend
#define _clog_10_ARGS_TRACE_DatapathSend(uniqueId, encoded_arg_string, arg2, arg3, arg4, arg5, arg6, arg6_len, arg7, arg7_len)\
tracepoint(CLOG_DATAPATH_RAW_C, DatapathSend , arg2, arg3, arg4, arg5, arg6_len, arg6, arg7_len, arg7);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, DatapathSend , arg2, arg3, arg4, arg5, arg6_len, arg6, arg7_len, arg7);\
#endif
@ -194,7 +194,7 @@ tracepoint(CLOG_DATAPATH_RAW_C, DatapathSend , arg2, arg3, arg4, arg5, arg6_len,
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_DatapathErrorStatus
#define _clog_5_ARGS_TRACE_DatapathErrorStatus(uniqueId, encoded_arg_string, arg2, arg3, arg4)\
tracepoint(CLOG_DATAPATH_RAW_C, DatapathErrorStatus , arg2, arg3, arg4);\
tracepoint(CLOG_DATAPATH_RAW_WIN_C, DatapathErrorStatus , arg2, arg3, arg4);\
#endif
@ -205,5 +205,5 @@ tracepoint(CLOG_DATAPATH_RAW_C, DatapathErrorStatus , arg2, arg3, arg4);\
}
#endif
#ifdef CLOG_INLINE_IMPLEMENTATION
#include "quic.clog_datapath_raw.c.clog.h.c"
#include "quic.clog_datapath_raw_win.c.clog.h.c"
#endif

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

@ -12,7 +12,7 @@
// arg2 = arg2 = Datapath = arg2
// arg3 = arg3 = HostName = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathResolveHostNameFailed,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, DatapathResolveHostNameFailed,
TP_ARGS(
const void *, arg2,
const char *, arg3),
@ -35,7 +35,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathResolveHostNameFailed,
// arg2 = arg2 = "CXPLAT_DATAPATH" = arg2
// arg3 = arg3 = sizeof(CXPLAT_ROUTE_RESOLUTION_WORKER) = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, AllocFailure,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, AllocFailure,
TP_ARGS(
const char *, arg2,
unsigned long long, arg3),
@ -58,7 +58,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, AllocFailure,
// arg2 = arg2 = Status = arg2
// arg3 = arg3 = "CxPlatThreadCreate" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, LibraryErrorStatus,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, LibraryErrorStatus,
TP_ARGS(
unsigned int, arg2,
const char *, arg3),
@ -79,7 +79,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, LibraryErrorStatus,
"Resolving hostname to IP");
// arg2 = arg2 = "Resolving hostname to IP" = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, LibraryError,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, LibraryError,
TP_ARGS(
const char *, arg2),
TP_FIELDS(
@ -102,7 +102,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, LibraryError,
// arg3 = arg3 = CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress) = arg3
// arg4 = arg4 = CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress) = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathCreated,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, DatapathCreated,
TP_ARGS(
const void *, arg2,
unsigned int, arg3_len,
@ -137,7 +137,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathCreated,
// arg5 = arg5 = CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->LocalAddress), &Packets[i]->Route->LocalAddress) = arg5
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->RemoteAddress), &Packets[i]->Route->RemoteAddress) = arg6
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathRecv,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, DatapathRecv,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,
@ -178,7 +178,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathRecv,
// arg6 = arg6 = CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress) = arg6
// arg7 = arg7 = CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress) = arg7
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathSend,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, DatapathSend,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,
@ -215,7 +215,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathSend,
// arg3 = arg3 = Status = arg3
// arg4 = arg4 = "ResolveIpNetEntry2" = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_C, DatapathErrorStatus,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_WIN_C, DatapathErrorStatus,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,

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

@ -0,0 +1,12 @@
#ifndef CLOG_DO_NOT_INCLUDE_HEADER
#include <clog.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#ifdef CLOG_INLINE_IMPLEMENTATION
#include "quic.clog_datapath_raw_xdp_linux.c.clog.h.c"
#endif

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

@ -2,16 +2,16 @@
#include <clog.h>
#endif
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER CLOG_DATAPATH_RAW_XDP_C
#define TRACEPOINT_PROVIDER CLOG_DATAPATH_RAW_XDP_WIN_C
#undef TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "datapath_raw_xdp.c.clog.h.lttng.h"
#if !defined(DEF_CLOG_DATAPATH_RAW_XDP_C) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define DEF_CLOG_DATAPATH_RAW_XDP_C
#define TRACEPOINT_INCLUDE "datapath_raw_xdp_win.c.clog.h.lttng.h"
#if !defined(DEF_CLOG_DATAPATH_RAW_XDP_WIN_C) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define DEF_CLOG_DATAPATH_RAW_XDP_WIN_C
#include <lttng/tracepoint.h>
#define __int64 __int64_t
#include "datapath_raw_xdp.c.clog.h.lttng.h"
#include "datapath_raw_xdp_win.c.clog.h.lttng.h"
#endif
#include <lttng/tracepoint-event.h>
#ifndef _clog_MACRO_QuicTraceLogInfo
@ -44,7 +44,7 @@ extern "C" {
----------------------------------------------------------*/
#ifndef _clog_5_ARGS_TRACE_FoundVF
#define _clog_5_ARGS_TRACE_FoundVF(uniqueId, encoded_arg_string, arg2, arg3, arg4)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, FoundVF , arg2, arg3, arg4);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, FoundVF , arg2, arg3, arg4);\
#endif
@ -64,7 +64,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, FoundVF , arg2, arg3, arg4);\
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_XdpInitialize
#define _clog_4_ARGS_TRACE_XdpInitialize(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpInitialize , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpInitialize , arg2, arg3);\
#endif
@ -84,7 +84,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpInitialize , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_XdpQueueStart
#define _clog_4_ARGS_TRACE_XdpQueueStart(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueStart , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueStart , arg2, arg3);\
#endif
@ -104,7 +104,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueStart , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_XdpWorkerStart
#define _clog_4_ARGS_TRACE_XdpWorkerStart(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerStart , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpWorkerStart , arg2, arg3);\
#endif
@ -122,7 +122,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerStart , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpRelease
#define _clog_3_ARGS_TRACE_XdpRelease(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpRelease , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpRelease , arg2);\
#endif
@ -140,7 +140,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpRelease , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpUninitializeComplete
#define _clog_3_ARGS_TRACE_XdpUninitializeComplete(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpUninitializeComplete , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpUninitializeComplete , arg2);\
#endif
@ -158,7 +158,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpUninitializeComplete , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpUninitialize
#define _clog_3_ARGS_TRACE_XdpUninitialize(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpUninitialize , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpUninitialize , arg2);\
#endif
@ -176,7 +176,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpUninitialize , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpWorkerShutdown
#define _clog_3_ARGS_TRACE_XdpWorkerShutdown(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdown , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpWorkerShutdown , arg2);\
#endif
@ -194,7 +194,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdown , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpQueueAsyncIoRx
#define _clog_3_ARGS_TRACE_XdpQueueAsyncIoRx(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRx , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoRx , arg2);\
#endif
@ -212,7 +212,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRx , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpQueueAsyncIoTx
#define _clog_3_ARGS_TRACE_XdpQueueAsyncIoTx(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTx , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoTx , arg2);\
#endif
@ -230,7 +230,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTx , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpQueueAsyncIoRxComplete
#define _clog_3_ARGS_TRACE_XdpQueueAsyncIoRxComplete(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRxComplete , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoRxComplete , arg2);\
#endif
@ -248,7 +248,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRxComplete , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpQueueAsyncIoTxComplete
#define _clog_3_ARGS_TRACE_XdpQueueAsyncIoTxComplete(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTxComplete , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoTxComplete , arg2);\
#endif
@ -266,7 +266,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTxComplete , arg2);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_XdpWorkerShutdownComplete
#define _clog_3_ARGS_TRACE_XdpWorkerShutdownComplete(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdownComplete , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpWorkerShutdownComplete , arg2);\
#endif
@ -286,7 +286,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdownComplete , arg2);\
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_LibraryErrorStatus
#define _clog_4_ARGS_TRACE_LibraryErrorStatus(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, LibraryErrorStatus , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, LibraryErrorStatus , arg2, arg3);\
#endif
@ -306,7 +306,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, LibraryErrorStatus , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_4_ARGS_TRACE_AllocFailure
#define _clog_4_ARGS_TRACE_AllocFailure(uniqueId, encoded_arg_string, arg2, arg3)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, AllocFailure , arg2, arg3);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, AllocFailure , arg2, arg3);\
#endif
@ -324,7 +324,7 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, AllocFailure , arg2, arg3);\
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_LibraryError
#define _clog_3_ARGS_TRACE_LibraryError(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_RAW_XDP_C, LibraryError , arg2);\
tracepoint(CLOG_DATAPATH_RAW_XDP_WIN_C, LibraryError , arg2);\
#endif
@ -335,5 +335,5 @@ tracepoint(CLOG_DATAPATH_RAW_XDP_C, LibraryError , arg2);\
}
#endif
#ifdef CLOG_INLINE_IMPLEMENTATION
#include "quic.clog_datapath_raw_xdp.c.clog.h.c"
#include "quic.clog_datapath_raw_xdp_win.c.clog.h.c"
#endif

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

@ -14,7 +14,7 @@
// arg3 = arg3 = Interface->IfIndex = arg3
// arg4 = arg4 = Interface->ActualIfIndex = arg4
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, FoundVF,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, FoundVF,
TP_ARGS(
const void *, arg2,
unsigned int, arg3,
@ -39,7 +39,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, FoundVF,
// arg2 = arg2 = Xdp = arg2
// arg3 = arg3 = Xdp->WorkerCount = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpInitialize,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpInitialize,
TP_ARGS(
const void *, arg2,
unsigned int, arg3),
@ -62,7 +62,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpInitialize,
// arg2 = arg2 = Queue = arg2
// arg3 = arg3 = Worker = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueStart,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueStart,
TP_ARGS(
const void *, arg2,
const void *, arg3),
@ -85,7 +85,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueStart,
// arg2 = arg2 = Worker = arg2
// arg3 = arg3 = QueueCount = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerStart,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpWorkerStart,
TP_ARGS(
const void *, arg2,
unsigned int, arg3),
@ -106,7 +106,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerStart,
Xdp);
// arg2 = arg2 = Xdp = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpRelease,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpRelease,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -125,7 +125,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpRelease,
Xdp);
// arg2 = arg2 = Xdp = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpUninitializeComplete,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpUninitializeComplete,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -144,7 +144,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpUninitializeComplete,
Xdp);
// arg2 = arg2 = Xdp = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpUninitialize,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpUninitialize,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -163,7 +163,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpUninitialize,
Worker);
// arg2 = arg2 = Worker = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdown,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpWorkerShutdown,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -182,7 +182,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdown,
Queue);
// arg2 = arg2 = Queue = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRx,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoRx,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -201,7 +201,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRx,
Queue);
// arg2 = arg2 = Queue = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTx,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoTx,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -220,7 +220,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTx,
Queue);
// arg2 = arg2 = Queue = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRxComplete,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoRxComplete,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -239,7 +239,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoRxComplete,
Queue);
// arg2 = arg2 = Queue = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTxComplete,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpQueueAsyncIoTxComplete,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -258,7 +258,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpQueueAsyncIoTxComplete,
Worker);
// arg2 = arg2 = Worker = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdownComplete,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, XdpWorkerShutdownComplete,
TP_ARGS(
const void *, arg2),
TP_FIELDS(
@ -279,7 +279,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, XdpWorkerShutdownComplete,
// arg2 = arg2 = ret = arg2
// arg3 = arg3 = "ConvertInterfaceIndexToLuid" = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, LibraryErrorStatus,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, LibraryErrorStatus,
TP_ARGS(
unsigned int, arg2,
const char *, arg3),
@ -302,7 +302,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, LibraryErrorStatus,
// arg2 = arg2 = "XDP Queues" = arg2
// arg3 = arg3 = Interface->QueueCount * sizeof(*Interface->Queues) = arg3
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, AllocFailure,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, AllocFailure,
TP_ARGS(
const char *, arg2,
unsigned long long, arg3),
@ -323,7 +323,7 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, AllocFailure,
"No more room for rules");
// arg2 = arg2 = "No more room for rules" = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_C, LibraryError,
TRACEPOINT_EVENT(CLOG_DATAPATH_RAW_XDP_WIN_C, LibraryError,
TP_ARGS(
const char *, arg2),
TP_FIELDS(

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

@ -4,4 +4,4 @@
#else
#define TRACEPOINT_DEFINE
#endif
#include "datapath_raw_xdp.c.clog.h"
#include "datapath_raw_linux.c.clog.h"

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

@ -0,0 +1 @@
#include <clog.h>

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

@ -0,0 +1,7 @@
#include <clog.h>
#ifdef BUILDING_TRACEPOINT_PROVIDER
#define TRACEPOINT_CREATE_PROBES
#else
#define TRACEPOINT_DEFINE
#endif
#include "datapath_raw_socket_win.c.clog.h"

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

@ -4,4 +4,4 @@
#else
#define TRACEPOINT_DEFINE
#endif
#include "datapath_raw.c.clog.h"
#include "datapath_raw_win.c.clog.h"

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

@ -0,0 +1 @@
#include <clog.h>

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

@ -0,0 +1,7 @@
#include <clog.h>
#ifdef BUILDING_TRACEPOINT_PROVIDER
#define TRACEPOINT_CREATE_PROBES
#else
#define TRACEPOINT_DEFINE
#endif
#include "datapath_raw_xdp_win.c.clog.h"

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

@ -85,6 +85,8 @@ extern "C" {
#define SIZEOF_STRUCT_MEMBER(StructType, StructMember) sizeof(((StructType *)0)->StructMember)
#define TYPEOF_STRUCT_MEMBER(StructType, StructMember) typeof(((StructType *)0)->StructMember)
#define SOCKET int
#if defined(__GNUC__) && __GNUC__ >= 7
#define __fallthrough __attribute__((fallthrough))
#else

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

@ -14,14 +14,18 @@ set(SOURCES crypt.c hashtable.c pcp.c platform_worker.c toeplitz.c)
if("${CX_PLATFORM}" STREQUAL "windows")
set(SOURCES ${SOURCES} platform_winuser.c storage_winuser.c)
if(QUIC_USE_XDP)
set(SOURCES ${SOURCES} datapath_raw.c datapath_raw_socket.c datapath_raw_xdp.c)
set(SOURCES ${SOURCES} datapath_raw_win.c datapath_raw_socket.c datapath_raw_socket_win.c datapath_raw_xdp_win.c)
else()
set(SOURCES ${SOURCES} datapath_winuser.c)
endif()
else()
set(SOURCES ${SOURCES} inline.c platform_posix.c storage_posix.c cgroup.c)
if(CX_PLATFORM STREQUAL "linux" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(SOURCES ${SOURCES} datapath_epoll.c)
if(QUIC_USE_XDP)
set(SOURCES ${SOURCES} datapath_raw_linux.c datapath_raw_socket.c datapath_raw_socket_linux.c datapath_raw_xdp_linux.c)
else()
set(SOURCES ${SOURCES} datapath_epoll.c)
endif()
else()
set(SOURCES ${SOURCES} datapath_kqueue.c)
endif()
@ -46,7 +50,7 @@ endif()
add_library(platform STATIC ${SOURCES})
if(QUIC_USE_XDP)
if ("${CX_PLATFORM}" STREQUAL "windows" AND QUIC_USE_XDP)
target_link_libraries(
platform
PUBLIC
@ -65,7 +69,7 @@ target_link_libraries(platform PRIVATE warnings main_binary_link_args)
set_property(TARGET platform PROPERTY FOLDER "${QUIC_FOLDER_PREFIX}libraries")
if(QUIC_USE_XDP)
if ("${CX_PLATFORM}" STREQUAL "windows" AND QUIC_USE_XDP)
target_include_directories(
platform
PRIVATE

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

@ -43,18 +43,6 @@ typedef struct QUIC_CACHEALIGN CXPLAT_ROUTE_RESOLUTION_WORKER {
CXPLAT_LIST_ENTRY Operations;
} CXPLAT_ROUTE_RESOLUTION_WORKER;
typedef struct CXPLAT_ROUTE_RESOLUTION_OPERATION {
//
// Link in the worker's operation queue.
// N.B. Multi-threaded access, synchronized by worker's operation lock.
//
CXPLAT_LIST_ENTRY WorkerLink;
MIB_IPNET_ROW2 IpnetRow;
void* Context;
uint8_t PathId;
CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback;
} CXPLAT_ROUTE_RESOLUTION_OPERATION;
typedef struct CXPLAT_DATAPATH {
CXPLAT_UDP_DATAPATH_CALLBACKS UdpHandlers;
@ -79,7 +67,7 @@ typedef struct CXPLAT_INTERFACE {
CXPLAT_LIST_ENTRY Link;
uint32_t IfIndex;
uint32_t ActualIfIndex;
UCHAR PhysicalAddress[ETH_MAC_ADDR_LEN];
uint8_t PhysicalAddress[ETH_MAC_ADDR_LEN];
struct {
struct {
BOOLEAN NetworkLayerXsum : 1;
@ -303,7 +291,7 @@ CxPlatSockPoolUninitialize(
// so it assumes that matches already.
//
inline
BOOL
BOOLEAN
CxPlatSocketCompare(
_In_ CXPLAT_SOCKET* Socket,
_In_ const QUIC_ADDR* LocalAddress,
@ -394,3 +382,102 @@ CxPlatFramingWriteHeaders(
_In_ uint32_t TcpAckNum,
_In_ uint8_t TcpFlags
);
//
// Ethernet / IP Framing Logic
//
#pragma pack(push)
#pragma pack(1)
typedef struct ETHERNET_HEADER {
uint8_t Destination[6];
uint8_t Source[6];
uint16_t Type;
uint8_t Data[0];
} ETHERNET_HEADER;
typedef struct IPV4_HEADER {
uint8_t VersionAndHeaderLength;
union {
uint8_t TypeOfServiceAndEcnField;
struct {
uint8_t EcnField : 2;
uint8_t TypeOfService : 6;
};
};
uint16_t TotalLength;
uint16_t Identification;
uint16_t FlagsAndFragmentOffset;
uint8_t TimeToLive;
uint8_t Protocol;
uint16_t HeaderChecksum;
uint8_t Source[4];
uint8_t Destination[4];
uint8_t Data[0];
} IPV4_HEADER;
typedef struct IPV6_HEADER {
uint32_t VersionClassEcnFlow;
uint16_t PayloadLength;
uint8_t NextHeader;
uint8_t HopLimit;
uint8_t Source[16];
uint8_t Destination[16];
uint8_t Data[0];
} IPV6_HEADER;
typedef struct IPV6_EXTENSION {
uint8_t NextHeader;
uint8_t Length;
uint16_t Reserved0;
uint32_t Reserved1;
uint8_t Data[0];
} IPV6_EXTENSION;
typedef struct UDP_HEADER {
uint16_t SourcePort;
uint16_t DestinationPort;
uint16_t Length;
uint16_t Checksum;
uint8_t Data[0];
} UDP_HEADER;
typedef struct TCP_HEADER {
uint16_t SourcePort;
uint16_t DestinationPort;
uint32_t SequenceNumber;
uint32_t AckNumber;
uint8_t X2 : 4;
uint8_t HeaderLength : 4;
uint8_t Flags;
uint16_t Window;
uint16_t Checksum;
uint16_t UrgentPointer;
} TCP_HEADER;
#pragma pack(pop)
//
// Constants for headers in wire format.
//
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define IPV4_VERSION 4
#define IPV6_VERSION 6
#define IPV4_VERSION_BYTE (IPV4_VERSION << 4)
#define IPV4_DEFAULT_VERHLEN ((IPV4_VERSION_BYTE) | (sizeof(IPV4_HEADER) / sizeof(uint32_t)))
#define IP_DEFAULT_HOP_LIMIT 128
#define ETHERNET_TYPE_IPV4 0x0008
#define ETHERNET_TYPE_IPV6 0xdd86

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

@ -0,0 +1,683 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
QUIC Raw (i.e. DPDK or XDP) Datapath Implementation (User Mode)
--*/
#include "datapath_raw_linux.h"
#ifdef QUIC_CLOG
#include "datapath_raw_linux.c.clog.h"
#endif
#pragma warning(disable:4116) // unnamed type definition in parentheses
#pragma warning(disable:4100) // unreferenced formal parameter
CXPLAT_THREAD_CALLBACK(CxPlatRouteResolutionWorkerThread, Context);
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDataPathRouteWorkerUninitialize(
_In_ CXPLAT_ROUTE_RESOLUTION_WORKER* Worker
)
{
Worker->Enabled = FALSE;
CxPlatEventSet(Worker->Ready);
//
// Wait for the thread to finish.
//
if (Worker->Thread) {
CxPlatThreadWait(&Worker->Thread);
CxPlatThreadDelete(&Worker->Thread);
}
CxPlatEventUninitialize(Worker->Ready);
CxPlatDispatchLockUninitialize(&Worker->Lock);
CxPlatPoolUninitialize(&Worker->OperationPool);
CXPLAT_FREE(Worker, QUIC_POOL_ROUTE_RESOLUTION_WORKER);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatDataPathRouteWorkerInitialize(
_Inout_ CXPLAT_DATAPATH* DataPath
)
{
QUIC_STATUS Status;
CXPLAT_ROUTE_RESOLUTION_WORKER* Worker =
CXPLAT_ALLOC_NONPAGED(
sizeof(CXPLAT_ROUTE_RESOLUTION_WORKER), QUIC_POOL_ROUTE_RESOLUTION_WORKER);
if (Worker == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_WORKER));
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Error;
}
Worker->Enabled = TRUE;
CxPlatEventInitialize(&Worker->Ready, FALSE, FALSE);
CxPlatDispatchLockInitialize(&Worker->Lock);
CxPlatListInitializeHead(&Worker->Operations);
CxPlatPoolInitialize(
FALSE,
sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION),
QUIC_POOL_ROUTE_RESOLUTION_OPER,
&Worker->OperationPool);
CXPLAT_THREAD_CONFIG ThreadConfig = {
CXPLAT_THREAD_FLAG_NONE,
0,
"RouteResolutionWorkerThread",
CxPlatRouteResolutionWorkerThread,
Worker
};
Status = CxPlatThreadCreate(&ThreadConfig, &Worker->Thread);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Status,
"CxPlatThreadCreate");
goto Error;
}
DataPath->RouteResolutionWorker = Worker;
Error:
if (QUIC_FAILED(Status)) {
if (Worker != NULL) {
CxPlatDataPathRouteWorkerUninitialize(Worker);
}
}
return Status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatDataPathInitialize(
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
_In_opt_ QUIC_EXECUTION_CONFIG* Config,
_Out_ CXPLAT_DATAPATH** NewDataPath
)
{
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
const size_t DatapathSize = CxPlatDpRawGetDatapathSize(Config);
BOOLEAN DpRawInitialized = FALSE;
BOOLEAN SockPoolInitialized = FALSE;
CXPLAT_FRE_ASSERT(DatapathSize > sizeof(CXPLAT_DATAPATH));
UNREFERENCED_PARAMETER(TcpCallbacks);
if (NewDataPath == NULL) {
return QUIC_STATUS_INVALID_PARAMETER;
}
if (UdpCallbacks != NULL) {
if (UdpCallbacks->Receive == NULL || UdpCallbacks->Unreachable == NULL) {
return QUIC_STATUS_INVALID_PARAMETER;
}
}
if (!CxPlatWorkersLazyStart(Config)) {
return QUIC_STATUS_OUT_OF_MEMORY;
}
CXPLAT_DATAPATH* DataPath = CXPLAT_ALLOC_PAGED(DatapathSize, QUIC_POOL_DATAPATH);
if (DataPath == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
DatapathSize);
return QUIC_STATUS_OUT_OF_MEMORY;
}
CxPlatZeroMemory(DataPath, DatapathSize);
CXPLAT_FRE_ASSERT(CxPlatRundownAcquire(&CxPlatWorkerRundown));
if (UdpCallbacks) {
DataPath->UdpHandlers = *UdpCallbacks;
}
if (Config && (Config->Flags & QUIC_EXECUTION_CONFIG_FLAG_QTIP)) {
DataPath->UseTcp = TRUE;
}
if (!CxPlatSockPoolInitialize(&DataPath->SocketPool)) {
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Error;
}
SockPoolInitialized = TRUE;
Status = CxPlatDpRawInitialize(DataPath, ClientRecvContextLength, Config);
if (QUIC_FAILED(Status)) {
goto Error;
}
DpRawInitialized = TRUE;
Status = CxPlatDataPathRouteWorkerInitialize(DataPath);
if (QUIC_FAILED(Status)) {
goto Error;
}
*NewDataPath = DataPath;
DataPath = NULL;
Error:
if (DataPath != NULL) {
#if DEBUG
DataPath->Uninitialized = TRUE;
#endif
if (DpRawInitialized) {
CxPlatDpRawUninitialize(DataPath);
} else {
if (SockPoolInitialized) {
CxPlatSockPoolUninitialize(&DataPath->SocketPool);
}
CXPLAT_FREE(DataPath, QUIC_POOL_DATAPATH);
CxPlatRundownRelease(&CxPlatWorkerRundown);
}
}
return Status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDataPathUninitialize(
_In_ CXPLAT_DATAPATH* Datapath
)
{
if (Datapath != NULL) {
#if DEBUG
CXPLAT_DBG_ASSERT(!Datapath->Freed);
CXPLAT_DBG_ASSERT(!Datapath->Uninitialized);
Datapath->Uninitialized = TRUE;
#endif
CxPlatDataPathRouteWorkerUninitialize(Datapath->RouteResolutionWorker);
CxPlatDpRawUninitialize(Datapath);
}
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDataPathUninitializeComplete(
_In_ CXPLAT_DATAPATH* Datapath
)
{
#if DEBUG
CXPLAT_DBG_ASSERT(!Datapath->Freed);
CXPLAT_DBG_ASSERT(Datapath->Uninitialized);
Datapath->Freed = TRUE;
#endif
CxPlatSockPoolUninitialize(&Datapath->SocketPool);
CXPLAT_FREE(Datapath, QUIC_POOL_DATAPATH);
CxPlatRundownRelease(&CxPlatWorkerRundown);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDataPathUpdateConfig(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ QUIC_EXECUTION_CONFIG* Config
)
{
UNREFERENCED_PARAMETER(Datapath);
UNREFERENCED_PARAMETER(Config);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
uint32_t
CxPlatDataPathGetSupportedFeatures(
_In_ CXPLAT_DATAPATH* Datapath
)
{
UNREFERENCED_PARAMETER(Datapath);
return 0;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
BOOLEAN
CxPlatDataPathIsPaddingPreferred(
_In_ CXPLAT_DATAPATH* Datapath
)
{
UNREFERENCED_PARAMETER(Datapath);
return FALSE;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Success_(QUIC_SUCCEEDED(return))
QUIC_STATUS
CxPlatDataPathGetLocalAddresses(
_In_ CXPLAT_DATAPATH* Datapath,
_Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
CXPLAT_ADAPTER_ADDRESS** Addresses,
_Out_ uint32_t* AddressesCount
)
{
UNREFERENCED_PARAMETER(Datapath);
UNREFERENCED_PARAMETER(Addresses);
UNREFERENCED_PARAMETER(AddressesCount);
return QUIC_STATUS_NOT_SUPPORTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Success_(QUIC_SUCCEEDED(return))
QUIC_STATUS
CxPlatDataPathGetGatewayAddresses(
_In_ CXPLAT_DATAPATH* Datapath,
_Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
QUIC_ADDR** GatewayAddresses,
_Out_ uint32_t* GatewayAddressesCount
)
{
UNREFERENCED_PARAMETER(Datapath);
UNREFERENCED_PARAMETER(GatewayAddresses);
UNREFERENCED_PARAMETER(GatewayAddressesCount);
return QUIC_STATUS_NOT_SUPPORTED;
}
void
CxPlatDataPathPopulateTargetAddress(
_In_ QUIC_ADDRESS_FAMILY Family,
_In_ ADDRINFO* AddrInfo,
_Out_ QUIC_ADDR* Address
)
{
UNREFERENCED_PARAMETER(Family);
UNREFERENCED_PARAMETER(AddrInfo);
UNREFERENCED_PARAMETER(Address);
}
// ->CxPlat
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatDataPathResolveAddress(
_In_ CXPLAT_DATAPATH* Datapath,
_In_z_ const char* HostName,
_Inout_ QUIC_ADDR* Address
)
{
UNREFERENCED_PARAMETER(Datapath);
UNREFERENCED_PARAMETER(HostName);
UNREFERENCED_PARAMETER(Address);
QUIC_STATUS Status = QUIC_STATUS_NOT_SUPPORTED;
return Status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatSocketCreateUdp(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ const CXPLAT_UDP_CONFIG* Config,
_Out_ CXPLAT_SOCKET** NewSocket
)
{
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
*NewSocket = CXPLAT_ALLOC_PAGED(sizeof(CXPLAT_SOCKET), QUIC_POOL_SOCKET);
if (*NewSocket == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_SOCKET",
sizeof(CXPLAT_SOCKET));
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Error;
}
QuicTraceEvent(
DatapathCreated,
"[data][%p] Created, local=%!ADDR!, remote=%!ADDR!",
*NewSocket,
CASTED_CLOG_BYTEARRAY(Config->LocalAddress ? sizeof(*Config->LocalAddress) : 0, Config->LocalAddress),
CASTED_CLOG_BYTEARRAY(Config->RemoteAddress ? sizeof(*Config->RemoteAddress) : 0, Config->RemoteAddress));
CxPlatZeroMemory(*NewSocket, sizeof(CXPLAT_SOCKET));
CxPlatRundownInitialize(&(*NewSocket)->Rundown);
(*NewSocket)->Datapath = Datapath;
(*NewSocket)->CallbackContext = Config->CallbackContext;
(*NewSocket)->CibirIdLength = Config->CibirIdLength;
(*NewSocket)->CibirIdOffsetSrc = Config->CibirIdOffsetSrc;
(*NewSocket)->CibirIdOffsetDst = Config->CibirIdOffsetDst;
(*NewSocket)->UseTcp = Datapath->UseTcp;
if (Config->CibirIdLength) {
memcpy((*NewSocket)->CibirId, Config->CibirId, Config->CibirIdLength);
}
if (Config->RemoteAddress) {
CXPLAT_FRE_ASSERT(!QuicAddrIsWildCard(Config->RemoteAddress)); // No wildcard remote addresses allowed.
(*NewSocket)->Connected = TRUE;
(*NewSocket)->RemoteAddress = *Config->RemoteAddress;
}
if (Config->LocalAddress) {
(*NewSocket)->LocalAddress = *Config->LocalAddress;
if (QuicAddrIsWildCard(Config->LocalAddress)) {
if (!(*NewSocket)->Connected) {
(*NewSocket)->Wildcard = TRUE;
}
} else {
CXPLAT_FRE_ASSERT((*NewSocket)->Connected); // Assumes only connected sockets fully specify local address
}
} else {
QuicAddrSetFamily(&(*NewSocket)->LocalAddress, QUIC_ADDRESS_FAMILY_INET6);
if (!(*NewSocket)->Connected) {
(*NewSocket)->Wildcard = TRUE;
}
}
CXPLAT_FRE_ASSERT((*NewSocket)->Wildcard ^ (*NewSocket)->Connected); // Assumes either a pure wildcard listener or a
// connected socket; not both.
Status = CxPlatTryAddSocket(&Datapath->SocketPool, *NewSocket);
if (QUIC_FAILED(Status)) {
goto Error;
}
CxPlatDpRawPlumbRulesOnSocket(*NewSocket, TRUE);
Error:
if (QUIC_FAILED(Status)) {
if (*NewSocket != NULL) {
CxPlatRundownUninitialize(&(*NewSocket)->Rundown);
CXPLAT_FREE(*NewSocket, QUIC_POOL_SOCKET);
*NewSocket = NULL;
}
}
return Status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatSocketCreateTcp(
_In_ CXPLAT_DATAPATH* Datapath,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_ const QUIC_ADDR* RemoteAddress,
_In_opt_ void* CallbackContext,
_Out_ CXPLAT_SOCKET** Socket
)
{
UNREFERENCED_PARAMETER(Datapath);
UNREFERENCED_PARAMETER(LocalAddress);
UNREFERENCED_PARAMETER(RemoteAddress);
UNREFERENCED_PARAMETER(CallbackContext);
UNREFERENCED_PARAMETER(Socket);
return QUIC_STATUS_NOT_SUPPORTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatSocketCreateTcpListener(
_In_ CXPLAT_DATAPATH* Datapath,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_opt_ void* RecvCallbackContext,
_Out_ CXPLAT_SOCKET** NewSocket
)
{
UNREFERENCED_PARAMETER(Datapath);
UNREFERENCED_PARAMETER(LocalAddress);
UNREFERENCED_PARAMETER(RecvCallbackContext);
UNREFERENCED_PARAMETER(NewSocket);
return QUIC_STATUS_NOT_SUPPORTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatSocketDelete(
_In_ CXPLAT_SOCKET* Socket
)
{
CxPlatDpRawPlumbRulesOnSocket(Socket, FALSE);
CxPlatRemoveSocket(&Socket->Datapath->SocketPool, Socket);
CxPlatRundownReleaseAndWait(&Socket->Rundown);
if (Socket->PausedTcpSend) {
CxPlatDpRawTxFree(Socket->PausedTcpSend);
}
if (Socket->CachedRstSend) {
CxPlatDpRawTxEnqueue(Socket->CachedRstSend);
}
CXPLAT_FREE(Socket, QUIC_POOL_SOCKET);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatSocketUpdateQeo(
_In_ CXPLAT_SOCKET* Socket,
_In_reads_(OffloadCount)
const CXPLAT_QEO_CONNECTION* Offloads,
_In_ uint32_t OffloadCount
)
{
UNREFERENCED_PARAMETER(Socket);
UNREFERENCED_PARAMETER(Offloads);
UNREFERENCED_PARAMETER(OffloadCount);
return QUIC_STATUS_NOT_SUPPORTED;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
uint16_t
CxPlatSocketGetLocalMtu(
_In_ CXPLAT_SOCKET* Socket
)
{
if (Socket->UseTcp) {
return 1488; // Reserve space for TCP header.
} else {
return 1500;
}
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatSocketGetLocalAddress(
_In_ CXPLAT_SOCKET* Socket,
_Out_ QUIC_ADDR* Address
)
{
*Address = Socket->LocalAddress;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatSocketGetRemoteAddress(
_In_ CXPLAT_SOCKET* Socket,
_Out_ QUIC_ADDR* Address
)
{
*Address = Socket->RemoteAddress;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatDpRawRxEthernet(
_In_ const CXPLAT_DATAPATH* Datapath,
_In_reads_(PacketCount)
CXPLAT_RECV_DATA** Packets,
_In_ uint16_t PacketCount
)
{
for (uint16_t i = 0; i < PacketCount; i++) {
CXPLAT_SOCKET* Socket = NULL;
CXPLAT_RECV_DATA* PacketChain = Packets[i];
CXPLAT_DBG_ASSERT(PacketChain->Next == NULL);
if (PacketChain->Reserved >= L4_TYPE_UDP) {
Socket =
CxPlatGetSocket(
&Datapath->SocketPool,
&PacketChain->Route->LocalAddress,
&PacketChain->Route->RemoteAddress);
}
if (Socket) {
if (PacketChain->Reserved == L4_TYPE_UDP || PacketChain->Reserved == L4_TYPE_TCP) {
uint8_t SocketType = Socket->UseTcp ? L4_TYPE_TCP : L4_TYPE_UDP;
//
// Found a match. Chain and deliver contiguous packets with the same 4-tuple.
//
while (i < PacketCount) {
QuicTraceEvent(
DatapathRecv,
"[data][%p] Recv %u bytes (segment=%hu) Src=%!ADDR! Dst=%!ADDR!",
Socket,
Packets[i]->BufferLength,
Packets[i]->BufferLength,
CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->LocalAddress), &Packets[i]->Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Packets[i]->Route->RemoteAddress), &Packets[i]->Route->RemoteAddress));
if (i == PacketCount - 1 ||
Packets[i+1]->Reserved != SocketType ||
Packets[i+1]->Route->LocalAddress.Ipv4.sin_port != Socket->LocalAddress.Ipv4.sin_port ||
!CxPlatSocketCompare(Socket, &Packets[i+1]->Route->LocalAddress, &Packets[i+1]->Route->RemoteAddress)) {
break;
}
Packets[i]->Next = Packets[i+1];
CXPLAT_DBG_ASSERT(Packets[i+1]->Next == NULL);
i++;
}
Datapath->UdpHandlers.Receive(Socket, Socket->CallbackContext, (CXPLAT_RECV_DATA*)PacketChain);
} else if (PacketChain->Reserved == L4_TYPE_TCP_SYN || PacketChain->Reserved == L4_TYPE_TCP_SYNACK) {
CxPlatDpRawSocketAckSyn(Socket, PacketChain);
CxPlatDpRawRxFree(PacketChain);
} else if (PacketChain->Reserved == L4_TYPE_TCP_FIN) {
CxPlatDpRawSocketAckFin(Socket, PacketChain);
CxPlatDpRawRxFree(PacketChain);
} else {
CxPlatDpRawRxFree(PacketChain);
}
CxPlatRundownRelease(&Socket->Rundown);
} else {
CxPlatDpRawRxFree(PacketChain);
}
}
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatRecvDataReturn(
_In_opt_ CXPLAT_RECV_DATA* RecvDataChain
)
{
CxPlatDpRawRxFree((const CXPLAT_RECV_DATA*)RecvDataChain);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
_Success_(return != NULL)
CXPLAT_SEND_DATA*
CxPlatSendDataAlloc(
_In_ CXPLAT_SOCKET* Socket,
_Inout_ CXPLAT_SEND_CONFIG* Config
)
{
return CxPlatDpRawTxAlloc(Socket, Config);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
_Success_(return != NULL)
QUIC_BUFFER*
CxPlatSendDataAllocBuffer(
_In_ CXPLAT_SEND_DATA* SendData,
_In_ uint16_t MaxBufferLength
)
{
SendData->Buffer.Length = MaxBufferLength;
return &SendData->Buffer;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatSendDataFree(
_In_ CXPLAT_SEND_DATA* SendData
)
{
CxPlatDpRawTxFree(SendData);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatSendDataFreeBuffer(
_In_ CXPLAT_SEND_DATA* SendData,
_In_ QUIC_BUFFER* Buffer
)
{
UNREFERENCED_PARAMETER(SendData);
UNREFERENCED_PARAMETER(Buffer);
// No-op
}
_IRQL_requires_max_(DISPATCH_LEVEL)
BOOLEAN
CxPlatSendDataIsFull(
_In_ CXPLAT_SEND_DATA* SendData
)
{
UNREFERENCED_PARAMETER(SendData);
return TRUE;
}
#define TH_ACK 0x10
_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
CxPlatSocketSend(
_In_ CXPLAT_SOCKET* Socket,
_In_ const CXPLAT_ROUTE* Route,
_In_ CXPLAT_SEND_DATA* SendData
)
{
if (Socket->UseTcp &&
Socket->Connected &&
Route->TcpState.Syncd == FALSE) {
Socket->PausedTcpSend = SendData;
CxPlatDpRawSocketSyn(Socket, Route);
return QUIC_STATUS_SUCCESS;
}
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));
CXPLAT_DBG_ASSERT(Route->State == RouteResolved);
CXPLAT_DBG_ASSERT(Route->Queue != NULL);
const CXPLAT_INTERFACE* Interface = CxPlatDpRawGetInterfaceFromQueue(Route->Queue);
CxPlatFramingWriteHeaders(
Socket, Route, &SendData->Buffer, SendData->ECN,
Interface->OffloadStatus.Transmit.NetworkLayerXsum,
Interface->OffloadStatus.Transmit.TransportLayerXsum,
Route->TcpState.SequenceNumber,
Route->TcpState.AckNumber,
TH_ACK);
CxPlatDpRawTxEnqueue(SendData);
return QUIC_STATUS_SUCCESS;
}
// ->CxPlat?
CXPLAT_THREAD_CALLBACK(CxPlatRouteResolutionWorkerThread, Context)
{
UNREFERENCED_PARAMETER(Context);
return 0;
}

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

@ -0,0 +1,27 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
--*/
#define QUIC_API_ENABLE_PREVIEW_FEATURES 1
#include "datapath_raw.h"
#include "platform_internal.h"
#include "quic_hashtable.h"
typedef struct CXPLAT_ROUTE_RESOLUTION_OPERATION {
//
// Link in the worker's operation queue.
// N.B. Multi-threaded access, synchronized by worker's operation lock.
//
CXPLAT_LIST_ENTRY WorkerLink;
// TODO: MIB_IPNET_ROW2 IpnetRow;
void* Context;
uint8_t PathId;
CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback;
} CXPLAT_ROUTE_RESOLUTION_OPERATION;

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

@ -14,58 +14,9 @@ Abstract:
#include "datapath_raw_socket.c.clog.h"
#endif
#include <stdio.h>
#pragma warning(disable:4116) // unnamed type definition in parentheses
#pragma warning(disable:4100) // unreferenced formal parameter
#ifdef _WIN32
#define SocketError() WSAGetLastError()
#else
#define SocketError() errno
#endif // _WIN32
//
// Socket Pool Logic
//
BOOLEAN
CxPlatSockPoolInitialize(
_Inout_ CXPLAT_SOCKET_POOL* Pool
)
{
if (!CxPlatHashtableInitializeEx(&Pool->Sockets, CXPLAT_HASH_MIN_SIZE)) {
return FALSE;
}
#ifdef _WIN32
int WsaError;
WSADATA WsaData;
if ((WsaError = WSAStartup(MAKEWORD(2, 2), &WsaData)) != 0) {
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
WsaError,
"WSAStartup");
CxPlatHashtableUninitialize(&Pool->Sockets);
return FALSE;
}
#endif // _WIN32
CxPlatRwLockInitialize(&Pool->Lock);
return TRUE;
}
void
CxPlatSockPoolUninitialize(
_Inout_ CXPLAT_SOCKET_POOL* Pool
)
{
#ifdef _WIN32
(void)WSACleanup();
#endif // _WIN32
CxPlatRwLockUninitialize(&Pool->Lock);
CxPlatHashtableUninitialize(&Pool->Sockets);
}
CXPLAT_SOCKET*
CxPlatGetSocket(
_In_ const CXPLAT_SOCKET_POOL* Pool,
@ -79,7 +30,7 @@ CxPlatGetSocket(
CxPlatRwLockAcquireShared(&((CXPLAT_SOCKET_POOL*)Pool)->Lock);
Entry = CxPlatHashtableLookup(&Pool->Sockets, LocalAddress->Ipv4.sin_port, &Context);
while (Entry != NULL) {
CXPLAT_SOCKET* Temp = CONTAINING_RECORD(Entry, CXPLAT_SOCKET, Entry);
CXPLAT_SOCKET* Temp = CXPLAT_CONTAINING_RECORD(Entry, CXPLAT_SOCKET, Entry);
if (CxPlatSocketCompare(Temp, LocalAddress, RemoteAddress)) {
if (CxPlatRundownAcquire(&Temp->Rundown)) {
Socket = Temp;
@ -92,360 +43,15 @@ CxPlatGetSocket(
return Socket;
}
QUIC_STATUS
CxPlatTryAddSocket(
_In_ CXPLAT_SOCKET_POOL* Pool,
_In_ CXPLAT_SOCKET* Socket
)
{
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
int Result;
CXPLAT_HASHTABLE_LOOKUP_CONTEXT Context;
CXPLAT_HASHTABLE_ENTRY* Entry;
QUIC_ADDR MappedAddress = {0};
SOCKET TempUdpSocket = INVALID_SOCKET;
int AssignedLocalAddressLength;
//
// Get (and reserve) a transport layer port from the OS networking stack by
// binding an auxiliary (dual stack) socket.
//
Socket->AuxSocket =
socket(
AF_INET6,
Socket->UseTcp ? SOCK_STREAM : SOCK_DGRAM,
Socket->UseTcp ? IPPROTO_TCP : IPPROTO_UDP);
if (Socket->AuxSocket == INVALID_SOCKET) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"socket");
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
int Option = FALSE;
Result =
setsockopt(
Socket->AuxSocket,
IPPROTO_IPV6,
IPV6_V6ONLY,
(char*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"Set IPV6_V6ONLY");
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
if (Socket->CibirIdLength) {
Option = TRUE;
Result =
setsockopt(
Socket->AuxSocket,
SOL_SOCKET,
SO_REUSEADDR,
(char*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"Set SO_REUSEADDR");
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
}
CxPlatConvertToMappedV6(&Socket->LocalAddress, &MappedAddress);
#if QUIC_ADDRESS_FAMILY_INET6 != AF_INET6
if (MappedAddress.Ipv6.sin6_family == QUIC_ADDRESS_FAMILY_INET6) {
MappedAddress.Ipv6.sin6_family = AF_INET6;
}
#endif
CxPlatRwLockAcquireExclusive(&Pool->Lock);
Result =
bind(
Socket->AuxSocket,
(struct sockaddr*)&MappedAddress,
sizeof(MappedAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"bind");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
if (Socket->Connected) {
CxPlatZeroMemory(&MappedAddress, sizeof(MappedAddress));
CxPlatConvertToMappedV6(&Socket->RemoteAddress, &MappedAddress);
#if QUIC_ADDRESS_FAMILY_INET6 != AF_INET6
if (MappedAddress.Ipv6.sin6_family == QUIC_ADDRESS_FAMILY_INET6) {
MappedAddress.Ipv6.sin6_family = AF_INET6;
}
#endif
if (Socket->UseTcp) {
//
// Create a temporary UDP socket bound to a wildcard port
// and connect this socket to the remote address.
// By doing this, the OS will select a local address for us.
//
uint16_t LocalPortChosen = 0;
QUIC_ADDR TempLocalAddress = {0};
AssignedLocalAddressLength = sizeof(TempLocalAddress);
Result =
getsockname(
Socket->AuxSocket,
(struct sockaddr*)&TempLocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
LocalPortChosen = TempLocalAddress.Ipv4.sin_port;
TempUdpSocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (TempUdpSocket == INVALID_SOCKET) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"temp udp socket");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
Option = FALSE;
Result =
setsockopt(
TempUdpSocket,
IPPROTO_IPV6,
IPV6_V6ONLY,
(char*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"Set IPV6_V6ONLY (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatZeroMemory(&TempLocalAddress, sizeof(TempLocalAddress));
CxPlatConvertToMappedV6(&Socket->LocalAddress, &TempLocalAddress);
TempLocalAddress.Ipv4.sin_port = 0;
Result =
bind(
TempUdpSocket,
(struct sockaddr*)&TempLocalAddress,
sizeof(TempLocalAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"bind (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
Result =
connect(
TempUdpSocket,
(struct sockaddr*)&MappedAddress,
sizeof(MappedAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"connect failed (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
Result =
getsockname(
TempUdpSocket,
(struct sockaddr*)&Socket->LocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
Socket->LocalAddress.Ipv4.sin_port = LocalPortChosen;
CXPLAT_FRE_ASSERT(Socket->LocalAddress.Ipv4.sin_port != 0);
} else {
Result =
connect(
Socket->AuxSocket,
(struct sockaddr*)&MappedAddress,
sizeof(MappedAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"connect failed");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
Result =
getsockname(
Socket->AuxSocket,
(struct sockaddr*)&Socket->LocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
}
} else {
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
Result =
getsockname(
Socket->AuxSocket,
(struct sockaddr*)&Socket->LocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
}
Entry = CxPlatHashtableLookup(&Pool->Sockets, Socket->LocalAddress.Ipv4.sin_port, &Context);
while (Entry != NULL) {
CXPLAT_SOCKET* Temp = CONTAINING_RECORD(Entry, CXPLAT_SOCKET, Entry);
if (CxPlatSocketCompare(Temp, &Socket->LocalAddress, &Socket->RemoteAddress)) {
Status = QUIC_STATUS_ADDRESS_IN_USE;
break;
}
Entry = CxPlatHashtableLookupNext(&Pool->Sockets, &Context);
}
if (QUIC_SUCCEEDED(Status)) {
CxPlatHashtableInsert(&Pool->Sockets, &Socket->Entry, Socket->LocalAddress.Ipv4.sin_port, &Context);
}
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Error:
if (QUIC_FAILED(Status) && Socket->AuxSocket != INVALID_SOCKET) {
closesocket(Socket->AuxSocket);
}
if (TempUdpSocket != INVALID_SOCKET) {
closesocket(TempUdpSocket);
}
return Status;
}
void
CxPlatRemoveSocket(
_In_ CXPLAT_SOCKET_POOL* Pool,
_In_ CXPLAT_SOCKET* Socket
)
{
CxPlatRwLockAcquireExclusive(&Pool->Lock);
CxPlatHashtableRemove(&Pool->Sockets, &Socket->Entry, NULL);
if (closesocket(Socket->AuxSocket) == SOCKET_ERROR) {
int Error = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Error,
"closesocket");
}
CxPlatRwLockReleaseExclusive(&Pool->Lock);
}
void
CxPlatResolveRouteComplete(
_In_ QUIC_CONNECTION* Connection,
_In_ void* Context,
_Inout_ CXPLAT_ROUTE* Route,
_In_reads_bytes_(6) const uint8_t* PhysicalAddress,
_In_ uint8_t PathId
)
{
QUIC_CONNECTION* Connection = (QUIC_CONNECTION*)Context;
CxPlatCopyMemory(&Route->NextHopLinkLayerAddress, PhysicalAddress, sizeof(Route->NextHopLinkLayerAddress));
Route->State = RouteResolved;
QuicTraceLogConnInfo(
@ -491,276 +97,6 @@ CxPlatUpdateRoute(
}
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatResolveRoute(
_In_ CXPLAT_SOCKET* Socket,
_Inout_ CXPLAT_ROUTE* Route,
_In_ uint8_t PathId,
_In_ void* Context,
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
)
{
#ifdef _WIN32
NETIO_STATUS Status = ERROR_SUCCESS;
MIB_IPFORWARD_ROW2 IpforwardRow = {0};
CXPLAT_ROUTE_STATE State = Route->State;
QUIC_ADDR LocalAddress = {0};
CXPLAT_DBG_ASSERT(!QuicAddrIsWildCard(&Route->RemoteAddress));
Route->State = RouteResolving;
QuicTraceEvent(
DatapathGetRouteStart,
"[data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress));
//
// Find the best next hop IP address.
//
Status =
GetBestRoute2(
NULL, // InterfaceLuid
IFI_UNSPECIFIED, // InterfaceIndex
&Route->LocalAddress, // SourceAddress
&Route->RemoteAddress, // DestinationAddress
0, // AddressSortOptions
&IpforwardRow,
&LocalAddress); // BestSourceAddress
if (Status != ERROR_SUCCESS) {
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Status,
"GetBestRoute2");
goto Done;
}
QuicTraceEvent(
DatapathGetRouteComplete,
"[data][%p] Query route result: %!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress));
if (State == RouteSuspected && !QuicAddrCompareIp(&LocalAddress, &Route->LocalAddress)) {
//
// We can't handle local address change here easily due to lack of full migration support.
//
Status = ERROR_INVALID_STATE;
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Status,
"GetBestRoute2 returned different local address for the suspected route");
goto Done;
} else {
LocalAddress.Ipv4.sin_port = Route->LocalAddress.Ipv4.sin_port; // Preserve local port.
Route->LocalAddress = LocalAddress;
}
//
// Find the interface that matches the route we just looked up.
//
CXPLAT_LIST_ENTRY* Entry = Socket->Datapath->Interfaces.Flink;
for (; Entry != &Socket->Datapath->Interfaces; Entry = Entry->Flink) {
CXPLAT_INTERFACE* Interface = CONTAINING_RECORD(Entry, CXPLAT_INTERFACE, Link);
if (Interface->IfIndex == IpforwardRow.InterfaceIndex) {
CXPLAT_DBG_ASSERT(sizeof(Interface->PhysicalAddress) == sizeof(Route->LocalLinkLayerAddress));
CxPlatCopyMemory(&Route->LocalLinkLayerAddress, Interface->PhysicalAddress, sizeof(Route->LocalLinkLayerAddress));
CxPlatDpRawAssignQueue(Interface, Route);
break;
}
}
if (Route->Queue == NULL) {
Status = ERROR_NOT_FOUND;
QuicTraceEvent(
DatapathError,
"[data][%p] ERROR, %s.",
Socket,
"no matching interface/queue");
goto Done;
}
//
// Map the next hop IP address to a link-layer address.
//
MIB_IPNET_ROW2 IpnetRow = {0};
IpnetRow.InterfaceLuid = IpforwardRow.InterfaceLuid;
if (QuicAddrIsWildCard(&IpforwardRow.NextHop)) { // On-link?
IpnetRow.Address = Route->RemoteAddress;
} else {
IpnetRow.Address = IpforwardRow.NextHop;
}
//
// Call GetIpNetEntry2 to see if there's already a cached neighbor.
//
Status = GetIpNetEntry2(&IpnetRow);
QuicTraceLogConnInfo(
RouteResolutionStart,
Context,
"Starting to look up neighbor on Path[%hhu] with status %u",
PathId,
Status);
//
// We need to force neighbor solicitation (NS) if any of the following is true:
// 1. No cached neighbor entry for the given destination address.
// 2. The neighbor entry isn't in a usable state.
// 3. When we are re-resolving a suspected route, the neighbor entry is the same as the existing one.
//
// We queue an operation on the route worker for NS because it involves network IO and
// we don't want our connection worker queue blocked.
//
if ((Status != ERROR_SUCCESS || IpnetRow.State <= NlnsIncomplete) ||
(State == RouteSuspected &&
memcmp(
Route->NextHopLinkLayerAddress,
IpnetRow.PhysicalAddress,
sizeof(Route->NextHopLinkLayerAddress)) == 0)) {
CXPLAT_ROUTE_RESOLUTION_WORKER* Worker = Socket->Datapath->RouteResolutionWorker;
CXPLAT_ROUTE_RESOLUTION_OPERATION* Operation = CxPlatPoolAlloc(&Worker->OperationPool);
if (Operation == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION));
Status = ERROR_NOT_ENOUGH_MEMORY;
goto Done;
}
Operation->IpnetRow = IpnetRow;
Operation->Context = Context;
Operation->Callback = Callback;
Operation->PathId = PathId;
CxPlatDispatchLockAcquire(&Worker->Lock);
CxPlatListInsertTail(&Worker->Operations, &Operation->WorkerLink);
CxPlatDispatchLockRelease(&Worker->Lock);
CxPlatEventSet(Worker->Ready);
Status = ERROR_IO_PENDING;
} else {
CxPlatResolveRouteComplete(Context, Route, IpnetRow.PhysicalAddress, PathId);
}
Done:
if (Status != ERROR_IO_PENDING && Status != ERROR_SUCCESS) {
Callback(Context, NULL, PathId, FALSE);
}
if (Status == ERROR_IO_PENDING) {
return QUIC_STATUS_PENDING;
} else {
return HRESULT_FROM_WIN32(Status);
}
#else // _WIN32
return QUIC_STATUS_NOT_SUPPORTED;
#endif // _WIN32
}
//
// Ethernet / IP Framing Logic
//
#pragma pack(push)
#pragma pack(1)
typedef struct ETHERNET_HEADER {
uint8_t Destination[6];
uint8_t Source[6];
uint16_t Type;
uint8_t Data[0];
} ETHERNET_HEADER;
typedef struct IPV4_HEADER {
uint8_t VersionAndHeaderLength;
union {
uint8_t TypeOfServiceAndEcnField;
struct {
uint8_t EcnField : 2;
uint8_t TypeOfService : 6;
};
};
uint16_t TotalLength;
uint16_t Identification;
uint16_t FlagsAndFragmentOffset;
uint8_t TimeToLive;
uint8_t Protocol;
uint16_t HeaderChecksum;
uint8_t Source[4];
uint8_t Destination[4];
uint8_t Data[0];
} IPV4_HEADER;
typedef struct IPV6_HEADER {
uint32_t VersionClassEcnFlow;
uint16_t PayloadLength;
uint8_t NextHeader;
uint8_t HopLimit;
uint8_t Source[16];
uint8_t Destination[16];
uint8_t Data[0];
} IPV6_HEADER;
typedef struct IPV6_EXTENSION {
uint8_t NextHeader;
uint8_t Length;
uint16_t Reserved0;
uint32_t Reserved1;
uint8_t Data[0];
} IPV6_EXTENSION;
typedef struct UDP_HEADER {
uint16_t SourcePort;
uint16_t DestinationPort;
uint16_t Length;
uint16_t Checksum;
uint8_t Data[0];
} UDP_HEADER;
typedef struct TCP_HEADER {
uint16_t SourcePort;
uint16_t DestinationPort;
uint32_t SequenceNumber;
uint32_t AckNumber;
uint8_t X2 : 4;
uint8_t HeaderLength : 4;
uint8_t Flags;
uint16_t Window;
uint16_t Checksum;
uint16_t UrgentPointer;
} TCP_HEADER;
#pragma pack(pop)
//
// Constants for headers in wire format.
//
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define IPV4_VERSION 4
#define IPV6_VERSION 6
#define IPV4_VERSION_BYTE (IPV4_VERSION << 4)
#define IPV4_DEFAULT_VERHLEN ((IPV4_VERSION_BYTE) | (sizeof(IPV4_HEADER) / sizeof(uint32_t)))
#define IP_DEFAULT_HOP_LIMIT 128
#define ETHERNET_TYPE_IPV4 0x0008
#define ETHERNET_TYPE_IPV6 0xdd86
_IRQL_requires_max_(DISPATCH_LEVEL)
static
void
@ -1212,7 +548,7 @@ CxPlatDpRawSocketAckSyn(
TcpFlags);
CxPlatDpRawTxEnqueue(SendData);
SendData = InterlockedFetchAndClearPointer(&Socket->PausedTcpSend);
SendData = InterlockedFetchAndClearPointer((void*)&Socket->PausedTcpSend);
if (SendData) {
CXPLAT_DBG_ASSERT(Socket->Connected);
QuicTraceEvent(

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

@ -0,0 +1,84 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
QUIC raw datapath socket and IP framing abstractions
--*/
#include "datapath_raw_linux.h"
#ifdef QUIC_CLOG
#include "datapath_raw_socket_linux.c.clog.h"
#endif
#pragma warning(disable:4116) // unnamed type definition in parentheses
#pragma warning(disable:4100) // unreferenced formal parameter
//
// Socket Pool Logic
//
BOOLEAN
CxPlatSockPoolInitialize(
_Inout_ CXPLAT_SOCKET_POOL* Pool
)
{
if (!CxPlatHashtableInitializeEx(&Pool->Sockets, CXPLAT_HASH_MIN_SIZE)) {
return FALSE;
}
CxPlatRwLockInitialize(&Pool->Lock);
return TRUE;
}
void
CxPlatSockPoolUninitialize(
_Inout_ CXPLAT_SOCKET_POOL* Pool
)
{
CxPlatRwLockUninitialize(&Pool->Lock);
CxPlatHashtableUninitialize(&Pool->Sockets);
}
void
CxPlatRemoveSocket(
_In_ CXPLAT_SOCKET_POOL* Pool,
_In_ CXPLAT_SOCKET* Socket
)
{
UNREFERENCED_PARAMETER(Pool);
UNREFERENCED_PARAMETER(Socket);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatResolveRoute(
_In_ CXPLAT_SOCKET* Socket,
_Inout_ CXPLAT_ROUTE* Route,
_In_ uint8_t PathId,
_In_ void* Context,
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
)
{
UNREFERENCED_PARAMETER(Socket);
UNREFERENCED_PARAMETER(Route);
UNREFERENCED_PARAMETER(PathId);
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(Callback);
return QUIC_STATUS_NOT_SUPPORTED;
}
QUIC_STATUS
CxPlatTryAddSocket(
_In_ CXPLAT_SOCKET_POOL* Pool,
_In_ CXPLAT_SOCKET* Socket
)
{
UNREFERENCED_PARAMETER(Pool);
UNREFERENCED_PARAMETER(Socket);
return QUIC_STATUS_NOT_SUPPORTED;
}

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

@ -0,0 +1,568 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
QUIC raw datapath socket and IP framing abstractions
--*/
#include "datapath_raw_win.h"
#ifdef QUIC_CLOG
#include "datapath_raw_socket_win.c.clog.h"
#endif
#define SocketError() WSAGetLastError()
#pragma warning(disable:4116) // unnamed type definition in parentheses
#pragma warning(disable:4100) // unreferenced formal parameter
//
// Socket Pool Logic
//
BOOLEAN
CxPlatSockPoolInitialize(
_Inout_ CXPLAT_SOCKET_POOL* Pool
)
{
if (!CxPlatHashtableInitializeEx(&Pool->Sockets, CXPLAT_HASH_MIN_SIZE)) {
return FALSE;
}
int WsaError;
WSADATA WsaData;
if ((WsaError = WSAStartup(MAKEWORD(2, 2), &WsaData)) != 0) {
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
WsaError,
"WSAStartup");
CxPlatHashtableUninitialize(&Pool->Sockets);
return FALSE;
}
return TRUE;
}
void
CxPlatSockPoolUninitialize(
_Inout_ CXPLAT_SOCKET_POOL* Pool
)
{
(void)WSACleanup();
}
void
CxPlatRemoveSocket(
_In_ CXPLAT_SOCKET_POOL* Pool,
_In_ CXPLAT_SOCKET* Socket
)
{
CxPlatRwLockAcquireExclusive(&Pool->Lock);
CxPlatHashtableRemove(&Pool->Sockets, &Socket->Entry, NULL);
if (closesocket(Socket->AuxSocket) == SOCKET_ERROR) {
int Error = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Error,
"closesocket");
}
CxPlatRwLockReleaseExclusive(&Pool->Lock);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatResolveRoute(
_In_ CXPLAT_SOCKET* Socket,
_Inout_ CXPLAT_ROUTE* Route,
_In_ uint8_t PathId,
_In_ void* Context,
_In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
)
{
NETIO_STATUS Status = ERROR_SUCCESS;
MIB_IPFORWARD_ROW2 IpforwardRow = {0};
CXPLAT_ROUTE_STATE State = Route->State;
QUIC_ADDR LocalAddress = {0};
CXPLAT_DBG_ASSERT(!QuicAddrIsWildCard(&Route->RemoteAddress));
Route->State = RouteResolving;
QuicTraceEvent(
DatapathGetRouteStart,
"[data][%p] Querying route, local=%!ADDR!, remote=%!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(Route->LocalAddress), &Route->LocalAddress),
CASTED_CLOG_BYTEARRAY(sizeof(Route->RemoteAddress), &Route->RemoteAddress));
//
// Find the best next hop IP address.
//
Status =
GetBestRoute2(
NULL, // InterfaceLuid
IFI_UNSPECIFIED, // InterfaceIndex
&Route->LocalAddress, // SourceAddress
&Route->RemoteAddress, // DestinationAddress
0, // AddressSortOptions
&IpforwardRow,
&LocalAddress); // BestSourceAddress
if (Status != ERROR_SUCCESS) {
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Status,
"GetBestRoute2");
goto Done;
}
QuicTraceEvent(
DatapathGetRouteComplete,
"[data][%p] Query route result: %!ADDR!",
Socket,
CASTED_CLOG_BYTEARRAY(sizeof(LocalAddress), &LocalAddress));
if (State == RouteSuspected && !QuicAddrCompareIp(&LocalAddress, &Route->LocalAddress)) {
//
// We can't handle local address change here easily due to lack of full migration support.
//
Status = ERROR_INVALID_STATE;
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
Status,
"GetBestRoute2 returned different local address for the suspected route");
goto Done;
} else {
LocalAddress.Ipv4.sin_port = Route->LocalAddress.Ipv4.sin_port; // Preserve local port.
Route->LocalAddress = LocalAddress;
}
//
// Find the interface that matches the route we just looked up.
//
CXPLAT_LIST_ENTRY* Entry = Socket->Datapath->Interfaces.Flink;
for (; Entry != &Socket->Datapath->Interfaces; Entry = Entry->Flink) {
CXPLAT_INTERFACE* Interface = CONTAINING_RECORD(Entry, CXPLAT_INTERFACE, Link);
if (Interface->IfIndex == IpforwardRow.InterfaceIndex) {
CXPLAT_DBG_ASSERT(sizeof(Interface->PhysicalAddress) == sizeof(Route->LocalLinkLayerAddress));
CxPlatCopyMemory(&Route->LocalLinkLayerAddress, Interface->PhysicalAddress, sizeof(Route->LocalLinkLayerAddress));
CxPlatDpRawAssignQueue(Interface, Route);
break;
}
}
if (Route->Queue == NULL) {
Status = ERROR_NOT_FOUND;
QuicTraceEvent(
DatapathError,
"[data][%p] ERROR, %s.",
Socket,
"no matching interface/queue");
goto Done;
}
//
// Map the next hop IP address to a link-layer address.
//
MIB_IPNET_ROW2 IpnetRow = {0};
IpnetRow.InterfaceLuid = IpforwardRow.InterfaceLuid;
if (QuicAddrIsWildCard(&IpforwardRow.NextHop)) { // On-link?
IpnetRow.Address = Route->RemoteAddress;
} else {
IpnetRow.Address = IpforwardRow.NextHop;
}
//
// Call GetIpNetEntry2 to see if there's already a cached neighbor.
//
Status = GetIpNetEntry2(&IpnetRow);
QuicTraceLogConnInfo(
RouteResolutionStart,
Context,
"Starting to look up neighbor on Path[%hhu] with status %u",
PathId,
Status);
//
// We need to force neighbor solicitation (NS) if any of the following is true:
// 1. No cached neighbor entry for the given destination address.
// 2. The neighbor entry isn't in a usable state.
// 3. When we are re-resolving a suspected route, the neighbor entry is the same as the existing one.
//
// We queue an operation on the route worker for NS because it involves network IO and
// we don't want our connection worker queue blocked.
//
if ((Status != ERROR_SUCCESS || IpnetRow.State <= NlnsIncomplete) ||
(State == RouteSuspected &&
memcmp(
Route->NextHopLinkLayerAddress,
IpnetRow.PhysicalAddress,
sizeof(Route->NextHopLinkLayerAddress)) == 0)) {
CXPLAT_ROUTE_RESOLUTION_WORKER* Worker = Socket->Datapath->RouteResolutionWorker;
CXPLAT_ROUTE_RESOLUTION_OPERATION* Operation = CxPlatPoolAlloc(&Worker->OperationPool);
if (Operation == NULL) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"CXPLAT_DATAPATH",
sizeof(CXPLAT_ROUTE_RESOLUTION_OPERATION));
Status = ERROR_NOT_ENOUGH_MEMORY;
goto Done;
}
Operation->IpnetRow = IpnetRow;
Operation->Context = Context;
Operation->Callback = Callback;
Operation->PathId = PathId;
CxPlatDispatchLockAcquire(&Worker->Lock);
CxPlatListInsertTail(&Worker->Operations, &Operation->WorkerLink);
CxPlatDispatchLockRelease(&Worker->Lock);
CxPlatEventSet(Worker->Ready);
Status = ERROR_IO_PENDING;
} else {
CxPlatResolveRouteComplete(Context, Route, IpnetRow.PhysicalAddress, PathId);
}
Done:
if (Status != ERROR_IO_PENDING && Status != ERROR_SUCCESS) {
Callback(Context, NULL, PathId, FALSE);
}
if (Status == ERROR_IO_PENDING) {
return QUIC_STATUS_PENDING;
} else {
return HRESULT_FROM_WIN32(Status);
}
}
QUIC_STATUS
CxPlatTryAddSocket(
_In_ CXPLAT_SOCKET_POOL* Pool,
_In_ CXPLAT_SOCKET* Socket
)
{
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
int Result;
CXPLAT_HASHTABLE_LOOKUP_CONTEXT Context;
CXPLAT_HASHTABLE_ENTRY* Entry;
QUIC_ADDR MappedAddress = {0};
SOCKET TempUdpSocket = INVALID_SOCKET;
int AssignedLocalAddressLength;
//
// Get (and reserve) a transport layer port from the OS networking stack by
// binding an auxiliary (dual stack) socket.
//
Socket->AuxSocket =
socket(
AF_INET6,
Socket->UseTcp ? SOCK_STREAM : SOCK_DGRAM,
Socket->UseTcp ? IPPROTO_TCP : IPPROTO_UDP);
if (Socket->AuxSocket == INVALID_SOCKET) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"socket");
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
int Option = FALSE;
Result =
setsockopt(
Socket->AuxSocket,
IPPROTO_IPV6,
IPV6_V6ONLY,
(char*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"Set IPV6_V6ONLY");
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
if (Socket->CibirIdLength) {
Option = TRUE;
Result =
setsockopt(
Socket->AuxSocket,
SOL_SOCKET,
SO_REUSEADDR,
(char*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"Set SO_REUSEADDR");
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
}
CxPlatConvertToMappedV6(&Socket->LocalAddress, &MappedAddress);
#if QUIC_ADDRESS_FAMILY_INET6 != AF_INET6
if (MappedAddress.Ipv6.sin6_family == QUIC_ADDRESS_FAMILY_INET6) {
MappedAddress.Ipv6.sin6_family = AF_INET6;
}
#endif
CxPlatRwLockAcquireExclusive(&Pool->Lock);
Result =
bind(
Socket->AuxSocket,
(struct sockaddr*)&MappedAddress,
sizeof(MappedAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"bind");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
if (Socket->Connected) {
CxPlatZeroMemory(&MappedAddress, sizeof(MappedAddress));
CxPlatConvertToMappedV6(&Socket->RemoteAddress, &MappedAddress);
#if QUIC_ADDRESS_FAMILY_INET6 != AF_INET6
if (MappedAddress.Ipv6.sin6_family == QUIC_ADDRESS_FAMILY_INET6) {
MappedAddress.Ipv6.sin6_family = AF_INET6;
}
#endif
if (Socket->UseTcp) {
//
// Create a temporary UDP socket bound to a wildcard port
// and connect this socket to the remote address.
// By doing this, the OS will select a local address for us.
//
uint16_t LocalPortChosen = 0;
QUIC_ADDR TempLocalAddress = {0};
AssignedLocalAddressLength = sizeof(TempLocalAddress);
Result =
getsockname(
Socket->AuxSocket,
(struct sockaddr*)&TempLocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
LocalPortChosen = TempLocalAddress.Ipv4.sin_port;
TempUdpSocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (TempUdpSocket == INVALID_SOCKET) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"temp udp socket");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
Option = FALSE;
Result =
setsockopt(
TempUdpSocket,
IPPROTO_IPV6,
IPV6_V6ONLY,
(char*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"Set IPV6_V6ONLY (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatZeroMemory(&TempLocalAddress, sizeof(TempLocalAddress));
CxPlatConvertToMappedV6(&Socket->LocalAddress, &TempLocalAddress);
TempLocalAddress.Ipv4.sin_port = 0;
Result =
bind(
TempUdpSocket,
(struct sockaddr*)&TempLocalAddress,
sizeof(TempLocalAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"bind (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
Result =
connect(
TempUdpSocket,
(struct sockaddr*)&MappedAddress,
sizeof(MappedAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"connect failed (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
Result =
getsockname(
TempUdpSocket,
(struct sockaddr*)&Socket->LocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname (temp udp socket)");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
Socket->LocalAddress.Ipv4.sin_port = LocalPortChosen;
CXPLAT_FRE_ASSERT(Socket->LocalAddress.Ipv4.sin_port != 0);
} else {
Result =
connect(
Socket->AuxSocket,
(struct sockaddr*)&MappedAddress,
sizeof(MappedAddress));
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"connect failed");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
Result =
getsockname(
Socket->AuxSocket,
(struct sockaddr*)&Socket->LocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
}
} else {
AssignedLocalAddressLength = sizeof(Socket->LocalAddress);
Result =
getsockname(
Socket->AuxSocket,
(struct sockaddr*)&Socket->LocalAddress,
&AssignedLocalAddressLength);
if (Result == SOCKET_ERROR) {
int WsaError = SocketError();
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Socket,
WsaError,
"getsockname");
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Status = HRESULT_FROM_WIN32(WsaError);
goto Error;
}
CxPlatConvertFromMappedV6(&Socket->LocalAddress, &Socket->LocalAddress);
}
Entry = CxPlatHashtableLookup(&Pool->Sockets, Socket->LocalAddress.Ipv4.sin_port, &Context);
while (Entry != NULL) {
CXPLAT_SOCKET* Temp = CXPLAT_CONTAINING_RECORD(Entry, CXPLAT_SOCKET, Entry);
if (CxPlatSocketCompare(Temp, &Socket->LocalAddress, &Socket->RemoteAddress)) {
Status = QUIC_STATUS_ADDRESS_IN_USE;
break;
}
Entry = CxPlatHashtableLookupNext(&Pool->Sockets, &Context);
}
if (QUIC_SUCCEEDED(Status)) {
CxPlatHashtableInsert(&Pool->Sockets, &Socket->Entry, Socket->LocalAddress.Ipv4.sin_port, &Context);
}
CxPlatRwLockReleaseExclusive(&Pool->Lock);
Error:
if (QUIC_FAILED(Status) && Socket->AuxSocket != INVALID_SOCKET) {
closesocket(Socket->AuxSocket);
}
if (TempUdpSocket != INVALID_SOCKET) {
closesocket(TempUdpSocket);
}
return Status;
}

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

@ -9,9 +9,9 @@ Abstract:
--*/
#include "datapath_raw.h"
#include "datapath_raw_win.h"
#ifdef QUIC_CLOG
#include "datapath_raw.c.clog.h"
#include "datapath_raw_win.c.clog.h"
#endif
#pragma warning(disable:4116) // unnamed type definition in parentheses

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

@ -0,0 +1,24 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
--*/
#define QUIC_API_ENABLE_PREVIEW_FEATURES 1
#include "datapath_raw.h"
#include "platform_internal.h"
#include "quic_hashtable.h"
typedef struct CXPLAT_ROUTE_RESOLUTION_OPERATION {
//
// Link in the worker's operation queue.
// N.B. Multi-threaded access, synchronized by worker's operation lock.
//
CXPLAT_LIST_ENTRY WorkerLink;
MIB_IPNET_ROW2 IpnetRow;
void* Context;
uint8_t PathId;
CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback;
} CXPLAT_ROUTE_RESOLUTION_OPERATION;

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

@ -0,0 +1,52 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
--*/
#define QUIC_API_ENABLE_PREVIEW_FEATURES 1
#include <stdio.h>
#include "platform_internal.h"
#define RX_BATCH_SIZE 16
#define MAX_ETH_FRAME_SIZE 1514
#define ADAPTER_TAG 'ApdX' // XdpA
#define IF_TAG 'IpdX' // XdpI
#define QUEUE_TAG 'QpdX' // XdpQ
#define RULE_TAG 'UpdX' // XdpU
#define RX_BUFFER_TAG 'RpdX' // XdpR
#define TX_BUFFER_TAG 'TpdX' // XdpT
#define PORT_SET_TAG 'PpdX' // XdpP
typedef struct XDP_INTERFACE XDP_INTERFACE;
typedef struct XDP_WORKER XDP_WORKER;
typedef struct XDP_DATAPATH XDP_DATAPATH;
typedef struct XDP_QUEUE XDP_QUEUE;
//
// Type of IO.
//
typedef enum DATAPATH_IO_TYPE {
DATAPATH_IO_SIGNATURE = 'XDPD',
DATAPATH_IO_RECV = DATAPATH_IO_SIGNATURE + 1,
DATAPATH_IO_SEND = DATAPATH_IO_SIGNATURE + 2
} DATAPATH_IO_TYPE;
//
// IO header for SQE->CQE based completions.
//
typedef struct DATAPATH_IO_SQE {
DATAPATH_IO_TYPE IoType;
DATAPATH_SQE DatapathSqe;
} DATAPATH_IO_SQE;
typedef struct QUIC_CACHEALIGN XDP_WORKER {
CXPLAT_EXECUTION_CONTEXT Ec;
DATAPATH_SQE ShutdownSqe;
const struct XDP_DATAPATH* Xdp;
CXPLAT_EVENTQ* EventQ;
XDP_QUEUE* Queues; // A linked list of queues, accessed by Next.
uint16_t ProcIndex;
} XDP_WORKER;

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

@ -0,0 +1,314 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
QUIC XDP Datapath Implementation (User Mode)
--*/
#define _CRT_SECURE_NO_WARNINGS 1 // TODO - Remove
#include "datapath_raw_linux.h"
#include "datapath_raw_xdp.h"
#ifdef QUIC_CLOG
#include "datapath_raw_xdp_linux.c.clog.h"
#endif
typedef struct XDP_DATAPATH {
CXPLAT_DATAPATH;
__attribute__((aligned(64)))
//
// Currently, all XDP interfaces share the same config.
//
CXPLAT_REF_COUNT RefCount;
uint32_t WorkerCount;
uint32_t RxBufferCount;
uint32_t RxRingSize;
uint32_t TxBufferCount;
uint32_t TxRingSize;
uint32_t PollingIdleTimeoutUs;
BOOLEAN TxAlwaysPoke;
BOOLEAN SkipXsum;
BOOLEAN Running; // Signal to stop workers.
// const XDP_API_TABLE *XdpApi;
XDP_WORKER Workers[0];
} XDP_DATAPATH;
typedef struct XDP_INTERFACE {
CXPLAT_INTERFACE;
uint16_t QueueCount;
uint8_t RuleCount;
CXPLAT_LOCK RuleLock;
// XDP_RULE* Rules;
XDP_QUEUE* Queues; // An array of queues.
const struct XDP_DATAPATH* Xdp;
} XDP_INTERFACE;
typedef struct XDP_QUEUE {
const XDP_INTERFACE* Interface;
XDP_WORKER* Worker;
struct XDP_QUEUE* Next;
uint8_t* RxBuffers;
// HANDLE RxXsk;
DATAPATH_IO_SQE RxIoSqe;
// XSK_RING RxFillRing;
// XSK_RING RxRing;
// HANDLE RxProgram;
uint8_t* TxBuffers;
// HANDLE TxXsk;
DATAPATH_IO_SQE TxIoSqe;
// XSK_RING TxRing;
// XSK_RING TxCompletionRing;
BOOLEAN RxQueued;
BOOLEAN TxQueued;
BOOLEAN Error;
CXPLAT_LIST_ENTRY WorkerTxQueue;
CXPLAT_SLIST_ENTRY WorkerRxPool;
// Move contended buffer pools to their own cache lines.
// TODO: Use better (more scalable) buffer algorithms.
// DECLSPEC_CACHEALIGN SLIST_HEADER RxPool;
// DECLSPEC_CACHEALIGN SLIST_HEADER TxPool;
// Move TX queue to its own cache line.
// DECLSPEC_CACHEALIGN
CXPLAT_LOCK TxLock;
CXPLAT_LIST_ENTRY TxQueue;
} XDP_QUEUE;
// -> CxPlat
typedef struct __attribute__((aligned(64))) XDP_RX_PACKET {
CXPLAT_RECV_DATA;
CXPLAT_ROUTE RouteStorage;
XDP_QUEUE* Queue;
// Followed by:
// uint8_t ClientContext[...];
// uint8_t FrameBuffer[MAX_ETH_FRAME_SIZE];
} XDP_RX_PACKET;
typedef struct __attribute__((aligned(64))) XDP_TX_PACKET {
CXPLAT_SEND_DATA;
XDP_QUEUE* Queue;
CXPLAT_LIST_ENTRY Link;
uint8_t FrameBuffer[MAX_ETH_FRAME_SIZE];
} XDP_TX_PACKET;
CXPLAT_RECV_DATA*
CxPlatDataPathRecvPacketToRecvData(
_In_ const CXPLAT_RECV_PACKET* const Context
)
{
return (CXPLAT_RECV_DATA*)(((uint8_t*)Context) - sizeof(XDP_RX_PACKET));
}
CXPLAT_RECV_PACKET*
CxPlatDataPathRecvDataToRecvPacket(
_In_ const CXPLAT_RECV_DATA* const Datagram
)
{
return (CXPLAT_RECV_PACKET*)(((uint8_t*)Datagram) + sizeof(XDP_RX_PACKET));
}
QUIC_STATUS
CxPlatGetInterfaceRssQueueCount(
_In_ uint32_t InterfaceIndex,
_Out_ uint16_t* Count
)
{
UNREFERENCED_PARAMETER(InterfaceIndex);
UNREFERENCED_PARAMETER(Count);
return QUIC_STATUS_NOT_SUPPORTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatXdpReadConfig(
_Inout_ XDP_DATAPATH* Xdp
)
{
//
// Default config.
//
Xdp->RxBufferCount = 8192;
Xdp->RxRingSize = 256;
Xdp->TxBufferCount = 8192;
Xdp->TxRingSize = 256;
Xdp->TxAlwaysPoke = FALSE;
// TODO
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDpRawInterfaceUninitialize(
_Inout_ XDP_INTERFACE* Interface
)
{
UNREFERENCED_PARAMETER(Interface);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatDpRawInterfaceInitialize(
_In_ XDP_DATAPATH* Xdp,
_Inout_ XDP_INTERFACE* Interface,
_In_ uint32_t ClientRecvContextLength
)
{
UNREFERENCED_PARAMETER(Xdp);
UNREFERENCED_PARAMETER(Interface);
UNREFERENCED_PARAMETER(ClientRecvContextLength);
return QUIC_STATUS_NOT_SUPPORTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
//_Requires_lock_held_(Interface->RuleLock)
void
CxPlatDpRawInterfaceUpdateRules(
_In_ XDP_INTERFACE* Interface
)
{
UNREFERENCED_PARAMETER(Interface);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
size_t
CxPlatDpRawGetDatapathSize(
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
)
{
const uint32_t WorkerCount =
(Config && Config->ProcessorCount) ? Config->ProcessorCount : CxPlatProcMaxCount();
return sizeof(XDP_DATAPATH) + (WorkerCount * sizeof(XDP_WORKER));
}
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatDpRawInitialize(
_Inout_ CXPLAT_DATAPATH* Datapath,
_In_ uint32_t ClientRecvContextLength,
_In_opt_ const QUIC_EXECUTION_CONFIG* Config
)
{
UNREFERENCED_PARAMETER(Datapath);
UNREFERENCED_PARAMETER(ClientRecvContextLength);
UNREFERENCED_PARAMETER(Config);
return QUIC_STATUS_NOT_SUPPORTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDpRawRelease(
_In_ XDP_DATAPATH* Xdp
)
{
UNREFERENCED_PARAMETER(Xdp);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDpRawUninitialize(
_In_ CXPLAT_DATAPATH* Datapath
)
{
UNREFERENCED_PARAMETER(Datapath);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDpRawPlumbRulesOnSocket(
_In_ CXPLAT_SOCKET* Socket,
_In_ BOOLEAN IsCreated
)
{
UNREFERENCED_PARAMETER(Socket);
UNREFERENCED_PARAMETER(IsCreated);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatDpRawAssignQueue(
_In_ const CXPLAT_INTERFACE* _Interface,
_Inout_ CXPLAT_ROUTE* Route
)
{
const XDP_INTERFACE* Interface = (const XDP_INTERFACE*)_Interface;
Route->Queue = &Interface->Queues[0];
}
_IRQL_requires_max_(DISPATCH_LEVEL)
const CXPLAT_INTERFACE*
CxPlatDpRawGetInterfaceFromQueue(
_In_ const void* Queue
)
{
return (const CXPLAT_INTERFACE*)((XDP_QUEUE*)Queue)->Interface;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatDpRawRxFree(
_In_opt_ const CXPLAT_RECV_DATA* PacketChain
)
{
UNREFERENCED_PARAMETER(PacketChain);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
CXPLAT_SEND_DATA*
CxPlatDpRawTxAlloc(
_In_ CXPLAT_SOCKET* Socket,
_Inout_ CXPLAT_SEND_CONFIG* Config
)
{
UNREFERENCED_PARAMETER(Socket);
UNREFERENCED_PARAMETER(Config);
return NULL;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatDpRawTxFree(
_In_ CXPLAT_SEND_DATA* SendData
)
{
UNREFERENCED_PARAMETER(SendData);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
void
CxPlatDpRawTxEnqueue(
_In_ CXPLAT_SEND_DATA* SendData
)
{
UNREFERENCED_PARAMETER(SendData);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
BOOLEAN
CxPlatXdpExecute(
_Inout_ void* Context,
_Inout_ CXPLAT_EXECUTION_STATE* State
)
{
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(State);
return FALSE;
}
void
CxPlatDataPathProcessCqe(
_In_ CXPLAT_CQE* Cqe
)
{
UNREFERENCED_PARAMETER(Cqe);
}

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

@ -11,46 +11,48 @@ Abstract:
#define _CRT_SECURE_NO_WARNINGS 1 // TODO - Remove
#include "datapath_raw.h"
#ifdef QUIC_CLOG
#include "datapath_raw_xdp.c.clog.h"
#endif
#include "datapath_raw_win.h"
#include "datapath_raw_xdp.h"
#include <wbemidl.h>
#include <afxdp_helper.h>
#include <xdpapi.h>
#include <stdio.h>
#define RX_BATCH_SIZE 16
#define MAX_ETH_FRAME_SIZE 1514
#ifdef QUIC_CLOG
#include "datapath_raw_xdp_win.c.clog.h"
#endif
#define ADAPTER_TAG 'ApdX' // XdpA
#define IF_TAG 'IpdX' // XdpI
#define QUEUE_TAG 'QpdX' // XdpQ
#define RULE_TAG 'UpdX' // XdpU
#define RX_BUFFER_TAG 'RpdX' // XdpR
#define TX_BUFFER_TAG 'TpdX' // XdpT
#define PORT_SET_TAG 'PpdX' // XdpP
typedef struct XDP_DATAPATH {
CXPLAT_DATAPATH;
DECLSPEC_CACHEALIGN
//
// Currently, all XDP interfaces share the same config.
//
CXPLAT_REF_COUNT RefCount;
uint32_t WorkerCount;
uint32_t RxBufferCount;
uint32_t RxRingSize;
uint32_t TxBufferCount;
uint32_t TxRingSize;
uint32_t PollingIdleTimeoutUs;
BOOLEAN TxAlwaysPoke;
BOOLEAN SkipXsum;
BOOLEAN Running; // Signal to stop workers.
const XDP_API_TABLE *XdpApi;
typedef struct XDP_INTERFACE XDP_INTERFACE;
typedef struct XDP_WORKER XDP_WORKER;
XDP_WORKER Workers[0];
} XDP_DATAPATH;
//
// Type of IO.
//
typedef enum DATAPATH_IO_TYPE {
DATAPATH_IO_SIGNATURE = 'XDPD',
DATAPATH_IO_RECV = DATAPATH_IO_SIGNATURE + 1,
DATAPATH_IO_SEND = DATAPATH_IO_SIGNATURE + 2
} DATAPATH_IO_TYPE;
//
// IO header for SQE->CQE based completions.
//
typedef struct DATAPATH_IO_SQE {
DATAPATH_IO_TYPE IoType;
DATAPATH_SQE DatapathSqe;
} DATAPATH_IO_SQE;
typedef struct XDP_INTERFACE {
CXPLAT_INTERFACE;
HANDLE XdpHandle;
uint16_t QueueCount;
uint8_t RuleCount;
CXPLAT_LOCK RuleLock;
XDP_RULE* Rules;
XDP_QUEUE* Queues; // An array of queues.
const struct XDP_DATAPATH* Xdp;
} XDP_INTERFACE;
typedef struct XDP_QUEUE {
const XDP_INTERFACE* Interface;
@ -85,57 +87,6 @@ typedef struct XDP_QUEUE {
CXPLAT_LIST_ENTRY TxQueue;
} XDP_QUEUE;
typedef struct XDP_INTERFACE {
CXPLAT_INTERFACE;
HANDLE XdpHandle;
uint16_t QueueCount;
uint8_t RuleCount;
CXPLAT_LOCK RuleLock;
XDP_RULE* Rules;
XDP_QUEUE* Queues; // An array of queues.
const struct XDP_DATAPATH* Xdp;
} XDP_INTERFACE;
typedef struct QUIC_CACHEALIGN XDP_WORKER {
CXPLAT_EXECUTION_CONTEXT Ec;
DATAPATH_SQE ShutdownSqe;
const struct XDP_DATAPATH* Xdp;
CXPLAT_EVENTQ* EventQ;
XDP_QUEUE* Queues; // A linked list of queues, accessed by Next.
uint16_t ProcIndex;
} XDP_WORKER;
void XdpWorkerAddQueue(_In_ XDP_WORKER* Worker, _In_ XDP_QUEUE* Queue) {
XDP_QUEUE** Tail = &Worker->Queues;
while (*Tail != NULL) {
Tail = &(*Tail)->Next;
}
*Tail = Queue;
Queue->Next = NULL;
Queue->Worker = Worker;
}
typedef struct XDP_DATAPATH {
CXPLAT_DATAPATH;
DECLSPEC_CACHEALIGN
//
// Currently, all XDP interfaces share the same config.
//
CXPLAT_REF_COUNT RefCount;
uint32_t WorkerCount;
uint32_t RxBufferCount;
uint32_t RxRingSize;
uint32_t TxBufferCount;
uint32_t TxRingSize;
uint32_t PollingIdleTimeoutUs;
BOOLEAN TxAlwaysPoke;
BOOLEAN SkipXsum;
BOOLEAN Running; // Signal to stop workers.
const XDP_API_TABLE *XdpApi;
XDP_WORKER Workers[0];
} XDP_DATAPATH;
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) XDP_RX_PACKET {
CXPLAT_RECV_DATA;
CXPLAT_ROUTE RouteStorage;
@ -152,6 +103,17 @@ typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) XDP_TX_PACKET {
uint8_t FrameBuffer[MAX_ETH_FRAME_SIZE];
} XDP_TX_PACKET;
void XdpWorkerAddQueue(_In_ XDP_WORKER* Worker, _In_ XDP_QUEUE* Queue) {
XDP_QUEUE** Tail = &Worker->Queues;
while (*Tail != NULL) {
Tail = &(*Tail)->Next;
}
*Tail = Queue;
Queue->Next = NULL;
Queue->Worker = Worker;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
BOOLEAN
CxPlatXdpExecute(