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