1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
source lib.sh
TESTS="
basic_tx_ipv4
basic_tx_ipv6
learning
proxy_ipv4
proxy_ipv6
"
VERBOSE=0
################################################################################
# Utilities
run_cmd()
{
local cmd="$1"
local out
local stderr="2>/dev/null"
if [ "$VERBOSE" = "1" ]; then
echo "COMMAND: $cmd"
stderr=
fi
out=$(eval "$cmd" "$stderr")
rc=$?
if [ "$VERBOSE" -eq 1 ] && [ -n "$out" ]; then
echo " $out"
fi
return $rc
}
################################################################################
# Cleanup
exit_cleanup_all()
{
cleanup_all_ns
exit "${EXIT_STATUS}"
}
################################################################################
# Tests
nh_stats_get()
{
ip -n "$ns1" -s -j nexthop show id 10 | jq ".[][\"group_stats\"][][\"packets\"]"
}
tc_stats_get()
{
tc_rule_handle_stats_get "dev dummy1 egress" 101 ".packets" "-n $ns1"
}
basic_tx_common()
{
local af_str=$1; shift
local proto=$1; shift
local local_addr=$1; shift
local plen=$1; shift
local remote_addr=$1; shift
RET=0
# Test basic Tx functionality. Check that stats are incremented on
# both the FDB nexthop group and the egress device.
run_cmd "ip -n $ns1 link add name dummy1 up type dummy"
run_cmd "ip -n $ns1 route add $remote_addr/$plen dev dummy1"
run_cmd "tc -n $ns1 qdisc add dev dummy1 clsact"
run_cmd "tc -n $ns1 filter add dev dummy1 egress proto $proto pref 1 handle 101 flower ip_proto udp dst_ip $remote_addr dst_port 4789 action pass"
run_cmd "ip -n $ns1 address add $local_addr/$plen dev lo"
run_cmd "ip -n $ns1 nexthop add id 1 via $remote_addr fdb"
run_cmd "ip -n $ns1 nexthop add id 10 group 1 fdb"
run_cmd "ip -n $ns1 link add name vx0 up type vxlan id 10010 local $local_addr dstport 4789"
run_cmd "bridge -n $ns1 fdb add 00:11:22:33:44:55 dev vx0 self static nhid 10"
run_cmd "ip netns exec $ns1 mausezahn vx0 -a own -b 00:11:22:33:44:55 -c 1 -q"
busywait "$BUSYWAIT_TIMEOUT" until_counter_is "== 1" nh_stats_get > /dev/null
check_err $? "FDB nexthop group stats did not increase"
busywait "$BUSYWAIT_TIMEOUT" until_counter_is "== 1" tc_stats_get > /dev/null
check_err $? "tc filter stats did not increase"
log_test "VXLAN FDB nexthop: $af_str basic Tx"
}
basic_tx_ipv4()
{
basic_tx_common "IPv4" ipv4 192.0.2.1 32 192.0.2.2
}
basic_tx_ipv6()
{
basic_tx_common "IPv6" ipv6 2001:db8:1::1 128 2001:db8:1::2
}
learning()
{
RET=0
# When learning is enabled on the VXLAN device, an incoming packet
# might try to refresh an FDB entry that points to an FDB nexthop group
# instead of an ordinary remote destination. Check that the kernel does
# not crash in this situation.
run_cmd "ip -n $ns1 address add 192.0.2.1/32 dev lo"
run_cmd "ip -n $ns1 address add 192.0.2.2/32 dev lo"
run_cmd "ip -n $ns1 nexthop add id 1 via 192.0.2.3 fdb"
run_cmd "ip -n $ns1 nexthop add id 10 group 1 fdb"
run_cmd "ip -n $ns1 link add name vx0 up type vxlan id 10010 local 192.0.2.1 dstport 12345 localbypass"
run_cmd "ip -n $ns1 link add name vx1 up type vxlan id 10020 local 192.0.2.2 dstport 54321 learning"
run_cmd "bridge -n $ns1 fdb add 00:11:22:33:44:55 dev vx0 self static dst 192.0.2.2 port 54321 vni 10020"
run_cmd "bridge -n $ns1 fdb add 00:aa:bb:cc:dd:ee dev vx1 self static nhid 10"
run_cmd "ip netns exec $ns1 mausezahn vx0 -a 00:aa:bb:cc:dd:ee -b 00:11:22:33:44:55 -c 1 -q"
log_test "VXLAN FDB nexthop: learning"
}
proxy_common()
{
local af_str=$1; shift
local local_addr=$1; shift
local plen=$1; shift
local remote_addr=$1; shift
local neigh_addr=$1; shift
local ping_cmd=$1; shift
RET=0
# When the "proxy" option is enabled on the VXLAN device, the device
# will suppress ARP requests and IPv6 Neighbor Solicitation messages if
# it is able to reply on behalf of the remote host. That is, if a
# matching and valid neighbor entry is configured on the VXLAN device
# whose MAC address is not behind the "any" remote (0.0.0.0 / ::). The
# FDB entry for the neighbor's MAC address might point to an FDB
# nexthop group instead of an ordinary remote destination. Check that
# the kernel does not crash in this situation.
run_cmd "ip -n $ns1 address add $local_addr/$plen dev lo"
run_cmd "ip -n $ns1 nexthop add id 1 via $remote_addr fdb"
run_cmd "ip -n $ns1 nexthop add id 10 group 1 fdb"
run_cmd "ip -n $ns1 link add name vx0 up type vxlan id 10010 local $local_addr dstport 4789 proxy"
run_cmd "ip -n $ns1 neigh add $neigh_addr lladdr 00:11:22:33:44:55 nud perm dev vx0"
run_cmd "bridge -n $ns1 fdb add 00:11:22:33:44:55 dev vx0 self static nhid 10"
run_cmd "ip netns exec $ns1 $ping_cmd"
log_test "VXLAN FDB nexthop: $af_str proxy"
}
proxy_ipv4()
{
proxy_common "IPv4" 192.0.2.1 32 192.0.2.2 192.0.2.3 \
"arping -b -c 1 -s 192.0.2.1 -I vx0 192.0.2.3"
}
proxy_ipv6()
{
proxy_common "IPv6" 2001:db8:1::1 128 2001:db8:1::2 2001:db8:1::3 \
"ndisc6 -r 1 -s 2001:db8:1::1 -w 1 2001:db8:1::3 vx0"
}
################################################################################
# Usage
usage()
{
cat <<EOF
usage: ${0##*/} OPTS
-t <test> Test(s) to run (default: all)
(options: $TESTS)
-p Pause on fail
-v Verbose mode (show commands and output)
EOF
}
################################################################################
# Main
while getopts ":t:pvh" opt; do
case $opt in
t) TESTS=$OPTARG;;
p) PAUSE_ON_FAIL=yes;;
v) VERBOSE=$((VERBOSE + 1));;
h) usage; exit 0;;
*) usage; exit 1;;
esac
done
require_command mausezahn
require_command arping
require_command ndisc6
require_command jq
if ! ip nexthop help 2>&1 | grep -q "stats"; then
echo "SKIP: iproute2 ip too old, missing nexthop stats support"
exit "$ksft_skip"
fi
trap exit_cleanup_all EXIT
for t in $TESTS
do
setup_ns ns1; $t; cleanup_all_ns;
done
|