Skip to content

Instantly share code, notes, and snippets.

@iguanajuice
Forked from oskar456/README.md
Last active April 27, 2026 18:53
Show Gist options
  • Select an option

  • Save iguanajuice/c634f89bae7b51ec089c2cd400b67c43 to your computer and use it in GitHub Desktop.

Select an option

Save iguanajuice/c634f89bae7b51ec089c2cd400b67c43 to your computer and use it in GitHub Desktop.
CLAT for Linux using Jool and ipvlan PoC

CLAT for Linux using ipvlan

This proof of concept uses ipvlan feature of Linux to split up main network interface into two in order to use one in a separate namespace with jool-siit performing CLAT translation.

This way, enabling CLAT is least intrusive to the default network namespace - no need to enable forwarding or touch firewall rules.

UPDATE 2024-02-01: Rewritten to use L2 ipvlan. This allows multicast and therefore NDP to work in the ipvlan interface so the setup is even simpler and there is no need to enable proxy NDP in the main namespace. Also the IPv4 PtP link is set up more efficiently using /32 addresses and explicit peer definition.

UPDATE 2026-04-27: Added better error handling. Will cleanup and exit if problems are encountered. Truncates interface name to 12 characters to ensure the 15-character limit is not exceeded. Include systemd serivce file for easy startup.

This gist is inspired by a similar gist by Thomas Schäfer.

#!/bin/bash
IFACE="$1"
CLAT_IF="v4-${IFACE:0:12}"
[[ "$#" -ne 1 ]] && {
echo "Usage: $0 <IFACE>"
exit -1
}
NATPREFIX="64:ff9b::/96"
NS="clat-$IFACE"
JOOL_SIIT="$(which jool_siit)"
cleanup_and_exit() {
ip netns del $NS
exit 1
}
# Create network namespace
ip netns add $NS
# Load kernel module
modprobe jool_siit || cleanup_and_exit
# PtP link for IPv4 traffic from main NS to CLAT NS
ip link add name ${CLAT_IF} type veth peer clat-v4
ip link set dev clat-v4 netns $NS
ip link set up dev ${CLAT_IF}
# ipvlan link using secondary address on host interface
ip link add name clat-v6 link ${IFACE} type ipvlan mode l2
ip link set dev clat-v6 netns $NS
# Set up IPv4 PtP link
ip -4 address add 192.0.0.1 peer 192.0.0.0/32 dev ${CLAT_IF}
ip -4 route add default via 192.0.0.0 dev ${CLAT_IF} || cleanup_and_exit
# The rest of the magic happens inside the network namespace
ip netns exec $NS sh -e <<EOF
ip link set up dev clat-v4
ip link set up dev clat-v6
ip -4 address add 192.0.0.0 peer 192.0.0.1/32 dev clat-v4
sleep 2 # Make sure ipvlan interface is up and SLAAC has succeeded
CLATADDR=\$(ip -c=never -6 addr show dev clat-v6 | sed -rn 's_^.*inet6 *(2[0-9a-f:]*)/.*\$_\\1_p' | head -n 1)
echo CLAT is using IPv6 address \$CLATADDR
$JOOL_SIIT instance add --netfilter --pool6 $NATPREFIX
$JOOL_SIIT eamt add \$CLATADDR 192.0.0.1
EOF
[ $? -ne 0 ] && cleanup_and_exit
echo "All set. To stop the clat, run: ip netns del $NS"
[Unit]
Description=CLAT (464xlat) using jool_siit and L2 ipvlan
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/local/bin/jool_clat.sh %i
ExecStop=ip netns del clat-%i
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment