Home / Alt manpages / tc-matchall(8)

  • tc-matchall(8)
  • Admin command
  • linux

Mirror or Sample Every Packet with tc matchall

tc's matchall filter has no conditions at all: it grabs every packet at a hook, which makes it the tool for mirroring or sampling traffic wholesale. You'll finish with a repeatable way to attach the filter, inspect the rule tc installed, and remove it again. The examples cover ingress mirroring and packet sampling.

  • Time. About fifteen minutes, plus a maintenance window if the interface carries production traffic.
  • Tools. tc from iproute2 6.1.0, a root shell or sudo, and two interface names if you're mirroring.

Read-only inspection needs no elevated privileges; adding qdiscs and filters normally does.

Checkpoint

This guide follows the installed tc-matchall(8) manpage, from iproute2 6.1.0-1ubuntu6.4. Current upstream documentation can use newer clsact examples, so keep the local syntax together when reproducing these commands.

1. Confirm the command and interfaces

Start with read-only checks. Replace the placeholder names only once you've identified the real devices:

$ tc -V
tc utility, iproute2-6.1.0, libbpf 1.3.0
$ ip -br link
$ tc qdisc show dev SOURCE_IFACE

Set SOURCE_IFACE to the interface whose packets you want to inspect and DEST_IFACE to a separate capture or monitoring interface. Do not choose either by pattern-matching a name, and never mirror a production interface to an untrusted port.

The last command shows whether the interface already has an ingress or root qdisc. Record that output before changing anything: a qdisc belongs to the interface, not to your shell session, and another administrator or service may already depend on it.

2. Create an ingress hook

An ingress qdisc with handle ffff: gives an ingress filter somewhere to attach:

$ sudo tc qdisc add dev SOURCE_IFACE handle ffff: ingress
$ sudo tc qdisc show dev SOURCE_IFACE
qdisc ingress ffff: dev SOURCE_IFACE parent ffff:fff1

Exact counters and formatting vary; seeing an ingress qdisc with handle ffff: is the check that matters. If the add command says the qdisc already exists, stop and inspect the existing setup rather than replacing it to make the example fit.

Warning

Adding traffic-control state changes packet handling immediately. Test on a spare interface or in a maintenance window first. If you created this ingress qdisc solely for the example, the recovery command is in step 6; it removes every ingress filter on that interface, so do not use it where the qdisc is shared.

3. Mirror every ingress packet

Attach the matchall filter with a generic mirred action. This copies matching traffic to the destination device; it does not move the original packet:

$ sudo tc filter add dev SOURCE_IFACE parent ffff: \
    matchall skip_sw \
    action mirred egress mirror \
    dev DEST_IFACE
  • skip_sw requests hardware processing only. Fine when the interface and driver support traffic-control offload; the command fails if they don't.
  • skip_hw forces software processing instead. Or omit both flags to let tc use whatever path is available:
$ sudo tc filter add dev SOURCE_IFACE parent ffff: \
    matchall skip_hw \
    action mirred egress mirror \
    dev DEST_IFACE

Do not install both examples: each adds another rule and can duplicate the mirrored traffic. A destination that feeds the source again creates a forwarding loop, so use a monitoring port or an isolated capture path.

Checkpoint

Inspect the filter rather than trusting a successful exit status:

$ sudo tc filter show dev SOURCE_IFACE parent ffff:
filter protocol all pref 49152 matchall
        action order 1: mirred (Egress Mirror to device DEST_IFACE) stolen

Preference numbers, action details and counters can differ; the output should identify matchall and the intended destination.

4. Sample instead of mirroring

Sampling earns its keep when a full copy would swamp the capture path. The manpage's sample action sends one packet in every 100 to psample group 12:

$ sudo tc qdisc add dev SAMPLE_IFACE handle ffff: ingress
$ sudo tc filter add dev SAMPLE_IFACE parent ffff: \
    matchall \
    action sample rate 100 group 12
$ sudo tc filter show dev SAMPLE_IFACE parent ffff:

This needs a consumer for the psample group: installing the filter alone prints nothing in your terminal. The group number is an integration value, so pick one your monitoring software expects and do not assume group 12 is globally special.

If you add a sample rule after the mirror rule on the same parent, both actions can run. Give each test interface one purpose, or inspect the full filter list and remove rules you no longer need.

5. Understand classid and direction

An action is optional. Instead, classid CLASSID sends every matching packet into a class on the attached qdisc; the class must already exist and the value is parsed as hexadecimal. Do not add a classid to an ingress example unless you've deliberately built the matching classful qdisc.

Ingress and egress are different hooks; the commands above attach to ingress. For egress mirroring, the installed manpage uses a root prio qdisc and attaches the filter to its parent:

$ sudo tc qdisc add dev SOURCE_IFACE handle 1: root prio
$ sudo tc filter add dev SOURCE_IFACE parent 1: \
    matchall skip_sw \
    action mirred egress mirror \
    dev DEST_IFACE

Warning

A root qdisc controls the interface's outgoing traffic. Adding this command can replace an existing root qdisc and disrupt shaping or queuing. Only use it after saving the current configuration and confirming this test owns the interface. Prefer a dedicated test device.

6. Verify and remove the test state

Generate a small amount of known traffic, then check counters or the capture consumer. For a read-only view of the current setup:

$ sudo tc -s filter show dev SOURCE_IFACE parent ffff:
$ sudo tc qdisc show dev SOURCE_IFACE

Rising counters confirm packets reached the filter. They don't prove a capture application decoded every copy, nor that hardware offload behaved exactly like software processing.

Remove the filter before removing its parent. If the interface has no other ingress filters and you created the qdisc for this test, remove the whole ingress qdisc:

$ sudo tc qdisc del dev SOURCE_IFACE ingress
$ sudo tc qdisc show dev SOURCE_IFACE

This is deliberately broad: it removes the ingress qdisc and every filter below it. If other rules exist, restore the configuration you recorded in step 1 instead of running a blind deletion. For the egress example, restore the previous root qdisc from your saved configuration; tc qdisc del dev SOURCE_IFACE root can remove more than this guide created.

7. Diagnose the common failures

  • File exists: a qdisc or filter is already present. Show the qdisc and filters, then choose a dedicated parent or coordinate a change.
  • Operation not supported with skip_sw: hardware offload is unavailable or disabled. Remove that requirement only after deciding software processing is acceptable.
  • No mirrored packets: confirm the filter direction, destination interface, destination capture process and counters. A successful add command does not create a listener.
  • Duplicate traffic: show all filters under the parent. Two matchall actions both match every packet; remove the extra rule or use separate test interfaces.

Done means

  • Version and state recorded. You confirmed the installed iproute2 version and recorded the existing qdisc state.
  • Filter attached correctly. A matchall rule sits on the intended ingress or egress hook.
  • Offload flag matches reality. You selected skip_sw, skip_hw or neither based on the actual offload requirement.
  • Output confirms it. tc filter show identifies the intended action and destination.
  • You know which mode you tested. Mirroring or psample, and how to restore the previous qdisc configuration.
  • Cleanup is done or documented. Temporary filters and qdiscs are removed, or their persistent ownership is written down.