xref: /openbsd-src/regress/sys/net/vxlan/vxlan_2.sh (revision ddd1eaf03dfad94f59c8a2ef97aaf1bd12b25626)
1#!/bin/ksh
2#	$Id: vxlan_2.sh,v 1.5 2024/02/29 06:54:29 anton Exp $
3
4
5CAPFILE=$(mktemp -t regress_vxlan.XXXXXXX)
6
7
8CURDIR=$(cd $(dirname $0); pwd)
9
10
11cleanup() {
12	for ifname in $CLEANUP_IFS; do
13		$SUDO ifconfig $ifname down
14	done
15	for ifname in $CLEANUP_IFS; do
16		$SUDO ifconfig $ifname destroy
17	done
18	rm $CAPFILE
19}
20
21do_ping()
22{
23	local source="$1"
24	local dest="${VXLAN_NETID}${2}"
25	$PING -q -c 1 -w 1 -V "$source" "$dest" > /dev/null # warm up arp
26	$PING -q -c 3 -w 1 -V "$source" "$dest" | grep -q ' 0.0% packet loss' && return
27	echo "Failed to ping $dest from vstack $source"
28	STATUS=1
29}
30
31cross_ping() {
32	local tcpdump_expr='udp src port 4789 and dst port 4789 and (ether multicast or ip multicast)'
33	local nomcast=
34	[[ $1 == nomcast ]] && nomcast=1 && shift
35	echo "cross_ping: vstacks=$@, ping=$PING, nomcast=$nomcast"
36	while [[ $# -gt 1 ]]; do
37		local source=$1 ; shift
38		:> $CAPFILE
39		if [[ -n $nomcast ]]; then
40			$SUDO tcpdump -i pair${source}0 -n -s 512 -w $CAPFILE "$tcpdump_expr" 2> /dev/null &
41			while ! [[ -s $CAPFILE ]]; do :; done
42		fi
43		for target in $@ ; do
44			do_ping $source $target
45		done
46		sleep 1
47		if [[ -n $nomcast ]]; then
48			$SUDO pkill -f "tcpdump -i pair${source}0 -n"
49			wait
50			if $SUDO tcpdump -s 512 -nr $CAPFILE | grep '.'; then
51				echo "Multicast traffic detected when pinging from rdomain $1"
52				STATUS=1
53			fi
54		fi
55	done
56}
57
58test_inet6()
59{
60	VXLAN_NETID="fd42::"
61	PING=ping6
62	for vstack in "$@"; do
63		$SUDO ifconfig "vxlan$vstack" inet6 "${VXLAN_NETID}${vstack}/64"
64	done
65	sleep 2 # sleep off DAD
66	cross_ping "$@"
67	[[ -n $DYNAMIC ]] && cross_ping ${DYNAMIC:+nomcast} "$@"
68	for vstack in "$@"; do
69		$SUDO ifconfig "vxlan$vstack" inet6 "${VXLAN_NETID}${vstack}/64" delete
70	done
71}
72
73test_inet()
74{
75	VXLAN_NETID="10.42.0."
76	PING=ping
77	for vstack in "$@"; do
78		$SUDO ifconfig "vxlan$vstack" inet "${VXLAN_NETID}${vstack}/24"
79	done
80	cross_ping "$@"
81	[[ -n $DYNAMIC ]] && cross_ping ${DYNAMIC:+nomcast} "$@"
82	for vstack in "$@"; do
83		$SUDO ifconfig "vxlan$vstack" inet "${VXLAN_NETID}${vstack}/24" delete
84	done
85}
86
87vstack_add() {
88	local vstack=$1
89	local vstack_pairname="pair${vstack}0"
90	local vstack_tunsrc="${PAIR_NETID}${vstack}"
91	[[ $AF == inet6 ]] && tundst_sufx="%${vstack_pairname}"
92
93	for ifname in "$vstack_pairname" "vxlan$vstack" "bridge$vstack"; do
94		iface_exists $ifname && abort_test "interface $ifname already exists"
95		CLEANUP_IFS="$ifname $CLEANUP_IFS"
96	done
97	$SUDO ifconfig "$vstack_pairname" rdomain "$vstack" $IFCONFIG_OPTS
98	$SUDO ifconfig "$vstack_pairname" "$AF" "${vstack_tunsrc}${PAIR_PREFX}" up
99	$SUDO ifconfig "vxlan$vstack" rdomain "$vstack" tunneldomain "$vstack" $IFCONFIG_OPTS
100	$SUDO ifconfig "vxlan$vstack" vnetid "$VNETID" tunnel "$vstack_tunsrc" "${VXLAN_TUNDST}${tundst_sufx}" parent "$vstack_pairname" up
101	[[ -n $DYNAMIC ]] && $SUDO ifconfig "bridge$vstack" rdomain "$vstack" add "vxlan$vstack" $IFCONFIG_OPTS up
102}
103
104
105. ${CURDIR}/vxlan_subr
106
107# Use the first rdomain as the vnetid.
108VNETID="$(set -- $RDOMAINS; echo $1)"
109RDOMAINS="$(set -- $RDOMAINS; shift 1; echo $@)"
110
111for rdom in $RDOMAINS; do
112	rdomain_is_used $rdom || abort_test "rdomain $rdom already in use"
113done
114
115rdomain_is_used $VNETID || abort_test "rdomain $rdom already in use"
116iface_exists "bridge$VNETID" && abort_test "interface bridge${VNETID} already exists"
117$SUDO ifconfig "bridge$VNETID" rdomain "$VNETID" $IFCONFIG_OPTS up
118
119case $AF in
120	inet)
121		PAIR_NETID="10.23.0."
122		PAIR_PREFX="/24"
123		VXLAN_TUNDST="224.0.2.$VNETID"
124		;;
125	inet6)
126		PAIR_NETID="fd23::"
127		PAIR_PREFX="/64"
128		VXLAN_TUNDST="ff02::$VNETID"
129		;;
130	*)
131		echo "Unknown AF $AF !"
132		exit 1
133esac
134
135trap cleanup 0 1 2 3 15
136
137for id in $RDOMAINS; do
138	vstack_add $id
139	iface_exists "pair${id}1" && abort_test "interface pair${id}1 already exists"
140	$SUDO ifconfig "pair${id}1" rdomain $VNETID $IFCONFIG_OPTS up
141	CLEANUP_IFS="pair${id}1 $CLEANUP_IFS"
142	$SUDO ifconfig "pair${id}1" patch "pair${id}0"
143	$SUDO ifconfig "bridge$VNETID" add "pair${id}1"
144done
145
146CLEANUP_IFS="bridge$VNETID $CLEANUP_IFS"
147
148for id in $RDOMAINS; do
149	CLEANUP_IFS="$CLEANUP_IFS lo${id}"
150done
151CLEANUP_IFS="$CLEANUP_IFS lo${VNETID}"
152
153STATUS=0
154
155test_inet $RDOMAINS
156
157test_inet6 $RDOMAINS
158
159exit $STATUS
160