TC-TUNNEL_KEY(8)
โจ tc-tunnel_key(8) โจ
Tunnel metadata action in tc(8) ๐ Linux
๐ซ NAME ๐ซ
tunnel_key โ okay so this is your tunnel metadata manipulation action ๐ซถ
๐ SYNOPSIS ๐
tc ... action tunnel_key { unset | SET }
SET := set src_ip ADDRESS dst_ip ADDRESS id KEY_ID dst_port UDP_PORT tos
TOS ttl TTL [ csum | nocsum ]
๐ฆ DESCRIPTION ๐ฆ
Okay bestie, so the tunnel_key action is giving tunnel vibes when it teams up with a shared IP tunnel device ๐ธ It lets you do IP tunnel en- or decapsulation on a packet, and the two modes are UNSET and SET โจ
UNSET is optional. Even if you skip it, the metadata gets released automatically once packet processing is done, so no stress ๐ It comes in handy when traffic is being forwarded between two tunnels, and the metadata from the first tunnel is used for the encapsulation done by the second one. Main character energy ๐
SET is the one that needs the source and destination IP ADDRESS plus the tunnel key id KEY_ID. The shared IP tunnel device uses those to build the tunnel header ๐ง Honestly the tunnel_key action is only really useful alongside a mirred redirect action to a shared IP tunnel device. That device is the one that uses the metadata (for SET) and unsets the metadata it created (for UNSET) ๐ฅ
๐ OPTIONS ๐
unsetโ unsets the tunnel metadata that the IP tunnel device created ๐ซง This isn't mandatory and only shows up in some specific use cases, as we covered above.setโ sets the tunnel metadata for the IP tunnel device to use ๐ You needsrc_ipanddst_ipfor this one.id,dst_port,geneve_opts,vxlan_optsanderspan_optsare optional bonuses โจidโ the tunnel ID (like the VNI in a VXLAN tunnel) ๐src_ipโ the outer header source IP address (IPv4 or IPv6) ๐ทdst_ipโ the outer header destination IP address (IPv4 or IPv6) ๐ทdst_portโ the outer header destination UDP port ๐ฆgeneve_optsโ Geneve variable length options ๐ฎ The format isCLASS:TYPE:DATA.CLASSis a 16bit hexadecimal value,TYPEis an 8bit hexadecimal value, andDATAis a variable length hexadecimal value. You can list several options at once by separating them with a comma ๐vxlan_optsโ VXLAN metadata options ๐ธ The format is justGBP, a 32bit number. Heads up, multiple options aren't supported here ๐erspan_optsโ ERSPAN metadata options ๐ง The format isVERSION:INDEX:DIR:HWID.VERSIONis an 8bit number,INDEXis a 32bit number, andDIRandHWIDare each an 8bit number. Multiple options aren't supported ๐ Also,INDEXis used whenVERSIONis 1, andDIRandHWIDare used whenVERSIONis 2 ๐ซถtosโ outer header TOS ๐ttlโ outer header TTL ๐[no]csumโ controls the outer UDP checksum ๐ฅ Withcsum(the default), the outer UDP checksum gets calculated and included in the packets. Withnocsum, the outer UDP checksum is zero. Note that if you use zero UDP checksums with IPv6, the other tunnel endpoint has to be configured to accept those packets. On Linux, that's theudp6zerocsumrxoption for the VXLAN tunnel interface ๐
๐ If you use nocsum with IPv6, make sure you actually know what you're doing. Zero UDP checksums give you weaker protection against corrupted packets. See RFC6935 for details.
nofragโ disallows IP fragmentation ๐ซ
๐ EXAMPLES ๐
Okay this first one is so cute ๐ It encapsulates incoming ICMP packets on eth0 into a vxlan tunnel. It sets the metadata to VNI 11, source IP 11.11.0.1 and destination IP 11.11.0.2, then redirects the packet with that metadata to the device vxlan0, which does the actual encapsulation using the metadata:
#tc qdisc add dev eth0 handle ffff: ingress
#tc filter add dev eth0 protocol ip parent ffff: \
flower \
ip_proto icmp \
action tunnel_key set \
src_ip 11.11.0.1 \
dst_ip 11.11.0.2 \
id 11 \
action mirred egress redirect dev vxlan0
And here's the unset function in action ๐ฆ Incoming VXLAN traffic with outer IPs and VNI 11 gets decapsulated by vxlan0, and the metadata is unset before it's redirected to the tunl1 device:
#tc qdisc add dev eth0 handle ffff: ingress
#tc filter add dev vxlan0 protocol ip parent ffff: flower \
enc_src_ip 11.11.0.2 enc_dst_ip 11.11.0.1 enc_key_id 11 action tunnel_key unset action mirred egress redirect dev tunl1
๐ SEE ALSO ๐
tc(8)๐ง
iproute2 ยท 10 Nov 201โฆ ๐ Stay iconic, bestie, and see you in the next packet ๐ซถโจ
๐ฆ 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 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 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