TC-TUNNEL_KEY(8)

๐Ÿ“ฆ
version 7.3.0 ยท 3 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, centos-stream 9, debian trixie, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

โœจ 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 need src_ip and dst_ip for this one. id, dst_port, geneve_opts, vxlan_opts and erspan_opts are 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 is CLASS:TYPE:DATA. CLASS is a 16bit hexadecimal value, TYPE is an 8bit hexadecimal value, and DATA is 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 just GBP, a 32bit number. Heads up, multiple options aren't supported here ๐Ÿ™ˆ
    • erspan_opts โ€” ERSPAN metadata options ๐Ÿงš The format is VERSION:INDEX:DIR:HWID. VERSION is an 8bit number, INDEX is a 32bit number, and DIR and HWID are each an 8bit number. Multiple options aren't supported ๐Ÿ’€ Also, INDEX is used when VERSION is 1, and DIR and HWID are used when VERSION is 2 ๐Ÿซถ
    • tos โ€” outer header TOS ๐Ÿ’…
    • ttl โ€” outer header TTL ๐Ÿ’…
    • [no]csum โ€” controls the outer UDP checksum ๐Ÿ”ฅ With csum (the default), the outer UDP checksum gets calculated and included in the packets. With nocsum, 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 the udp6zerocsumrx option 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 ๐Ÿ“š


iproute2 ยท 10 Nov 201โ€ฆ ๐Ÿ’– Stay iconic, bestie, and see you in the next packet ๐Ÿซถโœจ