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