зеркало из https://github.com/microsoft/msquic.git
Refactoring for cross-platform xdp placeholder (#3628)
This commit is contained in:
Родитель
dc64ccb47a
Коммит
f596ae5313
|
@ -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(
|
Загрузка…
Ссылка в новой задаче