Token bucket rate limiting helpers for BPF programs.
Provides comprehensive token bucket rate limiting implementation for XDP/TC programs. Common use cases include:
Token Bucket Algorithm:
Data Structures:
Usage: (require '[clj-ebpf.rate-limit :as rl])
;; Build rate limit check (rl/build-rate-limit-check config-map-fd 0 bucket-map-fd -16 -48 :pass :drop)
Token bucket rate limiting helpers for BPF programs.
Provides comprehensive token bucket rate limiting implementation
for XDP/TC programs. Common use cases include:
- Source IP rate limiting (DDoS protection)
- Backend rate limiting (overload protection)
- API rate limiting
- Connection rate limiting
Token Bucket Algorithm:
1. Each bucket has: tokens (current count), last_update (timestamp)
2. Config has: rate (tokens per second), burst (max tokens)
3. On each packet:
a. Calculate elapsed time since last_update
b. Add new tokens: elapsed_ns * rate / 1e9
c. Cap tokens at burst
d. If tokens >= 1, consume and allow
e. Else, rate limit (drop)
Data Structures:
- Config map (array): 16 bytes per entry (rate: 8, burst: 8)
- Bucket map (LRU hash): 16 bytes per entry (tokens: 8, last_update: 8)
- Token scale: 1000 (for sub-second precision)
Usage:
(require '[clj-ebpf.rate-limit :as rl])
;; Build rate limit check
(rl/build-rate-limit-check
config-map-fd 0 bucket-map-fd -16 -48 :pass :drop)(build-rate-limit-check config-map-fd
config-index
bucket-map-fd
key-stack-off
scratch-stack-off
skip-label
drop-label)Generate BPF instructions for token bucket rate limit check.
Implements token bucket algorithm:
Args: config-map-fd: FD for rate_limit_config array map config-index: Index in config map (e.g., 0 for source, 1 for backend) bucket-map-fd: FD for bucket LRU hash map key-stack-off: Stack offset where lookup key is stored scratch-stack-off: Stack offset for scratch space (needs 32 bytes) skip-label: Label to jump to if rate limiting disabled/passed drop-label: Label to jump to if rate limited
Register usage: r0: Scratch, return values r1-r5: Helper call arguments r6: Saved bucket pointer r7: Saved tokens value r8: Rate/config values r9: Burst/temp values
Stack usage (relative to scratch-stack-off): offset 0-7: config index for lookup offset 8-15: new bucket initialization (tokens) offset 16-23: new bucket initialization (last_update)
Returns: Vector of instructions/pseudo-instructions
Generate BPF instructions for token bucket rate limit check. Implements token bucket algorithm: 1. Load config from config-map at config-index 2. If rate == 0, skip (rate limiting disabled) 3. Load/create bucket from bucket-map using key at key-stack-off 4. Calculate elapsed time since last update 5. Add tokens: new_tokens = old_tokens + elapsed_us * rate / 1e6 6. Cap at burst 7. If tokens >= TOKEN-SCALE (1 token), consume and continue 8. Else jump to drop-label Args: config-map-fd: FD for rate_limit_config array map config-index: Index in config map (e.g., 0 for source, 1 for backend) bucket-map-fd: FD for bucket LRU hash map key-stack-off: Stack offset where lookup key is stored scratch-stack-off: Stack offset for scratch space (needs 32 bytes) skip-label: Label to jump to if rate limiting disabled/passed drop-label: Label to jump to if rate limited Register usage: r0: Scratch, return values r1-r5: Helper call arguments r6: Saved bucket pointer r7: Saved tokens value r8: Rate/config values r9: Burst/temp values Stack usage (relative to scratch-stack-off): offset 0-7: config index for lookup offset 8-15: new bucket initialization (tokens) offset 16-23: new bucket initialization (last_update) Returns: Vector of instructions/pseudo-instructions
(build-simple-rate-limit bucket-map-fd
key-stack-off
scratch-stack-off
rate
burst
skip-label
drop-label)Simplified rate limiting that doesn't use a config map.
Rate and burst are hardcoded, suitable for single-purpose rate limiters.
Args: bucket-map-fd: FD for bucket LRU hash map key-stack-off: Stack offset where lookup key is stored scratch-stack-off: Stack offset for scratch space (needs 24 bytes) rate: Tokens per second (unscaled, e.g., 100 for 100 req/s) burst: Maximum tokens (unscaled, e.g., 200) skip-label: Label to jump to on pass drop-label: Label to jump to on rate limit
Returns: Vector of instructions/pseudo-instructions
Simplified rate limiting that doesn't use a config map. Rate and burst are hardcoded, suitable for single-purpose rate limiters. Args: bucket-map-fd: FD for bucket LRU hash map key-stack-off: Stack offset where lookup key is stored scratch-stack-off: Stack offset for scratch space (needs 24 bytes) rate: Tokens per second (unscaled, e.g., 100 for 100 req/s) burst: Maximum tokens (unscaled, e.g., 200) skip-label: Label to jump to on pass drop-label: Label to jump to on rate limit Returns: Vector of instructions/pseudo-instructions
(encode-rate-limit-config rate burst)Encode rate limit config for userspace map update.
Args: rate: Tokens per second (unscaled) burst: Maximum tokens (unscaled)
Returns: Byte array suitable for map update (16 bytes)
Encode rate limit config for userspace map update. Args: rate: Tokens per second (unscaled) burst: Maximum tokens (unscaled) Returns: Byte array suitable for map update (16 bytes)
(rate-disabled-config)Create config that disables rate limiting.
Returns: Byte array with rate=0, burst=0
Create config that disables rate limiting. Returns: Byte array with rate=0, burst=0
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |