FastACL is an inline packet-filtering plugin for FD.io VPP. It receives traffic diverted to a scrubbing appliance, matches it against an ordered set of RFC 8955 (IPv4) / RFC 8956 (IPv6) FlowSpec rules, and applies an action — drop, rate-limit, or DSCP re-mark — to matching packets while forwarding the rest untouched.
This document is the operator reference: everything a system administrator needs to configure, run, and monitor FastACL from the VPP CLI. All commands are issued through vppctl (either vppctl <command> or interactively inside vppctl).
1. Concepts
- Rule — an ordered match/action entry. A packet is tested against all rules; the highest-precedence matching rule decides its fate.
- Order — the operator-assigned precedence of a rule (
order <N>). Lower order wins. Ties are broken by RFC 8955 §5.1 FlowSpec precedence, then by insertion order. - Index — the internal slot a rule occupies, shown in the
Indexcolumn ofshow fastacl rules.fastacl rule deltakes the index, not the order. - Match — one or more components (destination prefix, ports, TCP flags, …). A rule matches only when all its components match.
- Action — what happens to a matching packet:
drop,rate-limit, ordscp-mark. - TSS classifier — internally, rules that share the same shape (which fields they match on) are grouped into a "tuple" and looked up in a hash, so lookup cost scales with the number of distinct rule shapes, not the number of rules. This is transparent to the operator but visible in
show fastacl tuples. - Datapath modes — FastACL runs in either bridge mode (transparent L2 cross-connect between two ports) or routed mode (on the IPv4/IPv6 unicast path). The same rules and commands apply to both; only the interface wiring differs (see §3).
2. Startup configuration
FastACL is a VPP plugin. Enable it and optionally tune it in /etc/vpp/startup.conf:
plugins {
plugin fastacl_plugin.so { enable }
}
fastacl {
tss-bihash-buckets 65536
tss-bihash-memory-mb 128
}
| Stanza key | Default | Meaning |
|---|---|---|
tss-bihash-buckets <N> | 65536 | Hash buckets allocated per rule-shape (tuple). Raise for very large rule sets. Values below 1024 are clamped up. |
tss-bihash-memory-mb <N> | 128 | Memory cap (MB) per tuple hash. Values below 1 are clamped up. |
The fastacl { } stanza is optional; with no stanza the defaults above apply. Changes take effect at VPP start.
3. Enabling the filter on an interface
The filter is armed per interface. Nothing is filtered until you enable it.
set interface fastacl <interface> [enable | disable]
enable is the default when neither keyword is given. Enabling attaches the filter to both the routed (ip4-unicast / ip6-unicast) and bridged (l2-input) arcs of the interface; the unused arc stays dormant, so the same command works for both datapath modes.
Bridge mode — transparently filter traffic passing between two ports:
set interface l2 xconnect pg0 pg1 set interface l2 xconnect pg1 pg0 set interface fastacl pg0 set interface fastacl pg1
Routed mode — filter on an interface's IP path:
set interface fastacl TenGigabitEthernet0/0/0
List the interfaces that currently have the filter armed:
vpp# show fastacl interface pg0 pg1
Disable on one interface:
vpp# set interface fastacl pg0 disable fastacl disabled on pg0
4. Managing rules
4.1 Add a rule
Use the following syntax to add a rule:
fastacl rule add order <N>
[dst <ip4>/<len>] [dst6 <ip6>/<len>]
[src <ip4>/<len>] [src6 <ip6>/<len>]
[proto <N>]
[dst-port <N>[-<N>]] [src-port <N>[-<N>]] [either-port <N>[-<N>]]
[icmp-type <N>] [icmp-code <N>]
[tcp-flags value <hex> mask <hex>]
[pkt-len <N>[-<N>]]
[dscp <N>]
[fragment <N>] | [fragment flags <hex> mask <hex>]
[flex-match offset <N> len <N> mask 0x<hex> value 0x<hex> [op <N>]]
action {drop | dscp-mark <0-63> | rate-limit <bps> burst <bytes>}
[sample <N> [group <N>]]
order <N> and an action are required; every match component is optional, but a rule with no match components matches all traffic.
On success, the command prints the assigned index:
vpp# fastacl rule add order 10 dst 203.0.113.0/24 proto 17 dst-port 53 action drop rule index 0 added
See §5 for the match components and §6 for the actions.
4.2 Rule precedence
Rules are evaluated by precedence and the lowest order value wins. Give your most specific / highest-priority rules the lowest order numbers. Leave gaps (10, 20, 30, …) so you can insert rules later without renumbering.
4.3 Delete a rule
fastacl rule del {<index> | all}
<index> is the value in the Index column of show fastacl rules — not the order. Deleting a non-existent index returns an error:
vpp# fastacl rule del 0 rule index 0 deleted vpp# fastacl rule del all all rules deleted vpp# fastacl rule del 999 fastacl rule del: fastacl_rule_del returned -6
Common mistake: fastacl rule del 50 when 50 was the rule's order deletes nothing (returned -6). Look up the index in show fastacl rules first.
4.4 Rebuild the index after a bulk load
fastacl rule-reindex
When rules are loaded in bulk through the binary API, run rule-reindex once afterward to rebuild the TSS lookup index:
vpp# fastacl rule-reindex reindexed: 10 rules, 8 tuples, .011 s
Rules added one at a time through fastacl rule add are indexed immediately and do not need this.
5. Match components
All 12 RFC 8955/8956 match types are supported, for both IPv4 and IPv6. A rule matches only when every component present matches.
| Keyword | Type | Semantics | Example |
|---|---|---|---|
dst <ip4>/<len> | 1 | IPv4 destination prefix | dst 203.0.113.0/24 |
dst6 <ip6>/<len> | 1 | IPv6 destination prefix | dst6 2001:db8::/32 |
src <ip4>/<len> | 2 | IPv4 source prefix | src 198.51.100.0/24 |
src6 <ip6>/<len> | 2 | IPv6 source prefix | src6 2001:db8:a::/48 |
proto <N> | 3 | IP protocol / IPv6 next-header (exact) | proto 17 (UDP) |
dst-port <N>[-<N>] | 4 | Destination port or range | dst-port 80-443 |
src-port <N>[-<N>] | 5 | Source port or range | src-port 1024-65535 |
either-port <N>[-<N>] | 6 | Source or destination port in range | either-port 5000-6000 |
icmp-type <N> | 7 | ICMP / ICMPv6 type (exact) | icmp-type 8 |
icmp-code <N> | 8 | ICMP / ICMPv6 code (exact) | icmp-code 0 |
tcp-flags value <hex> mask <hex> | 9 | TCP flags: match value over the masked bits | tcp-flags value 0x02 mask 0x02 (SYN) |
pkt-len <N>[-<N>] | 10 | IP total length or range | pkt-len 0-64 |
dscp <N> | 11 | DSCP value (exact, 0–63) | dscp 46 |
fragment <N> | 12 | Fragment flags (see below) | fragment 2 |
flex-match … | — | Arbitrary offset/mask/value (see §5.2) | See below |
Ports and lengths accept either a single value (dst-port 53) or an inclusive range (dst-port 80-443). Protocol, DSCP, and ICMP type/code are exact matches.
5.1 Fragment flags
fragment <N> matches the fragmentation state, where <N> is the OR of:
| Bit | Value | Meaning |
|---|---|---|
| DF | 1 | Don't-Fragment set |
| IsF | 2 | Is a fragment (MF set, or offset > 0) |
| FF | 4 | First fragment (MF set, offset == 0) |
| LF | 8 | Last fragment (MF clear, offset > 0) |
fragment <N> uses <N> as both the required bits and the mask. For finer control use the explicit form fragment flags <hex> mask <hex>, e.g. fragment flags 0x2 mask 0x2 to match "is a fragment" regardless of the other bits. Hex (0x2) and decimal (2) are both accepted.
5.2 Flexible match
flex-match offset <N> len <N> mask 0x<hex> value 0x<hex> [op <N>]
Reads len bits (8, 16, or 32) at byte offset from the start of the Ethernet frame, applies mask, and compares against value using operator op:
| op | Comparison |
|---|---|
| 0 (default) | field == value |
| 1 | field < value |
| 2 | field > value |
| 3 | low ≤ field ≤ high (value packs min in the low 16 bits, max in the high 16) |
Up to 4 flex conditions may be combined in one rule.
Example — match the two bytes at offset 34:
flex-match offset 34 len 16 mask 0xffff value 0x1234
6. Actions
Every rule carries exactly one action.
| Action | Effect |
|---|---|
drop | Discard matching packets. |
dscp-mark <0-63> | Rewrite the packet's DSCP to the given value (0–63) and forward it. The IP checksum is fixed up automatically. |
rate-limit <bps> burst <bytes> | Police matching traffic to <bps> bits/sec with a <bytes> token-bucket burst. Conforming packets are forwarded; excess is dropped. Policing is per-rule (not per-flow). |
dscp-mark validates its argument — out of range is rejected:
vpp# fastacl rule add order 5 proto 6 action dscp-mark 99 fastacl rule add: dscp value must be 0-63
Examples:
fastacl rule add order 10 dst 203.0.113.0/24 proto 17 dst-port 53 action drop fastacl rule add order 20 proto 6 dst-port 80-443 action rate-limit 1000000000 burst 262144 fastacl rule add order 30 src 198.51.100.0/24 action dscp-mark 46
6.1 Sampling modifier
Append sample <N> [group <N>] to any rule to mirror 1-in-N matching packets to the kernel psample channel (see §8).
group <N> sets the psample group ID (default 0).
fastacl rule add order 100 proto 17 dst-port 123 action drop sample 1000
7. Monitoring and counters
7.1 List rules
vpp# show fastacl rules Index Order Dst Prefix Src Prefix Proto Match Extra Action Packets Bytes pps L3 bps L1 bps 0 10 203.0.113.0/24 * 17 dp=53 drop 0 0 0.0 pps 0.0 bps 0.0 bps 1 20 * * 6 dp=80-443 rate-limit 1 0 0 0.0 pps 0.0 bps 0.0 bps 2 30 * 198.51.100.0/24 * * dscp-mark 46 0 0 0.0 pps 0.0 bps 0.0 bps
The Action column is width-limited, so a long rate-limit rate is truncated in this view (e.g. rate-limit 1 above is the 1 Gbps rule) — the configured value is unaffected.
The Match Extra column encodes the non-prefix match components: dp= / sp= / ep= (dst/src/either port), fl=value/mask (TCP flags), len= (packet length), frag= (fragment flags), icmp-t= / icmp-c=, flex(offset,len,mask,value,op). * means "any".
When there are no rules the command prints no rules configured.
The Packets / Bytes columns are the per-rule totals and pps / L3 bps / L1 bps are live rates. L3 bps is the IP-layer rate; L1 bps adds the on-the-wire framing overhead and matches what a traffic generator reports. This is the per-rule counter view — there is no separate counters command.
7.2 Aggregate counters
vpp# show fastacl aggregate-counters
Aggregate counters:
Packets Bytes pps L3 bps L1 bps
Processed: 5 (5) 300 (300 B) 2.7 pps 1.3 Kbps 2.1 Kbps
Dropped: 5 (5) 300 (300 B) 2.7 pps 1.3 Kbps 2.1 Kbps
Plugin-wide totals: Processed is everything the filter saw; Dropped is what a rule discarded.
7.3 Clear counters
vpp# clear fastacl counters counters cleared
Zeroes all per-rule and aggregate counters. Rules themselves are untouched.
7.4 TSS classifier state
vpp# show fastacl tuples tuples: 8, ipv6 fallback: 1 rules id flags dplen splen v6 rules buckets 0 0xd 24 0 0 1 0 1 0xc 0 0 0 2 0
Diagnostic view of the internal classifier: one row per rule shape (tuple), how many rules share it, and the prefix lengths that define it. Useful for capacity planning — the number of tuples, not the number of rules, drives lookup cost.
8. Traffic sampling (psample)
FastACL can mirror a fraction of matching packets to the Linux psample netlink channel, where tools such as tcpdump / libpsample consumers or a flow collector can read them.
fastacl psample {enable | disable}
Sampling requires the kernel psample module. If it is not loaded, enabling reports:
vpp# fastacl psample enable fastacl psample: psample netlink family not found - is the psample module loaded?
Load it with modprobe psample on the host first. Per-rule sampling is armed with the sample <N> [group <N>] modifier on fastacl rule add (§6.1).
Inspect sampling state and per-rule sample counts:
vpp# show fastacl sampling psample: disabled rule ratio group sampled send-failed 9 1:1000 0 0 0
9. Common operational recipes
Blackhole a victim prefix's DNS reflection traffic:
fastacl rule add order 10 dst 203.0.113.0/24 proto 17 dst-port 53 action drop
Rate-limit inbound HTTP/HTTPS to 1 Gbps:
fastacl rule add order 20 proto 6 dst-port 80-443 action rate-limit 1000000000 burst 262144
Drop TCP SYN floods to a host:
fastacl rule add order 30 dst 203.0.113.10/32 proto 6 tcp-flags value 0x02 mask 0x02 action drop
Drop small-packet floods (≤ 64-byte frames):
fastacl rule add order 40 pkt-len 0-64 action drop
Drop an IPv6 ICMPv6 echo flood:
fastacl rule add order 50 dst6 2001:db8::/32 proto 58 icmp-type 128 action drop
Watch the effect, then clear the stats:
show fastacl rules show fastacl aggregate-counters clear fastacl counters
10. Troubleshooting
| Symptom | Cause / fix |
|---|---|
fastacl rule del … returned -6 | The index does not exist. fastacl rule del takes the index (show fastacl rules), not the order. |
dscp value must be 0-63 | dscp-mark argument out of range. |
| Rule added but nothing is filtered | The filter is not armed on the interface — run set interface fastacl <if> and confirm with show fastacl interface. |
psample netlink family not found | Kernel psample module not loaded — modprobe psample on the host. |
| Two rules overlap and the wrong one applies | Precedence is by lowest order. Give the intended rule a lower order value. |
unknown input '…' | A keyword or value was mistyped. Check the syntax in §4.1. |
11. Command quick reference
| Command | Purpose |
|---|---|
set interface fastacl <if> [enable|disable] | Arm / disarm the filter on an interface |
show fastacl interface | List armed interfaces |
fastacl rule add order <N> … action {…} | Add a rule |
fastacl rule del {<index>|all} | Delete a rule (by index) or all rules |
fastacl rule-reindex | Rebuild the index after a bulk API load |
show fastacl rules | List rules with match/action and per-rule counters |
show fastacl aggregate-counters | Plugin-wide processed/dropped totals |
show fastacl tuples | TSS classifier state (diagnostic) |
clear fastacl counters | Zero all counters |
fastacl psample {enable|disable} | Turn packet sampling on/off |
show fastacl sampling | Sampling state and per-rule sample counts |
