We’re integrating VPP (Vector Packet Processing) with Suricata 8.0.0 library mode for real-time IDPS functionality. The goal is to inject packets from VPP plugin thread into Suricata for detection with ProofPoint rules, then receive native EVE JSON alerts.
Three Approaches Attempted
Approach 1: Direct Library Integration
API Flow:
// VPP Plugin Thread:
LibSuricataInjectRaw(pkt_data, pkt_len, linktype, ts_ns);
↓ (inside libvppinject.c wrapper for suricata library APIs)
PacketGetFromQueueOrAlloc() → PacketCopyData() → DecodeEthernet()
↓
Manual signature matching → AlertQueueAppend() → Custom EVE JSON generation
Issues:
-
Counter assertion failures in library mode (
StatsRegisterCounter) -
Thread context mismatch (VPP thread vs Suricata thread)
-
DecodeEthernetcrashes due to stats counter registration
Approach 2: Crash-Safe Library Mode
API Flow:
// VPP Plugin Thread:
LibSuricataInjectRaw(pkt_data, pkt_len, linktype, ts_ns);
↓ (crash-safe version)
PacketGetFromQueueOrAlloc() → PacketCopyData() → Manual protocol detection
↓
Bypass all decoders → Direct signature matching → Custom EVE JSON
Issues:
-
Disabled decoders limit detection capabilities
-
Bypasses Suricata’s native pipeline
-
Manual EVE generation instead of native output
Approach 3: Queue-Based Input Module
API Flow:
// VPP Plugin Thread:
PacketGetFromQueueOrAlloc() → PacketCopyData() → VppPacketQueuePush()
↓ (Thread-safe queue handoff)
// Suricata Input Module Thread:
VppPacketQueuePop() → TmThreadsCaptureInjectPacket(tv, p);
↓
Native Suricata pipeline → Full decoding → Detection → Native EVE output
Configuration:
suricata:
library-mode: true
runmode: library
Questions for Community
-
Library Mode Thread Context: Is
TmThreadsCaptureInjectPacket()the correct API for library mode packet injection? Should packets always be injected from Suricata’s thread context rather than external threads? -
Input Module Registration: For custom input modules in library mode, should we register via
TmModuleReceive*Register()functions or is there a library-specific registration mechanism? -
Stats Counter Issue: Why do
StatsRegisterCounter()calls fail in library mode? Is there a proper way to initialize counters, or should library mode avoid them entirely? -
Best Practice Architecture: For high-performance packet processing (VPP integration), is the queue-based approach (Approach 3) the recommended pattern, or is there a more efficient direct injection method?
-
EVE Output: In library mode with custom input modules, does native EVE JSON output work automatically, or do we need additional configuration for
outputs.eve-log?
The queue-based approach (Approach 3) works but adds latency. Is there a direct library API that provides the same native processing without the queue overhead?
Environment: Suricata 8.0.0, VPP 23.06, Ubuntu 20.04, library mode integration