Liking cljdoc? Tell your friends :D

clj-ebpf.examples

Comprehensive examples demonstrating the clj-ebpf DSL for BPF programming.

These examples showcase various BPF program types and common patterns:

  • XDP (eXpress Data Path) programs for high-performance packet filtering
  • TC (Traffic Control) programs for packet classification
  • Packet parsing (Ethernet, IP, TCP/UDP headers)
  • BPF map operations (lookup, update, delete)
  • Tracing and debugging with helper functions
  • Statistics and counters

Each example is documented with its purpose, expected behavior, and the BPF concepts it demonstrates.

Comprehensive examples demonstrating the clj-ebpf DSL for BPF programming.

These examples showcase various BPF program types and common patterns:
- XDP (eXpress Data Path) programs for high-performance packet filtering
- TC (Traffic Control) programs for packet classification
- Packet parsing (Ethernet, IP, TCP/UDP headers)
- BPF map operations (lookup, update, delete)
- Tracing and debugging with helper functions
- Statistics and counters

Each example is documented with its purpose, expected behavior, and
the BPF concepts it demonstrates.
raw docstring

-mainclj

(-main & args)

Print list of available examples.

Print list of available examples.
sourceraw docstring

arithmetic-operations-democlj

(arithmetic-operations-demo)

Demonstrates various arithmetic operations.

Shows: ADD, SUB, MUL, DIV, MOD operations

Computes: ((10 + 5) * 2 - 3) / 4 = 27 / 4 = 6 (integer division)

Returns: 6 Use case: Educational example of ALU operations

Demonstrates various arithmetic operations.

Shows: ADD, SUB, MUL, DIV, MOD operations

Computes: ((10 + 5) * 2 - 3) / 4 = 27 / 4 = 6 (integer division)

Returns: 6
Use case: Educational example of ALU operations
sourceraw docstring

bitwise-operations-democlj

(bitwise-operations-demo)

Demonstrates bitwise operations.

Shows: AND, OR, XOR, LSH (left shift), RSH (right shift)

Computes bitmask operations:

  • Start with 0xFF (255)
  • AND with 0xF0 = 0xF0 (240)
  • OR with 0x05 = 0xF5 (245)
  • XOR with 0xAA = 0x5F (95)
  • LSH by 1 = 0xBE (190)
  • RSH by 2 = 0x2F (47)

Returns: 47 Use case: Bit manipulation, flag handling

Demonstrates bitwise operations.

Shows: AND, OR, XOR, LSH (left shift), RSH (right shift)

Computes bitmask operations:
- Start with 0xFF (255)
- AND with 0xF0 = 0xF0 (240)
- OR with 0x05 = 0xF5 (245)
- XOR with 0xAA = 0x5F (95)
- LSH by 1 = 0xBE (190)
- RSH by 2 = 0x2F (47)

Returns: 47
Use case: Bit manipulation, flag handling
sourceraw docstring

conditional-logic-democlj

(conditional-logic-demo)

Demonstrates conditional logic with jumps.

Implements: if (x > 10) return 1; else return 0;

Shows:

  • Conditional jumps (JGT)
  • Branch handling
  • Labels (implicit via jump offsets)

Returns: 1 if input > 10, else 0 Use case: Decision making, filtering logic

Demonstrates conditional logic with jumps.

Implements: if (x > 10) return 1; else return 0;

Shows:
- Conditional jumps (JGT)
- Branch handling
- Labels (implicit via jump offsets)

Returns: 1 if input > 10, else 0
Use case: Decision making, filtering logic
sourceraw docstring

examplesclj

Map of example names to their generator functions and descriptions.

Map of example names to their generator functions and descriptions.
sourceraw docstring

get-exampleclj

(get-example example-name)

Get bytecode for a specific example by keyword name.

Usage: (get-example :xdp-pass-all) (get-example :tcp-port-filter)

Get bytecode for a specific example by keyword name.

Usage:
  (get-example :xdp-pass-all)
  (get-example :tcp-port-filter)
sourceraw docstring

get-smp-processor-id-democlj

(get-smp-processor-id-demo)

Demonstrates getting current CPU ID.

Returns: Current CPU ID Use case: Per-CPU statistics, load balancing

Demonstrates getting current CPU ID.

Returns: Current CPU ID
Use case: Per-CPU statistics, load balancing
sourceraw docstring

kprobe-timestamp-loggerclj

(kprobe-timestamp-logger)

Logs timestamp using bpf_ktime_get_ns helper.

Demonstrates:

  1. Calling bpf_ktime_get_ns to get current kernel time
  2. Storing result for further processing

Returns: 0 (success) Use case: Performance monitoring, latency measurement

Logs timestamp using bpf_ktime_get_ns helper.

Demonstrates:
1. Calling bpf_ktime_get_ns to get current kernel time
2. Storing result for further processing

Returns: 0 (success)
Use case: Performance monitoring, latency measurement
sourceraw docstring

kprobe-with-trace-printkclj

(kprobe-with-trace-printk)

Demonstrates using bpf_trace_printk for debugging.

This example shows how to call bpf_trace_printk helper to log messages to the kernel trace buffer (/sys/kernel/debug/tracing/trace).

Note: The actual format string and arguments would need to be set up on the stack in a real implementation. This is a simplified version showing the call pattern.

Returns: 0 (success) Use case: Debugging BPF programs, logging events

Demonstrates using bpf_trace_printk for debugging.

This example shows how to call bpf_trace_printk helper to log
messages to the kernel trace buffer (/sys/kernel/debug/tracing/trace).

Note: The actual format string and arguments would need to be
set up on the stack in a real implementation. This is a simplified
version showing the call pattern.

Returns: 0 (success)
Use case: Debugging BPF programs, logging events
sourceraw docstring

list-examplesclj

(list-examples)

List all available examples with descriptions.

List all available examples with descriptions.
sourceraw docstring

perf-event-output-democlj

(perf-event-output-demo)

Demonstrates sending data to userspace via perf event buffer.

Shows the pattern for:

  1. Setting up data structure on stack
  2. Calling bpf_perf_event_output to send to userspace

Returns: 0 (success) Use case: Packet sampling, event logging to userspace

Demonstrates sending data to userspace via perf event buffer.

Shows the pattern for:
1. Setting up data structure on stack
2. Calling bpf_perf_event_output to send to userspace

Returns: 0 (success)
Use case: Packet sampling, event logging to userspace
sourceraw docstring

tc-ok-allclj

(tc-ok-all)

Simplest TC program - allows all packets.

Returns: TC_ACT_OK for all packets Use case: Testing TC attachment without filtering

Simplest TC program - allows all packets.

Returns: TC_ACT_OK for all packets
Use case: Testing TC attachment without filtering
sourceraw docstring

tc-packet-classifierclj

(tc-packet-classifier)

Classifies packets based on size with different TC actions.

Classification logic:

  • Packets < 64 bytes: TC_ACT_SHOT (drop)
  • Packets 64-1500 bytes: TC_ACT_OK (pass)
  • Packets > 1500 bytes: TC_ACT_PIPE (continue to next qdisc)

Returns: Different TC actions based on packet size Use case: QoS, traffic classification

Classifies packets based on size with different TC actions.

Classification logic:
- Packets < 64 bytes: TC_ACT_SHOT (drop)
- Packets 64-1500 bytes: TC_ACT_OK (pass)
- Packets > 1500 bytes: TC_ACT_PIPE (continue to next qdisc)

Returns: Different TC actions based on packet size
Use case: QoS, traffic classification
sourceraw docstring

tc-shot-allclj

(tc-shot-all)

Drops all packets at TC layer.

Returns: TC_ACT_SHOT for all packets Use case: TC-level packet drop for testing

Drops all packets at TC layer.

Returns: TC_ACT_SHOT for all packets
Use case: TC-level packet drop for testing
sourceraw docstring

xdp-aborted-on-errorclj

(xdp-aborted-on-error)

Returns XDP_ABORTED to signal an error condition.

Returns: XDP_ABORTED (signals error to kernel) Use case: Error handling, debugging malformed packets

Returns XDP_ABORTED to signal an error condition.

Returns: XDP_ABORTED (signals error to kernel)
Use case: Error handling, debugging malformed packets
sourceraw docstring

xdp-allowlist-filterclj

(xdp-allowlist-filter)

Implements IP allowlist using BPF map lookup.

Algorithm:

  1. Parse packet to extract source IP address
  2. Use source IP as key to look up in allowlist map
  3. If found in map: XDP_PASS
  4. If not found: XDP_DROP

IP source address offset: Ethernet (14) + IP src (12) = 26 bytes

Returns: XDP_PASS if source IP in allowlist, XDP_DROP otherwise Use case: Access control, IP filtering

Implements IP allowlist using BPF map lookup.

Algorithm:
1. Parse packet to extract source IP address
2. Use source IP as key to look up in allowlist map
3. If found in map: XDP_PASS
4. If not found: XDP_DROP

IP source address offset: Ethernet (14) + IP src (12) = 26 bytes

Returns: XDP_PASS if source IP in allowlist, XDP_DROP otherwise
Use case: Access control, IP filtering
sourceraw docstring

xdp-drop-allclj

(xdp-drop-all)

Drops all incoming packets at the driver level.

Returns: XDP_DROP for all packets Use case: Emergency packet drop, DDoS mitigation baseline

Drops all incoming packets at the driver level.

Returns: XDP_DROP for all packets
Use case: Emergency packet drop, DDoS mitigation baseline
sourceraw docstring

xdp-ethernet-parserclj

(xdp-ethernet-parser)

Parses Ethernet header and validates packet has enough data.

Ethernet header layout (14 bytes):

  • Destination MAC: 6 bytes (offset 0)
  • Source MAC: 6 bytes (offset 6)
  • EtherType: 2 bytes (offset 12)

Algorithm:

  1. Load data and data_end pointers from context
  2. Calculate packet end: data + 14 (Ethernet header size)
  3. Check if packet end > data_end (bounds check)
  4. If too short: return XDP_DROP
  5. Otherwise: return XDP_PASS

Returns: XDP_PASS if packet has complete Ethernet header, XDP_DROP otherwise Use case: Validate packet has minimum size before further processing

Parses Ethernet header and validates packet has enough data.

Ethernet header layout (14 bytes):
- Destination MAC: 6 bytes (offset 0)
- Source MAC: 6 bytes (offset 6)
- EtherType: 2 bytes (offset 12)

Algorithm:
1. Load data and data_end pointers from context
2. Calculate packet end: data + 14 (Ethernet header size)
3. Check if packet end > data_end (bounds check)
4. If too short: return XDP_DROP
5. Otherwise: return XDP_PASS

Returns: XDP_PASS if packet has complete Ethernet header, XDP_DROP otherwise
Use case: Validate packet has minimum size before further processing
sourceraw docstring

xdp-ethertype-filterclj

(xdp-ethertype-filter)

Filters packets based on EtherType field (IPv4 only).

EtherType values:

  • 0x0800 (2048): IPv4
  • 0x86DD: IPv6
  • 0x0806: ARP

Algorithm:

  1. Validate packet has Ethernet header (bounds check)
  2. Load EtherType from offset 12 (as big-endian u16)
  3. Check if EtherType == 0x0800 (IPv4)
  4. If IPv4: return XDP_PASS
  5. Otherwise: return XDP_DROP

Returns: XDP_PASS for IPv4 packets, XDP_DROP otherwise Use case: Filter to only process IPv4 traffic

Filters packets based on EtherType field (IPv4 only).

EtherType values:
- 0x0800 (2048): IPv4
- 0x86DD: IPv6
- 0x0806: ARP

Algorithm:
1. Validate packet has Ethernet header (bounds check)
2. Load EtherType from offset 12 (as big-endian u16)
3. Check if EtherType == 0x0800 (IPv4)
4. If IPv4: return XDP_PASS
5. Otherwise: return XDP_DROP

Returns: XDP_PASS for IPv4 packets, XDP_DROP otherwise
Use case: Filter to only process IPv4 traffic
sourceraw docstring

xdp-icmp-rate-limiterclj

(xdp-icmp-rate-limiter)

Rate limits ICMP packets to prevent ICMP flood attacks.

Pattern:

  1. Validate packet is ICMP (IP protocol = 1)
  2. Look up ICMP counter in map
  3. If counter exceeds threshold: drop
  4. Otherwise: increment counter and pass

Note: Simplified example for educational purposes

Returns: XDP_DROP if rate exceeded, XDP_PASS otherwise Use case: ICMP flood protection, rate limiting

Rate limits ICMP packets to prevent ICMP flood attacks.

Pattern:
1. Validate packet is ICMP (IP protocol = 1)
2. Look up ICMP counter in map
3. If counter exceeds threshold: drop
4. Otherwise: increment counter and pass

Note: Simplified example for educational purposes

Returns: XDP_DROP if rate exceeded, XDP_PASS otherwise
Use case: ICMP flood protection, rate limiting
sourceraw docstring

xdp-ip-protocol-filterclj

(xdp-ip-protocol-filter)

Filters packets based on IP protocol field (TCP only).

IP Protocol numbers:

  • 6: TCP
  • 17: UDP
  • 1: ICMP

Protocol field offset: Ethernet (14) + IP header offset 9 = 23 bytes

Algorithm:

  1. Validate Ethernet + IP headers exist
  2. Load protocol field from IP header (offset 9 in IP header)
  3. Check if protocol == 6 (TCP)
  4. If TCP: return XDP_PASS
  5. Otherwise: return XDP_DROP

Returns: XDP_PASS for TCP packets, XDP_DROP otherwise Use case: Filter to only process TCP traffic

Filters packets based on IP protocol field (TCP only).

IP Protocol numbers:
- 6: TCP
- 17: UDP
- 1: ICMP

Protocol field offset: Ethernet (14) + IP header offset 9 = 23 bytes

Algorithm:
1. Validate Ethernet + IP headers exist
2. Load protocol field from IP header (offset 9 in IP header)
3. Check if protocol == 6 (TCP)
4. If TCP: return XDP_PASS
5. Otherwise: return XDP_DROP

Returns: XDP_PASS for TCP packets, XDP_DROP otherwise
Use case: Filter to only process TCP traffic
sourceraw docstring

xdp-ipv4-parserclj

(xdp-ipv4-parser)

Parses IPv4 header and validates packet structure.

IPv4 header layout (minimum 20 bytes):

  • Version + IHL: 1 byte (offset 14)
  • Type of Service: 1 byte
  • Total Length: 2 bytes
  • ... (20 bytes total minimum)

Algorithm:

  1. Validate Ethernet header exists (14 bytes)
  2. Calculate IP header end: data + 14 + 20
  3. Bounds check: ensure packet has complete IP header
  4. Validate IP version (first 4 bits should be 4)

Returns: XDP_PASS if valid IPv4 packet, XDP_DROP otherwise Use case: Validate IPv4 packet structure before further processing

Parses IPv4 header and validates packet structure.

IPv4 header layout (minimum 20 bytes):
- Version + IHL: 1 byte (offset 14)
- Type of Service: 1 byte
- Total Length: 2 bytes
- ... (20 bytes total minimum)

Algorithm:
1. Validate Ethernet header exists (14 bytes)
2. Calculate IP header end: data + 14 + 20
3. Bounds check: ensure packet has complete IP header
4. Validate IP version (first 4 bits should be 4)

Returns: XDP_PASS if valid IPv4 packet, XDP_DROP otherwise
Use case: Validate IPv4 packet structure before further processing
sourceraw docstring

xdp-map-lookup-exampleclj

(xdp-map-lookup-example)

Demonstrates BPF map lookup operation.

This example shows how to:

  1. Set up a key in a register
  2. Load map FD (would be patched in by loader)
  3. Call bpf_map_lookup_elem helper
  4. Check return value (NULL or pointer to value)
  5. Handle success/failure paths

Note: Map FD at offset 0 would be replaced by the BPF loader with the actual map file descriptor.

Returns: XDP_PASS if key found in map, XDP_DROP otherwise Use case: Demonstrate map lookup pattern for allowlist/blocklist

Demonstrates BPF map lookup operation.

This example shows how to:
1. Set up a key in a register
2. Load map FD (would be patched in by loader)
3. Call bpf_map_lookup_elem helper
4. Check return value (NULL or pointer to value)
5. Handle success/failure paths

Note: Map FD at offset 0 would be replaced by the BPF loader
with the actual map file descriptor.

Returns: XDP_PASS if key found in map, XDP_DROP otherwise
Use case: Demonstrate map lookup pattern for allowlist/blocklist
sourceraw docstring

xdp-map-update-counterclj

(xdp-map-update-counter)

Demonstrates BPF map update to increment a counter.

This example shows how to:

  1. Look up current counter value in map
  2. If found: load value, increment, update map
  3. If not found: initialize counter to 1

Note: This is a simplified example. Real implementation would need atomic operations for thread safety.

Returns: XDP_PASS (always) Use case: Packet counting, statistics collection

Demonstrates BPF map update to increment a counter.

This example shows how to:
1. Look up current counter value in map
2. If found: load value, increment, update map
3. If not found: initialize counter to 1

Note: This is a simplified example. Real implementation would need
atomic operations for thread safety.

Returns: XDP_PASS (always)
Use case: Packet counting, statistics collection
sourceraw docstring

xdp-packet-size-filterclj

(xdp-packet-size-filter)

Filters packets based on size - drops small packets, passes large ones.

Algorithm:

  1. Load ctx->data_end into r2
  2. Load ctx->data into r3
  3. Calculate packet size: r2 = r2 - r3
  4. If size > 60 bytes: jump to pass label
  5. Otherwise: return XDP_DROP
  6. Pass label: return XDP_PASS

Returns: XDP_PASS for packets > 60 bytes, XDP_DROP otherwise Use case: Filter out small/malformed packets

Filters packets based on size - drops small packets, passes large ones.

Algorithm:
1. Load ctx->data_end into r2
2. Load ctx->data into r3
3. Calculate packet size: r2 = r2 - r3
4. If size > 60 bytes: jump to pass label
5. Otherwise: return XDP_DROP
6. Pass label: return XDP_PASS

Returns: XDP_PASS for packets > 60 bytes, XDP_DROP otherwise
Use case: Filter out small/malformed packets
sourceraw docstring

xdp-pass-allclj

(xdp-pass-all)

The simplest possible XDP program - passes all packets.

Returns: XDP_PASS for all packets Use case: Testing XDP attachment without filtering

The simplest possible XDP program - passes all packets.

Returns: XDP_PASS for all packets
Use case: Testing XDP attachment without filtering
sourceraw docstring

xdp-syn-flood-protectionclj

(xdp-syn-flood-protection)

Simple SYN flood protection using packet rate limiting.

This simplified example demonstrates the pattern for SYN flood protection:

  1. Parse packet to ensure it's TCP
  2. Check TCP flags for SYN
  3. Look up connection state in map
  4. Apply rate limiting logic

Note: This is a simplified educational example. Real SYN flood protection would require:

  • Proper TCP flag parsing
  • Per-source-IP rate limiting
  • Connection tracking
  • More sophisticated map operations

Returns: XDP_DROP for suspicious traffic, XDP_PASS otherwise Use case: DDoS mitigation, SYN flood protection

Simple SYN flood protection using packet rate limiting.

This simplified example demonstrates the pattern for SYN flood protection:
1. Parse packet to ensure it's TCP
2. Check TCP flags for SYN
3. Look up connection state in map
4. Apply rate limiting logic

Note: This is a simplified educational example. Real SYN flood protection
would require:
- Proper TCP flag parsing
- Per-source-IP rate limiting
- Connection tracking
- More sophisticated map operations

Returns: XDP_DROP for suspicious traffic, XDP_PASS otherwise
Use case: DDoS mitigation, SYN flood protection
sourceraw docstring

xdp-tcp-port-filterclj

(xdp-tcp-port-filter)

Filters TCP packets based on destination port (port 80/HTTP only).

TCP header layout (minimum 20 bytes, starts after IP header):

  • Source port: 2 bytes (offset 0)
  • Dest port: 2 bytes (offset 2)
  • Sequence number: 4 bytes
  • ...

Offset calculation:

  • Ethernet: 14 bytes
  • IP header: 20 bytes (minimum, IHL=5)
  • TCP dest port: +2 bytes
  • Total: 36 bytes to dest port

Algorithm:

  1. Validate packet has Ethernet + IP + TCP header start
  2. Load destination port (offset 36, assuming IHL=5)
  3. Convert from network byte order
  4. Check if port == 80 (HTTP)

Returns: XDP_PASS for HTTP traffic (port 80), XDP_DROP otherwise Use case: Filter HTTP traffic for inspection

Filters TCP packets based on destination port (port 80/HTTP only).

TCP header layout (minimum 20 bytes, starts after IP header):
- Source port: 2 bytes (offset 0)
- Dest port: 2 bytes (offset 2)
- Sequence number: 4 bytes
- ...

Offset calculation:
- Ethernet: 14 bytes
- IP header: 20 bytes (minimum, IHL=5)
- TCP dest port: +2 bytes
- Total: 36 bytes to dest port

Algorithm:
1. Validate packet has Ethernet + IP + TCP header start
2. Load destination port (offset 36, assuming IHL=5)
3. Convert from network byte order
4. Check if port == 80 (HTTP)

Returns: XDP_PASS for HTTP traffic (port 80), XDP_DROP otherwise
Use case: Filter HTTP traffic for inspection
sourceraw docstring

xdp-udp-port-range-filterclj

(xdp-udp-port-range-filter)

Filters UDP packets based on destination port range (1024-2048).

UDP header layout (8 bytes):

  • Source port: 2 bytes (offset 0)
  • Dest port: 2 bytes (offset 2)
  • Length: 2 bytes
  • Checksum: 2 bytes

Algorithm:

  1. Validate packet has Ethernet + IP + UDP headers
  2. Load destination port from UDP header
  3. Check if port >= 1024 AND port <= 2048
  4. Use two jump instructions for range check

Returns: XDP_PASS for UDP ports 1024-2048, XDP_DROP otherwise Use case: Filter UDP traffic in specific port range

Filters UDP packets based on destination port range (1024-2048).

UDP header layout (8 bytes):
- Source port: 2 bytes (offset 0)
- Dest port: 2 bytes (offset 2)
- Length: 2 bytes
- Checksum: 2 bytes

Algorithm:
1. Validate packet has Ethernet + IP + UDP headers
2. Load destination port from UDP header
3. Check if port >= 1024 AND port <= 2048
4. Use two jump instructions for range check

Returns: XDP_PASS for UDP ports 1024-2048, XDP_DROP otherwise
Use case: Filter UDP traffic in specific port range
sourceraw docstring

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