From 1e3bbdfbbb85e4fa92950934ef7a71e80d3043f3 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 12 Jul 2021 09:29:04 +0200 Subject: [PATCH] contrib: add script to test IPv6 prefix delegation Add a script to test IPv6 prefix delegation with NM, in different modes. --- contrib/scripts/test-prefix-delegation.sh | 151 ++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100755 contrib/scripts/test-prefix-delegation.sh diff --git a/contrib/scripts/test-prefix-delegation.sh b/contrib/scripts/test-prefix-delegation.sh new file mode 100755 index 0000000000..7fc4140eba --- /dev/null +++ b/contrib/scripts/test-prefix-delegation.sh @@ -0,0 +1,151 @@ +#!/bin/sh + +# Usage: ./test-prefix-delegation {ll|slaac|dhcp-stateful|dhcp-stateless} + +MODE=${1:-dhcp-stateful} + +cleanup() +{ + pkill -F dhcpd.pid + pkill -F radvd.pid + rm -f radvd.conf + rm -f dhcpd.conf + rm -f leases.conf + nmcli connection delete v1+ v2+ + ip netns del ns1 + ip netns del ns2 + ip link del v1 + ip link del v2 +} + +require() +{ + if ! command -v "$1" > /dev/null ; then + echo " *** Error: command '$1' not found" + exit 1 + fi +} + +exit_hook() +{ + cleanup > /dev/null 2>&1 +} + +require nmcli +require ip +require jq +require radvd +require dhcpd + +unalias ip 2> /dev/null + +cleanup +trap exit_hook EXIT + +# ns1 is the 'upstream' namespace that provides IPv6 connectivity +# through RA and DHCPv6. The DHCP server also acts as a delegating +# router for /60 prefixes. + +# ns2 is the 'downstream' namespace where a client obtains IPv6 +# connectivity through RA from NM. + +# NM is in the default namespace and has a connection to ns1 with +# ipv6.method=auto and to ns2 with ipv6.method=shared. + +ip netns add ns1 +ip netns add ns2 + +ip link add v1 type veth peer name v1p +ip link add v2 type veth peer name v2p + +ip link set v1p netns ns1 +ip link set v2p netns ns2 + +ip link set v1 up +ip link set v2 up + +ip -n ns1 link set v1p up +ip -n ns1 addr add dev v1p fc01::1/64 + +ip -n ns2 link set v2p up + +if [ "$MODE" = ll ]; then + adv_managed=off + adv_other=off +elif [ "$MODE" = slaac ]; then + adv_managed=off + adv_other=off + adv_prefix="prefix fc01::/64 {AdvOnLink on; AdvAutonomous on; AdvRouterAddr off; };" +elif [ "$MODE" = dhcp-stateless ]; then + adv_managed=off + adv_other=on + adv_prefix="prefix fc01::/64 {AdvOnLink on; AdvAutonomous on; AdvRouterAddr off; };" +elif [ "$MODE" = dhcp-stateful ]; then + adv_managed=on + adv_other=off + dhcp_range="range6 fc01::1000 fc01::ffff;" +else + echo "Unknown mode '$MODE'" + exit 1 +fi + +echo "Starting in $MODE mode..." + +cat > radvd.conf < dhcpd.conf < leases.conf +ip netns exec ns1 radvd -n -C radvd.conf -p radvd.pid & +ip netns exec ns1 dhcpd -6 -d -cf dhcpd.conf -lf leases.conf -pf dhcpd.pid & + +nmcli connection add type ethernet ifname v1 con-name v1+ ipv4.method disabled ipv6.method auto autoconnect no +nmcli connection add type ethernet ifname v2 con-name v2+ ipv4.method disabled ipv6.method shared autoconnect no + +nmcli connection up v1+ + +sleep 5 + +nmcli connection up v2+ + +sleep 5 + +ip a show dev v1 +ip a show dev v2 + +addr=$(ip -j addr show dev v1 | jq -r '.[0].addr_info[] | select(.scope=="link")'.local) +prefix="fc01:bbbb:1::/32" +ip netns exec ns1 ip route add $prefix via $addr dev v1p + +# kernel does IPv6 autoconf in ns2 ... + +sleep 10 + +# check connectivity to ns1 +if ! ip -n ns2 a show dev v2p | grep 'fc01:bbbb:[a-f0-9\:]\+/64'; then + ip -n ns2 a show dev v2p + echo "ERROR: no address" + exit 1 +fi + +if ! ip netns exec ns2 ping -c2 fc01::1; then + echo "ERROR: ping failed" + exit 1 +fi + +echo "OK"