在 eBPF 中,什么时候应该用 bpf_htons、bpf_htonl、bpf_ntohs、bpf_ntohl?
这些 bpf_* 函数是 eBPF 程序中用于字节序转换的辅助函数。它们的作用与标准的 C 库中的 htons、htonl、ntohs、ntohl 类似,但针对 BPF 环境进行了优化或封装。它们用于在主机字节序(Host Byte Order)和网络字节序(Network Byte Order)之间进行转换。
简而言之,当在 BPF 程序中处理网络协议头部(如 IP、TCP、UDP)中的多字节字段时,就需要使用这些函数。
网络协议标准(例如,IPv4、TCP、UDP)规定所有多字节数值(如端口号、IP 地址、校验和等)都必须以网络字节序(大端序,Big-Endian)传输。
备注
bpf_ntohs(Network To Host Short) &bpf_ntohl(Network To Host Long)
其将一个来自网络数据包的 16 位(s - short)或 32 位(l - long)数值从网络字节序转换为主机字节序。
使用场景:
- 读取网络包数据时: 当需要从接收到的网络数据包中提取字段(如 TCP/UDP 端口号、IP 地址、序列号、窗口大小等)并在 BPF 程序内部进行数值比较或计算时。
- 原因: BPF 程序运行在内核中,默认以主机字节序(通常是小端序,但在大端系统上可能是大端序)进行操作和计算。为了正确解释网络数据包中按大端序存储的值,必须进行转换。
备注
bpf_htons(Host To Network Short) &bpf_htonl(Host To Network Long)
其将一个 16 位或 32 位数值从主机字节序转换为网络字节序。
使用场景:
- 修改或生成网络包数据时: 当您的 BPF 程序(例如 XDP/TC 程序)需要修改数据包头部中的多字节字段(如修改目标端口号),或者创建新的网络数据包头部时。
- 原因: 任何写入到数据包中准备发送到网络上的多字节字段,都必须遵循网络标准,以网络字节序(大端序)存储。
| 函数 | 作用 | 字节数 | 使用场景 |
|---|---|---|---|
bpf_ntohs | 网络 –> 主机 | 2 字节(short) | 读取端口号、校验和等。 |
bpf_ntohl | 网络 –> 主机 | 4 字节(long) | 读取 IP 地址、序列号等。 |
bpf_htons | 主机 –> 网络 | 2 字节(short) | 写入/修改端口号等。 |
bpf_htonl | 主机 –> 网络 | 4 字节(long) | 写入/修改 IP 地址等。 |