Comprehensive examples demonstrating the clj-ebpf DSL for BPF programming.
These examples showcase various BPF program types and common patterns:
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.
(-main & args)Print list of available examples.
Print list of available examples.
(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
(bitwise-operations-demo)Demonstrates bitwise operations.
Shows: AND, OR, XOR, LSH (left shift), RSH (right shift)
Computes bitmask operations:
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
(conditional-logic-demo)Demonstrates conditional logic with jumps.
Implements: if (x > 10) return 1; else return 0;
Shows:
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
Map of example names to their generator functions and descriptions.
Map of example names to their generator functions and descriptions.
(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)
(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
(kprobe-timestamp-logger)Logs timestamp using bpf_ktime_get_ns helper.
Demonstrates:
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
(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
(list-examples)List all available examples with descriptions.
List all available examples with descriptions.
(perf-event-output-demo)Demonstrates sending data to userspace via perf event buffer.
Shows the pattern for:
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
(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
(tc-packet-classifier)Classifies packets based on size with different TC actions.
Classification logic:
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
(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
(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
(xdp-allowlist-filter)Implements IP allowlist using BPF map lookup.
Algorithm:
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
(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
(xdp-ethernet-parser)Parses Ethernet header and validates packet has enough data.
Ethernet header layout (14 bytes):
Algorithm:
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
(xdp-ethertype-filter)Filters packets based on EtherType field (IPv4 only).
EtherType values:
Algorithm:
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
(xdp-icmp-rate-limiter)Rate limits ICMP packets to prevent ICMP flood attacks.
Pattern:
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
(xdp-ip-protocol-filter)Filters packets based on IP protocol field (TCP only).
IP Protocol numbers:
Protocol field offset: Ethernet (14) + IP header offset 9 = 23 bytes
Algorithm:
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
(xdp-ipv4-parser)Parses IPv4 header and validates packet structure.
IPv4 header layout (minimum 20 bytes):
Algorithm:
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
(xdp-map-lookup-example)Demonstrates BPF map lookup operation.
This example shows how to:
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
(xdp-map-update-counter)Demonstrates BPF map update to increment a counter.
This example shows how to:
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
(xdp-packet-size-filter)Filters packets based on size - drops small packets, passes large ones.
Algorithm:
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
(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
(xdp-syn-flood-protection)Simple SYN flood protection using packet rate limiting.
This simplified example demonstrates the pattern for SYN flood protection:
Note: This is a simplified educational example. Real SYN flood protection would require:
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
(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):
Offset calculation:
Algorithm:
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
(xdp-udp-port-range-filter)Filters UDP packets based on destination port range (1024-2048).
UDP header layout (8 bytes):
Algorithm:
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
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 |