Deep Packet Inspection inside FD.io VPP — classify 300+ applications (YouTube, Zoom, Netflix, SIP, TLS, QUIC, BitTorrent, GTP-U, and more) directly in the data-plane forwarding path using ntop/nDPI.
- No mirror port. No external DPI box. Classification runs as a VPP feature arc node on
ip4-unicast/ip6-unicast. - < 8 ns overhead per cached packet (bihash lookup + opaque write).
- 100G–800G line rate — VPP multi-worker, scales linearly.
- Apache 2.0 — free to use, evaluate, and build on.
Status: pre-production. Lab-validated on our own bench, not yet deployed in production. The figures below are bench measurements, not production telemetry.
Part of the PacketLens plugin suite by PacketFlow.
$ docker compose -f compose.demo.yaml up
Opens Grafana at http://localhost:3001 showing live per-application traffic counters for 12 injected TLS flows (YouTube, Netflix, GitHub, Spotify, TikTok, Amazon, Instagram, Facebook, WhatsApp, Google, Twitter).
Or run it in your browser via Killercoda — no install required:
https://killercoda.com/packetlens/course/packetlens-demo
vpp# show ndpi applications
Application Flows Packets Bytes %
YouTube 1 20 2320 8.4%
NetFlix 1 20 2320 8.4%
Github 1 20 2220 8.1%
Zoom 1 20 2300 8.4%
Spotify 1 20 2340 8.5%
...
vpp# show ndpi flows
Src IP Dst IP Proto SPort DPort App SNI Bytes
10.10.10.2 10.10.10.100 6 10001 443 YouTube www.youtube.com 580
10.10.10.2 10.10.10.100 6 10009 443 Zoom zoom.us 580
- Docker (for the easiest path)
- Or: VPP 25.10+ + libndpi-dev + CMake 3.16+
docker compose -f compose.demo.yaml up
# Grafana → http://localhost:3001 (no login)mkdir build && cd build
cmake ..
make -j$(nproc)pytest test/test_ndpi.py test/test_smoke.py test/test_stats.py -vvpp-ndpi registers as a node on the ip4-unicast and ip6-unicast feature arcs. It writes classification results into the VPP buffer opaque area — a 12-byte struct read by downstream plugins in the same arc pass:
typedef struct {
u16 app_protocol; /* nDPI app ID (e.g., 114 = YouTube, 225 = SIP) */
u8 category; /* nDPI category (e.g., 5 = VideoStreaming) */
u32 risk; /* nDPI risk bitmask (Tor, malware C2, etc.) */
u8 classified; /* 0=classifying, 1=cached, 2=gave_up */
u8 _pad[4];
} ndpi_buffer_opaque_t;Per-worker flow table: bihash_16_8 (IPv4) / bihash_48_8 (IPv6) — no cross-worker contention.
Classification: first 3–8 packets per flow are submitted to nDPI; once classified the result is cached for the remainder of the flow lifetime.
| Metric | Value | Notes |
|---|---|---|
| Overhead (classifying) | ~150 ns/pkt | First 3–8 pkts per flow |
| Overhead (cached) | ~8 ns/pkt | bihash lookup only |
| Protocols classified | 300+ | nDPI 4.2.0 |
| Max flows per worker | 1M | configurable |
| Classification convergence | 3–8 pkts | 95th pct, TCP/TLS |
All of these ship in this repository under Apache 2.0. policy, policer_ndpi,
ipfix and flowspec compile into ndpi_plugin.so to avoid cross-.so symbol
dependencies; cdr and flowspec_recv are separate plugins.
| Plugin | Node | What it does |
|---|---|---|
ndpi |
ndpi-observe |
classify: app, category, SNI, JA3, risk |
policy |
ndpi-policy |
enforce: drop / permit by application |
policer_ndpi |
ndpi-policer |
rate-limit: per-app token bucket, DSCP marking |
ipfix |
— | export: RFC 7011 IPFIX enriched with nDPI metadata |
flowspec |
flowspec-process |
react: BGP FlowSpec push to an upstream PE |
flowspec_recv |
flowspec-recv |
scrub: enforce RFC 8955 rules from a controller |
cdr |
cdr-observe |
mirror: SIP CDR export via HEP3 to Homer |
exporter |
— | scrape: Prometheus metrics, Grafana dashboard |
Related repositories: ndpi-observe (TC/eBPF classifier, no VPP required) and vpp-rtp-asr (inline RTP tap with streaming speech recognition).
Commercial support available from PacketFlow.
vpp-ndpi/
├── CMakeLists.txt
├── src/plugins/ndpi/ Core DPI classification plugin (C)
├── src/plugins/policy/ Per-application permit / drop
├── src/plugins/policer_ndpi/ Per-application rate limiting
├── src/plugins/ipfix/ IPFIX / NetFlow export
├── src/plugins/flowspec/ BGP FlowSpec push
├── src/plugins/flowspec_recv/ BGP FlowSpec enforcement
├── src/plugins/cdr/ SIP CDR export (HEP3)
├── exporter/ Prometheus metrics exporter (Go)
├── test/ pytest integration tests
├── scripts/ Demo entrypoint
├── labs/ Grafana + Prometheus configs
├── compose.demo.yaml One-command demo stack
├── Dockerfile.ci CI build image
├── Dockerfile.demo Demo image (VPP + plugin + synthetic traffic)
├── .devcontainer/ GitHub Codespaces config
└── killercoda/ Browser-based interactive demo scenario
Apache 2.0. Dynamically links libndpi (LGPL-3.0-or-later).