Christian Deacon <gamemann@xxxxxxxxxxx> writes: > Hey Toke, > > Thank you for your response! > > Unfortunately, I still haven't been able to get the for loop to work > properly. I've also noticed if I use `iph->ihl * 4` when initializing > the `byte` pointer, it produces the following error: > > ``` > R5 !read_ok > processed 732 insns (limit 1000000) max_states_per_insn 4 total_states > 16 peak_states 16 mark_read 10 > ``` > > It seems I need to use a static size such as `sizeof(struct iphdr)`. > Though, not all packets would have an IP header length of 20 bytes. I've > tried performing checks with the length as well: > > ``` > uint8_t len = iph->ihl * 4; > > if (len < 20) > { > return XDP_DROP; > } > else if (len > 36) > { > return XDP_DROP; > } > > // Setting len to 20 or any other value works fine. > // len = 20; > > uint8_t *byte = data + sizeof(struct ethhdr) + len + l4headerLen; > ``` > > However, no luck. I'm not sure what I can do to make BPF believe this is > safe. Hmm, maybe have a look at Jesper's experiments with getting to the end of the packet: https://github.com/xdp-project/xdp-tutorial/pull/123 https://github.com/xdp-project/xdp-tutorial/pull/124 Not sure if he ended up concluding anything definite about what the best technique is :) > I was also wondering about the following: > > > Use a matching algorithm that doesn't require looping through the > packet byte-by-byte as you're doing now. For instance, you could have a > hash map that uses the payload you're trying to match as the key with an > appropriate chunk size. > > Do you know of any BPF Helper/kernel functions that can hash the > payload? I looked at the BPF Helpers function list, but wasn't able to > find anything for XDP sadly. I would like to attempt to implement > something like this to see if I can avoid for loops since they aren't > working well with BPF from what I've seen. No, there's no direct hashing helper for XDP. I just meant that you could use the (chunk of) the payload directly as a key in a hashmap. Something like: struct hash_key { u8 payload[CHUNK_SIZE]; } int xdp_main(ctx) { struct hash_key lookup_key = {}; int *verdict; [...] memcpy(&lookup_key, ctx->data, CHUNK_SIZE); verdict = bpf_map_lookup_elem(&lookup_key, ...); if (verdict) do_something_with(*verdict); } (You'd still need to convince the verifier that the memcpy from packet data is safe, of course). -Toke