WSL2 编译内核支持 ebpf & xdp

  • wsl2 更换内核,支持完整 ebpf

  • 资料来源:

    • https://gist.github.com/MarioHewardt/5759641727aae880b29c8f715ba4d30f
    • https://massoudasadiblog.blogspot.com/2024/07/ebpf-on-wsl2-kernel-version-6x-ubuntu.html
  • 更新

    1
    2
    3
    2024.09.08 初始
    2024.09.08 补充 docker
    2024.10.01 补充完整编译 libxdp 流程

导语

要不然说 win11 是最好的 linux 发行版, 最近工作都是基于 xdp, 寻思在 wsl2 下也搭建个测试环境. 微软已经做好了 😊🤣.

正文

wsl2 的 定制内核 目前已经升级到了 6.6.36.6 具备完整的 ebpf 支持, 但是尚未添加到 wsl2 --update 下. 因此需要做的就是自行编译 6.6.36.6 版本内核, 在 wsl.config 中指定新的内核,以新内核启动就能获得对 ebpf 的完整支持.

主要参考这一篇, eBPF on WSL2 [kernel version 6.x] [Ubuntu] [x64] [Arm64] [2024], 下文是在其基础上的记录:

编译启动自定义内核

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sudo apt update && sudo apt upgrade
# 工具链
sudo apt update && sudo apt install build-essential flex bison libssl-dev libelf-dev bc python3 pahole

# 获取 6.36.6 源码
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git --depth=1 -b linux-msft-wsl-6.6.36.6
cd WSL2-Linux-Kernel

# 将 bpf 的配置合并进入 kconfig
./scripts/kconfig/merge_config.sh Microsoft/config-wsl tools/testing/selftests/bpf/config

# 编译内核 时间可能需要蛮久的 | V=1 防止无聊
make -j$(nproc) KCONFIG_CONFIG=Microsoft/config-wsl V=1
# 安装 modules
sudo make modules_install headers_install

# 内核镜像拷贝到 host 这里是 c 盘的根目录了
cp arch/x86/boot/bzImage /mnt/c/

接下来需要指定 wsl2 启动的内核

  • 编辑 .wslconfig 指定 kernel 位置 kernel=C:\\Image
1
2
[wsl2]
kernel=C:\\bzImage
  • 最后 wsl --shutdown 当当当, 再次 uname -r 即可以看到新的内核启动了.

编译 xdp-tools

正常 ebpf / xdp 开发, 还需要安装对应的配置工具和内核头文件

1
2
3
4
# 各种编译工具 注意这里不包含 libbpf 和 libxdp, 这两个是后面自行编译的, 源内的的版本有点太老了
sudo apt install linux-libc-dev clang llvm libelf-dev libpcap-dev build-essential libc6-dev-i386 libcap-ng-dev libbfd-dev
#
sudo apt install linux-tools-common

xdp-tools 是一个大杂烩, 不仅包括了 libxdp 还有一系列的 xdp 辅助工具, 后面会一一介绍, 这里仅编译安装.

1
2
3
4
5
6
# 下载 xdp-tools
git clone https://github.com/xdp-project/xdp-tools.git
cd xdp-tools

# 加载 libbpf 源码等
git submodule init && git submodule update

先编译安装 libbpf

1
2
3
4
cd xdp-tools/lib/libbpf
cd src
make
sudo make install

此时回到 xdp-tools 目录看看支持情况

  • bpftool 可以回到 WSL2-Linux-Kernel/tools/bpf/bpftool 编译安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ./configure
Found clang binary 'clang-12' with version 12 (from 'Ubuntu clang version 12.0.0-3ubuntu1~20.04.5')
bpftool not found or doesn't support skeleton generation; not building all tools
libbpf support: system v0.5.0
perf_buffer__consume support: yes
btf__load_from_kernel_by_id support: yes
btf__type_cnt support: no
bpf_object__next_map support: no
bpf_object__next_program support: no
bpf_program__insn_cnt support: no
bpf_program__type support: no
bpf_program__flags support: no
bpf_program__expected_attach_type support: no
bpf_map_create support: no
perf_buffer__new_raw support: yes
bpf_xdp_attach support: no
bpf_map__set_autocreate support: no
bpf_prog_test_run_opts support: yes
bpf_xdp_query support: no
secure_getenv support: yes
cap-ng support: yes

可以继续编译并安装了

1
2
make
sudo make install

安装完成后可以 xdp-loader 验证下网卡对 xdp 的支持情况, wsl2 下的网卡只支持基本的功能, 但是调试和学习足够了.

1
2
3
4
5
6
7
8
9
$ sudo xdp-loader features eth0
[sudo] password for js:
NETDEV_XDP_ACT_BASIC: yes
NETDEV_XDP_ACT_REDIRECT: yes
NETDEV_XDP_ACT_NDO_XMIT: yes
NETDEV_XDP_ACT_XSK_ZEROCOPY: no
NETDEV_XDP_ACT_HW_OFFLOAD: no
NETDEV_XDP_ACT_RX_SG: no
NETDEV_XDP_ACT_NDO_XMIT_SG: no

其他

如果是自行编辑的 kernel 的 kconfig 文件, 可能出现安装 docker 后无法启动问题 -> https://github.com/microsoft/WSL/issues/11742#issuecomment-2272557613

  • 在编译镜像时候将多个模块直接编译进入内核
1
2
3
4
5
6
7
CONFIG_BRIDGE=y
CONFIG_BRIDGE_NETFILTER=y
CONFIG_NFT_COMPAT=y
CONFIG_NETFILTER_XT_NAT=y
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y

另一个相关的 issue: https://github.com/docker/for-win/issues/13638