A optimized C library for Longest Prefix Match (LPM) lookups supporting both IPv4 and IPv6 addresses. The library uses multi-bit trie with 8-bit stride for optimal performance and supports CPU vectorization.
- High Performance: Multi-bit trie with 8-bit stride reduces trie depth and improves cache.
- Dual Stack Support: Native support for both IPv4 (32-bit) and IPv6 (128-bit) addresses.
- SIMD Optimizations: Dynamic dispatching via libdynemit. (SSE2, SSE4.2, AVX, AVX2, AVX512F)
- Batch Processing: Vectorized batch lookup for processing multiple addresses simultaneously.
- Branchless Design: Optimized lookup paths with minimal branch mispredictions.
- Cache-Friendly: Aligned data structures and prefetching for optimal cache utilization.
- C23 Standard: Written in modern C with best practices.

IPv4 and IPv6 single lookup comparison among different CPU architectures

Batch lookups leverage SIMD vectorization for even higher throughput

Algorithm rankings showing mean throughput at small prefixes sets
For detailed benchmarks and methodology, see docs/BENCHMARKS.md.
Browse all benchmark charts in docs/images/.
Ubuntu/Debian
apt install build-essential cmake libc6-devCentOS/RHEL/Rocky Linux
yum install gcc gcc-c++ make cmake3 glibc-develFedora
dnf install gcc gcc-c++ make cmake glibc-devel# Clone with submodules
git clone --recursive https://github.com/MuriloChianfa/liblpm.git
cd liblpm
# Or if already cloned, initialize submodules
git submodule update --init --recursive
# Build
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install#include <lpm.h>
int main() {
lpm_trie_t *trie = lpm_create(LPM_IPV4_MAX_DEPTH);
// 192.168.0.0/16 -> next hop 100
uint8_t prefix[] = {192, 168, 0, 0};
lpm_add(trie, prefix, 16, 100);
uint8_t addr[] = {192, 168, 1, 1};
uint32_t next_hop = lpm_lookup(trie, addr);
lpm_destroy(trie);
return 0;
}lpm_create(max_depth)- Create LPM trie (32 for IPv4, 128 for IPv6)lpm_add(trie, prefix, prefix_len, next_hop)- Add prefix to trielpm_delete(trie, prefix, prefix_len)- Remove prefix from trielpm_destroy(trie)- Free all resources
lpm_lookup(trie, addr)- Single address lookuplpm_lookup_ipv4(trie, addr)- IPv4-specific lookuplpm_lookup_ipv6(trie, addr)- IPv6-specific lookuplpm_lookup_all(trie, addr)- Lookup for multiple match
liblpm provides idiomatic bindings for multiple languages:
- C - Native library (see include/lpm.h)
- C++ - Modern C++17 wrapper with zero-cost abstraction (see bindings/cpp/README.md)
- Go - Go binding with cgo (see bindings/go/README.md)
Note: All bindings use network byte order (big-endian) for IP addresses, which is the internet standard. See docs/BYTE_ORDER.md for details on data formats and integration.
The library includes some fuzzing tests to ensure robustness and catch edge cases. The fuzzing tests cover memory safety, API robustness, edge cases, and performance under stress.
cd build
ctest --verbose # Run test suite
./benchmarks/bench_lookup # Run benchmarks
./tests/fuzz_setup.sh # Setup fuzzing environment
./build_afl.sh # Build with AFL instrumentation
./run_fuzz.sh # Run AFL fuzzingFor detailed information about the fuzzing tests, coverage areas,
and advanced fuzzing techniques, see tests/FUZZING.md.
Docker Containers
For a reproducible development environment with the latest toolchain (GCC 15.2, Clang 21.1, CMake 4.2), you can use Docker containers:
# Build all containers
./scripts/docker-build.sh all
# Interactive development
docker run -it --rm -v "$PWD:/workspace" liblpm-dev
# Run tests
docker run --rm liblpm-test
# Run fuzzing
docker run --rm --cpus=4 liblpm-fuzz- liblpm-dev: Complete development environment
- liblpm-test: Automated testing with valgrind and cppcheck
- liblpm-fuzz: AFL++ fuzzing for security testing
- liblpm-cpp: C++ bindings development and testing
- liblpm-go: Go bindings development and testing
- liblpm-benchmark: DPDK rte_lpm performance comparison
For complete documentation, see docs/DOCKER.md.
liblpm binaries are cryptographically signed with GPG for authenticity verification. To verify a downloaded binary:
Import the maintainer's public key directly from the keyserver using the key fingerprint:
gpg --keyserver keys.openpgp.org --recv-keys 3E1A1F401A1C47BC77D1705612D0D82387FC53B0Alternative options
Using the shorter key ID:
gpg --keyserver keys.openpgp.org --recv-keys 12D0D82387FC53B0Alternative keyserver (if keys.openpgp.org is unavailable):
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 3E1A1F401A1C47BC77D1705612D0D82387FC53B0You should see output confirming the key was imported:
gpg: key 12D0D82387FC53B0: public key "MuriloChianfa <murilo.chianfa@outlook.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
Assuming you have downloaded both the binary (liblpm.so or liblpm.a) and its signature file (liblpm.so.asc or liblpm.a.asc):
gpg --verify liblpm.so.asc liblpm.soIf the signature is valid, you should see:
gpg: Signature made [date and time]
gpg: using EDDSA key 3E1A1F401A1C47BC77D1705612D0D82387FC53B0
gpg: Good signature from "MuriloChianfa <murilo.chianfa@outlook.com>"
If you see "BAD signature", do not use the binary - it may have been tampered with or corrupted.
Additional documentation:
- Byte Order and Data Format - Endianness, IP address storage, and integration guide
- C++ API Reference - C++ wrapper documentation
- Go API Reference - Go bindings documentation
We welcome contributions from the community! Whether you're fixing bugs, adding features, improving documentation, or reporting issues, your help is appreciated.
- Contributing Guide - How to contribute, coding standards, and development workflow
- Code of Conduct - Community guidelines and expected behavior
- Issue Templates - Report bugs or request features
- Pull Request Templates - Submit changes with our PR templates
Before contributing, please read our Contributing Guide and Code of Conduct.
If you discover any security vulnerabilities, please DO NOT open a public issue. Instead, refer to our Security Policy for instructions on how to report security issues responsibly.
This project is licensed under the Boost Software License 1.0 - see the LICENSE file for details.
If you use liblpm in your research or project, please cite it using the information in CITATION.cff.