Skip to content

Instantly share code, notes, and snippets.

@ymmt2005
Last active May 16, 2018 01:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ymmt2005/f7d82a7252ae32e73c1cbb4ae3114e5d to your computer and use it in GitHub Desktop.
Save ymmt2005/f7d82a7252ae32e73c1cbb4ae3114e5d to your computer and use it in GitHub Desktop.
Test Linux weird behavior on ECMP routes
#!/bin/sh -e
NS=testns
BR1=testbr1
VETH1=testveth1
BR2=testbr2
VETH2=testveth2
LINKS="$VETH1 $VETH2 $BR1 $BR2"
NET1=192.168.11.xx/24
NET2=192.168.12.xx/24
IPNS="ip netns exec $NS ip"
clean() {
for l in $LINKS; do
if ip -o link show $l >/dev/null 2>&1; then
ip link del $l
fi
done
if ip netns list | grep -q $NS; then
#ip netns exec $NS ip link del node0
ip netns del $NS
fi
}
trap clean INT QUIT TERM HUP PIPE 0
make_address() {
local net addr
net=$1
addr=$2
echo $net | sed "s/xx/$addr/"
}
cidr2ip() {
echo $1 | cut -d / -f 1
}
GW1=$(make_address $NET1 1)
GW2=$(make_address $NET2 1)
ADDR1=$(make_address $NET1 2)
ADDR2=$(make_address $NET2 2)
setup_veth() {
local br veth dest
br=$1
veth=$2
dest=$3
ip link add $br type bridge
ip link add $veth type veth peer name ${veth}_
ip link set $br up
ip link set $veth master $br up
ip link set ${veth}_ netns $NS name $dest up
}
setup() {
ip netns add $NS
$IPNS link set lo up
setup_veth $BR1 $VETH1 eth0
setup_veth $BR2 $VETH2 eth1
local gw1 gw2
ip addr add $GW1 dev $BR1
ip addr add $GW2 dev $BR2
$IPNS addr add $ADDR1 dev eth0
$IPNS addr add $ADDR2 dev eth1
$IPNS route add 0.0.0.0/0 nexthop via $(cidr2ip $GW1) nexthop via $(cidr2ip $GW2)
}
setup_node0() {
$IPNS link add node0 type dummy
$IPNS link set node0 up
$IPNS addr add 192.168.10.2/32 dev node0
}
test_route_from() {
local dest dev from r rdev
dest=$1
dev=$2
from=$3
r=$($IPNS -o route get $dest from $from)
rdev=$(echo $r | sed -nr 's/^.*dev (eth[[:digit:]]+).*/\1/p')
if [ "$dev" != "$rdev" ]; then
echo "WRONG dev/from pair: ip -o route get $dest from $from:"
printf "%s\n" "$r"
return
fi
}
test_route() {
test_route_from "$1" eth0 $(cidr2ip $ADDR1)
test_route_from "$1" eth1 $(cidr2ip $ADDR2)
}
run_tests() {
test_route 12.34.56.78
test_route 216.58.200.160
test_route 216.58.200.161
test_route 216.58.200.162
test_route 216.58.200.163
test_route 216.58.200.164
test_route 52.85.149.10
test_route 52.85.149.11
test_route 52.85.149.12
test_route 52.85.149.13
test_route 52.85.149.14
}
# main
setup
#setup_node0
run_tests
read -p "Press enter to finish" ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment