ematch(8)
okay bestie, welcome to ematch(8) on Linux ๐ this is the page for extended matches, the fancy little rules you bolt onto basic, cgroup or flow filters โจ
โจ NAME โจ
ematch is the extended match system for the basic, cgroup or flow filters. It's giving precision ๐
โจ SYNOPSIS โจ
tc filter add .. basic match EXPR .. flowid ..
EXPR := TERM [ { and | or } EXPR ]
TERM := [ not ] { MATCH | '(' EXPR ')' }
MATCH := module '(' ARGS ')'
ARGS := ARG1 ARG2 ..
โจ MATCHES โจ
Okay so here's the menu of matches you can pick from ๐
๐ cmp
Simple comparison ematch. It does an arithmetic compare of packet data against a value you give it, so you're basically asking "is this bigger, smaller, or equal?" ๐ฆ
cmp( ALIGN at OFFSET [ ATTRS ] { eq | lt | gt } VALUE )
ALIGN := { u8 | u16 | u32 }
ATTRS := [ layer LAYER ] [ mask MASK ] [ trans ]
LAYER := { link | network | transport | 0..2 }
๐ธ meta
Metadata ematch. It checks metadata about the packet instead of the bytes ๐ง
meta( OBJECT { eq | lt |gt } OBJECT )
OBJECT := { META_ID | VALUE }
META_ID := id [ shift SHIFT ] [ mask MASK ]
Here are the meta attributes you can use:
randomโ a random 32 bit value ๐ฒloadavg_1โ load average over the last 5 minutesnf_markโ the Netfilter mark ๐ฅvlanโ the VLAN tagsk_rcvbufโ the receive buffer sizesk_snd_queueโ the send queue length
Want the full list? Just run this and it'll spill all the tea:
# tc filter add dev eth1 basic match 'meta(list)'
๐ nbyte
Matches a packet data byte sequence. Basically you hunt for a specific string of bytes ๐
nbyte( NEEDLE at OFFSET [ layer LAYER ] )
NEEDLE := { string | c-escape-sequence }
OFFSET := int
LAYER := { link | network | transport | 0..2 }
๐ซถ u32
The u32 ematch, bestie. Pretty straightforward ๐
u32( ALIGN VALUE MASK at [ nexthdr+ ] OFFSET )
ALIGN := { u8 | u16 | u32 }
๐ ipset
Tests a packet for ipset membership โจ
ipset( SETNAME FLAGS )
SETNAME := string
FLAGS := { FLAG [, FLAGS] }
The flag options are the same ones you'd use with the iptables "set" match, so if you already know that, you're set ๐
When you use the ipset ematch with the "ip_set_hash:net,iface" set type, you can query the interface with "src,dst" (source ip address, outgoing interface) or "src,src" (source ip address, incoming interface) syntax ๐ฆ
๐ ipt
Tests a packet against xtables matches ๐
ipt( [-6] -m MATCH_NAME FLAGS )
MATCH_NAME := string
FLAGS := { FLAG [, FLAGS] }
The flag options are the same ones the xtables match you picked uses. So check that match's flags and you're golden โญ
๐ง canid
ematch rule to match CAN frames ๐
canid( IDLIST )
IDLIST := IDSPEC[IDLIST]
IDSPEC := { โsffโ CANID | โeffโ CANID }
CANID := ID[:MASK]
ID, MASK := hexadecimal number (i.e. 0x123)
โจ CAVEATS โจ
bestie, read this part carefully ๐ญ The ematch syntax uses '(' and ')' to group expressions. All braces need to be escaped properly so the shell commandline doesn't grab them and mess everything up ๐
When you use the ipset ematch with the "ifb" device, the outgoing device will be the ifb device itself, e.g. "ifb0". The original interface (i.e. the device the packet arrived on) is treated as the incoming interface.
โจ EXAMPLE & USAGE โจ
Here's the vibe. You start every one of these with the usual filter command ๐
# tc filter add .. basic match ...
# 'cmp(u16 at 3 layer 2 mask 0xff00 gt 20)'
# 'meta(nfmark gt 24)' and 'meta(tcindex mask 0xf0 eq 0xf0)'
# 'nbyte("ababa" at 12 layer 1)'
# 'u32(u16 0x1122 0xffff at nexthdr+4)'
Check if the packet's source ip address is a member of the set named bulk:
# 'ipset(bulk src)'
Check if the packet's source ip and the interface it arrived on are a member of the "hash:net,iface" set named interactive:
# 'ipset(interactive src,src)'
Check if the packet matches an IPSec state with reqid 1:
# 'ipt(-m policy --dir in --pol ipsec --reqid 1)'
โจ AUTHOR โจ
The extended match infrastructure was added by Thomas Graf. Iconic behavior ๐
that's the whole page, bestie ๐ซถ it's from iproute2, dated 6 August 2012, and the manual is ematch(8). stay iconic ๐ โจ
๐ฆ where this page comes from
- alpine 3.22: iproute2-doc 6.15.0-r0 ยท GPL-2.0-or-later
- alpine 3.23: iproute2-doc 6.17.0-r0 ยท GPL-2.0-or-later
- alpine 3.24: iproute2-doc 7.0.0-r0 ยท GPL-2.0-or-later
- arch rolling: iproute2 7.2.0-1
- arch rolling: iproute2 7.3.0-1 ยท GPL-2.0-or-later
- centos-stream 10: iproute-tc 7.0.0-2.el10 ยท GPL-2.0-or-later
- centos-stream 9: iproute-tc 6.17.0-3.el9 ยท GPL-2.0-or-later
- debian bookworm: iproute2 6.1.0-3 ยท GPL-2.0-only
- debian trixie: iproute2 6.15.0-1 ยท GPL-2.0-only
- fedora 43: iproute-tc 6.14.0-2.fc43 ยท GPL-2.0-or-later
- fedora 44: iproute-tc 6.17.0-2.fc44 ยท GPL-2.0-or-later
- nixos 26.05: iproute2 7.0.0
- nixpkgs unstable: iproute2 7.2.0
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- ubuntu jammy: iproute2 5.15.0-1ubuntu2 ยท GPL-2.0-only
- ubuntu jammy: iproute2 5.15.0-1ubuntu2.2 ยท GPL-2.0-only
- ubuntu noble: iproute2 6.1.0-1ubuntu6 ยท GPL-2.0-only
- ubuntu noble: iproute2 6.1.0-1ubuntu6.4 ยท GPL-2.0-only
- ubuntu questing: iproute2 6.16.0-1ubuntu2
- ubuntu questing: iproute2 6.16.0-1ubuntu2.1 ยท GPL-2.0-only
- ubuntu questing: iproute2 6.16.0-1ubuntu2.2
- ubuntu resolute: iproute2 6.19.0-1ubuntu1 ยท GPL-2.0-only
- ubuntu resolute: iproute2 6.19.0-1ubuntu1.1 ยท GPL-2.0-only
- ubuntu stonking: iproute2 7.2.0-1ubuntu1 ยท GPL-2.0-only
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms