diff --git a/include/ebpf_nethooks.h b/include/ebpf_nethooks.h index 18f849bfc..aa2ecf3e5 100644 --- a/include/ebpf_nethooks.h +++ b/include/ebpf_nethooks.h @@ -149,9 +149,6 @@ typedef struct bpf_sock_addr uint32_t protocol; ///< IP protocol. uint32_t compartment_id; ///< Network compartment Id. } bpf_sock_addr_t; -#ifdef _MSC_VER -#pragma warning(pop) -#endif /** * @brief Handle socket operation. Currently supports ingress/egress connection initialization. @@ -172,3 +169,57 @@ typedef struct bpf_sock_addr */ typedef int sock_addr_hook_t(bpf_sock_addr_t* context); + +typedef enum _bpf_sock_op_type +{ + /** @brief Indicates when an active (outbound) connection is established. **/ + BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB, + /** @brief Indicates when a passive (inbound) connection is established. **/ + BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB, + /** @brief Indicates when a connection is deleted. **/ + BPF_SOCK_OPS_CONNECTION_DELETED_CB +} bpf_sock_op_type_t; + +typedef struct _bpf_sock_ops +{ + bpf_sock_op_type_t op; + uint32_t family; ///< IP address family. + struct + { + union + { + uint32_t local_ip4; + uint32_t local_ip6[4]; + }; ///< Local IP address. + uint32_t local_port; + }; ///< Local IP address and port stored in network byte order. + struct + { + union + { + uint32_t remote_ip4; + uint32_t remote_ip6[4]; + }; ///< Remote IP address. + uint32_t remote_port; + }; ///< Remote IP address and port stored in network byte order. + uint8_t protocol; ///< IP protocol. +} bpf_sock_ops_t; + +/** + * @brief Handle socket event notification. Currently notifies ingress/egress connection establishment and tear down. + * + * Program type: \ref EBPF_PROGRAM_TYPE_SOCK_OPS + * + * Attach type(s): + * \ref EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS + * + * @param[in] context \ref bpf_sock_ops_t + * @return 0 on success, or a negative error in case of failure. + * + */ +typedef int +sock_ops_hook_t(bpf_sock_ops_t* context); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif \ No newline at end of file diff --git a/include/ebpf_program_attach_type_guids.h b/include/ebpf_program_attach_type_guids.h index f9604a05a..d5015e574 100644 --- a/include/ebpf_program_attach_type_guids.h +++ b/include/ebpf_program_attach_type_guids.h @@ -67,6 +67,13 @@ extern "C" __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT = { 0xa82e37b4, 0xaee7, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}}; + /** @brief Attach type for handling socket event notifications. + * + * Program type: \ref EBPF_PROGRAM_TYPE_SOCK_OPS + */ + __declspec(selectany) ebpf_attach_type_t EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS = { + 0x837d02cd, 0x3251, 0x4632, {0x8d, 0x94, 0x60, 0xd3, 0xb4, 0x57, 0x69, 0xf2}}; + /** @brief Attach type implemented by eBPF Sample Extension driver, used for testing. * * Program type: \ref EBPF_PROGRAM_TYPE_SAMPLE @@ -115,6 +122,13 @@ extern "C" __declspec(selectany) ebpf_program_type_t EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR = { 0x92ec8e39, 0xaeec, 0x11ec, {0x9a, 0x30, 0x18, 0x60, 0x24, 0x89, 0xbe, 0xee}}; + /** @brief Program type for handling socket event notifications. + * + * Attach type(s): \ref EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS + */ + __declspec(selectany) ebpf_program_type_t EBPF_PROGRAM_TYPE_SOCK_OPS = { + 0x43fb224d, 0x68f8, 0x46d6, {0xaa, 0x3f, 0xc8, 0x56, 0x51, 0x8c, 0xbb, 0x32}}; + /** @brief Program type for handling calls from the eBPF sample extension. Used for * testing. * diff --git a/include/ebpf_structs.h b/include/ebpf_structs.h index db4fca4ca..6b79b95b6 100644 --- a/include/ebpf_structs.h +++ b/include/ebpf_structs.h @@ -7,6 +7,7 @@ #pragma once #if !defined(NO_CRT) +#include #include #endif #include "ebpf_windows.h" @@ -147,6 +148,17 @@ enum bpf_prog_type */ BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + /** @brief Program type for handling various socket event notifications such as connection established etc. + * + * **eBPF program prototype:** \ref sock_ops_hook_t + * + * **Attach type(s):** + * \ref BPF_CGROUP_SOCK_OPS + * + * **Helpers available:** all helpers defined in bpf_helpers.h + */ + BPF_PROG_TYPE_SOCK_OPS, + /** @brief Program type for handling calls from the eBPF sample extension. Used for * testing. * @@ -214,6 +226,12 @@ enum bpf_attach_type */ BPF_CGROUP_INET6_RECV_ACCEPT, + /** @brief Attach type for handling various socket event notifications. + * + * **Program type:** \ref BPF_PROG_TYPE_SOCK_OPS + */ + BPF_CGROUP_SOCK_OPS, + /** @brief Attach type implemented by eBPF Sample Extension driver, used for testing. * * **Program type:** \ref BPF_PROG_TYPE_SAMPLE diff --git a/include/net/ip.h b/include/net/ip.h index e42c0c6c6..e1209527c 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -7,6 +7,9 @@ #define IPPROTO_UDP 17 #define IPPROTO_IPV6 41 +#define AF_INET 2 +#define AF_INET6 23 + #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union diff --git a/libs/api/libbpf_program.cpp b/libs/api/libbpf_program.cpp index 797373ca6..21f917ab1 100644 --- a/libs/api/libbpf_program.cpp +++ b/libs/api/libbpf_program.cpp @@ -27,6 +27,9 @@ _get_ebpf_program_type(enum bpf_prog_type type) case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: program_type = &EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR; break; + case BPF_PROG_TYPE_SOCK_OPS: + program_type = &EBPF_PROGRAM_TYPE_SOCK_OPS; + break; } return program_type; } @@ -66,6 +69,9 @@ _get_ebpf_attach_type(enum bpf_attach_type type) case BPF_CGROUP_INET6_RECV_ACCEPT: attach_type = &EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT; break; + case BPF_CGROUP_SOCK_OPS: + attach_type = &EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS; + break; } return attach_type; @@ -219,6 +225,7 @@ _does_attach_type_support_attachable_fd(enum bpf_attach_type type) case BPF_CGROUP_INET6_CONNECT: case BPF_CGROUP_INET4_RECV_ACCEPT: case BPF_CGROUP_INET6_RECV_ACCEPT: + case BPF_CGROUP_SOCK_OPS: supported = TRUE; break; } diff --git a/libs/api_common/windows_platform_common.cpp b/libs/api_common/windows_platform_common.cpp index 0fff18b98..49d8cbd25 100644 --- a/libs/api_common/windows_platform_common.cpp +++ b/libs/api_common/windows_platform_common.cpp @@ -79,6 +79,19 @@ const EbpfProgramType windows_sock_addr_program_type = { (uint64_t)&EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, {"cgroup/connect4", "cgroup/connect6", "cgroup/recv_accept4", "cgroup/recv_accept6"}}; +// +// SOCK_OPS. +// +const ebpf_context_descriptor_t g_sock_ops_context_descriptor = { + sizeof(bpf_sock_ops_t), + -1, // Offset into ctx struct for pointer to data, or -1 if none. + -1, // Offset into ctx struct for pointer to data, or -1 if none. + -1, // Offset into ctx struct for pointer to metadata, or -1 if none. +}; + +const EbpfProgramType windows_sock_ops_program_type = { + "sockops", &g_sock_ops_context_descriptor, (uint64_t)&EBPF_PROGRAM_TYPE_SOCK_OPS, {"sockops"}}; + // // Global lists and vectors of program and attach types. // @@ -88,6 +101,7 @@ const std::vector windows_program_types = { windows_xdp_program_type, windows_bind_program_type, windows_sock_addr_program_type, + windows_sock_ops_program_type, windows_sample_ext_program_type}; typedef struct _ebpf_section_definition @@ -110,6 +124,8 @@ const std::vector windows_section_definitions = { {"cgroup/recv_accept4", &EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, &EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT}, // socket recv/accept v6. {"cgroup/recv_accept6", &EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, &EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT}, + // sockops. + {"sockops", &EBPF_PROGRAM_TYPE_SOCK_OPS, &EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS}, // Sample Extension. {"sample_ext", &EBPF_PROGRAM_TYPE_SAMPLE, &EBPF_ATTACH_TYPE_SAMPLE}, }; @@ -126,10 +142,11 @@ struct ebpf_attach_type_compare const std::map windows_section_names = { {EBPF_ATTACH_TYPE_XDP, "xdp"}, {EBPF_ATTACH_TYPE_BIND, "bind"}, - {EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT, "sock_connect4"}, - {EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT, "sock_connect6"}, - {EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT, "sock_recv_accept4"}, - {EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT, "sock_recv_accept6"}, + {EBPF_ATTACH_TYPE_CGROUP_INET4_CONNECT, "cgroup/connect4"}, + {EBPF_ATTACH_TYPE_CGROUP_INET6_CONNECT, "cgroup/connect6"}, + {EBPF_ATTACH_TYPE_CGROUP_INET4_RECV_ACCEPT, "cgroup/recv_accept4"}, + {EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT, "cgroup/recv_accept6"}, + {EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS, "sockops"}, {EBPF_ATTACH_TYPE_SAMPLE, "sample_ext"}}; const EbpfProgramType& diff --git a/netebpfext/net_ebpf_ext_program_info.h b/netebpfext/net_ebpf_ext_program_info.h index 388f4cee7..5512497c4 100644 --- a/netebpfext/net_ebpf_ext_program_info.h +++ b/netebpfext/net_ebpf_ext_program_info.h @@ -41,3 +41,13 @@ static ebpf_context_descriptor_t _ebpf_sock_addr_context_descriptor = { }; static ebpf_program_info_t _ebpf_sock_addr_program_info = { {"sock_addr", &_ebpf_sock_addr_context_descriptor, {0}}, 0, NULL}; + +// SOCK_OPS program information. +static ebpf_context_descriptor_t _ebpf_sock_ops_context_descriptor = { + sizeof(bpf_sock_ops_t), + -1, // Offset into ctx struct for pointer to data, or -1 if none. + -1, // Offset into ctx struct for pointer to data, or -1 if none. + -1, // Offset into ctx struct for pointer to metadata, or -1 if none. +}; +static ebpf_program_info_t _ebpf_sock_ops_program_info = { + {"sockops", &_ebpf_sock_ops_context_descriptor, {0}}, 0, NULL}; diff --git a/tests/end_to_end/end_to_end.cpp b/tests/end_to_end/end_to_end.cpp index cf312f3c3..d83b36c42 100644 --- a/tests/end_to_end/end_to_end.cpp +++ b/tests/end_to_end/end_to_end.cpp @@ -871,9 +871,10 @@ TEST_CASE("verify section", "[end_to_end]") } static void -_cgroup_sock_addr_load_test( +_cgroup_load_test( _In_z_ const char* file, _In_z_ const char* name, + ebpf_program_type_t& program_type, ebpf_attach_type_t& attach_type, ebpf_execution_type_t execution_type) { @@ -883,8 +884,8 @@ _cgroup_sock_addr_load_test( fd_t program_fd; _test_helper_end_to_end test_helper; - single_instance_hook_t hook(EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, attach_type); - program_info_provider_t program_info(EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR); + single_instance_hook_t hook(program_type, attach_type); + program_info_provider_t program_info(program_type); result = ebpf_program_load(file, nullptr, nullptr, execution_type, &object, &program_fd, &error_message); @@ -907,6 +908,16 @@ _cgroup_sock_addr_load_test( bpf_object__close(object); } +static void +_cgroup_sock_addr_load_test( + _In_z_ const char* file, + _In_z_ const char* name, + ebpf_attach_type_t& attach_type, + ebpf_execution_type_t execution_type) +{ + _cgroup_load_test(file, name, EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR, attach_type, execution_type); +} + #define DECLARE_CGROUP_SOCK_ADDR_LOAD_TEST(file, name, attach_type, execution_type) \ TEST_CASE("cgroup_sockaddr_load_test_" #name "_" #attach_type "_" #execution_type, "[cgroup_sock_addr]") \ { \ @@ -928,6 +939,16 @@ DECLARE_CGROUP_SOCK_ADDR_LOAD_TEST( EBPF_ATTACH_TYPE_CGROUP_INET6_RECV_ACCEPT, EBPF_EXECUTION_JIT); +TEST_CASE("cgroup_sockops_load_test", "[cgroup_sockops]") +{ + _cgroup_load_test( + "sockops.o", + "connection_monitor", + EBPF_PROGRAM_TYPE_SOCK_OPS, + EBPF_ATTACH_TYPE_CGROUP_SOCK_OPS, + EBPF_EXECUTION_JIT); +} + TEST_CASE("verify_test0", "[sample_extension]") { _test_helper_end_to_end test_helper; diff --git a/tests/end_to_end/helpers.h b/tests/end_to_end/helpers.h index 0a45c1e8b..2f466db4c 100644 --- a/tests/end_to_end/helpers.h +++ b/tests/end_to_end/helpers.h @@ -302,6 +302,12 @@ static ebpf_program_data_t _ebpf_sock_addr_program_data = {&_ebpf_sock_addr_prog static ebpf_extension_data_t _ebpf_sock_addr_program_info_provider_data = { TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_sock_addr_program_data), &_ebpf_sock_addr_program_data}; +// SOCK_OPS. +static ebpf_program_data_t _ebpf_sock_ops_program_data = {&_ebpf_sock_ops_program_info, NULL}; + +static ebpf_extension_data_t _ebpf_sock_ops_program_info_provider_data = { + TEST_NET_EBPF_EXTENSION_NPI_PROVIDER_VERSION, sizeof(_ebpf_sock_ops_program_data), &_ebpf_sock_ops_program_data}; + // Sample extension. static ebpf_program_data_t _test_ebpf_sample_extension_program_data = {&_sample_ebpf_extension_program_info, NULL}; @@ -317,24 +323,19 @@ typedef class _program_info_provider public: _program_info_provider(ebpf_program_type_t program_type) : program_type(program_type) { - ebpf_program_data_t* program_data; if (program_type == EBPF_PROGRAM_TYPE_XDP) { provider_data = &_ebpf_xdp_program_info_provider_data; - program_data = (ebpf_program_data_t*)provider_data->data; - program_data->program_info->program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_XDP; } else if (program_type == EBPF_PROGRAM_TYPE_BIND) { provider_data = &_ebpf_bind_program_info_provider_data; - program_data = (ebpf_program_data_t*)provider_data->data; - program_data->program_info->program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_BIND; - } else if (program_type == EBPF_PROGRAM_TYPE_SAMPLE) { - provider_data = &_test_ebpf_sample_extension_program_info_provider_data; - program_data = (ebpf_program_data_t*)provider_data->data; - program_data->program_info->program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_SAMPLE; } else if (program_type == EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR) { provider_data = &_ebpf_sock_addr_program_info_provider_data; - program_data = (ebpf_program_data_t*)provider_data->data; - program_data->program_info->program_type_descriptor.program_type = EBPF_PROGRAM_TYPE_CGROUP_SOCK_ADDR; + } else if (program_type == EBPF_PROGRAM_TYPE_SOCK_OPS) { + provider_data = &_ebpf_sock_ops_program_info_provider_data; + } else if (program_type == EBPF_PROGRAM_TYPE_SAMPLE) { + provider_data = &_test_ebpf_sample_extension_program_info_provider_data; } + ebpf_program_data_t* program_data = (ebpf_program_data_t*)provider_data->data; + program_data->program_info->program_type_descriptor.program_type = program_type; REQUIRE( ebpf_provider_load( diff --git a/tests/libs/util/socket_helper.h b/tests/libs/util/socket_helper.h index bff8553ce..12d40e5ee 100644 --- a/tests/libs/util/socket_helper.h +++ b/tests/libs/util/socket_helper.h @@ -13,8 +13,6 @@ #include #include -#include "ebpf_udp.h" - /** * @brief Helper function that converts an IP address string into a sockaddr_storage with address family 6, unspecified * scope and port set to zero. A v4 mapped IPv6 address is returned if the input address string is IPv4. diff --git a/tests/sample/sample.vcxproj b/tests/sample/sample.vcxproj index 10167de43..70ac9887d 100644 --- a/tests/sample/sample.vcxproj +++ b/tests/sample/sample.vcxproj @@ -195,6 +195,16 @@ $(OutputPath)%(Filename).o $(OutputPath)%(Filename).o + + CppCode + clang -target bpf -O2 -Werror -c %(Filename).c -o %(Filename).o + %(Filename).o;%(Outputs) + true + clang -g -target bpf -O2 -Werror -I../../include -I../socket -c %(Filename).c -o $(OutputPath)%(Filename).o + clang -g -target bpf -O2 -Werror -I../../include -I../socket -c %(Filename).c -o $(OutputPath)%(Filename).o + $(OutputPath)%(Filename).o + $(OutputPath)%(Filename).o + diff --git a/tests/sample/sockops.c b/tests/sample/sockops.c new file mode 100644 index 000000000..c64733cb8 --- /dev/null +++ b/tests/sample/sockops.c @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation +// SPDX-License-Identifier: MIT + +#include "bpf_helpers.h" +#include "net/ip.h" +#include "socket_tests_common.h" + +SEC("maps") +struct bpf_map_def connection_map = { + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(connection_tuple_t), + .value_size = sizeof(uint32_t), + .max_entries = 1}; + +SEC("maps") +struct bpf_map_def audit_map = {.type = BPF_MAP_TYPE_RINGBUF, .max_entries = 256 * 1024}; + +typedef struct _audit_entry +{ + connection_tuple_t tuple; + bool outbound : 1; + bool connected : 1; +} audit_entry_t; + +int +handle_v4(bpf_sock_ops_t* ctx, bool outbound, bool connected) +{ + int result = 0; + audit_entry_t audit_entry = {0}; + + audit_entry.tuple.src_ip.ipv4 = (outbound) ? ctx->local_ip4 : ctx->remote_ip4; + audit_entry.tuple.src_port = (outbound) ? ctx->local_port : ctx->remote_port; + audit_entry.tuple.dst_ip.ipv4 = (outbound) ? ctx->remote_ip4 : ctx->local_ip4; + audit_entry.tuple.dst_port = (outbound) ? ctx->remote_port : ctx->local_port; + audit_entry.tuple.protocol = ctx->protocol; + audit_entry.outbound = outbound; + audit_entry.connected = connected; + + if (bpf_map_lookup_elem(&connection_map, &audit_entry.tuple) != NULL) { + result = bpf_ringbuf_output(&audit_map, &audit_entry, sizeof(audit_entry), 0); + } + + return result; +} + +int +handle_v6(bpf_sock_ops_t* ctx, bool outbound, bool connected) +{ + int result = 0; + audit_entry_t audit_entry = {0}; + void* ip6 = NULL; + + ip6 = (outbound) ? ctx->local_ip6 : ctx->remote_ip6; + __builtin_memcpy(audit_entry.tuple.src_ip.ipv6, ip6, sizeof(uint32_t) * 4); + audit_entry.tuple.src_port = (outbound) ? ctx->local_port : ctx->remote_port; + ip6 = (outbound) ? ctx->remote_ip6 : ctx->local_ip6; + __builtin_memcpy(audit_entry.tuple.dst_ip.ipv6, ip6, sizeof(uint32_t) * 4); + audit_entry.tuple.dst_port = (outbound) ? ctx->remote_port : ctx->local_port; + audit_entry.tuple.protocol = ctx->protocol; + audit_entry.outbound = outbound; + audit_entry.connected = connected; + + if (bpf_map_lookup_elem(&connection_map, &audit_entry.tuple) != NULL) { + result = bpf_ringbuf_output(&audit_map, &audit_entry, sizeof(audit_entry), 0); + } + + return result; +} + +SEC("sockops") +int +connection_monitor(bpf_sock_ops_t* ctx) +{ + int result = 0; + bool outbound; + bool connected; + switch (ctx->op) { + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + outbound = true; + connected = true; + break; + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + outbound = false; + connected = true; + break; + case BPF_SOCK_OPS_CONNECTION_DELETED_CB: + outbound = false; + connected = false; + break; + default: + result = -1; + } + if (result == 0) + result = (ctx->family == AF_INET) ? handle_v4(ctx, outbound, connected) : handle_v6(ctx, outbound, connected); + + return result; +} diff --git a/tests/socket/socket_tests.vcxproj b/tests/socket/socket_tests.vcxproj index 8ef568db8..9be736e14 100644 --- a/tests/socket/socket_tests.vcxproj +++ b/tests/socket/socket_tests.vcxproj @@ -113,7 +113,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - $(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)tests\end_to_end;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(SolutionDir)tests\sample;$(SolutionDir)tests\sample\ext\inc;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) + $(SolutionDir)include;$(SolutionDir)tests\libs\util;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) Console @@ -125,7 +125,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - $(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)tests\end_to_end;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(SolutionDir)tests\sample;$(SolutionDir)tests\sample\ext\inc;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) + $(SolutionDir)include;$(SolutionDir)tests\libs\util;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) Console diff --git a/tests/xdp/xdp_tests.cpp b/tests/xdp/xdp_tests.cpp index 264fde7a1..aafdbea86 100644 --- a/tests/xdp/xdp_tests.cpp +++ b/tests/xdp/xdp_tests.cpp @@ -8,6 +8,7 @@ #define CATCH_CONFIG_RUNNER #include "catch_wrapper.hpp" +#include "ebpf_udp.h" #include "socket_helper.h" #include "xdp_tests_common.h" diff --git a/tests/xdp/xdp_tests.vcxproj b/tests/xdp/xdp_tests.vcxproj index dd77b08ad..90ce75859 100644 --- a/tests/xdp/xdp_tests.vcxproj +++ b/tests/xdp/xdp_tests.vcxproj @@ -113,7 +113,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - $(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)tests\end_to_end;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(SolutionDir)tests\sample;$(SolutionDir)tests\sample\ext\inc;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) + $(SolutionDir)include;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\sample;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) Console @@ -125,7 +125,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - $(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)libs\execution_context;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)tests\end_to_end;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(SolutionDir)tests\sample;$(SolutionDir)tests\sample\ext\inc;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) + $(SolutionDir)include;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\sample;$(OutDir);$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;%(AdditionalIncludeDirectories) Console