576 строки
34 KiB
C
576 строки
34 KiB
C
// Copyright (c) eBPF for Windows contributors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include "net_ebpf_ext.h"
|
|
|
|
#include <TraceLoggingProvider.h>
|
|
#include <winmeta.h>
|
|
|
|
TRACELOGGING_DEFINE_PROVIDER(
|
|
net_ebpf_ext_tracelog_provider,
|
|
"NetEbpfExtProvider",
|
|
// {f2f2ca01-ad02-4a07-9e90-95a2334f3692}
|
|
(0xf2f2ca01, 0xad02, 0x4a07, 0x9e, 0x90, 0x95, 0xa2, 0x33, 0x4f, 0x36, 0x92));
|
|
|
|
static bool _net_ebpf_ext_trace_initiated = false;
|
|
|
|
NTSTATUS
|
|
net_ebpf_ext_trace_initiate()
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
if (_net_ebpf_ext_trace_initiated) {
|
|
goto Exit;
|
|
}
|
|
|
|
status = TraceLoggingRegister(net_ebpf_ext_tracelog_provider);
|
|
if (status != STATUS_SUCCESS) {
|
|
goto Exit;
|
|
} else {
|
|
_net_ebpf_ext_trace_initiated = true;
|
|
}
|
|
Exit:
|
|
return status;
|
|
}
|
|
|
|
// Prevent tail call optimization of the call to TraceLoggingUnregister to resolve verifier stop C4/DD
|
|
// "An attempt was made to unload a driver without calling EtwUnregister".
|
|
#pragma optimize("", off)
|
|
void
|
|
net_ebpf_ext_trace_terminate()
|
|
{
|
|
if (_net_ebpf_ext_trace_initiated) {
|
|
TraceLoggingUnregister(net_ebpf_ext_tracelog_provider);
|
|
_net_ebpf_ext_trace_initiated = false;
|
|
}
|
|
}
|
|
#pragma optimize("", on)
|
|
|
|
#define KEYWORD_BASE NET_EBPF_EXT_TRACELOG_KEYWORD_BASE
|
|
#define KEYWORD_BIND NET_EBPF_EXT_TRACELOG_KEYWORD_BIND
|
|
#define KEYWORD_EXT NET_EBPF_EXT_TRACELOG_KEYWORD_EXTENSION
|
|
#define KEYWORD_SOCK_ADDR NET_EBPF_EXT_TRACELOG_KEYWORD_SOCK_ADDR
|
|
#define KEYWORD_SOCK_OPS NET_EBPF_EXT_TRACELOG_KEYWORD_SOCK_OPS
|
|
#define KEYWORD_XDP NET_EBPF_EXT_TRACELOG_KEYWORD_XDP
|
|
|
|
#define CASE_BASE case _NET_EBPF_EXT_TRACELOG_KEYWORD_BASE
|
|
#define CASE_BIND case _NET_EBPF_EXT_TRACELOG_KEYWORD_BIND
|
|
#define CASE_EXT case _NET_EBPF_EXT_TRACELOG_KEYWORD_EXTENSION
|
|
#define CASE_SOCK_ADDR case _NET_EBPF_EXT_TRACELOG_KEYWORD_SOCK_ADDR
|
|
#define CASE_SOCK_OPS case _NET_EBPF_EXT_TRACELOG_KEYWORD_SOCK_OPS
|
|
#define CASE_XDP case _NET_EBPF_EXT_TRACELOG_KEYWORD_XDP
|
|
|
|
#define LEVEL_LOG_ALWAYS NET_EBPF_EXT_TRACELOG_LEVEL_LOG_ALWAYS
|
|
#define LEVEL_CRITICAL NET_EBPF_EXT_TRACELOG_LEVEL_CRITICAL
|
|
#define LEVEL_ERROR NET_EBPF_EXT_TRACELOG_LEVEL_ERROR
|
|
#define LEVEL_WARNING NET_EBPF_EXT_TRACELOG_LEVEL_WARNING
|
|
#define LEVEL_INFO NET_EBPF_EXT_TRACELOG_LEVEL_INFO
|
|
#define LEVEL_VERBOSE NET_EBPF_EXT_TRACELOG_LEVEL_VERBOSE
|
|
|
|
#define CASE_LOG_ALWAYS case _NET_EBPF_EXT_TRACELOG_LEVEL_LOG_ALWAYS
|
|
#define CASE_CRITICAL case _NET_EBPF_EXT_TRACELOG_LEVEL_CRITICAL
|
|
#define CASE_LEVEL_ERROR case _NET_EBPF_EXT_TRACELOG_LEVEL_ERROR
|
|
#define CASE_WARNING case _NET_EBPF_EXT_TRACELOG_LEVEL_WARNING
|
|
#define CASE_INFO case _NET_EBPF_EXT_TRACELOG_LEVEL_INFO
|
|
#define CASE_VERBOSE case _NET_EBPF_EXT_TRACELOG_LEVEL_VERBOSE
|
|
|
|
#define NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_KEYWORD_SWITCH(api_name, status) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE(KEYWORD_BASE, api_name, status); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE(KEYWORD_EXT, api_name, status); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE(KEYWORD_BIND, api_name, status); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE(KEYWORD_SOCK_ADDR, api_name, status); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE(KEYWORD_SOCK_OPS, api_name, status); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE(KEYWORD_XDP, api_name, status); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 6262) // Function uses 'N' bytes of stack. Consider moving some data to heap.
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_ntstatus_api_failure(
|
|
net_ebpf_ext_tracelog_keyword_t keyword, _In_z_ const char* api_name, NTSTATUS status)
|
|
{
|
|
NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_KEYWORD_SWITCH(api_name, status);
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING_KEYWORD_SWITCH(api_name, status, message, string_value) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING(KEYWORD_BASE, api_name, status, message, string_value); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING(KEYWORD_EXT, api_name, status, message, string_value); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING(KEYWORD_BIND, api_name, status, message, string_value); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING( \
|
|
KEYWORD_SOCK_ADDR, api_name, status, message, string_value); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING( \
|
|
KEYWORD_SOCK_OPS, api_name, status, message, string_value); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING(KEYWORD_XDP, api_name, status, message, string_value); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_ntstatus_api_failure_message_string(
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* api_name,
|
|
NTSTATUS status,
|
|
_In_z_ const char* message,
|
|
_In_z_ const char* string_value)
|
|
{
|
|
NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_MESSAGE_STRING_KEYWORD_SWITCH(api_name, status, message, string_value);
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_MESSAGE_KEYWORD_SWITCH(trace_level, message) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE(trace_level, KEYWORD_BASE, message); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE(trace_level, KEYWORD_BIND, message); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE(trace_level, KEYWORD_EXT, message); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE(trace_level, KEYWORD_SOCK_ADDR, message); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE(trace_level, KEYWORD_SOCK_OPS, message); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE(trace_level, KEYWORD_XDP, message); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_message(
|
|
net_ebpf_ext_tracelog_level_t trace_level, net_ebpf_ext_tracelog_keyword_t keyword, _In_z_ const char* message)
|
|
{
|
|
switch (trace_level) {
|
|
CASE_LOG_ALWAYS:
|
|
NET_EBPF_EXT_LOG_MESSAGE_KEYWORD_SWITCH(LEVEL_LOG_ALWAYS, message);
|
|
break;
|
|
CASE_CRITICAL:
|
|
NET_EBPF_EXT_LOG_MESSAGE_KEYWORD_SWITCH(LEVEL_CRITICAL, message);
|
|
break;
|
|
CASE_LEVEL_ERROR:
|
|
NET_EBPF_EXT_LOG_MESSAGE_KEYWORD_SWITCH(LEVEL_ERROR, message);
|
|
break;
|
|
CASE_WARNING:
|
|
NET_EBPF_EXT_LOG_MESSAGE_KEYWORD_SWITCH(LEVEL_WARNING, message);
|
|
break;
|
|
CASE_INFO:
|
|
NET_EBPF_EXT_LOG_MESSAGE_KEYWORD_SWITCH(LEVEL_INFO, message);
|
|
break;
|
|
CASE_VERBOSE:
|
|
NET_EBPF_EXT_LOG_MESSAGE_KEYWORD_SWITCH(LEVEL_VERBOSE, message);
|
|
break;
|
|
default:
|
|
ebpf_assert(!"Invalid trace level");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_MESSAGE_STRING_KEYWORD_SWITCH(trace_level, message, string_value) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_STRING(trace_level, KEYWORD_BASE, message, string_value); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_STRING(trace_level, KEYWORD_BIND, message, string_value); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_STRING(trace_level, KEYWORD_EXT, message, string_value); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_STRING(trace_level, KEYWORD_SOCK_ADDR, message, string_value); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_STRING(trace_level, KEYWORD_SOCK_OPS, message, string_value); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_STRING(trace_level, KEYWORD_XDP, message, string_value); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_message_string(
|
|
net_ebpf_ext_tracelog_level_t trace_level,
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* message,
|
|
_In_z_ const char* string_value)
|
|
{
|
|
switch (trace_level) {
|
|
CASE_LOG_ALWAYS:
|
|
NET_EBPF_EXT_LOG_MESSAGE_STRING_KEYWORD_SWITCH(LEVEL_LOG_ALWAYS, message, string_value);
|
|
break;
|
|
CASE_CRITICAL:
|
|
NET_EBPF_EXT_LOG_MESSAGE_STRING_KEYWORD_SWITCH(LEVEL_CRITICAL, message, string_value);
|
|
break;
|
|
CASE_LEVEL_ERROR:
|
|
NET_EBPF_EXT_LOG_MESSAGE_STRING_KEYWORD_SWITCH(LEVEL_ERROR, message, string_value);
|
|
break;
|
|
CASE_WARNING:
|
|
NET_EBPF_EXT_LOG_MESSAGE_STRING_KEYWORD_SWITCH(LEVEL_WARNING, message, string_value);
|
|
break;
|
|
CASE_INFO:
|
|
NET_EBPF_EXT_LOG_MESSAGE_STRING_KEYWORD_SWITCH(LEVEL_INFO, message, string_value);
|
|
break;
|
|
CASE_VERBOSE:
|
|
NET_EBPF_EXT_LOG_MESSAGE_STRING_KEYWORD_SWITCH(LEVEL_VERBOSE, message, string_value);
|
|
break;
|
|
default:
|
|
ebpf_assert(!"Invalid trace level");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS_KEYWORD_SWITCH(trace_level, message, status) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(trace_level, KEYWORD_BASE, message, status); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(trace_level, KEYWORD_BIND, message, status); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(trace_level, KEYWORD_EXT, message, status); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(trace_level, KEYWORD_SOCK_ADDR, message, status); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(trace_level, KEYWORD_SOCK_OPS, message, status); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS(trace_level, KEYWORD_XDP, message, status); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_message_ntstatus(
|
|
net_ebpf_ext_tracelog_level_t trace_level,
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* message,
|
|
NTSTATUS status)
|
|
{
|
|
switch (trace_level) {
|
|
CASE_LOG_ALWAYS:
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS_KEYWORD_SWITCH(LEVEL_LOG_ALWAYS, message, status);
|
|
break;
|
|
CASE_CRITICAL:
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS_KEYWORD_SWITCH(LEVEL_CRITICAL, message, status);
|
|
break;
|
|
CASE_LEVEL_ERROR:
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS_KEYWORD_SWITCH(LEVEL_ERROR, message, status);
|
|
break;
|
|
CASE_WARNING:
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS_KEYWORD_SWITCH(LEVEL_WARNING, message, status);
|
|
break;
|
|
CASE_INFO:
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS_KEYWORD_SWITCH(LEVEL_INFO, message, status);
|
|
break;
|
|
CASE_VERBOSE:
|
|
NET_EBPF_EXT_LOG_MESSAGE_NTSTATUS_KEYWORD_SWITCH(LEVEL_VERBOSE, message, status);
|
|
break;
|
|
default:
|
|
ebpf_assert(!"Invalid trace level");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_MESSAGE_UINT32_KEYWORD_SWITCH(trace_level, message, status) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT32(trace_level, KEYWORD_BASE, message, status); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT32(trace_level, KEYWORD_BIND, message, status); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT32(trace_level, KEYWORD_EXT, message, status); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT32(trace_level, KEYWORD_SOCK_ADDR, message, status); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT32(trace_level, KEYWORD_SOCK_OPS, message, status); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT32(trace_level, KEYWORD_XDP, message, status); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_message_uint32(
|
|
net_ebpf_ext_tracelog_level_t trace_level,
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* message,
|
|
uint32_t value)
|
|
{
|
|
switch (trace_level) {
|
|
CASE_LOG_ALWAYS:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT32_KEYWORD_SWITCH(LEVEL_LOG_ALWAYS, message, value);
|
|
break;
|
|
CASE_CRITICAL:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT32_KEYWORD_SWITCH(LEVEL_CRITICAL, message, value);
|
|
break;
|
|
CASE_LEVEL_ERROR:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT32_KEYWORD_SWITCH(LEVEL_ERROR, message, value);
|
|
break;
|
|
CASE_WARNING:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT32_KEYWORD_SWITCH(LEVEL_WARNING, message, value);
|
|
break;
|
|
CASE_INFO:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT32_KEYWORD_SWITCH(LEVEL_INFO, message, value);
|
|
break;
|
|
CASE_VERBOSE:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT32_KEYWORD_SWITCH(LEVEL_VERBOSE, message, value);
|
|
break;
|
|
default:
|
|
ebpf_assert(!"Invalid trace level");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_MESSAGE_UINT64_KEYWORD_SWITCH(trace_level, message, status) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64(trace_level, KEYWORD_BASE, message, status); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64(trace_level, KEYWORD_BIND, message, status); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64(trace_level, KEYWORD_EXT, message, status); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64(trace_level, KEYWORD_SOCK_ADDR, message, status); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64(trace_level, KEYWORD_SOCK_OPS, message, status); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64(trace_level, KEYWORD_XDP, message, status); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_message_uint64(
|
|
net_ebpf_ext_tracelog_level_t trace_level,
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* message,
|
|
uint64_t value)
|
|
{
|
|
switch (trace_level) {
|
|
CASE_LOG_ALWAYS:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_KEYWORD_SWITCH(LEVEL_LOG_ALWAYS, message, value);
|
|
break;
|
|
CASE_CRITICAL:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_KEYWORD_SWITCH(LEVEL_CRITICAL, message, value);
|
|
break;
|
|
CASE_LEVEL_ERROR:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_KEYWORD_SWITCH(LEVEL_ERROR, message, value);
|
|
break;
|
|
CASE_WARNING:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_KEYWORD_SWITCH(LEVEL_WARNING, message, value);
|
|
break;
|
|
CASE_INFO:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_KEYWORD_SWITCH(LEVEL_INFO, message, value);
|
|
break;
|
|
CASE_VERBOSE:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_KEYWORD_SWITCH(LEVEL_VERBOSE, message, value);
|
|
break;
|
|
default:
|
|
ebpf_assert(!"Invalid trace level");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64_KEYWORD_SWITCH(api_name, status, value1, value2) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64(KEYWORD_BASE, api_name, status, value1, value2); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64(KEYWORD_EXT, api_name, status, value1, value2); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64(KEYWORD_BIND, api_name, status, value1, value2); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64(KEYWORD_SOCK_ADDR, api_name, status, value1, value2); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64(KEYWORD_SOCK_OPS, api_name, status, value1, value2); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64(KEYWORD_XDP, api_name, status, value1, value2); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_ntstatus_api_failure_uint64_uint64(
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* api_name,
|
|
NTSTATUS status,
|
|
uint64_t value1,
|
|
uint64_t value2)
|
|
{
|
|
NET_EBPF_EXT_LOG_NTSTATUS_API_FAILURE_UINT64_UINT64_KEYWORD_SWITCH(api_name, status, value1, value2);
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_KEYWORD_SWITCH(trace_level, message, value1, value2) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64(trace_level, KEYWORD_BASE, message, value1, value2); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64(trace_level, KEYWORD_EXT, message, value1, value2); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64(trace_level, KEYWORD_BIND, message, value1, value2); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64(trace_level, KEYWORD_SOCK_ADDR, message, value1, value2); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64(trace_level, KEYWORD_SOCK_OPS, message, value1, value2); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64(trace_level, KEYWORD_XDP, message, value1, value2); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_message_uint64_uint64(
|
|
net_ebpf_ext_tracelog_level_t trace_level,
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* message,
|
|
uint64_t value1,
|
|
uint64_t value2)
|
|
{
|
|
switch (trace_level) {
|
|
CASE_LOG_ALWAYS:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_LOG_ALWAYS, message, value1, value2);
|
|
break;
|
|
CASE_CRITICAL:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_CRITICAL, message, value1, value2);
|
|
break;
|
|
CASE_LEVEL_ERROR:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_ERROR, message, value1, value2);
|
|
break;
|
|
CASE_WARNING:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_WARNING, message, value1, value2);
|
|
break;
|
|
CASE_INFO:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_INFO, message, value1, value2);
|
|
break;
|
|
CASE_VERBOSE:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_VERBOSE, message, value1, value2);
|
|
break;
|
|
default:
|
|
ebpf_assert(!"Invalid trace level");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64_KEYWORD_SWITCH(trace_level, message, value1, value2, value3) \
|
|
switch (keyword) { \
|
|
CASE_BASE: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64(trace_level, KEYWORD_BASE, message, value1, value2, value3); \
|
|
break; \
|
|
CASE_EXT: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64(trace_level, KEYWORD_EXT, message, value1, value2, value3); \
|
|
break; \
|
|
CASE_BIND: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64(trace_level, KEYWORD_BIND, message, value1, value2, value3); \
|
|
break; \
|
|
CASE_SOCK_ADDR: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64( \
|
|
trace_level, KEYWORD_SOCK_ADDR, message, value1, value2, value3); \
|
|
break; \
|
|
CASE_SOCK_OPS: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64( \
|
|
trace_level, KEYWORD_SOCK_OPS, message, value1, value2, value3); \
|
|
break; \
|
|
CASE_XDP: \
|
|
_NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64(trace_level, KEYWORD_XDP, message, value1, value2, value3); \
|
|
break; \
|
|
default: \
|
|
ebpf_assert(!"Invalid keyword"); \
|
|
break; \
|
|
}
|
|
|
|
__declspec(noinline) void net_ebpf_ext_log_message_uint64_uint64_uint64(
|
|
net_ebpf_ext_tracelog_level_t trace_level,
|
|
net_ebpf_ext_tracelog_keyword_t keyword,
|
|
_In_z_ const char* message,
|
|
uint64_t value1,
|
|
uint64_t value2,
|
|
uint64_t value3)
|
|
{
|
|
switch (trace_level) {
|
|
CASE_LOG_ALWAYS:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_LOG_ALWAYS, message, value1, value2, value3);
|
|
break;
|
|
CASE_CRITICAL:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_CRITICAL, message, value1, value2, value3);
|
|
break;
|
|
CASE_LEVEL_ERROR:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_ERROR, message, value1, value2, value3);
|
|
break;
|
|
CASE_WARNING:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_WARNING, message, value1, value2, value3);
|
|
break;
|
|
CASE_INFO:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_INFO, message, value1, value2, value3);
|
|
break;
|
|
CASE_VERBOSE:
|
|
NET_EBPF_EXT_LOG_MESSAGE_UINT64_UINT64_UINT64_KEYWORD_SWITCH(LEVEL_VERBOSE, message, value1, value2, value3);
|
|
break;
|
|
default:
|
|
ebpf_assert(!"Invalid trace level");
|
|
break;
|
|
}
|
|
}
|
|
#pragma warning(pop)
|