|
wired
libc-free QUIC/HTTP3 SDK in C for x86_64-linux
|
AF_XDP socket setup: socket(2)/setsockopt(2)/getsockopt(2)/mmap(2)/bind(2) sequence that turns a raw AF_XDP fd into four ready-to-poll SPSC rings (fill/comp/rx/tx) over one UMEM. More...
Go to the source code of this file.
Data Structures | |
| struct | xsk_cfg |
| Caller-supplied configuration for one AF_XDP socket. More... | |
| struct | xsk |
| One open AF_XDP socket: the fd, its UMEM, the four rings, and the mmap regions backing them (kept so xsksetup_close can munmap them). More... | |
Macros | |
| #define | XSKSETUP_UMEM_FRAMES 1024u |
| Fixed capacity: one UMEM frame per fill/comp/rx/tx ring entry slot count below, matching xskumem's XSKUMEM_FRAMES (1024 frames of 2048B = 2MiB). | |
| #define | XSKSETUP_FRAME_SIZE 2048u |
| Byte size of one UMEM frame, matching xskumem's XSKUMEM_FRAME_SIZE. | |
| #define | XSKSETUP_UMEM_LEN ((u64)XSKSETUP_UMEM_FRAMES * XSKSETUP_FRAME_SIZE) |
| Total UMEM byte length. | |
| #define | XSKSETUP_RX_POOL_FRAMES 256u |
| Number of UMEM frames (0..XSKSETUP_RX_POOL_FRAMES) reserved for the kernel's fill/RX side (xsksetup_prime_fill). | |
| #define | XSKSETUP_RING_ENTRIES 64u |
| Entries per ring (fill/comp/rx/tx), must be a power of two. | |
Functions | |
| i64 | xsksetup_open (xsk *x, const xsk_cfg *cfg) |
| Open one AF_XDP socket bound to cfg->ifindex/queue_id: socket -> UMEM anonymous mmap -> XDP_UMEM_REG -> ring size setsockopts -> XDP_MMAP_OFFSETS -> mmap the four rings -> xskring_init each -> bind -> prime the fill ring with all RX-pool frames. | |
| void | xsksetup_close (xsk *x) |
| Tear down x: munmap every ring region and the UMEM, close the fd. | |
| i64 | xsksetup_kick_tx (i64 fd) |
| Wake the kernel to service the TX ring (sendto with no data, matching the driver's XDP_COPY bind mode which needs an explicit kick). | |
| i64 | xsksetup_stats (i64 fd, u64 out[6]) |
| Read XDP_STATISTICS into out[6]: rx_dropped, rx_invalid_descs, tx_invalid_descs, rx_ring_full, rx_fill_ring_empty_descs, tx_ring_empty_descs (linux/if_xdp.h struct xdp_statistics order). | |
AF_XDP socket setup: socket(2)/setsockopt(2)/getsockopt(2)/mmap(2)/bind(2) sequence that turns a raw AF_XDP fd into four ready-to-poll SPSC rings (fill/comp/rx/tx) over one UMEM.
Everything above this layer (ring op / frame parse / bpf) is pure and already tested; this file is only the syscall plumbing that wires those parts to the kernel.
| #define XSKSETUP_RX_POOL_FRAMES 256u |
Number of UMEM frames (0..XSKSETUP_RX_POOL_FRAMES) reserved for the kernel's fill/RX side (xsksetup_prime_fill).
The remainder (XSKSETUP_UMEM_FRAMES - XSKSETUP_RX_POOL_FRAMES) is the server's TX pool (srvxdp's SRVXDP_TXPOOL_FRAMES). Skewed toward TX: an HTTP/3 server mostly transmits (response bodies) and rarely needs many RX frames in flight at once.
| #define XSKSETUP_UMEM_FRAMES 1024u |
Fixed capacity: one UMEM frame per fill/comp/rx/tx ring entry slot count below, matching xskumem's XSKUMEM_FRAMES (1024 frames of 2048B = 2MiB).
A 1MB file at a ~1400B QUIC packet size needs ~750 in-flight TX frames; the prior 128-frame UMEM (64 TX) stalled on txpool exhaustion well before that (observed as xdp_statistics.tx_ring_empty_descs = 14352 on a real VPS run). 1024 gives headroom above that without growing the mmap past a few MiB.
| #define XSKSETUP_UMEM_LEN ((u64)XSKSETUP_UMEM_FRAMES * XSKSETUP_FRAME_SIZE) |
Total UMEM byte length.
Cast to u64 before multiplying: both operands are u32, and a plain u32*u32 product then gets implicitly widened when used as a u64 length/offset (bugprone-implicit-widening-of-multiplication-result). The current constants fit in 32 bits either way, but computing the product in the target width is what the mmap length/UMEM offset math needs.
| void xsksetup_close | ( | xsk * | x | ) |
Tear down x: munmap every ring region and the UMEM, close the fd.
Safe to call twice (a second call is a no-op: fd is left at -1 after the first).
Open one AF_XDP socket bound to cfg->ifindex/queue_id: socket -> UMEM anonymous mmap -> XDP_UMEM_REG -> ring size setsockopts -> XDP_MMAP_OFFSETS -> mmap the four rings -> xskring_init each -> bind -> prime the fill ring with all RX-pool frames.
On any failure, everything allocated so far is unwound and a negative errno is returned.
| x | zero-initialized output; filled in on success |
| cfg | ifindex/queue_id/bind_flags |