Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new neteventebpfext eBPF extension for processing network events. #28

Merged
merged 73 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 68 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
6d1388a
wip
gtrevi Apr 27, 2024
3ca4e4c
wip
gtrevi Apr 28, 2024
1bacb1c
wip
gtrevi Apr 28, 2024
bdd01d5
wip
gtrevi Apr 28, 2024
7ff6f12
fix git_commit_id.h bug
gtrevi Apr 28, 2024
d1b9226
wip
gtrevi Apr 28, 2024
a2648af
wip
gtrevi Apr 30, 2024
f67502b
wip
gtrevi May 2, 2024
fa18f94
full build
gtrevi May 2, 2024
45e996a
Merge remote-tracking branch 'upstream/main' into gtrevi/add-pktmoneb…
gtrevi May 2, 2024
1e2204d
add prog info calls and references fo all bpf projects
gtrevi May 3, 2024
d9e9c5e
wip
gtrevi May 3, 2024
e370f72
sync naming
gtrevi May 3, 2024
ddc1007
dep test
gtrevi May 3, 2024
c7bac76
fix clear-store contention
gtrevi May 3, 2024
729e554
fix
gtrevi May 4, 2024
cd70b4d
fix
gtrevi May 4, 2024
87bb367
add driver management
gtrevi May 4, 2024
2ec716a
Add UM event buffering
gtrevi May 7, 2024
261ef61
nit
gtrevi May 7, 2024
b4a0013
wip
gtrevi May 7, 2024
84dfceb
wip
gtrevi May 7, 2024
c512783
wip
gtrevi May 7, 2024
d940af5
wip
gtrevi May 8, 2024
460fb57
add RAII driver_helper
gtrevi May 9, 2024
ba2b609
add new utils library
gtrevi May 10, 2024
3c31f37
nit fix
gtrevi May 10, 2024
b523b40
fix prog data
gtrevi May 11, 2024
1cf0880
wip
gtrevi May 13, 2024
545f1dc
wip
gtrevi May 15, 2024
b41a8a2
wip
gtrevi May 16, 2024
72632a0
wip
gtrevi May 16, 2024
6ae9659
wip
gtrevi May 16, 2024
6dda8ff
wip
gtrevi May 17, 2024
e7849bc
rename
gtrevi May 17, 2024
de2f446
wip
gtrevi May 17, 2024
6eea960
wip
gtrevi May 21, 2024
c3f7849
wip
gtrevi May 21, 2024
8fea9d2
wip
gtrevi May 22, 2024
341bd1c
wip
gtrevi May 22, 2024
229afde
add event interval configuration in registry
gtrevi May 22, 2024
712badc
wip
gtrevi May 22, 2024
887873d
wip
gtrevi May 22, 2024
799f3a4
wip
gtrevi May 23, 2024
105c5c7
wip
gtrevi May 23, 2024
980ecfe
wip
gtrevi May 24, 2024
0a0fabe
cleanup
gtrevi May 24, 2024
6231521
merge main
gtrevi May 28, 2024
058c7be
sync sln
gtrevi May 28, 2024
a906620
wip
gtrevi May 28, 2024
b3303ce
wip
gtrevi May 28, 2024
c9c7f3a
wip
gtrevi May 28, 2024
5d17bef
wip
gtrevi May 29, 2024
c3b7532
wip
gtrevi May 29, 2024
71884c6
wip
gtrevi May 31, 2024
53b6c6f
update NPI
gtrevi May 31, 2024
44e6efa
fix analyzer warning
gtrevi Jun 1, 2024
10596ee
update netevent
gtrevi Jun 3, 2024
85bc10a
add docs
gtrevi Jun 3, 2024
556e85e
revise NPI
gtrevi Jun 4, 2024
3436ad9
doc
gtrevi Jun 4, 2024
df0023e
Merge branch 'microsoft:main' into gtrevi/add-pktmonebpfext
gtrevi Jun 4, 2024
afc7eb8
doc, update npiid, mem optimizations
gtrevi Jun 4, 2024
1c133cd
add dynamic buffer optimization
gtrevi Jun 5, 2024
84f93ee
cleanup
gtrevi Jun 5, 2024
602a805
feedback
gtrevi Jun 6, 2024
47b4d01
add load/unload tests
gtrevi Jun 6, 2024
5aeb2f9
fix
gtrevi Jun 6, 2024
3711617
workaround ebpf issue #2667
gtrevi Jun 6, 2024
da025df
add new function in tracelog library, misc
gtrevi Jun 7, 2024
caa71d2
consolidate macros in library header
gtrevi Jun 7, 2024
39471aa
tracing
gtrevi Jun 7, 2024
4c0d873
Merge branch 'microsoft:main' into gtrevi/add-pktmonebpfext
gtrevi Jun 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ jobs:
environment: windows-2022
capture_etw: true

# Run the neteventebpfext unit tests in GitHub.
neteventebpfext_units:
# Always run this job.
needs: regular
if: github.event_name == 'schedule' || github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch'
uses: ./.github/workflows/reusable-test.yml
with:
name: neteventebpfext unit tests
pre_test: powershell -file .\Install-eBpfForWindows.ps1 0.16.0
test_command: .\neteventebpfext_unit.exe -d yes
build_artifact: Build-x64
environment: windows-2022
code_coverage: true
gather_dumps: true
capture_etw: true
leak_detection: true

ossar:
# Always run this job.
needs: regular
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/reusable-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ jobs:
run: |
.\ntos_ebpf_ext_export_program_info.exe --clear
.\ntos_ebpf_ext_export_program_info.exe
.\netevent_ebpf_ext_export_program_info.exe --clear
.\netevent_ebpf_ext_export_program_info.exe

- name: Run pre test command
if: steps.skip_check.outputs.should_skip != 'true' && (inputs.environment != 'ebpf_cicd_tests_ws2019' && inputs.environment != 'ebpf_cicd_tests_ws2022' && inputs.environment != 'ebpf_cicd_perf_ws2022')
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# NTOS eBPF Extensions

An [eBPF for Windows](https://github.com/microsoft/ebpf-for-windows) extension that permits developers to leverage existing public
This repository contains source code libraries for accelerating the development of eBPF extensions for Windows, as they are documented in the [eBPF for Windows - eBPF extensions](https://github.com/microsoft/ebpf-for-windows/blob/main/docs/eBpfExtensions.md) documentation.

The following eBPF extensions are included in this repository:

- `ntosebpfext`: An eBPF extension that permits developers to leverage existing public
hooks in the Windows kernel to gather data and influence policy of the OS.

- [`neteventebpfext`](./docs/neteventebpfext.md): An eBPF extension that attaches to network events sourced by [NMR Provider Modules](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/initializing-and-registering-a-provider-module) that implement the `neteventebpfext`'s Network Provider Interface (NPI).

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Expand Down
169 changes: 169 additions & 0 deletions docs/neteventebpfext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Net Event eBPF Extension (neteventebpfext)

## Introduction

Thi extension provides a way to capture network events generated from kernel components using eBPF. The extension is built on top of
the [eBPF for Windows](https://github.com/microsoft/ebpf-for-windows), as per the [eBPF Extensions](https://github.com/microsoft/ebpf-for-windows/blob/main/docs/eBpfExtensions.md) model,
and leverages the library files from this repo.

## Getting Started

### Prerequisites

- eBPF for Windows must be installed. Please follow the instructions in the [eBPF for Windows - Getting started](https://github.com/microsoft/ebpf-for-windows/blob/main/docs/GettingStarted.md)
guide to install the eBPF for Windows components on a test-enabled Windows machine/VM.

### Building & Testing the extension

After cloning the repository, make sure to initialize the submodules by running the following command from the root of the repository:

```bash
.\scripts\initialize_repo.ps1
```

Then, build the `ntosebpfext.sln` solution from the root of the repository, by running the following command:

```bash
msbuild ntosebpfext.sln /p:Configuration=Debug /p:Platform=x64
```

To regards of this extension, the following artifacts will be generated in the `x64\Debug` (in this case) directory:

- `netevent_ebpf_ext_export_program_info.exe` - A user-mode cmdlet that exports the eBPF program information to the eBPF store.
- `neteventebpfext.sys` - The driver that loads the eBPF program and attaches it to the network events.
- `nteevent_sim.sys` - The driver that simulates network events.
- `netevent_monitor.sys` - The native eBPF program that will be invoked by the `neteventebpfext` extension upon receiving network events,
which will store them in a ring-buffer map.
- `neteventebpfext_unit.exe` - An end-to-end unit test that includes a user-mode application that reads the network events from the ring buffer.
The test will generate network events using the `netevent_sim` driver, which will flow through the `neteventebpfext` extension and into the
`netevent_monitor` eBPF program, which will store the events in the ring buffer map.

#### Testing

To run the end-to-end unit test, you can use the `neteventebpfext_unit.exe` application as follows:

```bash
# Required only if the eBPF program information is not exported yet
netevent_ebpf_ext_export_program_info.exe

# Run the test with debugging enabled
neteventebpfext_unit.exe -d yes
```

This test will perform the following steps:

1. Export the eBPF program info to the eBPF Store (located in System's registry, under `HKCU\Software\eBPF`).
1. Load & start the `nteevent_sim.sys` driver.
1. Load & start the `neteventebpfext.sys` driver.
1. Load and attach the `netevent_monitor.sys` eBPF program.
1. Register a callback to read the network events from the ring buffer.
1. Display the network events generated by the `nteevent_sim` driver.
1. Stop and unload all the drivers.

## Installing the extension

Once generated the artifacts, to deploy the extension you need to:

- Export the eBPF program to the system's eBPF store using the `netevent_ebpf_ext_export_program_info.exe` application:

```bash
netevent_ebpf_ext_export_program_info.exe --clear # Mainly, to clear-out any previous eBPF program information related to this program type.
netevent_ebpf_ext_export_program_info.exe
```

- Load and start the `neteventebpfext.sys` eBPF extension driver which will enable loading eBPF programs of type `netevent_monitor`
and attaching the to the network event source:

```bash
sc create neteventebpfext type=kernel start=demand binPath=neteventebpfext.sys
sc start neteventebpfext
```

## Development

[eBPF for Windows Extensions](https://github.com/microsoft/ebpf-for-windows/blob/main/docs/eBpfExtensions.md) use
the [Network Module Registar (NMR)](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/network-module-registrar2)
to interact with the eBPF programs (through eBPF Core), and NMR providers. The `neteventebpfext` extension is an implementation of
an Network Provider Interface (NPI) client that attaches to the network events sourced by providers its same NPI.

### Writing an eBPF program that attaches to the `neteventebpfext` extension

The simplest way to write an eBPF program that attaches to the network events is to review the `netevent_monitor.c` eBPF program that is
provided in the `\tools\netevent_monitor` project. This program will store the network events in a ring buffer map.

The Network Provider Interface (NPI) in `include\ebpf_netevent_hooks.h`defines the following structure for the network events:

```c
typedef struct
{
unsigned char* event_data_start; ///< Pointer to start of the data associated with the event.
unsigned char* event_data_end; ///< Pointer to end of the data associated with the event (i.e. first byte *outside*
///< the memory range).
} netevent_event_info_t;
```

To write your own eBPF program, you must create your own project (similar to the `netevent_monitor` project) and define a section
of type `netevent_monitor` in your eBPF program. The `netevent_monitor` section is used by the `neteventebpfext` extension to attach
the eBPF program to the network events.

```c
#include "ebpf_helpers.h"
#include "ebpf_netevent_hooks.h" // For the netevent_event_md_t and netevent_event_hook_t definitions.

// Define any eBPF maps that you need here
struct
{
//... my_map members
} my_map SEC(".maps");

// The following line is optional, but is used to verify
// that the MyNetEventHandler prototype is correct or the compiler
// would complain when the function is actually defined below.
netevent_event_hook_t MyNetEventHandler;

// Define the eBPF program that will be attached to the network events.
SEC("netevent_monitor")
int
MyNetEventHandler(netevent_event_md_t* ctx)
{
// Your eBPF program logic here

return 0;
}
```

The extension supports attaching multiple eBPF programs (as NPI clients), to which the network events will be dispatched.

### Writing an NMR provider that generates network events

Under `tools\netevent_sim`, you can find a simple NMR provider that generates demo network events, with detailed comments.
The provider is implemented as a native kernel driver and showcases how to register itself to the NMR as an NPI provider and generate network events using the NMR API through a configurable kernel timer.

In `ebpf_extensions\neteventebpfext\netevent_ebpf_ext_event.c` you can find the definition of NPIID to be used by the NMR provider,
along with the dispatch table exported by the eBPF extension as an NMR client:

```c
const NPIID netevent_npiid = {0x2227e819, 0x8d8b, 0x11d4, {0xab, 0xad, 0x00, 0x90, 0x27, 0x71, 0x9e, 0x09}};
```

The dispatch table for the network events provider is defined in `ebpf_extensions\neteventebpfext\netevent_ebpf_ext_event.c` as follows:

```c
typedef struct _ebpf_helper_function_addresses
{
ebpf_extension_header_t header; ///< Common eBPF For Windows Extension header.
UINT32 helper_function_count; ///< Number of helper functions in the dispatch table.
UINT64* helper_function_address; ///< Array of helper function addresses.
} ebpf_helper_function_addresses_t;
```

Currently, the `neteventebpfext` extension supports the following helper function (which will so be the only element in the `helper_function_address` array):

```c
void _ebpf_netevent_push_event(_In_ netevent_event_md_t* netevent_event)
```

This function will dispatch the network event to all the eBPF programs attached to the extension.

For a more in-depth understanding of NMR and how to develop NPI providers & clients, please refer to the
[Network Module Registar (NMR) documentation](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/network-module-registrar2).
Loading
Loading