#!/usr/bin/bash set -x set -e # Layer 3+4 5-tuple hash echo 1 > /proc/sys/net/ipv4/fib_multipath_hash_policy echo 1 > /proc/sys/net/ipv6/fib_multipath_hash_policy # learn quickly of dead hosts so they are removed from the hash table echo 1 > /proc/sys/net/ipv4/fib_multipath_use_neigh # IPv4 defaults ipv4_default=${ipv4_default:-0.0.0.0/0} ipv4_host=${ipv4_host:-198.51.100.0/32} ipv4_anycast=${ipv4_anycast:-203.0.113.0/32} # IPv6 defaults ipv6_default=${ipv6_default:-::/0} ipv6_host=${ipv6_host:-100::1/128} ipv6_anycast=${ipv6_anycast:-fd00::1/128} # session defaults ip_family=${ip_family:-inet4} ip_default=${ipv4_default} ip_host=${ipv4_host} ip_anycast=${ipv4_anycast} # operator inet family choice for session case "$1" in "-4") ip_family=inet4 ip_default=$ipv4_default ip_host=$ipv4_host ip_anycast=$ipv4_anycast ;; "-6") ip_family=inet6 ip_default=$ipv6_default ip_host=$ipv6_host ip_anycast=$ipv6_anycast ;; esac # routes back to host targets this address ip addr add $ip_host dev lo # number of hosts participating in load-balancing the anycast address max=${max:-10} # range = 1-255 nsnum=1 # base interface names INside and OUTside namespaces vethin=2000 vethout=1000 # base of the anycast route command required to create multi-host nexthop cmd="ip route add $ip_anycast" # create and configure the network namespaces for nsnum in $(seq 1 $max); do vethin="veth$((2000 + nsnum))" vethout="veth$((1000 + nsnum))" echo "nsnum=$nsnum vethin=$vethin vethout=$vethout" # IP address inside network namespace if [ "x$ip_family" = "xinet4" ]; then if_ip="192.0.2.${nsnum}/32" else if_ip="$(printf "fd00:b00b:1e00::%x" $nsnum)" fi # one more load-balancer for the anycast route cmd="$cmd nexthop via ${if_ip%/*} weight 10" ip netns add ns${nsnum} ip link add $vethout type veth peer name $vethin ip link set $vethout up # move peer into namespace ip link set $vethin netns ns${nsnum} ip netns exec ns${nsnum} ip link set $vethin name eth0 ip netns exec ns${nsnum} ip addr add $if_ip dev eth0 ip netns exec ns${nsnum} ip link set eth0 up # route back to host ip netns exec ns${nsnum} ip route add $ip_host dev eth0 # default route via host ip netns exec ns${nsnum} ip route add $ip_default via ${ip_host%/*} ip route add $if_ip dev $vethout # attach anycast address to the namespace ip netns exec ns${nsnum} ip addr add $ip_anycast dev lo ip netns exec ns${nsnum} ip link set dev lo up done $cmd