I am new to XDP eBPF. I have a BPF program intended to Drop the UDP packets but it's unable to load since it gets rejected by the kernel verifier. Below is the code:
#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";
This is what appears when loading the program:
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!
I figured out the error appears on the UDP check statement if (ip->protocol == IPPROTO_UDP)
, because when I comment the check, it loads up with no errors.
So, what I need to know that, why the kernel verifier is rejecting the UDP check statement (as mentioned earlier), and what can be done to resolve it to solve the error.
Thanks.