我正在尝试检测带有 VLAN 标签的数据包。我有一些 PCAP 文件包含要测试的 VLAN 标记数据包。示例数据包的 Wireshark 屏幕截图:
在阅读了一些教程后,我编写了以下代码:
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/in.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
#define bpf_printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})
SEC("xdpvlan")
int myxdpprogram(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if ((void*)eth + sizeof(*eth) <= data_end) {
bpf_printk("h_proto is: 0x%x, ETH_P_8021Q is: 0x%x\n", bpf_ntohs(eth->h_proto), ETH_P_8021Q);
}
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
中的输出/sys/kernel/debug/tracing/trace
是这样的:
bpf_trace_printk: h_proto is: 0x800, ETH_P_8021Q is: 0x8100
我期望:
bpf_trace_printk: h_proto is: 0x8100, ETH_P_8021Q is: 0x8100
我正在使用 Fedora 34 进行测试,内核版本:5.11.12-300.fc34.x86_64
. 为什么h_proto
不等于0x8100
?
更新
我有两台虚拟机,我tcpreplay
用来将数据包(PCAP 文件)从一个虚拟机发送到另一个具有 eBPF 程序的虚拟机。虚拟机通过仅主机接口连接。我使用以下方法加载程序:
ip link set dev ens37 xdpgeneric obj xdp_vlan_kern.o sec xdpvlan