TC ingress filters

tcfilter and luci-app-tcfilter manage persistent tc filter … ingress rules through UCI, with a LuCI front-end and a live status view. Their purpose is to drive hardware tc-flower offload (for example the Realtek DSA PIE engine) on targets where no higher-level configuration layer for it exists.

Not in a stable release yet. Tracked upstream in:

Discussion and testing feedback: forum thread.

tcfilter does not model the flower match/action fields. The match and the action are written verbatim as tc syntax in option spec; the package owns the lifecycle:

  • one config rule per filter — device, pref, spec, enabled, optional cosmetic label
  • pref is mandatory — it is how a rule is removed again
  • rules are applied at boot, re-applied on ifup and on netdev add (hotplug), removed on stop
  • a procd reload trigger re-applies on config changes, so LuCI Save & Apply and uci commit tcfilter && reload_config take effect on their own
  • installed (device, pref) pairs are tracked in /var/run/tcfilter.state, so a rule deleted from the config is still torn down on the next reload
  • the clsact qdisc is added if missing but never removed (other users may share it); only the individual filters are deleted

luci-app-tcfilter adds Network → TC Filters: a grid to edit the rules plus a status table below it, polled every 5 s, parsing tc -s -j filter show … ingress — protocol, match, offload flag (skip_sw / skip_hw), in_hw, action, packet count, label.

Not packaged in a release or the snapshot feeds yet. Build tcfilter and luci-app-tcfilter from the pull requests above, or wait for them to reach the snapshot repositories, after which the usual applies:

apk update
apk add luci-app-tcfilter

Both are PKGARCH:=all. tcfilter pulls in tc-full (the full iproute2 tc); the BusyBox tc cannot do flower or JSON output.

Pre-built packages for realtek/rtl930x testing are linked from the forum thread.

/etc/config/tcfilter:

config tcfilter 'global'
	option enabled '1'

config rule
	option label   'Drop-mDNS (IPv4)'
	option device  'lan1'
	option pref    '49153'
	option spec    'protocol ip flower ip_proto udp dst_port 5353 skip_sw action drop'
	option enabled '1'

spec is everything that would follow

tc filter add dev <device> ingress pref <pref>

i.e. the optional protocol, the filter kind and its match, and the action. Use skip_sw so a match the hardware cannot offload fails loudly instead of silently installing in software.

The shipped config carries a few disabled examples (AVM FRITZ!Box powerline discovery, mDNS) — set device, flip enabled to 1.

Option Required Description
device yes network device the filter is attached to
pref yes tc preference number; how the rule is identified and removed
spec yes the match + action, verbatim tc syntax
enabled no (default 1) apply this rule
label no cosmetic; shown in log messages and the LuCI view
/etc/init.d/tcfilter start | stop | reload | show
/etc/init.d/tcfilter reapply_dev lan1

On the Realtek DSA target a flower … skip_sw ingress rule is programmed into the switch PIE engine. Several driver fixes were needed to make that path usable; all are in the pull requests linked above. Verified on a Zyxel XGS1210-12 (RTL9302C):

  • per-rule tc -s hardware packet counters work for every offloaded rule, not only the one that lands on PIE rule id 0
  • dst_port / src_port matching offloads precisely — previously a dst_port 5353 rule silently degraded to “drop all UDP
  • generic EtherType matching, ARP / IPv4 / IPv6 fast paths, drop / trap / redirect actions, per-port binding via the source-port mask

Combining an L3 address match with an L4 port match in one offloaded rule is rejected (-EOPNOTSUPP) on this hardware — the ingress PIE blocks do not carry a template with both fields. A plain dst_port match works.

  • ingress / clsact only
  • no dry-run validation — an invalid spec is reported via logread only
  • the free-form spec is passed to tc by word-split (no shell); anyone who can edit the config can install redirect / mirror rules
  • Last modified: 2026/09/04 12:34
  • by mab-wien