kernel/bpf/lpm_trie.c
Source file repositories/reference/linux-study-clean/kernel/bpf/lpm_trie.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/bpf/lpm_trie.c- Extension
.c- Size
- 23049 bytes
- Lines
- 790
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bpf.hlinux/btf.hlinux/err.hlinux/slab.hlinux/spinlock.hlinux/vmalloc.hnet/ipv6.huapi/linux/btf.hlinux/btf_ids.hasm/rqspinlock.hlinux/bpf_mem_alloc.h
Detected Declarations
struct lpm_trie_nodestruct lpm_trie_nodestruct lpm_triefunction prefixfunction __longest_prefix_matchfunction longest_prefix_matchfunction trie_check_add_elemfunction trie_update_elemfunction trie_delete_elemfunction rcu_access_pointerfunction trie_freefunction trie_get_next_keyfunction trie_check_btffunction trie_mem_usage
Annotated Snippet
struct lpm_trie_node {
struct lpm_trie_node __rcu *child[2];
u32 prefixlen;
u32 flags;
u8 data[];
};
struct lpm_trie {
struct bpf_map map;
struct lpm_trie_node __rcu *root;
struct bpf_mem_alloc ma;
size_t n_entries;
size_t max_prefixlen;
size_t data_size;
rqspinlock_t lock;
};
/* This trie implements a longest prefix match algorithm that can be used to
* match IP addresses to a stored set of ranges.
*
* Data stored in @data of struct bpf_lpm_key and struct lpm_trie_node is
* interpreted as big endian, so data[0] stores the most significant byte.
*
* Match ranges are internally stored in instances of struct lpm_trie_node
* which each contain their prefix length as well as two pointers that may
* lead to more nodes containing more specific matches. Each node also stores
* a value that is defined by and returned to userspace via the update_elem
* and lookup functions.
*
* For instance, let's start with a trie that was created with a prefix length
* of 32, so it can be used for IPv4 addresses, and one single element that
* matches 192.168.0.0/16. The data array would hence contain
* [0xc0, 0xa8, 0x00, 0x00] in big-endian notation. This documentation will
* stick to IP-address notation for readability though.
*
* As the trie is empty initially, the new node (1) will be places as root
* node, denoted as (R) in the example below. As there are no other node, both
* child pointers are %NULL.
*
* +----------------+
* | (1) (R) |
* | 192.168.0.0/16 |
* | value: 1 |
* | [0] [1] |
* +----------------+
*
* Next, let's add a new node (2) matching 192.168.0.0/24. As there is already
* a node with the same data and a smaller prefix (ie, a less specific one),
* node (2) will become a child of (1). In child index depends on the next bit
* that is outside of what (1) matches, and that bit is 0, so (2) will be
* child[0] of (1):
*
* +----------------+
* | (1) (R) |
* | 192.168.0.0/16 |
* | value: 1 |
* | [0] [1] |
* +----------------+
* |
* +----------------+
* | (2) |
* | 192.168.0.0/24 |
* | value: 2 |
* | [0] [1] |
* +----------------+
*
* The child[1] slot of (1) could be filled with another node which has bit #17
* (the next bit after the ones that (1) matches on) set to 1. For instance,
* 192.168.128.0/24:
*
* +----------------+
* | (1) (R) |
* | 192.168.0.0/16 |
* | value: 1 |
* | [0] [1] |
* +----------------+
* | |
* +----------------+ +------------------+
* | (2) | | (3) |
* | 192.168.0.0/24 | | 192.168.128.0/24 |
* | value: 2 | | value: 3 |
* | [0] [1] | | [0] [1] |
* +----------------+ +------------------+
*
* Let's add another node (4) to the game for 192.168.1.0/24. In order to place
* it, node (1) is looked at first, and because (4) of the semantics laid out
* above (bit #17 is 0), it would normally be attached to (1) as child[0].
* However, that slot is already allocated, so a new node is needed in between.
* That node does not have a value attached to it and it will never be
* returned to users as result of a lookup. It is only there to differentiate
Annotation
- Immediate include surface: `linux/bpf.h`, `linux/btf.h`, `linux/err.h`, `linux/slab.h`, `linux/spinlock.h`, `linux/vmalloc.h`, `net/ipv6.h`, `uapi/linux/btf.h`.
- Detected declarations: `struct lpm_trie_node`, `struct lpm_trie_node`, `struct lpm_trie`, `function prefix`, `function __longest_prefix_match`, `function longest_prefix_match`, `function trie_check_add_elem`, `function trie_update_elem`, `function trie_delete_elem`, `function rcu_access_pointer`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.