#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <netinet/in.h>
#include <linux/udp.h>
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/pkt_cls.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_perf_event.h>
#include <netinet/in.h>
struct bpf_map_def SEC("maps") timestamp_map = {
.type = BPF_MAP_TYPE_PERCPU_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(uint64_t),
.max_entries = 1,
};
SEC("filter")
int icmp_timestamp(struct __sk_buff *skb) {
void *data_end = (void *)(long)skb->data_end;
void *data = (void *)(long)skb->data;
struct ethhdr *eth = data;
if (eth->h_proto == htons(ETH_P_IP)) {
struct iphdr *ip = data + sizeof(struct ethhdr);
if (ip->protocol == IPPROTO_ICMP) {
uint64_t timestamp = bpf_ktime_get_ns();
int key = 0;
bpf_map_update_elem(×tamp_map, &key, ×tamp, BPF_ANY);
return XDP_PASS;
}
}
return XDP_DROP;
}
char _license[] SEC("license") = "GPL";
#Here is the bpf source code. I have compiled the above source code successfully but I was unable to load it into the kernel. The command I used to load the compiled source code was sudo bpftool prog load name_of_code.o /sys/fs/bpf/name_of_code
#And also the error i am encountering with is
libbpf: prog 'icmp_timestamp': BPF program load failed: Permission denied
libbpf: prog 'icmp_timestamp': -- BEGIN PROG LOAD LOG --
reg type unsupported for arg#0 function icmp_timestamp#26
0: R1=ctx(off=0,imm=0) R10=fp0
; void *data = (void *)(long)skb->data;
0: (61) r1 = *(u32 *)(r1 +76)
invalid bpf_context access off=76 size=4
processed 1 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
libbpf: prog 'icmp_timestamp': failed to load: -13
libbpf: failed to load object 'rocode.o'
Error: failed to load object file
TL;DR. Your context should be
struct xdp_md *xdp
instead ofstruct __sk_buff *skb
.Note you will also need to check that your packet is big enough to read at the offsets you want. For example:
I'd also recommend to pass the program type to bpftool:
Explanation
Your program was rejected by the BPF verifier. We can know that because verifier logs are printed (the bits with the bytecode).
Here, it's saying that the second access to the context argument (
skb->data
) is trying to load memory from an incorrect offset into the context memory. That's the context offset you're loading from doesn't match what the verifier expects.Seeing the return codes you used, I'm guessing you're trying to use a program of type XDP. In that case, the context should be of type
struct xdp_md
.