Cilium eBPF-Go在Windows上
Cilium eBPF-Go on Windows

原始链接: https://ebpf-go.dev/contributing/windows/

这份文档概述了`ebpf-go`库中对Windows eBPF (efW)基本交互支持的现状,该库目前仍在开发中。efW具有解释器、JIT和原生驱动程序模式,稳定版本可能会侧重于原生驱动程序。该库利用JIT进行测试。Windows支持需要使用特定于平台的ELF文件和完整的eBPF API的子集,不支持的API函数将返回`ErrNotSupported`。 开发需要一台Windows虚拟机,需要安装Visual Studio和efW运行时。安装efW后,可以在目录中运行`go test`。预编译的二进制文件可能可用。由于C++/Go接口的原因,调试具有挑战性,建议使用WinDbg检查C++代码。测试中的`-trace-log`标志可以启用efW子系统的跟踪以进行调试。efW使用多层错误代码,需要仔细解释Windows系统错误、RPC错误和`errno`值。

Hacker News 最新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Cilium eBPF-Go 在 Windows 上 (ebpf-go.dev) 5 分,作者 tanelpoder,2 小时前 | 隐藏 | 过去 | 收藏 | 讨论 加入我们,参加 6 月 16-17 日在旧金山举办的 AI 初创公司学校! 指导原则 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系我们 搜索:

原文

The library has basic support for interacting with eBPF for Windows (efW). Things are subject to change because eBPF for Windows has not had a stable (signed) release yet.

Differences between Linux and eBPF for Windows

  • eBPF for Windows has three distinct modes of operation: an interpreter, a JIT and a way to compile eBPF to a native Windows driver. The native driver can be signed using the usual mechanisms. It is likely that a stable release of eBPF for Windows will only support native drivers. The library supports both mechanisms, and relies on the JIT for its testsuite. This is because the native Windows driver mechanism still comes with significant downsides.
  • eBPF for Windows has a large user-space component which ebpf-go calls into via dynamic runtime linking. This uses the same infrastructure as CGo but does not require a C toolchain and is therefore trivial to distribute.

Platform specific ELFs

ELFs compiled against Linux and Windows headers are not binary compatible. Add the following to ELFs targeting Windows until there is an official way to declare the platform:

Exported API

The library only supports a subset of the full API on Windows, because the eBPF for Windows runtime doesn't yet or never will support certain features. API which are not supported will return ErrNotSupported. Some interfaces such as Linux-specific link types are removed outright, but this is kept to a minimum since it is very cumbersome for users to deal with API that change based on platform.

Development setup

The port is developed using a Windows VM running on a Linux host. There is a script which automates the Windows installation. After the installation finishes you should be able to SSH to the VM and follow the instructions to clone and build eBPF for Windows. Execute Import-VsEnv (installed by the setup script) to add msbuild to PATH.

Pre-built eBPF for Windows binaries

You may be able to download precompiled binaries from the efW CI/CD pipeline. Look for an artifact called "Build-x64-Debug", which should contain setup-ebpf.ps1 mentioned below.

After compilation finishes you can install the runtime:

(You can pass -Uninstall to the script to remove a previous installation.)

You can now run the Go unit tests of the library:

Tests fail with load ebpfapi.dll: not found

This usually means that either the Windows runtime is not installed or that the efW installation folder is not on the PATH yet. The latter tends to happen when executing tests via ssh, since sshd doesn't pick up changes in the environment without restarting. Restart the service by issuing Restart-Service sshd from a powershell prompt and then re-establish the ssh session.

efW extensions

efW separates the runtime from the implementation of the various hooks / program types. The hooks are shipped as extensions in a separate Windows kernel service. Installing an extension involves two steps:

  1. Installing the extension as a Windows kernel service.
  2. Registering the program type(s) in the "eBPF Store".

For ntosebpfext the setup process looks as follows, assuming the extension has already been built:

Debugging

Debugging on Windows is a bit painful, since we call from Go into ebpfapi.dll which is implemented in C++. There is currently no debugger which understands both C++ and Go.

The most fruitful approach is to use WinDbg. It will catch exceptions in C++ code, give useful backtraces and allows stepping through source code.

Run the WinDbg GUI as an administrator and then open the executable via Ctrl-E. At the prompt you can set a breakpoint on bpf():

This will halt execution once the library calls into bpf() inside ebpfapi.dll. Use the CDB commands or the GUI to navigate.

It may be possible to use CDB to debug via the command line, but this doesn't seem to work via ssh.

Windows trace log

The testmain package has a small bit of instrumentation which enables tracing of the efW subsystem on demand. Simply pass the -trace-log flag when running tests:

Enabling the instrumentation can fail if the tests crashed too often. In that case you can manually stop and remove the tracing entries via the GUI: compmgmt.msc -> "Performance" -> "Data Collector Sets" -> "Event Trace Sessions". Look for sessions containing "ebpf-go". Rebooting might also help.

Interpreting error codes

efW uses several layers of error codes.

  • Windows system error codes and RPC errors are sometimes exposed by exceptions, which appear in the trace log.
  • ebpf_result_t: wraps Windows errors and is returned from "native" efW API.
  • Unix-style errno, as defined by Windows' errno.h: wraps ebpf_result_t and is returned from libbpf and bpf() API. Unfortunately not all errno values line up with Linux. This usually manifests in cryptic Errno(119) errors.

Last updated 2025-03-24
Authored by Lorenz Bauer

联系我们 contact @ memedata.com