Skip to content

High-Performance SIMD accelerated Longest Prefix Match (LPM) Library, supporting IPv4/IPv6 addresses by multi-bit trie of 8-bit stride

License

Notifications You must be signed in to change notification settings

MuriloChianfa/liblpm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

High-Performance Longest Prefix Match Library

Version License: Boost Platform Code Coverage CI CodeQL

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.

Features

  • 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.

Building

Requirements

Ubuntu/Debian
apt install build-essential cmake libc6-dev
CentOS/RHEL/Rocky Linux
yum install gcc gcc-c++ make cmake3 glibc-devel
Fedora
dnf install gcc gcc-c++ make cmake glibc-devel

Build & Install

# 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

Usage

Basic Example

#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;
}

API Reference

Core Functions

  • lpm_create(max_depth) - Create LPM trie (32 for IPv4, 128 for IPv6)
  • lpm_add(trie, prefix, prefix_len, next_hop) - Add prefix to trie
  • lpm_delete(trie, prefix, prefix_len) - Remove prefix from trie
  • lpm_destroy(trie) - Free all resources

Lookup Functions

  • lpm_lookup(trie, addr) - Single address lookup
  • lpm_lookup_ipv4(trie, addr) - IPv4-specific lookup
  • lpm_lookup_ipv6(trie, addr) - IPv6-specific lookup
  • lpm_lookup_all(trie, addr) - Lookup for multiple match

Language Bindings

liblpm provides idiomatic bindings for multiple languages:

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.

Tests and Fuzzing

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 fuzzing

For detailed information about the fuzzing tests, coverage areas,
and advanced fuzzing techniques, see tests/FUZZING.md.

Containerized Development

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:

Quick Start with Docker

# 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

Available Containers

  • 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.

Verifying Binary Signatures

liblpm binaries are cryptographically signed with GPG for authenticity verification. To verify a downloaded binary:

1. Import the Public Key

Import the maintainer's public key directly from the keyserver using the key fingerprint:

gpg --keyserver keys.openpgp.org --recv-keys 3E1A1F401A1C47BC77D1705612D0D82387FC53B0
Alternative options

Using the shorter key ID:

gpg --keyserver keys.openpgp.org --recv-keys 12D0D82387FC53B0

Alternative keyserver (if keys.openpgp.org is unavailable):

gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 3E1A1F401A1C47BC77D1705612D0D82387FC53B0

You 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

2. Verify the Signature

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.so

If 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.

Documentation

Additional documentation:

Contributing

We welcome contributions from the community! Whether you're fixing bugs, adding features, improving documentation, or reporting issues, your help is appreciated.

Before contributing, please read our Contributing Guide and Code of Conduct.

Security

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.

License

This project is licensed under the Boost Software License 1.0 - see the LICENSE file for details.

Citation

If you use liblpm in your research or project, please cite it using the information in CITATION.cff.

Credits

About

High-Performance SIMD accelerated Longest Prefix Match (LPM) Library, supporting IPv4/IPv6 addresses by multi-bit trie of 8-bit stride

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project