Skip to content

Instantly share code, notes, and snippets.

@oskar456
Last active February 7, 2024 21:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oskar456/d898bf2e11b642757800a5ccdc2415aa to your computer and use it in GitHub Desktop.
Save oskar456/d898bf2e11b642757800a5ccdc2415aa 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.

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

#!/bin/bash
IFACE="$1"
[[ "$#" -ne 1 ]] && {
echo "Usage: $0 <IFACE>"
exit -1
}
NATPREFIX="64:ff9b::/96"
NS="clat-$IFACE"
JOOL_SIIT="$(which jool_siit)"
ip netns add $NS
# PtP link for IPv4 traffic from main NS to CLAT NS
ip link add name ${IFACE}-v4 type veth peer ${IFACE}-clat-v4
ip link set dev ${IFACE}-clat-v4 netns $NS
ip link set up dev ${IFACE}-v4
# ipvlan link using secondary address on host interface
ip link add name ${IFACE}-clat-v6 link ${IFACE} type ipvlan mode l2
ip link set dev ${IFACE}-clat-v6 netns $NS
# Set up IPv4 PtP link
ip -4 address add 192.0.0.1 peer 192.0.0.0/32 dev ${IFACE}-v4
ip -4 route add default via 192.0.0.0 dev ${IFACE}-v4
# The rest of the magic happens inside the network namespace
ip netns exec $NS sh <<EOF
ip link set up dev ${IFACE}-clat-v4
ip link set up dev ${IFACE}-clat-v6
ip -4 address add 192.0.0.0 peer 192.0.0.1/32 dev ${IFACE}-clat-v4
sleep 2 # Make sure ipvlan interface is up and SLAAC has succeeded
CLATADDR=\$(ip -c=never -6 addr show dev ${IFACE}-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
echo "All set. To stop the clat, run: ip netns del $NS"
#!/bin/bash
IFACE="$1"
[[ "$#" -ne 1 ]] && {
echo "Usage: $0 <IFACE>"
exit -1
}
NATPREFIX="64:ff9b::/96"
V4ADDR="192.0.0.4"
NS="clat-$IFACE"
JOOL_SIIT="$(which jool_siit)"
ip netns add $NS
# PtP link for IPv4 traffic from main NS to CLAT NS
ip link add name ${IFACE}-v4 type veth peer ${IFACE}-clat-v4
ip link set dev ${IFACE}-clat-v4 netns $NS
ip link set up dev ${IFACE}-v4
# ipvlan link using secondary address on host interface
ip link add name ${IFACE}-clat-v6 link ${IFACE} type ipvlan mode l2
ip link set dev ${IFACE}-clat-v6 netns $NS
# Set up IPv4 PtP link
ip -4 address add ${V4ADDR}/32 dev ${IFACE}-v4
ip -4 route add default dev ${IFACE}-v4
# The rest of the magic happens inside the network namespace
ip netns exec $NS sh <<EOF
ip link set up dev ${IFACE}-clat-v4
ip link set up dev ${IFACE}-clat-v6
ip link set up dev lo
ip -4 route add ${V4ADDR} dev ${IFACE}-clat-v4
ip -4 route add default dev lo
sysctl -q net.ipv4.conf.${IFACE}-clat-v4.proxy_arp=1
sysctl -q net.ipv4.conf.${IFACE}-clat-v4.forwarding=1
sleep 2 # Make sure ipvlan interface is up and SLAAC has succeeded
CLATADDR=\$(ip -c=never -6 addr show dev ${IFACE}-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 ${V4ADDR}
EOF
echo "All set. To stop the clat, run: ip netns del $NS"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment