From 6a54714ec224adb3762263719dd09a2b1d04d6da Mon Sep 17 00:00:00 2001 From: Alessandro Gario <5714290+alessandrogario@users.noreply.github.com> Date: Tue, 26 Apr 2022 14:39:37 +0200 Subject: [PATCH] cmake: Add base targets (#882) Signed-off-by: Alessandro Gario --- .github/workflows/cicd.yml | 7 + .github/workflows/reusable-build.yml | 34 +++++ .github/workflows/reusable-cmake-build.yml | 59 ++++++++ .gitmodules | 3 + CMakeLists.txt | 47 ++++++ cmake/codesign.cmake | 27 ++++ cmake/codesign_helper.cmake | 23 +++ cmake/git_commit.cmake | 38 +++++ cmake/midl_compiler_finder.cmake | 22 +++ cmake/options.cmake | 33 ++++ cmake/settings.cmake | 55 +++++++ docs/GettingStarted.md | 44 +++++- ebpfapi/CMakeLists.txt | 60 ++++++++ ebpfcore/CMakeLists.txt | 52 +++++++ ebpfsvc/CMakeLists.txt | 57 +++++++ external/CMakeLists.txt | 166 +++++++++++++++++++++ external/FindWDK | 1 + libs/CMakeLists.txt | 10 ++ libs/api/CMakeLists.txt | 53 +++++++ libs/api_common/CMakeLists.txt | 58 +++++++ libs/ebpfnetsh/CMakeLists.txt | 41 +++++ libs/execution_context/CMakeLists.txt | 79 ++++++++++ libs/platform/CMakeLists.txt | 160 ++++++++++++++++++++ libs/service/CMakeLists.txt | 39 +++++ libs/ubpf/CMakeLists.txt | 74 +++++++++ netebpfext/CMakeLists.txt | 78 ++++++++++ packaging/CMakeLists.txt | 152 +++++++++++++++++++ packaging/README.md | 35 +++++ rpc_interface/CMakeLists.txt | 53 +++++++ scripts/CMakeLists.txt | 13 ++ scripts/create_package_data.bat | 77 ++++++++++ tests/CMakeLists.txt | 9 ++ tests/api_test/CMakeLists.txt | 40 +++++ tests/bpf2c_tests/CMakeLists.txt | 148 ++++++++++++++++++ tests/libs/CMakeLists.txt | 5 + tests/libs/common/CMakeLists.txt | 34 +++++ tests/libs/util/CMakeLists.txt | 48 ++++++ tests/performance/CMakeLists.txt | 52 +++++++ tests/unit/CMakeLists.txt | 66 ++++++++ tests/xdp/CMakeLists.txt | 39 +++++ tools/CMakeLists.txt | 9 ++ tools/bpf2c/CMakeLists.txt | 82 ++++++++++ tools/dnsflood/CMakeLists.txt | 15 ++ tools/encode_program_info/CMakeLists.txt | 56 +++++++ tools/netsh/CMakeLists.txt | 50 +++++++ tools/port_leak/CMakeLists.txt | 15 ++ tools/port_quota/CMakeLists.txt | 20 +++ 47 files changed, 2337 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/reusable-cmake-build.yml create mode 100644 CMakeLists.txt create mode 100644 cmake/codesign.cmake create mode 100644 cmake/codesign_helper.cmake create mode 100644 cmake/git_commit.cmake create mode 100644 cmake/midl_compiler_finder.cmake create mode 100644 cmake/options.cmake create mode 100644 cmake/settings.cmake create mode 100644 ebpfapi/CMakeLists.txt create mode 100644 ebpfcore/CMakeLists.txt create mode 100644 ebpfsvc/CMakeLists.txt create mode 100644 external/CMakeLists.txt create mode 160000 external/FindWDK create mode 100644 libs/CMakeLists.txt create mode 100644 libs/api/CMakeLists.txt create mode 100644 libs/api_common/CMakeLists.txt create mode 100644 libs/ebpfnetsh/CMakeLists.txt create mode 100644 libs/execution_context/CMakeLists.txt create mode 100644 libs/platform/CMakeLists.txt create mode 100644 libs/service/CMakeLists.txt create mode 100644 libs/ubpf/CMakeLists.txt create mode 100644 netebpfext/CMakeLists.txt create mode 100644 packaging/CMakeLists.txt create mode 100644 packaging/README.md create mode 100644 rpc_interface/CMakeLists.txt create mode 100644 scripts/CMakeLists.txt create mode 100644 scripts/create_package_data.bat create mode 100644 tests/CMakeLists.txt create mode 100644 tests/api_test/CMakeLists.txt create mode 100644 tests/bpf2c_tests/CMakeLists.txt create mode 100644 tests/libs/CMakeLists.txt create mode 100644 tests/libs/common/CMakeLists.txt create mode 100644 tests/libs/util/CMakeLists.txt create mode 100644 tests/performance/CMakeLists.txt create mode 100644 tests/unit/CMakeLists.txt create mode 100644 tests/xdp/CMakeLists.txt create mode 100644 tools/CMakeLists.txt create mode 100644 tools/bpf2c/CMakeLists.txt create mode 100644 tools/dnsflood/CMakeLists.txt create mode 100644 tools/encode_program_info/CMakeLists.txt create mode 100644 tools/netsh/CMakeLists.txt create mode 100644 tools/port_leak/CMakeLists.txt create mode 100644 tools/port_quota/CMakeLists.txt diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index db1961d8b..1d1279c55 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -30,6 +30,13 @@ jobs: uses: ./.github/workflows/reusable-build.yml with: build_artifact: Build-x64 + generate_release_package: true + + cmake: + if: github.event_name != 'pull_request' + uses: ./.github/workflows/reusable-cmake-build.yml + with: + build_artifact: Build-x64 # Build with C++ static analyzer. analyze: diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index 4c4191534..9ea9b5c6a 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -16,6 +16,9 @@ on: build_options: required: false type: string + generate_release_package: + required: false + type: boolean build_codeql: required: false type: boolean @@ -105,6 +108,37 @@ jobs: path: ${{github.workspace}}/${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} retention-days: 5 + - name: Generate the package data + if: matrix.configurations == 'Release' && inputs.generate_release_package == true + shell: cmd + working-directory: ${{github.workspace}}/${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} + env: + SOURCE_DIR: ${{github.workspace}} + run: | + ${{github.workspace}}/scripts/create_package_data.bat + + - name: Generate the MSI release package + if: matrix.configurations == 'Release' && inputs.generate_release_package == true + working-directory: ${{env.GITHUB_WORKSPACE}} + run: | + cmake -S packaging -B package -DEBPFFORWINDOWS_PROGRAM_DATA="${{github.workspace}}\${{env.BUILD_PLATFORM}}\${{env.BUILD_CONFIGURATION}}\package_data" "-DEBPFFORWINDOWS_VERSION=1.0.0" -DCPACK_GENERATOR=WIX + cmake --build package --target package + + - name: Locate the packages + if: matrix.configurations == 'Release' && inputs.generate_release_package == true + working-directory: ${{env.GITHUB_WORKSPACE}} + id: packages + shell: bash + run: | + echo ::set-output name=REL_MSI_PACKAGE_PATH::$(ls package/*.msi) + + - name: Upload the MSI package + if: matrix.configurations == 'Release' && inputs.generate_release_package == true + uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + with: + name: ebpf-for-windows.msi + path: ${{ steps.packages.outputs.REL_MSI_PACKAGE_PATH }} + - name: Perform CodeQL Analysis if: inputs.build_codeql == true uses: github/codeql-action/analyze@1ed1437484560351c5be56cf73a48a279d116b78 diff --git a/.github/workflows/reusable-cmake-build.yml b/.github/workflows/reusable-cmake-build.yml new file mode 100644 index 000000000..bdc737044 --- /dev/null +++ b/.github/workflows/reusable-cmake-build.yml @@ -0,0 +1,59 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +# This workflow performs a CMake-based build of the project. + +name: Reusable CMake Workflow + +on: + workflow_call: + inputs: + # Name associated with the output of this build. + build_artifact: + required: true + type: string + +permissions: + contents: read + +jobs: + build: + timeout-minutes: 60 + + strategy: + matrix: + configurations: [Debug, Release] + + runs-on: windows-2019 + + env: + BUILD_ARTIFACT_NAME: ${{inputs.build_artifact}} + BUILD_CONFIGURATION: ${{matrix.configurations}} + BUILD_PLATFORM: x64 + CMAKE_GENERATOR: Visual Studio 16 2019 + PLATFORM_TOOLSET: v142 + + steps: + - uses: actions/checkout@b0e28b5ac45a892f91e7d036f8200cf5ed489415 + with: + submodules: 'recursive' + + - name: Cache nuget packages + uses: actions/cache@f63a711791a8e7cc2d5463afc081136e00085800 + env: + cache-name: cache-nuget-modules + with: + path: packages + key: ${{ runner.os }}-${{env.BUILD_PLATFORM}}-${{env.BUILD_CONFIGURATION}}-${{env.BUILD_ARTIFACT_NAME}}-${{ hashFiles('**/packages.config') }} + + - name: Configure the project + working-directory: ${{env.GITHUB_WORKSPACE}} + shell: cmd + run: | + cmake -S . -B build -G "${{env.CMAKE_GENERATOR}}" -A ${{env.BUILD_PLATFORM}} -T ${{env.PLATFORM_TOOLSET}} + + - name: Build the project + working-directory: ${{env.GITHUB_WORKSPACE}} + shell: cmd + run: | + cmake --build build --config ${{env.BUILD_CONFIGURATION }} diff --git a/.gitmodules b/.gitmodules index 45d1c5380..67a05dd1e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "external/Catch2"] path = external/Catch2 url = https://github.com/catchorg/Catch2.git +[submodule "external/FindWDK"] + path = external/FindWDK + url = https://github.com/SergiusTheBest/FindWDK diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..ac2d482ad --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,47 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.20) +project("ebpf-for-windows") + +include("cmake/options.cmake") +include("cmake/settings.cmake") +include("cmake/git_commit.cmake") +include("cmake/codesign.cmake") +include("cmake/midl_compiler_finder.cmake") + +list(APPEND CMAKE_MODULE_PATH + "${CMAKE_SOURCE_DIR}/external/FindWDK/cmake" +) + +locateMidlCompiler() +find_package(WDK REQUIRED) + +add_subdirectory("external") +add_subdirectory("rpc_interface") +add_subdirectory("ebpfapi") +add_subdirectory("libs") +add_subdirectory("tools") +add_subdirectory("ebpfsvc") +add_subdirectory("netebpfext") +add_subdirectory("ebpfcore") +add_subdirectory("scripts") + +if(EBPFFORWINDOWS_ENABLE_TESTS) + include("CTest") + enable_testing() + + add_subdirectory("tests") +endif() + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + install( + DIRECTORY "include" + DESTINATION "." + ) + + install( + FILES "LICENSE.txt" + DESTINATION "." + ) +endif() \ No newline at end of file diff --git a/cmake/codesign.cmake b/cmake/codesign.cmake new file mode 100644 index 000000000..462250366 --- /dev/null +++ b/cmake/codesign.cmake @@ -0,0 +1,27 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +function(codeSign target_name) + if(NOT EXISTS "${EBPFFORWINDOWS_CODESIGN_CERTIFICATE_PATH}") + return() + endif() + + if(NOT EBPFFORWINDOWS_CODESIGN_PASSWORD_ENV_VAR STREQUAL "") + set(optional_cert_password + "-Dpassword_env_var:STRING=${EBPFFORWINDOWS_CODESIGN_PASSWORD_ENV_VAR}" + ) + endif() + + add_custom_command( + TARGET + "${target_name}" + + POST_BUILD + + COMMAND + "${CMAKE_COMMAND}" "-Dcertificate_path:PATH=${EBPFFORWINDOWS_CODESIGN_CERTIFICATE_PATH}" ${optional_cert_password} "-Dbinary_path:PATH=$" -P "${CMAKE_SOURCE_DIR}/cmake/codesign_helper.cmake" + + COMMENT + "ebpf-for-windows - Code signing: ${target_name}" + ) +endfunction() diff --git a/cmake/codesign_helper.cmake b/cmake/codesign_helper.cmake new file mode 100644 index 000000000..5a6a9a64e --- /dev/null +++ b/cmake/codesign_helper.cmake @@ -0,0 +1,23 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +find_program(signtool_path "SignTool") +if(NOT signtool_path) + message(FATAL_ERROR "ebpf-for-windows: Code signing was enabled but the SignTool binary was not found") +endif() + +if(NOT password_env_var STREQUAL "") + set(optional_cert_password + "/p" + "$ENV{${password_env_var}}" + ) +endif() + +execute_process( + COMMAND "${signtool_path}" sign /f "${certificate_path}" ${optional_cert_password} /tr "http://timestamp.digicert.com" /td sha256 /fd sha256 "${binary_path}" + RESULT_VARIABLE signtool_output +) + +if(NOT ${signtool_output} EQUAL 0) + message(FATAL_ERROR "ebpf-for-windows - Failed to codesign the following binary: ${binary_path}") +endif() diff --git a/cmake/git_commit.cmake b/cmake/git_commit.cmake new file mode 100644 index 000000000..cb441f0f7 --- /dev/null +++ b/cmake/git_commit.cmake @@ -0,0 +1,38 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +find_program(git_path "git") +if(NOT git_path) + set(git_commit_id "0") +else() + execute_process( + COMMAND "${git_path}" rev-parse HEAD + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE "git_commit_id" + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() + +set(git_commit_id_file_name "git_commit_id.h") +set(git_commit_id_file_path "${CMAKE_CURRENT_BINARY_DIR}/${git_commit_id_file_name}") + +add_custom_command( + OUTPUT "${git_commit_id_file_path}" + COMMAND "${CMAKE_COMMAND}" -E echo "#define GIT_COMMIT_ID \"${git_commit_id}\"" > "${git_commit_id_file_path}.temp" + COMMAND "${CMAKE_COMMAND}" -E rename "${git_commit_id_file_path}.temp" "${git_commit_id_file_path}" + VERBATIM + COMMENT "ebpf-for-windows - Generating git_commit_id.h" +) + +add_custom_target(git_commit_id_builder + DEPENDS "${git_commit_id_file_path}" +) + +add_library("git_commit_id" INTERFACE) +add_dependencies("git_commit_id" + "git_commit_id_builder" +) + +target_include_directories("git_commit_id" INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}" +) diff --git a/cmake/midl_compiler_finder.cmake b/cmake/midl_compiler_finder.cmake new file mode 100644 index 000000000..6223ce9dc --- /dev/null +++ b/cmake/midl_compiler_finder.cmake @@ -0,0 +1,22 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +function(locateMidlCompiler) + file(GLOB_RECURSE midl_path_list + "C:/Program Files (x86)/Windows Kits/10/bin/*/x64/midl.exe" + ) + + list(SORT midl_path_list) + + foreach(midl_path ${midl_path_list}) + get_filename_component(parent_midl_path "${midl_path}" DIRECTORY) + list(APPEND midl_path_hints "${parent_midl_path}") + endforeach() + + message(STATUS "ebpf-for-windows: Attempting to locate midl.exe using the following hints: ${midl_path_hints}") + + find_program(MIDL_COMPILER_PATH "midl.exe" + HINTS ${midl_path_hints} + REQUIRED + ) +endfunction() diff --git a/cmake/options.cmake b/cmake/options.cmake new file mode 100644 index 000000000..11b9ca76c --- /dev/null +++ b/cmake/options.cmake @@ -0,0 +1,33 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +option(EBPFFORWINDOWS_ENABLE_TESTS "Set to true to enable tests" true) +option(EBPFFORWINDOWS_ENABLE_INSTALL "Set to true to enable the install target") +option(EBPFFORWINDOWS_ENABLE_DISABLE_EBPF_INTERPRETER "Set to true to compile with the interpreter always disabled") + +set(EBPFFORWINDOWS_CODESIGN_CERTIFICATE_PATH "" CACHE STRING "Path to the certificate used for signing") +set(EBPFFORWINDOWS_CODESIGN_PASSWORD_ENV_VAR "" CACHE STRING "Name of the environment variable containing the certificate password") + +set(EBPFFORWINDOWS_WDK_WINVER "0x0A00" CACHE STRING "WINVER value passed to the Windows Driver Kit. Defaults to Windows 10 (0x0A00)") +set(EBPFFORWINDOWS_WDK_KMDF_VERSION "1.15" CACHE STRING "KMDF version used for drivers. Defaults to 1.15") + +if(EXISTS "${EBPFFORWINDOWS_CODESIGN_CERTIFICATE_PATH}") + set(codesign_enabled true) +else() + set(codesign_enabled false) +endif() + +message(STATUS "ebpf-for-windows - Tests: ${EBPFFORWINDOWS_ENABLE_TESTS}") +message(STATUS "ebpf-for-windows - Install targets: ${EBPFFORWINDOWS_ENABLE_INSTALL}") +message(STATUS "ebpf-for-windows - eBPF interpreter disabled: ${EBPFFORWINDOWS_ENABLE_DISABLE_EBPF_INTERPRETER}") +message(STATUS "ebpf-for-windows - Code signing enabled: ${codesign_enabled}") +message(STATUS "ebpf-for-windows - WDK_WINVER: ${EBPFFORWINDOWS_WDK_WINVER}") +message(STATUS "ebpf-for-windows - KMDF version: ${EBPFFORWINDOWS_WDK_KMDF_VERSION}") + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "/Program Files/${CMAKE_PROJECT_NAME}" CACHE PATH "" FORCE) + endif() + + message(STATUS "ebpf-for-windows - CMAKE_INSTALL_PREFIX set to ${CMAKE_INSTALL_PREFIX}") +endif() diff --git a/cmake/settings.cmake b/cmake/settings.cmake new file mode 100644 index 000000000..9ebdb7b85 --- /dev/null +++ b/cmake/settings.cmake @@ -0,0 +1,55 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +# Some targets do not play well with the default definitions (such +# as bpftool and /DWIN32). Remove them from the variables for now +set(settings_variable_list + "CMAKE_C_FLAGS_RELEASE" + "CMAKE_C_FLAGS_DEBUG" + "CMAKE_C_FLAGS_RELWITHDEBINFO" + + "CMAKE_CXX_FLAGS_RELEASE" + "CMAKE_CXX_FLAGS_DEBUG" + "CMAKE_CXX_FLAGS_RELWITHDEBINFO" + + "CMAKE_C_FLAGS" + "CMAKE_CXX_FLAGS" +) + +foreach(settings_variable ${settings_variable_list}) + string(REPLACE "/D_WINDOWS" "" "${settings_variable}" ${${settings_variable}}) + string(REPLACE "/DWIN32" "" "${settings_variable}" ${${settings_variable}}) +endforeach() + +add_library("ebpf_for_windows_base_definitions" INTERFACE) +target_compile_definitions("ebpf_for_windows_base_definitions" INTERFACE + $<$:_DEBUG> + $<$:NDEBUG> + $<$:NDEBUG> +) + +add_library("ebpf_for_windows_common_settings" INTERFACE) +target_compile_definitions("ebpf_for_windows_common_settings" INTERFACE + UNICODE + _UNICODE +) + +target_link_libraries("ebpf_for_windows_common_settings" INTERFACE + "ebpf_for_windows_base_definitions" +) + + +if(EBPFFORWINDOWS_ENABLE_DISABLE_EBPF_INTERPRETER) + target_compile_definitions("ebpf_for_windows_common_settings" INTERFACE + CONFIG_BPF_JIT_ALWAYS_ON=1 + ) +endif() + +add_library("ebpf_for_windows_cpp_settings" INTERFACE) +target_link_libraries("ebpf_for_windows_cpp_settings" INTERFACE + "ebpf_for_windows_common_settings" +) + +target_compile_features("ebpf_for_windows_cpp_settings" INTERFACE + cxx_std_17 +) diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index b7c83ddaf..da38683db 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -25,7 +25,7 @@ if ((get-filehash $env:TEMP\Setup-DeveEnv.ps1).Hash -eq 'C0632C7015BE9BF78AD36A8 ``` 3. Launch Visual Studio Installer and select "MSVC v142 - VS 2019 C++ x64/x86 Spectre-mitigated libs (latest)" -## How to clone and build the project +## How to clone and build the project using Visual Studio This section outlines the steps to build, prepare and build the eBPF-For-Windows project. ### Cloning the project @@ -92,6 +92,48 @@ and a few binaries just used for demo'ing eBPF functionality, as in the demo wal * `port_quota.exe`: A sample utility to illustrate using eBPF to manage port quotas to defend against `port_leak.exe` and similar "buggy" apps. +## How to clone and build the project using CMake + +### Cloning the project +```bash +git clone --recurse-submodules https://github.com/microsoft/ebpf-for-windows.git +``` + +### Configuring the project + +```bash +cmake -S ebpf-for-windows -B build +``` + +### Building the project + +Configuration: It is advised to use the Debug configuration for now. + +```bash +cmake --build build --config +``` + +### Running the tests + +Configure with the `EBPFFORWINDOWS_ENABLE_TESTS` option (enabled by default) + +```bash +cmake -S ebpf-for-windows -B build -DEBPFFORWINDOWS_ENABLE_TESTS=true +``` + +Then build the tests + +```bash +cmake -S ebpf-for-windows -B build +``` + +Finally, invoke CTest: + +``` +cd build +ctest -V -C Debug +``` + ## Installing eBPF for Windows Windows requires that one of the following criteria be met prior to loading a driver: diff --git a/ebpfapi/CMakeLists.txt b/ebpfapi/CMakeLists.txt new file mode 100644 index 000000000..6b5898985 --- /dev/null +++ b/ebpfapi/CMakeLists.txt @@ -0,0 +1,60 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("EbpfApi" SHARED + Source.def + + pch.h + resource.h + + dllmain.cpp + rpc_client.cpp + + ../libs/thunk/windows/platform.cpp + ../resource/ebpf_resource.rc +) + +target_include_directories("EbpfApi" PRIVATE + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/libs/api_common" + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +target_link_libraries("EbpfApi" PRIVATE + "ebpf_for_windows_cpp_settings" + "api" + "api_common" + "external::ebpfverifier" + "platform_user" + "ubpf_user" + "rpc_interface" + "git_commit_id" + "bpf2c_driver" + "Mincore.lib" +) + +target_compile_definitions("EbpfApi" PRIVATE + EBPFAPI_EXPORTS + _WINDOWS + _USRDLL +) + +codeSign("EbpfApi") + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + # Only install the .dll file, without the .lib + install( + TARGETS "EbpfApi" + RUNTIME DESTINATION "." + ) + + # Only install the .lib file, without the .dll + install( + TARGETS "EbpfApi" + ARCHIVE DESTINATION "lib" + ) +endif() diff --git a/ebpfcore/CMakeLists.txt b/ebpfcore/CMakeLists.txt new file mode 100644 index 000000000..fe975d04a --- /dev/null +++ b/ebpfcore/CMakeLists.txt @@ -0,0 +1,52 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +wdk_add_driver("EbpfCore" WINVER "${EBPFFORWINDOWS_WDK_WINVER}" KMDF "${EBPFFORWINDOWS_WDK_KMDF_VERSION}" + resource.h + ebpf_drv.c + + ../resource/ebpf_resource.rc +) + +target_include_directories("EbpfCore" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/kernel" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +target_link_directories("EbpfCore" PRIVATE + "${WDK_ROOT}/Lib/${WDK_VERSION}/km/x64" +) + +target_link_libraries("EbpfCore" + "ebpf_for_windows_common_settings" + "execution_context_kernel" + "platform_kernel" + "external::ebpfverifier_headers" + "ubpf_kernel" + "git_commit_id" + "Netio.lib" +) + +target_compile_definitions("EbpfCore" PRIVATE + BINARY_COMPATIBLE=0 + NT + NDIS60 + POOL_NX_OPTIN_AUTO +) + +codeSign("EbpfCore") + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + install( + TARGETS "EbpfCore" + DESTINATION "drivers" + ) + + install( + FILES "EbpfCore.inf" + DESTINATION "drivers" + ) +endif() diff --git a/ebpfsvc/CMakeLists.txt b/ebpfsvc/CMakeLists.txt new file mode 100644 index 000000000..37882d053 --- /dev/null +++ b/ebpfsvc/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("ebpfsvc" + ../resource/ebpf_resource.rc + + resource.h + svc_common.h + + ../libs/thunk/windows/platform.cpp + rpc_api.cpp + svcmain.cpp + + rpc_util.h + rpc_util.cpp +) + +target_include_directories("ebpfsvc" PRIVATE + "${CMAKE_SOURCE_DIR}/libs/api_common" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/service" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/rpc_interface" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +target_link_libraries("ebpfsvc" PRIVATE + "ebpf_for_windows_cpp_settings" + "api_common" + "platform_user" + "rpc_interface" + "service" + "ubpf_user" + "git_commit_id" + "external::ebpfverifier" + "Mincore.lib" +) + +target_compile_definitions("ebpfsvc" PRIVATE + EBPFSVC_EXPORTS + _WINDOWS + _USRDLL +) + +codeSign("ebpfsvc") + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + install( + TARGETS "ebpfsvc" + DESTINATION "." + ) +endif() diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 000000000..286fc4e07 --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,166 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_subdirectory("ebpf-verifier" EXCLUDE_FROM_ALL) +add_subdirectory("Catch2" EXCLUDE_FROM_ALL) + +# Special target that we can link to external dependencies +# to override build settings +add_library("ebpf_for_windows_external_settings" INTERFACE) +target_compile_options("ebpf_for_windows_external_settings" INTERFACE + "/w" +) + +target_compile_definitions("ebpf_for_windows_external_settings" INTERFACE + "_CRT_SECURE_NO_WARNINGS" + "_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS" +) + +# +# Catch2 +# + +target_link_libraries("Catch2" PRIVATE + "ebpf_for_windows_external_settings" +) + +# +# ebpfverifier +# + +target_link_libraries("ebpfverifier" PRIVATE + "ebpf_for_windows_external_settings" +) + +# Fix missing INTERFACE include directories +target_include_directories("ebpfverifier" INTERFACE + ebpf-verifier/src + ebpf-verifier/external/elfio +) + +# Fix missing dependency between ebpfverifier and yaml-cpp +add_dependencies("ebpfverifier" + "yaml-cpp" +) + +add_library("external::ebpfverifier" ALIAS "ebpfverifier") + +# Some targets end up requiring ebpfverifier by mistake due to +# the ebpf_program_types.h header. For now, create an interface +# target just to export the include directory +add_library("ebpfverifier_headers" INTERFACE) +target_include_directories("ebpfverifier_headers" INTERFACE + ebpf-verifier/src +) + +add_library("external::ebpfverifier_headers" ALIAS "ebpfverifier_headers") + +# +# boost (downloaded by ebpfverifier) +# + +add_library("boost" INTERFACE) +target_include_directories("boost" INTERFACE + "${CMAKE_BINARY_DIR}/packages/boost/lib/native/include" +) + +add_library("external::boost" ALIAS "boost") + +# +# libbpf +# + +# This target has been split from bpftool, since its headers +# are also referenced by the 'api' target +add_library("libbpf" + bpftool/libbpf/src/hashmap.c + bpftool/libbpf/src/libbpf.c +) + +target_include_directories("libbpf" PUBLIC + "${CMAKE_SOURCE_DIR}/external/bpftool" + "${CMAKE_SOURCE_DIR}/external/bpftool/libbpf/src" + "${CMAKE_SOURCE_DIR}/external/bpftool/libbpf/include" + "${CMAKE_SOURCE_DIR}/include" +) + +target_link_libraries("libbpf" + PRIVATE + "ebpf_for_windows_external_settings" + "ebpf_for_windows_common_settings" + + PUBLIC + "external::ebpfverifier" +) + +target_compile_definitions("libbpf" PUBLIC + BPFTOOL_VERSION="0.1" + _CONSOLE +) + +add_library("external::libbpf" ALIAS "libbpf") + +# +# bpftool +# + +add_executable("bpftool" + win-c/source/getopt.c + + bpftool/src/common.c + bpftool/src/json_writer.c + bpftool/src/link.c + bpftool/src/main.c + bpftool/src/map.c + bpftool/src/net.c + bpftool/src/prog.c +) + +target_include_directories("bpftool" PRIVATE + "${CMAKE_SOURCE_DIR}/external/win-c/include" +) + +target_link_libraries("bpftool" PRIVATE + "ebpf_for_windows_external_settings" + "ebpf_for_windows_common_settings" + "EbpfApi" + "external::libbpf" + + iphlpapi.lib + kernel32.lib + user32.lib + gdi32.lib + winspool.lib + comdlg32.lib + advapi32.lib + shell32.lib + ole32.lib + oleaut32.lib + uuid.lib + odbc32.lib + odbccp32.lib +) + +add_executable("external::bpftool" ALIAS "bpftool") + +codeSign("bpftool") + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + install( + TARGETS "bpftool" + DESTINATION "." + ) + + set(include_dir_list + "asm" + "linux" + "uapi" + ) + + foreach(include_dir ${include_dir_list}) + install( + DIRECTORY "bpftool/libbpf/include/${include_dir}" + DESTINATION "include/libbpf" + ) + endforeach() +endif() diff --git a/external/FindWDK b/external/FindWDK new file mode 160000 index 000000000..43fd504e1 --- /dev/null +++ b/external/FindWDK @@ -0,0 +1 @@ +Subproject commit 43fd504e1dc31996812ac7f7cdcbbbd3561c17d0 diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt new file mode 100644 index 000000000..40a313fc8 --- /dev/null +++ b/libs/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_subdirectory("api") +add_subdirectory("api_common") +add_subdirectory("execution_context") +add_subdirectory("platform") +add_subdirectory("ebpfnetsh") +add_subdirectory("service") +add_subdirectory("ubpf") diff --git a/libs/api/CMakeLists.txt b/libs/api/CMakeLists.txt new file mode 100644 index 000000000..1460fa1fe --- /dev/null +++ b/libs/api/CMakeLists.txt @@ -0,0 +1,53 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("api" STATIC + ../thunk/platform.h + + api_internal.h + pch.h + rpc_client.h + + bpf_syscall.cpp + ebpf_api.cpp + libbpf_link.cpp + libbpf_map.cpp + libbpf_object.cpp + libbpf_program.cpp + libbpf_system.cpp + + Verifier.h + Verifier.cpp + + windows_platform.hpp + windows_platform.cpp +) + +target_include_directories("api" PRIVATE + "${CMAKE_SOURCE_DIR}/libs/api_common" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/rpc_interface" + "${CMAKE_SOURCE_DIR}/libs/service" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/include/bpf" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" + "${CMAKE_SOURCE_DIR}/libs/thunk" +) + +target_link_libraries("api" PRIVATE + "ebpf_for_windows_cpp_settings" + "rpc_interface" + "encode_program_info_headers" + "external::ebpfverifier" + "external::boost" + "external::libbpf" +) + +target_compile_definitions("api" PRIVATE + _WINDOWS + _USRDLL +) diff --git a/libs/api_common/CMakeLists.txt b/libs/api_common/CMakeLists.txt new file mode 100644 index 000000000..ec2da4906 --- /dev/null +++ b/libs/api_common/CMakeLists.txt @@ -0,0 +1,58 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("api_common" STATIC + windows_helpers.cpp + windows_program_type.h + + map_descriptors.hpp + map_descriptors.cpp + + windows_platform_common.hpp + windows_platform_common.cpp + + api_common.hpp + api_common.cpp + + device_helper.hpp + device_helper.cpp +) + +target_include_directories("api_common" PRIVATE + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" + "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" + "${CMAKE_SOURCE_DIR}/libs/thunk" +) + +target_link_libraries("api_common" PRIVATE + "ebpf_for_windows_cpp_settings" + "encode_program_info_headers" + "NetEbpfExt_headers" + "external::boost" + "external::ebpfverifier" +) + +target_compile_definitions("api_common" PRIVATE + _WINDOWS + _USRDLL +) + +# In order to get around cyclic dependency issues, create an interface +# target that just exports the header files. +# +# This property can later be added back into "api_common" when the +# dependency graph is fixed +add_library("api_common_headers" INTERFACE) +target_include_directories("api_common_headers" SYSTEM INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +target_link_libraries("api_common" INTERFACE + "api_common_headers" +) diff --git a/libs/ebpfnetsh/CMakeLists.txt b/libs/ebpfnetsh/CMakeLists.txt new file mode 100644 index 000000000..b3567de05 --- /dev/null +++ b/libs/ebpfnetsh/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("netsh_static" STATIC + tokens.h + + elf.h + elf.cpp + + links.h + links.cpp + + pins.h + pins.cpp + + programs.h + programs.cpp + + utilities.h + utilities.cpp + + maps.h + maps.cpp +) + +target_include_directories("netsh_static" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/thunk" +) + +target_link_libraries("netsh_static" + PRIVATE + "ebpf_for_windows_cpp_settings" + + PUBLIC + "external::libbpf" +) + +target_compile_definitions("netsh_static" PRIVATE + _LIB +) diff --git a/libs/execution_context/CMakeLists.txt b/libs/execution_context/CMakeLists.txt new file mode 100644 index 000000000..d6dcba15b --- /dev/null +++ b/libs/execution_context/CMakeLists.txt @@ -0,0 +1,79 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +set(execution_context_sources + ebpf_core.h + ebpf_core.c + + ebpf_link.h + ebpf_link.c + + ebpf_maps.h + ebpf_maps.c + + ebpf_native.h + ebpf_native.c + + ebpf_program.h + ebpf_program.c + + ebpf_protocol.h + ebpf_general_helpers.c +) + +# +# execution_context_user +# + +add_library("execution_context_user" STATIC + ${execution_context_sources} +) + +target_include_directories("execution_context_user" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" +) + +target_link_libraries("execution_context_user" PRIVATE + "ebpf_for_windows_common_settings" + "external::ebpfverifier_headers" +) + +target_compile_definitions("execution_context_user" PRIVATE + _LIB +) + +# +# execution_context_kernel +# + +wdk_add_library("execution_context_kernel" STATIC WINVER "${EBPFFORWINDOWS_WDK_WINVER}" + ${execution_context_sources} +) + +target_include_directories("execution_context_kernel" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/kernel" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" +) + +target_link_libraries("execution_context_kernel" PRIVATE + "ebpf_for_windows_base_definitions" + "external::ebpfverifier_headers" +) + +target_compile_definitions("execution_context_kernel" PRIVATE + $<$:_DEBUG> + $<$:NDEBUG> + WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP + WINAPI_PARTITION_DESKTOP=1 + WINAPI_PARTITION_SYSTEM=1 + WINAPI_PARTITION_APP=1 + WINAPI_PARTITION_PC_APP=1 + _NO_CRT_STDIO_INLINE=1 +) diff --git a/libs/platform/CMakeLists.txt b/libs/platform/CMakeLists.txt new file mode 100644 index 000000000..8f54d2dc8 --- /dev/null +++ b/libs/platform/CMakeLists.txt @@ -0,0 +1,160 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +# +# ebpf_program_types_interface +# + +set(ebpf_program_types_h_name "ebpf_program_types_h.h") +set(ebpf_program_types_h_path "${CMAKE_CURRENT_BINARY_DIR}/${ebpf_program_types_h_name}") + +set(ebpf_program_types_c_name "ebpf_program_types_c.c") +set(ebpf_program_types_c_path "${CMAKE_CURRENT_BINARY_DIR}/${ebpf_program_types_c_name}") + +add_custom_command( + OUTPUT + "${ebpf_program_types_h_path}" + "${ebpf_program_types_c_path}" + + COMMAND + "${MIDL_COMPILER_PATH}" "/I${CMAKE_SOURCE_DIR}/external/ebpf-verifier/src" "/I${CMAKE_SOURCE_DIR}/include" /W1 /nologo /char signed /env x64 /h "ebpf_program_types_h.h" /notlb /client stub /server none /target NT60 /acf ../ebpf_program_types.acf /protocol dce ../ebpf_program_types.idl + + COMMAND + "${CMAKE_COMMAND}" -E rename "${ebpf_program_types_h_name}" "${ebpf_program_types_h_path}" + + COMMAND + "${CMAKE_COMMAND}" -E rename "${ebpf_program_types_c_name}" "${ebpf_program_types_c_path}" + + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}/user" + + DEPENDS + "ebpf_program_types.idl" + + COMMENT + "ebpf-for-windows - Building: ebpf_program_types.idl" + + VERBATIM +) + +add_custom_target("ebpf_program_types_interface_builder" + DEPENDS "${ebpf_program_types_h_path}" +) + +add_library("ebpf_program_types_interface" OBJECT + "${ebpf_program_types_c_path}" +) + +add_dependencies("ebpf_program_types_interface" + "ebpf_program_types_interface_builder" +) + +target_include_directories("ebpf_program_types_interface" INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}" +) + +# +# platform_{user,kernel} +# + +set(platform_user_sources + ebpf_async.h + ebpf_async.c + + ebpf_bitmap.h + ebpf_bitmap.c + + ebpf_epoch.h + ebpf_epoch.c + + ebpf_object.h + ebpf_object.c + + ebpf_pinning_table.h + ebpf_pinning_table.c + + ebpf_ring_buffer.h + ebpf_ring_buffer.c + + ebpf_state.h + ebpf_state.c + + ebpf_handle.h + ebpf_platform.h + + ebpf_program_types.c + ebpf_error.c + ebpf_etw.c + ebpf_hash_table.c + ebpf_interlocked.c + ebpf_serialize.c + ebpf_trampoline.c +) + +set(platform_kernel_include_dirs + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" +) + +# +# platform_user +# + +add_library("platform_user" STATIC + ${platform_user_sources} + user/framework.h + user/ebpf_extension_user.c + user/ebpf_handle_user.c + user/ebpf_platform_user.cpp + user/ebpf_native_user.c +) + +target_include_directories("platform_user" PRIVATE + ${platform_kernel_include_dirs} + "${CMAKE_SOURCE_DIR}/libs/platform/user" +) + +target_link_libraries("platform_user" PRIVATE + "ebpf_for_windows_cpp_settings" + "ebpf_program_types_interface" + "ebpfverifier_headers" +) + +target_compile_definitions("platform_user" PRIVATE + _LIB +) + +# +# platform_kernel +# + +wdk_add_library("platform_kernel" STATIC WINVER "${EBPFFORWINDOWS_WDK_WINVER}" + ${platform_user_sources} + kernel/ebpf_extension_kernel.c + kernel/ebpf_handle_kernel.c + kernel/ebpf_platform_kernel.c + kernel/ebpf_native_kernel.c +) + +target_include_directories("platform_kernel" PRIVATE + ${platform_kernel_include_dirs} + "${CMAKE_SOURCE_DIR}/libs/platform/kernel" + "${CMAKE_SOURCE_DIR}/libs/epoch" +) + +target_link_libraries("platform_kernel" PRIVATE + "ebpf_for_windows_common_settings" + "ebpf_program_types_interface" + "external::ebpfverifier_headers" +) + +target_compile_definitions("platform_kernel" PRIVATE + WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP + WINAPI_PARTITION_DESKTOP=1 + WINAPI_PARTITION_SYSTEM=1 + WINAPI_PARTITION_APP=1 + WINAPI_PARTITION_PC_APP=1 + _KRPCENV_ + _NO_CRT_STDIO_INLINE=1 +) diff --git a/libs/service/CMakeLists.txt b/libs/service/CMakeLists.txt new file mode 100644 index 000000000..baf4aaa27 --- /dev/null +++ b/libs/service/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("service" STATIC + api_service.h + api_service.cpp + + verifier_service.h + verifier_service.cpp + + windows_platform_service.hpp + windows_platform_service.cpp +) + +target_include_directories("service" PRIVATE + "${CMAKE_SOURCE_DIR}/rpc_interface" + "${CMAKE_SOURCE_DIR}/libs/api_common" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" + "${CMAKE_SOURCE_DIR}/libs/thunk" +) + +target_link_libraries("service" PRIVATE + "ebpf_for_windows_cpp_settings" + "rpc_interface" + "encode_program_info_headers" + "external::boost" + "external::ebpfverifier" +) + +target_compile_definitions("service" PRIVATE + _WINDOWS + _USRDLL +) diff --git a/libs/ubpf/CMakeLists.txt b/libs/ubpf/CMakeLists.txt new file mode 100644 index 000000000..48d0ca8bf --- /dev/null +++ b/libs/ubpf/CMakeLists.txt @@ -0,0 +1,74 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +set(ubpf_sources + ../../external/ubpf/vm/ebpf.h + ../../external/ubpf/vm/ubpf_int.h +) + +set(ubpf_include_dirs + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/ubpf" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" +) + +# +# ubpf_user +# + +add_library("ubpf_user" STATIC + ${ubpf_sources} + + ../../external/ubpf/vm/ubpf_jit_x86_64.h + user/ubpf_user.c +) + +target_include_directories("ubpf_user" PRIVATE + ${ubpf_include_dirs} + "${CMAKE_SOURCE_DIR}/libs/platform/user" +) + +target_link_libraries("ubpf_user" PRIVATE + "ebpf_for_windows_common_settings" + "rpc_interface" + "encode_program_info_headers" + "external::boost" +) + +target_compile_options("ubpf_user" PRIVATE + /w +) + +target_compile_definitions("ubpf_user" PRIVATE + _LIB + __x86_64__ +) + +# +# ubpf_kernel +# + +wdk_add_library("ubpf_kernel" STATIC WINVER "${EBPFFORWINDOWS_WDK_WINVER}" + ${ubpf_sources} + kernel/ubpf_kernel.c +) + +target_compile_options("ubpf_kernel" PRIVATE + "/WX-" +) + +target_include_directories("ubpf_kernel" PRIVATE + ${ubpf_include_dirs} + "${CMAKE_SOURCE_DIR}/libs/platform/kernel" +) + +target_compile_definitions("ubpf_kernel" PRIVATE + WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP + WINAPI_PARTITION_DESKTOP=1 + WINAPI_PARTITION_SYSTEM=1 + WINAPI_PARTITION_APP=1 + WINAPI_PARTITION_PC_APP=1 + _NO_CRT_STDIO_INLINE=1 +) diff --git a/netebpfext/CMakeLists.txt b/netebpfext/CMakeLists.txt new file mode 100644 index 000000000..4f6dfb479 --- /dev/null +++ b/netebpfext/CMakeLists.txt @@ -0,0 +1,78 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +wdk_add_driver("NetEbpfExt" WINVER "${EBPFFORWINDOWS_WDK_WINVER}" KMDF "${EBPFFORWINDOWS_WDK_KMDF_VERSION}" + net_ebpf_ext.h + net_ebpf_ext.c + + net_ebpf_ext_bind.h + net_ebpf_ext_bind.c + + net_ebpf_ext_hook_provider.h + net_ebpf_ext_hook_provider.c + + net_ebpf_ext_prog_info_provider.h + net_ebpf_ext_prog_info_provider.c + + net_ebpf_ext_sock_addr.h + net_ebpf_ext_sock_addr.c + + net_ebpf_ext_xdp.h + net_ebpf_ext_xdp.c + + net_ebpf_ext_sock_ops.h + net_ebpf_ext_sock_ops.c + + net_ebpf_ext_program_info.h + resource.h + + net_ebpf_ext_drv.c +) + +target_include_directories("NetEbpfExt" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/kernel" +) + +target_link_directories("NetEbpfExt" PRIVATE + "${WDK_ROOT}/Lib/${WDK_VERSION}/km/x64" +) + +target_link_libraries("NetEbpfExt" + "ebpf_for_windows_common_settings" + "external::ebpfverifier_headers" + "Ndis.lib" + "Netio.lib" + "Fwpkclnt.lib" + "wdmsec.lib" +) + +target_compile_definitions("NetEbpfExt" PRIVATE + BINARY_COMPATIBLE=0 + NT + NDIS60 + POOL_NX_OPTIN_AUTO +) + +# api_common includes NetEbpfExt's headers. Since this is a driver +# and it does not make sense to link against it, for now create +# an interface target that just exports the include directory. +add_library("NetEbpfExt_headers" INTERFACE) +target_include_directories("NetEbpfExt_headers" SYSTEM INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +codeSign("NetEbpfExt") + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + install( + TARGETS "NetEbpfExt" + DESTINATION "drivers" + ) + + install( + FILES "netebpfext.inf" + DESTINATION "drivers" + ) +endif() \ No newline at end of file diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt new file mode 100644 index 000000000..43f35246e --- /dev/null +++ b/packaging/CMakeLists.txt @@ -0,0 +1,152 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.22) +project("ebpf-for-windows") + +set(EBPFFORWINDOWS_PROGRAM_DATA "" CACHE PATH "Path containing program data") +if(EBPFFORWINDOWS_PROGRAM_DATA STREQUAL "") + message(FATAL_ERROR "ebpf-for-windows Invalid program data path") +endif() + +if(NOT CPACK_GENERATOR) + message(FATAL_ERROR "ebpf-for-windows - No generator selected") +endif() + +set(EBPFFORWINDOWS_VERSION "" CACHE STRING "Package version") +if(EBPFFORWINDOWS_VERSION STREQUAL "") + message(FATAL_ERROR "ebpf-for-windows - No version has been set") +endif() + +set(CPACK_PACKAGE_VERSION "${EBPFFORWINDOWS_VERSION}") +set(CPACK_PACKAGE_DESCRIPTION "eBPF implementation that runs on top of Windows.") +set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") +set(CPACK_PACKAGE_VENDOR "Microsoft") +set(CPACK_PACKAGE_CONTACT "opencode@microsoft.com") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/microsoft/ebpf-for-windows") +set(CPACK_PACKAGE_RELOCATABLE ON) +set(CPACK_RESOURCE_FILE_LICENSE "${EBPFFORWINDOWS_PROGRAM_DATA}/LICENSE.txt") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") + +# +# Runtime +# + +install( + FILES + "${EBPFFORWINDOWS_PROGRAM_DATA}/bpftool.exe" + "${EBPFFORWINDOWS_PROGRAM_DATA}/bpf2c.exe" + "${EBPFFORWINDOWS_PROGRAM_DATA}/ebpfsvc.exe" + + "${EBPFFORWINDOWS_PROGRAM_DATA}/EbpfApi.dll" + "${EBPFFORWINDOWS_PROGRAM_DATA}/ebpfnetsh.dll" + + "${EBPFFORWINDOWS_PROGRAM_DATA}/ebpf-all.guid" + "${EBPFFORWINDOWS_PROGRAM_DATA}/ebpf-printk.guid" + "${EBPFFORWINDOWS_PROGRAM_DATA}/ebpfforwindows.wprp" + + "${EBPFFORWINDOWS_PROGRAM_DATA}/LICENSE.txt" + + DESTINATION + "." + + COMPONENT + "Runtime" +) + +install( + DIRECTORY + "${EBPFFORWINDOWS_PROGRAM_DATA}/drivers" + + DESTINATION + "." + + COMPONENT + "Runtime" +) + +install( + DIRECTORY + "${EBPFFORWINDOWS_PROGRAM_DATA}/scripts" + + DESTINATION + "." + + COMPONENT + "Runtime" +) + +# +# Development +# + +install( + DIRECTORY + "${EBPFFORWINDOWS_PROGRAM_DATA}/include" + + DESTINATION + "." + + COMPONENT + "Development" +) + +install( + DIRECTORY + "${EBPFFORWINDOWS_PROGRAM_DATA}/lib" + + DESTINATION + "." + + COMPONENT + "Development" +) + +# +# Testing and debugging +# + +install( + DIRECTORY + "${EBPFFORWINDOWS_PROGRAM_DATA}/testing" + + DESTINATION + "testing" + + COMPONENT + "Testing" +) + +if(CPACK_GENERATOR STREQUAL "WIX") + set(CPACK_WIX_UPGRADE_GUID "b6bcacb1-c872-4159-abcb-43a50668056c") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}") + set(CPACK_WIX_EXTENSIONS "WixUtilExtension") + +elseif(CPACK_GENERATOR STREQUAL "NuGet") + set(CPACK_NUGET_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}") + set(CPACK_NUGET_PACKAGE_AUTHORS "${CPACK_PACKAGE_NAME}") + set(CPACK_NUGET_PACKAGE_TITLE "${CPACK_PACKAGE_NAME}") + set(CPACK_NUGET_PACKAGE_OWNERS "${CPACK_PACKAGE_NAME}") + set(CPACK_NUGET_PACKAGE_COPYRIGHT "Copyright (c) Microsoft Corporation") + set(CPACK_NUGET_PACKAGE_LICENSEURL "https://raw.githubusercontent.com/microsoft/ebpf-for-windows/main/LICENSE.txt") + set(CPACK_NUGET_PACKAGE_DESCRIPTION_SUMMARY "${CPACK_NUGET_PACKAGE_DESCRIPTION}") + set(CPACK_NUGET_PACKAGE_RELEASE_NOTES "${CPACK_PACKAGE_HOMEPAGE_URL}/releases/tag/${CPACK_PACKAGE_VERSION}") + set(CPACK_NUGET_PACKAGE_TAGS "ebpf bpf windows") +endif() + +include(CPack) + +cpack_add_component("Runtime" + DISPLAY_NAME "Runtime components" + REQUIRED +) + +cpack_add_component("Testing" + DISPLAY_NAME "Testing components" + DISABLED +) + +cpack_add_component("Development" + DISPLAY_NAME "Development components" + DISABLED +) diff --git a/packaging/README.md b/packaging/README.md new file mode 100644 index 000000000..57eae377d --- /dev/null +++ b/packaging/README.md @@ -0,0 +1,35 @@ +# Packaging instructions + +## Prerequisits + +The [WiX toolset](https://wixtoolset.org/) should be installed and reachable via PATH. + +## Configure the main project with `-DEBPFFORWINDOWS_ENABLE_INSTALL=true` + +``` +cmake -S . -B build -DEBPFFORWINDOWS_ENABLE_INSTALL=true +``` + +## Build and install the project + +Note that this will install ebpf-for-windows to the `/Program Files/ebpf-for-windows` directory. You can use the `DESTDIR` environment variable to override this. + +``` +cmake --build . --config Debug --target install +``` + +## Configure the packaging project + +The generator can either be: + * WIX + * NuGet + +``` +cmake -S packaging -B package -DEBPFFORWINDOWS_PROGRAM_DATA="C:\Program Files\ebpf-for-windows" -DEBPFFORWINDOWS_VERSION=1.0.0 -DCPACK_GENERATOR=WIX +``` + +## Build the package + +``` +cmake --build package --target package +``` \ No newline at end of file diff --git a/rpc_interface/CMakeLists.txt b/rpc_interface/CMakeLists.txt new file mode 100644 index 000000000..972a582c1 --- /dev/null +++ b/rpc_interface/CMakeLists.txt @@ -0,0 +1,53 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +set(rpc_interface_h_name "rpc_interface_h.h") +set(rpc_interface_c_name "rpc_interface_c.c") +set(rpc_interface_s_name "rpc_interface_s.c") + +set(rpc_interface_h_path "${CMAKE_CURRENT_BINARY_DIR}/${rpc_interface_h_name}") +set(rpc_interface_c_path "${CMAKE_CURRENT_BINARY_DIR}/${rpc_interface_c_name}") +set(rpc_interface_s_path "${CMAKE_CURRENT_BINARY_DIR}/${rpc_interface_s_name}") + +add_custom_command( + OUTPUT + "${rpc_interface_h_path}" + "${rpc_interface_c_path}" + "${rpc_interface_s_path}" + + COMMAND + "${MIDL_COMPILER_PATH}" "/I${CMAKE_SOURCE_DIR}/include" "/I${CMAKE_SOURCE_DIR}/libs/api" /W1 /nologo /char unsigned /env x64 /h "${rpc_interface_h_name}" /tlb "x64/$<$:Debug>$<$:Release>/rpc_interface.tlb" /target NT100 /prefix server ebpf_server_ /prefix client ebpf_client_ rpc_interface.idl + + COMMAND + "${CMAKE_COMMAND}" -E rename "${rpc_interface_h_name}" "${rpc_interface_h_path}" + + COMMAND + "${CMAKE_COMMAND}" -E rename "${rpc_interface_c_name}" "${rpc_interface_c_path}" + + COMMAND + "${CMAKE_COMMAND}" -E rename "${rpc_interface_s_name}" "${rpc_interface_s_path}" + + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + + DEPENDS + "rpc_interface.idl" + + COMMENT + "ebpf-for-windows - Building: rpc_interface.idl" + + VERBATIM +) + +add_custom_target("rpc_interface_builder" + DEPENDS "${rpc_interface_h_path}" +) + +add_library("rpc_interface" INTERFACE) +add_dependencies("rpc_interface" + "rpc_interface_builder" +) + +target_include_directories("rpc_interface" INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}" +) diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt new file mode 100644 index 000000000..aaf4069d7 --- /dev/null +++ b/scripts/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + install( + FILES + "install-ebpf.bat" + "uninstall-ebpf.bat" + + DESTINATION + "scripts" + ) +endif() diff --git a/scripts/create_package_data.bat b/scripts/create_package_data.bat new file mode 100644 index 000000000..61ad80c8f --- /dev/null +++ b/scripts/create_package_data.bat @@ -0,0 +1,77 @@ +@echo off + +mkdir package_data +copy bpftool.exe package_data +copy bpf2c.exe package_data +copy ebpfsvc.exe package_data +copy EbpfApi.dll package_data +copy ebpfnetsh.dll package_data +copy ebpf-all.guid package_data +copy ebpf-printk.guid package_data +copy ebpfforwindows.wprp package_data +copy %SOURCE_DIR%\LICENSE.txt package_data + +mkdir package_data\lib +copy EbpfApi.lib package_data\lib + +mkdir package_data\drivers +copy NetEbpfExt\NetEbpfExt.sys package_data\drivers +copy NetEbpfExt\NetEbpfExt.inf package_data\drivers + +copy EbpfCore\EbpfCore.sys package_data\drivers +copy EbpfCore\EbpfCore.inf package_data\drivers + +mkdir package_data\scripts +copy %SOURCE_DIR%\scripts\install-ebpf.bat package_data\scripts +copy %SOURCE_DIR%\scripts\uninstall-ebpf.bat package_data\scripts + +mkdir package_data\testing +copy api_test.exe testing +copy api_test.pdb testing +copy bindmonitor.o testing +copy bindmonitor_ringbuf.o testing +copy bindmonitor_tailcall.o testing +copy bpf.o testing +copy bpf_call.o testing +copy bpftool.pdb testing +copy cgroup_sock_addr.o testing +copy decap_permit_packet.o testing +copy divide_by_zero.o testing +copy droppacket.o testing +copy droppacket_um.dll testing +copy droppacket_um.pdb testing +copy droppacket_unsafe.o testing +copy ebpf_client.exe testing +copy ebpf_client.pdb testing +copy EbpfApi.pdb testing +copy ebpfnetsh.pdb testing +copy encap_reflect_packet.o testing +copy map.o testing +copy map_in_map.o testing +copy map_in_map_v2.o testing +copy map_reuse.o testing +copy map_reuse_2.o testing +copy printk.o testing +copy printk_unsafe.o testing +copy reflect_packet.o testing +copy run_tests.bat testing +copy sample_ebpf_ext.sys testing +copy sample_ext_app.exe testing +copy sample_ext_app.pdb testing +copy tail_call.o testing +copy tail_call_bad.o testing +copy tail_call_map.o testing +copy tail_call_multiple.o testing +copy test_sample_ebpf.o testing +copy test_utility_helpers.o testing +copy unit_tests.exe testing +copy unit_tests.pdb testing + +robocopy /E /IS %SOURCE_DIR%\include package_data\include + +mkdir package_data\include\libbpf +robocopy /E /IS %SOURCE_DIR%\external\bpftool\libbpf\include\asm package_data\include\libbpf\asm +robocopy /E /IS %SOURCE_DIR%\external\bpftool\libbpf\include\linux package_data\include\libbpf\linux +robocopy /E /IS %SOURCE_DIR%\external\bpftool\libbpf\include\uapi package_data\include\libbpf\uapi + +exit /b 0 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..dc1c669bd --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_subdirectory("api_test") +add_subdirectory("libs") +add_subdirectory("bpf2c_tests") +add_subdirectory("performance") +add_subdirectory("xdp") +add_subdirectory("unit") diff --git a/tests/api_test/CMakeLists.txt b/tests/api_test/CMakeLists.txt new file mode 100644 index 000000000..9ae6be649 --- /dev/null +++ b/tests/api_test/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("api_test" + api_test.cpp +) + +target_include_directories("api_test" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/tests/end_to_end" + "${CMAKE_SOURCE_DIR}/tests/libs/util" + "${CMAKE_SOURCE_DIR}/tests/libs/common" + "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/libs/Platform" + "${CMAKE_SOURCE_DIR}/libs/Platform/user" + "${CMAKE_SOURCE_DIR}/libs/thunk" + "${CMAKE_SOURCE_DIR}/netebpfext" +) + +target_link_libraries("api_test" PRIVATE + "ebpf_for_windows_cpp_settings" + "common_tests" + "EbpfApi" + "rpc_interface" + "test_util" + "Catch2::Catch2WithMain" + "ws2_32.lib" +) + +target_compile_definitions("api_test" PRIVATE + _WINSOCK_DEPRECATED_NO_WARNINGS + _CONSOLE +) + +add_test( + NAME "api_test" + COMMAND "${CMAKE_COMMAND}" -E env "PATH=$;$ENV{PATH}" "$" +) diff --git a/tests/bpf2c_tests/CMakeLists.txt b/tests/bpf2c_tests/CMakeLists.txt new file mode 100644 index 000000000..834f9a324 --- /dev/null +++ b/tests/bpf2c_tests/CMakeLists.txt @@ -0,0 +1,148 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("bpf2c_tests" + ../../tools/bpf2c/bpf_code_generator.h + ../../tools/bpf2c/bpf_code_generator.cpp + + bpf_assembler.h + bpf_assembler.cpp + + raw_bpf.cpp + elf_bpf.cpp +) + +target_include_directories("bpf2c_tests" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/tools/bpf2c" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" + "${CMAKE_SOURCE_DIR}/external/ebpf-verifier/src" +) + +target_link_libraries("bpf2c_tests" PRIVATE + "ebpf_for_windows_cpp_settings" + "EbpfApi" + "external::ebpfverifier" + "test_util" + "Catch2::Catch2WithMain" + + # Generated in the bpf2c directory. Required because elf_bpf.cpp + # is including bpf2c.cpp + # + # It would be better not to include the .cpp file like that and instead + # make a library + "bpf2c_driver" + "bpf2c_dll" +) + +target_compile_definitions("bpf2c_tests" PRIVATE + _CONSOLE + BPF2C_VERBOSE +) + +target_compile_options("bpf2c_tests" PRIVATE + "/WX-" +) + +configure_file( + bpf_test.cpp + "${CMAKE_CURRENT_BINARY_DIR}/bpf_test.cpp" + COPYONLY +) + +add_test( + NAME "bpf2c_tests" + COMMAND "${CMAKE_COMMAND}" -E env "PATH=$;$ENV{PATH}" "$" +) + +set(expected_file_list + bindmonitor_dll.txt + bindmonitor_raw.txt + bindmonitor_ringbuf_dll.txt + bindmonitor_ringbuf_raw.txt + bindmonitor_ringbuf_sys.txt + bindmonitor_sys.txt + bindmonitor_tailcall_dll.txt + bindmonitor_tailcall_raw.txt + bindmonitor_tailcall_sys.txt + bpf_call_dll.txt + bpf_call_raw.txt + bpf_call_sys.txt + bpf_dll.txt + bpf_raw.txt + bpf_sys.txt + cgroup_sock_addr_dll.txt + cgroup_sock_addr_raw.txt + cgroup_sock_addr_sys.txt + decap_permit_packet_dll.txt + decap_permit_packet_raw.txt + decap_permit_packet_sys.txt + divide_by_zero_dll.txt + divide_by_zero_raw.txt + divide_by_zero_sys.txt + droppacket_dll.txt + droppacket_raw.txt + droppacket_sys.txt + droppacket_unsafe_dll.txt + droppacket_unsafe_raw.txt + droppacket_unsafe_sys.txt + encap_reflect_packet_dll.txt + encap_reflect_packet_raw.txt + encap_reflect_packet_sys.txt + sockops_dll.txt + sockops_raw.txt + sockops_sys.txt + map_dll.txt + map_in_map_dll.txt + map_in_map_raw.txt + map_in_map_sys.txt + map_in_map_v2_dll.txt + map_in_map_v2_raw.txt + map_in_map_v2_sys.txt + map_raw.txt + map_reuse_2_dll.txt + map_reuse_2_raw.txt + map_reuse_2_sys.txt + map_reuse_dll.txt + map_reuse_raw.txt + map_reuse_sys.txt + map_sys.txt + printk_dll.txt + printk_legacy_dll.txt + printk_legacy_raw.txt + printk_legacy_sys.txt + printk_raw.txt + printk_sys.txt + printk_unsafe_dll.txt + printk_unsafe_raw.txt + printk_unsafe_sys.txt + reflect_packet_dll.txt + reflect_packet_raw.txt + reflect_packet_sys.txt + tail_call_bad_dll.txt + tail_call_bad_raw.txt + tail_call_bad_sys.txt + tail_call_dll.txt + tail_call_map_dll.txt + tail_call_map_raw.txt + tail_call_map_sys.txt + tail_call_multiple_dll.txt + tail_call_multiple_raw.txt + tail_call_multiple_sys.txt + tail_call_raw.txt + tail_call_sys.txt + test_sample_ebpf_dll.txt + test_sample_ebpf_raw.txt + test_sample_ebpf_sys.txt + test_utility_helpers_dll.txt + test_utility_helpers_raw.txt + test_utility_helpers_sys.txt +) + +foreach(expected_file ${expected_file_list}) + configure_file( + "expected/${expected_file}" + "${CMAKE_CURRENT_BINARY_DIR}/${expected_file}" + COPYONLY + ) +endforeach() diff --git a/tests/libs/CMakeLists.txt b/tests/libs/CMakeLists.txt new file mode 100644 index 000000000..e51c7dcf3 --- /dev/null +++ b/tests/libs/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_subdirectory("common") +add_subdirectory("util") \ No newline at end of file diff --git a/tests/libs/common/CMakeLists.txt b/tests/libs/common/CMakeLists.txt new file mode 100644 index 000000000..50412ce07 --- /dev/null +++ b/tests/libs/common/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("common_tests" STATIC + common_tests.cpp + ../../../libs/thunk/windows/platform.cpp +) + +target_include_directories("common_tests" PRIVATE + "${CMAKE_SOURCE_DIR}/tests/libs/util" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/libs/thunk" + "${CMAKE_SOURCE_DIR}/tests/util" + "${CMAKE_SOURCE_DIR}/tests/sample" +) + +target_include_directories("common_tests" SYSTEM INTERFACE + "${CMAKE_SOURCE_DIR}/tests/libs/util" + "${CMAKE_SOURCE_DIR}/tests/libs/common" +) + +target_link_libraries("common_tests" + PRIVATE + "ebpf_for_windows_cpp_settings" + + PUBLIC + "external::libbpf" + "Catch2::Catch2" +) + +target_compile_definitions("common_tests" PRIVATE + _CONSOLE +) diff --git a/tests/libs/util/CMakeLists.txt b/tests/libs/util/CMakeLists.txt new file mode 100644 index 000000000..4e7344ceb --- /dev/null +++ b/tests/libs/util/CMakeLists.txt @@ -0,0 +1,48 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("test_util" STATIC + capture_helper.cpp + + netsh_helper.cpp + + program_helper.h + program_helper.cpp + + service_helper.h + service_helper.cpp + + socket_helper.h + socket_helper.cpp +) + +target_include_directories("test_util" PRIVATE + "${CMAKE_SOURCE_DIR}/libs/api_common" + "${CMAKE_SOURCE_DIR}/libs/ebpfnetsh" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/tests/end_to_end" + "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" + "${CMAKE_SOURCE_DIR}/netebpfext" + "${CMAKE_SOURCE_DIR}/libs/thunk" +) + +target_include_directories("test_util" SYSTEM INTERFACE + "${CMAKE_SOURCE_DIR}/tests/libs/util" + "${CMAKE_SOURCE_DIR}/tests/libs/common" +) + +target_link_libraries("test_util" + PRIVATE + "ebpf_for_windows_cpp_settings" + + PUBLIC + "external::libbpf" + "Catch2::Catch2" +) + +target_compile_definitions("test_util" PRIVATE + _LIB +) diff --git a/tests/performance/CMakeLists.txt b/tests/performance/CMakeLists.txt new file mode 100644 index 000000000..da7c74fd2 --- /dev/null +++ b/tests/performance/CMakeLists.txt @@ -0,0 +1,52 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("ebpf_performance" + performance_measure.h + + ExecutionContext.cpp + platform.cpp + + performance.h + performance.cpp +) + +target_include_directories("ebpf_performance" PRIVATE + "${CMAKE_SOURCE_DIR}/libs/api_common" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/libs/ebpfnetsh" + "${CMAKE_SOURCE_DIR}/tests/libs/util" + "${CMAKE_SOURCE_DIR}/tests/libs/common" + "${CMAKE_SOURCE_DIR}/external/ebpf-verifier/src" + "${CMAKE_SOURCE_DIR}/libs/service" + "${CMAKE_SOURCE_DIR}/rpc_interface" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/tests/end_to_end" + "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm/inc" + "${CMAKE_SOURCE_DIR}/libs/thunk/mock" + "${CMAKE_SOURCE_DIR}/netebpfext" +) + +target_link_libraries("ebpf_performance" PRIVATE + "ebpf_for_windows_cpp_settings" + "execution_context_user" + "platform_user" + "ubpf_user" + "Catch2::Catch2WithMain" + "Mincore.lib" + "external::libbpf" +) + +target_compile_definitions("ebpf_performance" PRIVATE + _CONSOLE +) + +add_test( + NAME "ebpf_performance" + COMMAND "ebpf_performance" +) diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt new file mode 100644 index 000000000..ac2a7901b --- /dev/null +++ b/tests/unit/CMakeLists.txt @@ -0,0 +1,66 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("unit_tests" + ../../libs/execution_context/unit/execution_context_unit_test.cpp + libbpf_test.cpp + + ../../libs/platform/unit/platform_unit_test.cpp + + ../end_to_end/netsh_test.cpp + ../end_to_end/end_to_end.cpp + + ../../libs/thunk/mock/mock.h + ../../libs/thunk/mock/mock.cpp + + ../end_to_end/helpers.h + + ../end_to_end/test_helper.hpp + ../end_to_end/test_helper.cpp +) + +target_include_directories("unit_tests" PRIVATE + "${CMAKE_SOURCE_DIR}/libs/api_common" + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/libs/ebpfnetsh" + "${CMAKE_SOURCE_DIR}/tests/libs/util" + "${CMAKE_SOURCE_DIR}/tests/libs/common" + "${CMAKE_SOURCE_DIR}/external/ebpf-verifier/src" + "${CMAKE_SOURCE_DIR}/libs/service" + "${CMAKE_SOURCE_DIR}/rpc_interface" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/tests/end_to_end" + "${CMAKE_SOURCE_DIR}/tests/sample" + "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" + "${CMAKE_SOURCE_DIR}//tests/xdp" + "${CMAKE_SOURCE_DIR}/tools/encode_program_info" + "${CMAKE_SOURCE_DIR}/libs/thunk" + "${CMAKE_SOURCE_DIR}/libs/thunk/mock" + "${CMAKE_SOURCE_DIR}//netebpfext" +) + +target_link_libraries("unit_tests" PRIVATE + "ebpf_for_windows_cpp_settings" + "api" + "api_common" + "Catch2::Catch2WithMain" + "common_tests" + "netsh_static" + "external::ebpfverifier" + "execution_context_user" + "platform_user" + "rpc_interface" + "service" + "test_util" + "ubpf_user" + "encode_program_info_headers" + "Mincore.lib" +) + +add_test( + NAME "unit_tests" + COMMAND "unit_tests" +) diff --git a/tests/xdp/CMakeLists.txt b/tests/xdp/CMakeLists.txt new file mode 100644 index 000000000..d4bc2d0cc --- /dev/null +++ b/tests/xdp/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("xdp_tests" + xdp_tests.cpp +) + +target_include_directories("xdp_tests" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/libs/execution_context" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/external/ebpf-verifier/src" + "${CMAKE_SOURCE_DIR}/tests/end_to_end" + "${CMAKE_SOURCE_DIR}/tests/libs/util" + "${CMAKE_SOURCE_DIR}/tests/libs/common" + "${CMAKE_SOURCE_DIR}/tests/sample" + "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" +) + +target_link_libraries("xdp_tests" PRIVATE + "ebpf_for_windows_cpp_settings" + "common_tests" + "EbpfApi" + "test_util" + "ws2_32.lib" + "Catch2::Catch2" +) + +target_compile_definitions("xdp_tests" PRIVATE + _CONSOLE + _WINSOCK_DEPRECATED_NO_WARNINGS +) + +add_test( + NAME "xdp_tests" + COMMAND "${CMAKE_COMMAND}" -E env "PATH=$;$ENV{PATH}" "$" +) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 000000000..f198621a3 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_subdirectory("encode_program_info") +add_subdirectory("netsh") +add_subdirectory("bpf2c") +add_subdirectory("dnsflood") +add_subdirectory("port_leak") +add_subdirectory("port_quota") diff --git a/tools/bpf2c/CMakeLists.txt b/tools/bpf2c/CMakeLists.txt new file mode 100644 index 000000000..5fb9c44eb --- /dev/null +++ b/tools/bpf2c/CMakeLists.txt @@ -0,0 +1,82 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("bpf2c" + ../../include/bpf2c.h + ../../external/ebpf-verifier/src/btf_parser.h + + bpf_code_generator.h + bpf_code_generator.cpp + + bpf2c.cpp +) + +target_include_directories("bpf2c" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/external/ubpf/vm" +) + +target_link_libraries("bpf2c" PRIVATE + "ebpf_for_windows_cpp_settings" + "EbpfApi" + "external::ebpfverifier" +) + +target_compile_definitions("bpf2c" PRIVATE + _CONSOLE +) + +codeSign("bpf2c") + +function(generateTemplate source_file_name) + find_program(powershell_path "powershell" REQUIRED) + + set(template_name "${source_file_name}.template") + set(template_path "${CMAKE_CURRENT_BINARY_DIR}/${template_name}") + + add_custom_command( + OUTPUT + "${template_path}" + + COMMAND + "${powershell_path}" -NonInteractive -ExecutionPolicy Unrestricted "${CMAKE_SOURCE_DIR}/scripts/escape_text.ps1" "${CMAKE_CURRENT_SOURCE_DIR}/${source_file_name}.c" "${template_path}" + + VERBATIM + + COMMENT + "ebpf-for-windows - Generating: ${source_file_name}" + + WORKING_DIRECTORY + "${CMAKE_CURRENT_BINARY_DIR}" + ) + + add_custom_target("${source_file_name}_builder" + DEPENDS "${template_path}" + ) + + add_library("${source_file_name}" INTERFACE) + target_include_directories("${source_file_name}" INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}" + ) + + add_dependencies("${source_file_name}" + "${source_file_name}_builder" + ) +endfunction() + +generateTemplate("bpf2c_driver") +target_link_libraries("bpf2c" PRIVATE + "bpf2c_driver" +) + +generateTemplate("bpf2c_dll") +target_link_libraries("bpf2c" PRIVATE + "bpf2c_dll" +) + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + install( + TARGETS "bpf2c" + DESTINATION "." + ) +endif() diff --git a/tools/dnsflood/CMakeLists.txt b/tools/dnsflood/CMakeLists.txt new file mode 100644 index 000000000..200d79722 --- /dev/null +++ b/tools/dnsflood/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("dnsflood" + dns_flood.cpp +) + +target_link_libraries("dnsflood" PRIVATE + "ebpf_for_windows_cpp_settings" +) + +target_compile_definitions("dnsflood" PRIVATE + _WINSOCK_DEPRECATED_NO_WARNINGS + _CONSOLE +) diff --git a/tools/encode_program_info/CMakeLists.txt b/tools/encode_program_info/CMakeLists.txt new file mode 100644 index 000000000..6410d1a9a --- /dev/null +++ b/tools/encode_program_info/CMakeLists.txt @@ -0,0 +1,56 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("encode_program_info" + encode_program_info.cpp +) + +target_include_directories("encode_program_info" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/platform" + "${CMAKE_SOURCE_DIR}/libs/platform/user" + "${CMAKE_SOURCE_DIR}/libs/api" + "${CMAKE_SOURCE_DIR}/netebpfext" + "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" +) + +target_link_libraries("encode_program_info" PRIVATE + "ebpf_for_windows_cpp_settings" + "execution_context_user" + "platform_user" + "api_common_headers" + "external::ebpfverifier" + "external::boost" + "Kernel32.lib" + "Mincore.lib" +) + +target_compile_definitions("encode_program_info" PRIVATE + _CONSOLE +) + +# Use encode_program_info to generate the headers +set(encode_program_info_log "${CMAKE_CURRENT_BINARY_DIR}/log.txt") + +add_custom_command( + OUTPUT "${encode_program_info_log}" + COMMAND "$" > "${encode_program_info_log}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + COMMENT "ebpf-for-windows - Running: encode_program_info" + VERBATIM +) + +add_custom_target(encode_program_info_runner + DEPENDS "${encode_program_info_log}" +) + +# Create a target that will export the include path for the generated +# headers when linked against +add_library("encode_program_info_headers" INTERFACE) +add_dependencies("encode_program_info_headers" + "encode_program_info_runner" +) + +target_include_directories("encode_program_info_headers" INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}" +) diff --git a/tools/netsh/CMakeLists.txt b/tools/netsh/CMakeLists.txt new file mode 100644 index 000000000..4ae1083cc --- /dev/null +++ b/tools/netsh/CMakeLists.txt @@ -0,0 +1,50 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_library("ebpfnetsh" SHARED + ../../libs/ebpfnetsh/elf.h + ../../libs/ebpfnetsh/programs.h + ../../libs/ebpfnetsh/tokens.h + + ../../resource/ebpf_resource.rc + ../../libs/thunk/windows/platform.cpp + + resource.h + ebpfnetsh.rc + dllmain.c +) + +target_include_directories("ebpfnetsh" PRIVATE + "${CMAKE_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/libs/ebpfnetsh" + "${CMAKE_SOURCE_DIR}/external/ebpf-verifier/src" + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +target_link_libraries("ebpfnetsh" PRIVATE + "ebpf_for_windows_cpp_settings" + "netsh_static" + "EbpfApi" + "git_commit_id" + "Iphlpapi.lib" + "Netsh.lib" +) + +target_compile_definitions("ebpfnetsh" PRIVATE + EBPFNETSH_EXPORTS + _WINDOWS + _USRDLL +) + +codeSign("ebpfnetsh") + +if(EBPFFORWINDOWS_ENABLE_INSTALL) + # Only install the .dll file, without the .lib + install( + TARGETS "ebpfnetsh" + + RUNTIME + DESTINATION "." + COMPONENT Runtime + ) +endif() \ No newline at end of file diff --git a/tools/port_leak/CMakeLists.txt b/tools/port_leak/CMakeLists.txt new file mode 100644 index 000000000..d0ca3835c --- /dev/null +++ b/tools/port_leak/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("port_leak" + port_leak.cpp +) + +target_link_libraries("port_leak" PRIVATE + "ebpf_for_windows_cpp_settings" + "ws2_32.lib" +) + +target_compile_definitions("port_leak" PRIVATE + _CONSOLE +) diff --git a/tools/port_quota/CMakeLists.txt b/tools/port_quota/CMakeLists.txt new file mode 100644 index 000000000..ba9ee83a4 --- /dev/null +++ b/tools/port_quota/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: MIT + +add_executable("port_quota" + port_quota.cpp +) + +target_link_libraries("port_quota" PRIVATE + "ebpf_for_windows_cpp_settings" + "EbpfApi" + "external::libbpf" +) + +target_include_directories("port_quota" PRIVATE + "${CMAKE_SOURCE_DIR}/include" +) + +target_compile_definitions("port_quota" PRIVATE + _CONSOLE +)