I want to measure packet latency for my AF-XDP program. I was looking at this reference: https://github.com/xdp-project/xdp-project/blob/master/areas/arm64/xdp_for_tsn.org
and adapted it to this:
SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {
int index = ctx->rx_queue_index;
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
const unsigned long long kstamp = bpf_ktime_get_ns();
if(data - sizeof(unsigned long long) <= data_end) {
ctx->data_meta = ctx->data - sizeof(unsigned long long);
memcpy(&ctx->data_meta, &kstamp, sizeof(unsigned long long));
}
...
}
Access in user-space then happens like this:
static bool process_packet(struct xsk_socket_info *xsk, uint64_t addr, uint32_t len) {
uint8_t *pkt = xsk_umem__get_data(xsk->umem->buffer, addr);
uint8_t *pkt_meta = xsk_umem__get_data(xsk->umem->buffer, addr - sizeof(unsigned long long));
const unsigned long long kstamp = (uint64_t) pkt_meta[7] << 56 | (uint64_t) pkt_meta[6] << 48 | (uint64_t) pkt_meta[5] << 40
| (uint64_t) pkt_meta[4] << 32 | (uint64_t) pkt_meta[3] << 24 | (uint64_t) pkt_meta[2] << 16
| (uint64_t) pkt_meta[1] << 8 | (uint64_t) pkt_meta[0];
...
}
But I am not able to load the XDP-program into the kernel:
Load XDP program...
libbpf: load bpf program failed: Permission denied
libbpf: -- BEGIN DUMP LOG ---
libbpf:
0: (bf) r6 = r1
1: (61) r1 = *(u32 *)(r6 +16)
2: (63) *(u32 *)(r10 -4) = r1
3: (61) r7 = *(u32 *)(r6 +4)
4: (61) r8 = *(u32 *)(r6 +0)
5: (85) call bpf_ktime_get_ns#5
6: (bf) r1 = r8
7: (07) r1 += -8
8: (2d) if r1 > r7 goto pc+3
R0_w=inv(id=0) R1_w=pkt(id=0,off=-8,r=0,imm=0) R6_w=ctx(id=0,off=0,imm=0) R7_w=pkt_end(id=0,off=0,imm=0) R8_w=pkt(id=0,off=0,r=0,imm=0) R10=fp0 fp-8=mmmm????
9: (63) *(u32 *)(r6 +8) = r0
invalid bpf_context access off=8 size=4
processed 10 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
libbpf: -- END LOG --
I mean, this shouldn't be possible - right? Because XDP is all about valid memory accesses and why would an access outside the defined borders data and data_end ever be valid?
Imho it could work if ctx->data_meta is left unchanged - but then I have the problem in user space because I don't know where data_meta is located. Is there any libbpf helper-function to gain access to packet meta data?
It could also be that the access is valid but my range check is wrong...
ctx->data - <something>before adding headroom first, as this would be before the beginning of packet data and therefore out of range indeed. Note that the code you used as an example is described as “pseudo-code”, not necessarily something complete/functional. Does that help? - Qeoleheadroom- what is that? How can I add it? - binaryBigIntdata, e.g. to push new encapsulation headers. Note I didn't have time to read your question in details and I don't know if this is what you need at all. - Qeolebpf_xdp_adjust_metaalways fails (returning< 0). I guess my device driver doesn't support this? - binaryBigInt-EACCES,-EINVALor-ENOTSUPP. The last case would indicate that your driver does not support XDP metadata. - Qeole