So I've been trying to access the iphdr using eBPF.
static inline int parse_ipv4(void *data, u64 nh_off, void *data_end) {
struct iphdr *iph = data + nh_off;
if ((void*)&iph[1] > data_end)
return 0;
return iph->protocol;
}
When I use the code above in the eBPF function, it works fine like :
if (h_proto == htons(ETH_P_IP)){
index = parse_ipv4(data, nh_off, data_end);
Like this, calling parse_ipv4 function works.
However, if I try to access the ipheader directly without using the function, it doesn't work.
if (h_proto == htons(ETH_P_IP)){
index = parse_ipv4(data, nh_off, data_end);
struct iphdr *iph2 = sizeof(*eth) + nh_off;
}
This gives me an error : HINT: The invalid mem access 'inv' error can happen if you try to dereference memory without first using bpf_probe_read() to copy it to the BPF stack. Sometimes the bpf_probe_read is automatic by the bcc rewriter, other times you'll need to be explicit.
and fails to activate.
Thank you so much in advance!
Unless I misunderstand your program, the following:
struct iphdr *iph2 = sizeof(*eth) + nh_off;
looks erroneous. Instead, iph2
should be something like data + nh_off
, just as in your function, no? If you set it to the sum of two sizes, without any base address, then you try to access data at an arbitrary memory location (something like 0x28
I guess), which of course is not permitted.