我是 XDP eBPF 的新手。我有一个旨在丢弃 UDP 数据包的 BPF 程序,但它无法加载,因为它被内核验证程序拒绝。下面是代码:
#include <linux/bpf.h>
#include <linux/icmp.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("xdp")
int dropper(struct xdp_md *ctx) {
unsigned int ipsize = 0;
void *data = (void *)(unsigned long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
ipsize = sizeof(*eth);
struct iphdr *ip = (struct iphdr *)((char*)ctx->data + ipsize);
if (ip->protocol == IPPROTO_UDP) {
return XDP_DROP;
}
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
这是加载程序时出现的内容:
Prog section 'xdp' rejected: Permission denied (13)!
- Type: 6
- Instructions: 30 (0 over limit)
- License: GPL
Verifier analysis:
0: (7b) *(u64 *)(r10 -16) = r1
1: (b7) r1 = 0
2: (63) *(u32 *)(r10 -20) = r1
last_idx 2 first_idx 0
regs=2 stack=0 before 1: (b7) r1 = 0
3: (79) r1 = *(u64 *)(r10 -16)
4: (61) r1 = *(u32 *)(r1 +0)
5: (7b) *(u64 *)(r10 -32) = r1
6: (79) r1 = *(u64 *)(r10 -16)
7: (61) r1 = *(u32 *)(r1 +4)
8: (7b) *(u64 *)(r10 -40) = r1
9: (79) r1 = *(u64 *)(r10 -32)
10: (7b) *(u64 *)(r10 -48) = r1
11: (b7) r1 = 14
12: (63) *(u32 *)(r10 -20) = r1
13: (79) r1 = *(u64 *)(r10 -16)
14: (61) r1 = *(u32 *)(r1 +0)
15: (61) r2 = *(u32 *)(r10 -20)
16: (0f) r1 += r2
last_idx 16 first_idx 0
regs=4 stack=0 before 15: (61) r2 = *(u32 *)(r10 -20)
17: (7b) *(u64 *)(r10 -56) = r1
18: (79) r1 = *(u64 *)(r10 -56)
19: (71) r1 = *(u8 *)(r1 +9)
invalid access to packet, off=9 size=1, R1(id=1,off=0,r=0)
R1 offset is outside of the packet
processed 20 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
Error fetching program/map!
我发现错误出现在 UDP 检查语句 if 上(ip->protocol == IPPROTO_UDP)
,因为当我评论检查时,它加载时没有错误。
所以,我需要知道的是,为什么内核验证程序拒绝 UDP 检查语句(如前所述),以及可以采取什么措施来解决它以解决错误。
谢谢。