Consume eBPF program flags feature and match Linux behavior for discontiguous frames
mtfriesen opened this issue · 5 comments
- Consume microsoft/ebpf-for-windows#3576 once it is completed
- Prohibit inspection of discontiguous frames unless
BPF_F_XDP_HAS_FRAGS
is set for the program.
I think discontiguous frames may be a bit different than what BPF_F_XDP_HAS_FRAGS
helps with?
It think BPF_F_XDP_HAS_FRAGS
helps in case of jumbo frames when the packet cannot fit in 1 page? (I may be wrong though)
It's really hard to say for certain, because anything definite about the meaning of the flag is GPL-only. That said, the crux of the problem is that eBPF direct packet access is incompatible with virtually-discontiguous buffers, which may arise for a variety of reasons across OS platforms. On Windows in generic XDP mode, buffers may be virtually contiguous because of MDL splits, but may be virtually contiguous across pages within one memory allocation, somewhat unlike XDP on Linux.
I think the best we can do from a cross-platform compat perspective is to honor the intent/reason for the flag, which is to provide a way for programs to opt in to discontiguous frame APIs in general.
https://lpc.events/event/11/contributions/939/attachments/771/1551/xdp-multi-buff.pdf
This states the "current" requirements for XDP:
- BPF Direct-Access for validating correctness
- No paged frames support, data cannot be split across pages
- Read and Write access to the DMA buffers
- Disable jumbo frames (packet < PAGESIZE) loading a BPF program
Based on above, if jumbo frames are not supported, it looks like the whole packet is always expected to be in a virtually contiguous memory. So I think the problem we currently have with multiple MDLs is a Windows specific problem?
Yeah, that slide deck from 2021 has aged, and there has definitely been Linux work in the area since then. That said, yes, the MDL problem is Windows-specific, but again, the problem manifests in a way that is identical to the problem Linux has with their page allocator for packet data. It is simply a problem of virtually discontiguous buffers at the eBPF program layer, though the nitty-gritty details are clearly different within the actual implementations.
Yes we can decide to "reuse" the same flag for a slightly different problem on Windows; I was mainly trying to understand what the real usage of that flag on Linux is.
If we want to implement that flag, I think we will need the following changes:
- Implement new helper functions
bpf_xdp_load_bytes()
andbpf_xdp_store_bytes()
- Enlighten the eBPF programs that it cannot assume the buffer is directly accessible (even if it is not a jumbo packet), and it should use appropriate helper functions to fetch data.