Skip to content

About

FastACL Community - line rate capable in line filtering for VPP

Resources

Stars

17 stars

Watchers

3 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

FastACL — Community Edition

A high-performance inline packet-filtering plugin for FD.io VPP, built for DDoS mitigation at 100 Gbps line rate. FastACL implements the RFC 8955 (IPv4) and RFC 8956 (IPv6) FlowSpec match model as a VPP feature-arc node, designed to act as a scrubbing data plane driven by an external detection system (for example FastNetMon) over VPP's CLI and binary API.

Released under the Apache License 2.0 — the same licence as VPP itself.

Plugin documentation in VPP's own format, covering the classifier architecture, is at src/plugins/fastacl/fastacl.rst — the location VPP expects a plugin's docs, so it works unchanged if the plugin is built inside a VPP tree.

Features

  • All 12 RFC 8955/8956 match types, IPv4 and IPv6 (dual-stack): destination and source prefix, IP protocol, destination/source/either port ranges, ICMP type and code, TCP flags (value + bitmask), packet length, DSCP, and fragment flags.
  • drop and permit actions, with the action type carried in the classifier result so the fast path never dereferences the rule pool to discard a packet. permit matches and forwards unchanged, which is what makes a sample-only rule possible; an action is mandatory, because type 0 is drop and an omitted one would silently discard the traffic a tap rule was added to observe.
  • Per-rule traffic sampling — an exact (not statistical) 1-in-N ratio per rule, with the copy taken before the action is applied, so a rule can show what it discarded. Delivery is over the kernel psample netlink channel, readable by any ordinary Linux program.
  • Classifier built on VPP's ACL plugin: rules are loaded into one ACL and matched against its TupleMerge hash tables; packet length, DSCP, fragment bits and the FlowSpec rule for later fragments are checked on each candidate. The ACL plugin is used unmodified, on stock FD.io VPP.
  • Rule ordering following RFC 8955 §5.1 component-wise precedence, with single and batch rule installation.
  • Dual-stack scoping that follows the rule, not the family. A rule applies to the family its addresses name, and to both when it names no address — so proto 17 dst-port 53 action drop filters IPv4 and IPv6, rather than silently exempting IPv6.
  • Per-rule and aggregate counters, including packet/byte totals and wire-rate telemetry (pps, L3 bps, and L1 bps accounting for framing overhead).
  • Routed and bridged operation from one datapath: the filter attaches to the ip4-unicast / ip6-unicast arcs and to l2-input-ip4 / l2-input-ip6.
  • VPP binary API and CLI for every operation.

Building

The plugin builds out-of-tree against installed VPP development packages and runs on stock FD.io VPP; the ACL plugin is used unmodified:

# Prerequisites: VPP 25.10 or 26.06 dev packages (vpp-dev, libvppinfra-dev)
#                libnl-3 headers (libnl-3-dev, libnl-genl-3-dev) for psample
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
make -C build -j"$(nproc)"

The result is build/lib/vpp_plugins/fastacl_plugin.so. Point VPP at it with a plugin_path, or copy it into VPP's plugin directory:

plugins {
  path /path/to/build/lib/vpp_plugins
  plugin fastacl_plugin.so { enable }
}

Quick start

Enable the filter on an interface, then install rules:

set interface fastacl TenGigabitEthernet0/0/0

# Drop UDP/53 to a prefix
fastacl rule add order 10 dst 10.0.0.0/24 proto 17 dst-port 53 action drop

# Tap: match and forward, sampling 1 packet in 1000 (pass/accept also work)
fastacl rule add order 15 dst 10.0.0.0/24 action permit sample 1000

# Drop TCP SYN to an IPv6 prefix, sampling 1 packet in 100 before the drop
fastacl rule add order 20 dst6 2001:db8::/32 proto 6 \
    tcp-flags value 0x02 mask 0x02 action drop sample 100

show fastacl rules
show fastacl aggregate-counters
show fastacl classifier

# Per-rule counters are exact and on by default; turn the counter write off
fastacl per-rule-stats disable
fastacl per-rule-stats            # no argument reports the current state

show fastacl classifier reports how many ACL entries the rule set expanded to, with the ACL index and the lookup context it is bound to.

To read sampled packets, enable the psample channel and attach any psample consumer:

fastacl psample enable
show fastacl sampling

Tuning

The plugin has no startup stanza of its own, and needs nothing in the acl-plugin one. What matters is VPP's own configuration. The hardware lab's 32-worker ConnectX-7 box at 100 GbE runs:

memory  { main-heap-size 12G  main-heap-page-size 2M }
statseg { size 12G }
buffers { buffers-per-numa 2097152 }
cpu     { main-core 0  corelist-workers 1-31 }
dpdk {
  dev 0000:81:00.0 {
    num-rx-queues 32  num-tx-queues 32
    num-rx-desc 4096  num-tx-desc 4096
    rss { ipv4 ipv6 l3-src-only }
  }
}
  • num-rx-desc is the one that surprises people. Large RX buffers evict the rule table from the last-level cache and every per-rule counter write becomes a cache miss; 4096 measures an order of magnitude less ingress loss than 8192 at a million rules. Nothing in the plugin sets it.
  • statseg size has to cover the per-rule counters — rules x (workers + 1) x 16 bytes.
  • main-heap-size bounds the rule-set size: it holds the rule pool and everything the ACL plugin builds from the rules, including its hash tables. A million rules that each expand to one ACL entry take about 0.9 GB of it (measured: 869 MB above an idle VPP), and a rule that expands to several entries costs proportionally more, so 12G leaves room for several million. 2 MB pages are worth setting.
  • The acl-plugin stanza's hash lookup heap size and hash lookup hash memory have no effect on current VPP; hash lookup hash buckets (default 65536) is optional tuning for very large rule sets.
  • rss { ipv4 ipv6 } is not optional for dual-stack work. Without ipv6 in the list the NIC hashes the whole family to one queue, and one worker.

Performance notes

Classification cost follows the ACL plugin's TupleMerge lookup: it depends on how many distinct mask types the rule set produces, not on the number of rules. Rules that constrain packet length, DSCP or fragment flags cost a re-check when they are candidates. Later fragments are looked up through the hash too, and the lookup never writes the ACL plugin's shared hit counter, so a single rule hit by every worker does not contend on one cache line. Every rule change rebuilds the ACL -- about 0.4 s at a million rules -- so a large rule set is best loaded with the batch API.

Sustaining 100 Gbps at small frame sizes requires the usual VPP data-plane hygiene: multiple worker threads each pinned to a dedicated core, RSS spreading traffic across as many receive queues as there are workers, isolated cores (isolcpus, nohz_full, rcu_nocbs), and C-states limited.

Relationship to the commercial edition

This Community Edition is a complete, self-contained filter. A separately licensed commercial edition adds a flexible match engine (arbitrary offset/length/bitmask conditions), named prefix sets for large IP lists, and additional actions. Nothing in this repository depends on those components.

Licence

Apache License 2.0 — see LICENSE.

About

FastACL Community - line rate capable in line filtering for VPP

Resources

Stars

17 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages