Home / Alt manpages / tc-simple(8)

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

Test tc ingress matches with the simple action

You will attach iproute2's simple action to an ingress filter, make it print a message when a matching packet arrives, inspect the filter counter, and remove the test configuration. This is a diagnostic exercise, not a production traffic-control design: the action is described by its manual page as a pedagogical example. Allow about 15 minutes, plus time to arrange a packet that matches your chosen filter.

The examples target the installed Ubuntu package iproute2 6.1.0-1ubuntu6.4, whose tc reports iproute2 6.1.0. The kernel module is present here as act_simple on kernel 6.8. Your filter syntax or module packaging can differ on another release.

1. Check the tools and choose an interface

You need root privileges for the commands that add or remove a qdisc and filter. Reading the version, interface list and kernel log is normally unprivileged, although reading all kernel messages may be restricted by your system policy. Choose an interface that will receive a harmless test packet. Replace eth0 below with its real name.

$ tc -V
tc utility, iproute2-6.1.0, libbpf 1.3.0
$ ip -br link
$ modinfo act_simple | sed -n '1,8p'

If modinfo cannot find act_simple, stop here and check whether your kernel was built with the example action. Do not improvise a different action name. The action is loaded when the kernel needs it on systems that provide it, or it can be loaded explicitly with sudo modprobe act_simple if your normal kernel-module policy permits that.

2. Add an ingress hook

Ingress is the point where packets arrive at the device. Adding this qdisc changes the live interface, so do it only on an interface where a short diagnostic interruption is acceptable. The command requires elevation:

$ sudo tc qdisc add dev eth0 ingress

Confirm that the hook exists before adding the filter:

$ tc qdisc show dev eth0
qdisc ingress ffff: parent ffff:fff1 ----------------

The handle and spacing can vary. The useful result is an ingress qdisc for the selected device. If the command says that one already exists, do not add a second copy. Inspect it with tc qdisc show dev eth0 and continue only if it is the test hook you intend to use.

3. Match ICMP and print a message

The filter below follows the installed tc-simple(8) example. It selects IPv4 ICMP by matching protocol number 1, then invokes the simple action. The 0xff mask says that all eight protocol bits are significant. This is an elevated command and changes packet processing on eth0:

$ sudo tc filter add dev eth0 parent ffff: protocol ip prio 5 \
    u32 match ip protocol 1 0xff flowid 1:1 \
    action simple sdata "Incoming ICMP"

sdata is the string printed each time the action is reached. index is optional; omit it here and the kernel assigns an action index. The action also accepts a control result such as ok, drop, continue, pipe or reclassify. Do not add one casually: those values decide what tc does after the action, and the default behaviour is not a substitute for choosing a policy you understand.

Check that the filter and action are installed:

$ tc -s filter show dev eth0 parent ffff:
filter protocol ip pref 5 u32
    ...
    action order 1: Simple <Incoming ICMP>
    ...
    Sent 0 bytes 0 pkt ...

Your output contains generated classifier handles and more statistics. Before traffic arrives, the packet count should be zero or otherwise show no new match from this test.

4. Generate one matching packet

From another host, or from a separate terminal using a destination that will answer, send one IPv4 ping to the address represented by eth0. The exact destination is environment-specific:

$ ping -c 1 192.0.2.1

192.0.2.1 is documentation space and will not normally answer. Replace it with a reachable address on your test network. A failed ping can still produce an outgoing ICMP packet, but this filter is on ingress, so what matters is an ICMP packet arriving at eth0. An inbound echo request is the clearest test. Avoid sending test traffic across an interface carrying a sensitive service.

Look for the message in the kernel log. Depending on permissions and logging configuration, use one of these read-only checks:

$ sudo dmesg | grep 'simple: Incoming ICMP'
[... ] simple: Incoming ICMP
$ sudo journalctl -k -b --no-pager | grep 'simple: Incoming ICMP'

The manual shows the simple: prefix. Timestamps and the exact line format are kernel-specific. If no line appears, check the counter first. A counter increase means the filter matched even if the log is rate-limited, restricted, or viewed through a different kernel-log facility.

5. Verify the counter and understand a miss

Run the statistics query again:

$ tc -s filter show dev eth0 parent ffff:

Find the Simple <Incoming ICMP> action and compare its Sent ... pkt value with the earlier check. One matching packet should increase the packet count by one, although background traffic or repeated tests can make the number larger. The byte count records matched packet bytes.

If the count remains unchanged, check the common boundaries in order: the packet may have arrived on a different interface, it may have been IPv6 rather than IPv4, or it may not have been ICMP. Confirm the device and address family, then inspect the filter without changing it:

$ ip -br addr show dev eth0
$ tc filter show dev eth0 parent ffff:
$ tc -s filter show dev eth0 parent ffff:

The action does not inspect arbitrary application text. It prints only when the classifier reaches it, so changing sdata will not make a non-matching packet match.

6. Remove the temporary configuration

Remove the filter first, then the ingress qdisc. These commands require elevation and restore the interface to its pre-test traffic-control state only if the qdisc was created by this exercise. If you found an existing ingress qdisc in step 2, use its owner's documented cleanup instead.

$ sudo tc filter del dev eth0 parent ffff: protocol ip prio 5 u32
$ sudo tc qdisc del dev eth0 ingress
$ tc qdisc show dev eth0

The final query should no longer show the temporary ingress qdisc. If filter deletion reports that the classifier cannot be found, inspect the filter list and remove the exact test filter rather than deleting unrelated filters. If the qdisc deletion reports that it is absent, the hook may already have been removed; verify before retrying.

Done means

  • The installed tc and act_simple versions were checked.
  • An ingress filter matched the intended IPv4 ICMP packet.
  • The simple action message appeared in the kernel log, or its packet counter showed the match.
  • No production packet policy was inferred from this pedagogical action.
  • The temporary filter and ingress qdisc were removed, and the interface was checked afterwards.