Liking cljdoc? Tell your friends :D

clj-ebpf.rate-limit

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)

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)
raw docstring

BUCKET-OFF-LAST-UPDATEclj

source

BUCKET-OFF-TOKENSclj

source

build-rate-limit-checkclj

(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:

  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

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
sourceraw docstring

build-simple-rate-limitclj

(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
sourceraw docstring

CONFIG-OFF-BURSTclj

source

CONFIG-OFF-RATEclj

source

encode-rate-limit-configclj

(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)
sourceraw docstring

MAX-ELAPSED-USclj

source

NS-PER-SECclj

source

NS-PER-USclj

source

rate-disabled-configclj

(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
sourceraw docstring

TOKEN-SCALEclj

source

US-PER-SECclj

source

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close