#!/bin/sh color_default=$(tput setaf 7); color_config=$(tput setaf 3); color_error=$(tput setaf 1); color_log=$(tput setaf 8); echo "${color_log}" echo ' ___ _ _ _____ ' echo ' / __| | /_\_ _|' echo '| (__| |__ / _ \| | ' echo ' \___|____/_/ \_\_| ' #### # FETCH ENVIRONMENT # # nat64_prefix: # - fetch by dns AAAA-entry ipv4only.arpa # nat64_subnet: # - /96 # ifname_ex: # - get by route to "nat64_prefix" # v4_address: # - your ipv4 address # v4_gw: # - ipv4 address on gateway where routed # v4_subnet: # - /30 # - subnet size of clat ipv4 address # v4_status_ping: # - 8.8.8.8 # v6_address_clat (not configable): # - generated by internal link local and routed src # v6_subnet_clat (should not configured): # - /64 # if [ -r /etc/clatd.env ]; then source /etc/clatd.env; fi # # TODO: # - skip if ipv4 default route exists # - improve $v6_address_clat generation for ipv6 address in namespace nat64_prefix=${nat64_prefix:-"$(dig +short ipv4only.arpa AAAA | sed 's/c000:a[ab]//' | head -1)"} if [ $? -ne 0 ]; then echo "${color_error}dns failed: no request to ipv4only.arpa possible${color_log}" exit 1 fi if [ "$nat64_prefix" == "" ]; then echo "${color_error}nat64 prefix/subnet unkown${color_log}" exit 1 fi nat64_subnet=${nat64_subnet:-96} echo "${color_default}nat64 prefix/subnet: ${color_config}$nat64_prefix${color_default}/${color_config}$nat64_subnet${color_log}" ifname_ex="$(ip r g ${nat64_prefix}0 | grep -Po 'dev \K[0-9a-z]+')" echo "${color_default}over interface: ${color_config}$ifname_ex${color_log}" # ipv4 v4_address=${v4_address:-"192.0.0.2"} v4_gw=${v4_gw:-"192.0.0.1"} v4_subnet=${v4_subnet:-30} echo "${color_default}ipv4: ${color_config}$v4_address${color_default}/${color_config}$v4_subnet${color_default} gw: ${color_config}$v4_gw${color_log}" v4_status_ping=${v4_status_ping:-"8.8.8.8"} # ipv6 subnet - should not be changed v6_subnet_clat=${v6_subnet_clat:-64} # # END #### namespace_setup() { echo "${color_default}> namespace setup${color_log}" ip netns add jool ip link add name clat type veth peer name to_world ip link set up dev clat ip link set up dev to_world netns jool } namespace_network() { echo "${color_default}> namespace network${color_log}" clat_ll=$(ip -6 address show scope link dev clat | grep -Po 'inet6 \K[0-9a-f:]+') internal_ll=$(ip netns exec jool ip -6 address show scope link dev to_world | grep -Po 'inet6 \K[0-9a-f:]+') v6_address_clat="$(ip r g ${nat64_prefix}0 | grep -Po 'src \K[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:')$(echo $internal_ll | grep -Po 'fe80::\K[0-9a-f:]+')" echo "${color_default}ipv6 address clat: ${color_config}$v6_address_clat${color_default}/${color_config}$v6_subnet_clat${color_log}" ip netns exec jool ip -6 address add $v6_address_clat/$v6_subnet_clat dev to_world ip netns exec jool ip -6 route add default via $clat_ll dev to_world ip netns exec jool ip -4 address add $v4_gw/$v4_subnet dev to_world } jool_setup() { echo "${color_default}> setup jool in namespace${color_log}" if ! ip netns exec jool modprobe jool_siit; then echo "${color_error}module jool_siit not found${color_log}" ip netns del jool exit 1 fi ip netns exec jool jool_siit instance add --netfilter --pool6 $nat64_prefix/$nat64_subnet ip netns exec jool jool_siit eamt add $v4_address $v6_address_clat } route_ipv6 () { echo "${color_default}> routing ipv6 to namespace${color_log}" echo 1 > /proc/sys/net/ipv6/conf/$ifname_ex/proxy_ndp echo 1 tee /proc/sys/net/ipv6/conf/*/forwarding ip -6 neigh add proxy $v6_address_clat dev $ifname_ex ip -6 route add $v6_address_clat/128 via $internal_ll dev clat } route_ipv4() { echo "${color_default}> routing ipv4 to namespace${color_log}" ip -4 address add $v4_address/$v4_subnet dev clat ip -4 route add default via $v4_gw dev clat } start() { echo "${color_default}clat start${color_log}" namespace_setup namespace_network jool_setup route_ipv6 route_ipv4 } stop() { echo "${color_default}clat stop${color_log}" ip netns del jool } status () { echo "${color_default}clat status${color_log}" if ip netns pids jool; then echo "${color_default}clat setup: ${color_config} yes" echo -n "${color_default}ipv6 address clat: ${color_config}" ip netns exec jool ip -6 a show to_world | grep -Po 'inet6 \K[0-9a-f:]+\/[0-9]+' | head -1 ping -4 -I clat $v4_status_ping -c 1 1> /dev/null if [ $? -eq 0 ]; then echo "${color_default}clat ipv4 ping: ${color_config} yes${color_log}" else echo "${color_default}clat ipv4 ping: ${color_error} no${color_log}" exit 1 fi else echo "${color_default}clat setup: ${color_error} no${color_log}" ping -4 $v4_status_ping -c 1 1> /dev/null if [ $? -eq 0 ]; then echo "${color_default}ipv4 ping: ${color_config} yes${color_log}" else echo "${color_default}ipv4 ping: ${color_error} no${color_log}" exit 2 fi exit 1 fi } reload() { if ip netns pids jool; then echo "${color_default}reload: clat found${color_log}" stop sleep 1 echo "------------------------------" fi start } toggle() { if ip netns pids jool; then echo "${color_default}toggle: clat found${color_log}" stop else echo "${color_default}toggle: clat not found${color_log}" start fi } case "$1" in start) echo "------------------------------" start ;; stop) echo "------------------------------" stop ;; status) echo "------------------------------" status ;; restart) echo "------------------------------" stop sleep 1 echo "------------------------------" start ;; reload) echo "------------------------------" reload ;; help) echo "------------------------------" echo "${color_default}Usage: {start|stop|status|reload|restart|toggle}${color_log}" exit 1 ;; "") echo "------------------------------" toggle ;; esac exit $?