1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Test bonding options with mode 1,5,6 5 6ALL_TESTS=" 7 prio 8 arp_validate 9 num_grat_arp 10" 11 12lib_dir=$(dirname "$0") 13source ${lib_dir}/bond_topo_3d1c.sh 14 15skip_prio() 16{ 17 local skip=1 18 19 # check if iproute support prio option 20 ip -n ${s_ns} link set eth0 type bond_slave prio 10 21 [[ $? -ne 0 ]] && skip=0 22 23 # check if kernel support prio option 24 ip -n ${s_ns} -d link show eth0 | grep -q "prio 10" 25 [[ $? -ne 0 ]] && skip=0 26 27 return $skip 28} 29 30skip_ns() 31{ 32 local skip=1 33 34 # check if iproute support ns_ip6_target option 35 ip -n ${s_ns} link add bond1 type bond ns_ip6_target ${g_ip6} 36 [[ $? -ne 0 ]] && skip=0 37 38 # check if kernel support ns_ip6_target option 39 ip -n ${s_ns} -d link show bond1 | grep -q "ns_ip6_target ${g_ip6}" 40 [[ $? -ne 0 ]] && skip=0 41 42 ip -n ${s_ns} link del bond1 43 44 return $skip 45} 46 47active_slave="" 48active_slave_changed() 49{ 50 local old_active_slave=$1 51 local new_active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" \ 52 ".[].linkinfo.info_data.active_slave") 53 [ "$new_active_slave" != "$old_active_slave" -a "$new_active_slave" != "null" ] 54} 55 56check_active_slave() 57{ 58 local target_active_slave=$1 59 slowwait 5 active_slave_changed $active_slave 60 active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave") 61 test "$active_slave" = "$target_active_slave" 62 check_err $? "Current active slave is $active_slave but not $target_active_slave" 63} 64 65# Test bonding prio option 66prio_test() 67{ 68 local param="$1" 69 RET=0 70 71 # create bond 72 bond_reset "${param}" 73 74 # check bonding member prio value 75 ip -n ${s_ns} link set eth0 type bond_slave prio 0 76 ip -n ${s_ns} link set eth1 type bond_slave prio 10 77 ip -n ${s_ns} link set eth2 type bond_slave prio 11 78 cmd_jq "ip -n ${s_ns} -d -j link show eth0" \ 79 ".[].linkinfo.info_slave_data | select (.prio == 0)" "-e" &> /dev/null 80 check_err $? "eth0 prio is not 0" 81 cmd_jq "ip -n ${s_ns} -d -j link show eth1" \ 82 ".[].linkinfo.info_slave_data | select (.prio == 10)" "-e" &> /dev/null 83 check_err $? "eth1 prio is not 10" 84 cmd_jq "ip -n ${s_ns} -d -j link show eth2" \ 85 ".[].linkinfo.info_slave_data | select (.prio == 11)" "-e" &> /dev/null 86 check_err $? "eth2 prio is not 11" 87 88 bond_check_connection "setup" 89 90 # active slave should be the primary slave 91 check_active_slave eth1 92 93 # active slave should be the higher prio slave 94 ip -n ${s_ns} link set $active_slave down 95 check_active_slave eth2 96 bond_check_connection "fail over" 97 98 # when only 1 slave is up 99 ip -n ${s_ns} link set $active_slave down 100 check_active_slave eth0 101 bond_check_connection "only 1 slave up" 102 103 # when a higher prio slave change to up 104 ip -n ${s_ns} link set eth2 up 105 bond_check_connection "higher prio slave up" 106 case $primary_reselect in 107 "0") 108 check_active_slave "eth2" 109 ;; 110 "1") 111 check_active_slave "eth0" 112 ;; 113 "2") 114 check_active_slave "eth0" 115 ;; 116 esac 117 local pre_active_slave=$active_slave 118 119 # when the primary slave change to up 120 ip -n ${s_ns} link set eth1 up 121 bond_check_connection "primary slave up" 122 case $primary_reselect in 123 "0") 124 check_active_slave "eth1" 125 ;; 126 "1") 127 check_active_slave "$pre_active_slave" 128 ;; 129 "2") 130 check_active_slave "$pre_active_slave" 131 ip -n ${s_ns} link set $active_slave down 132 bond_check_connection "pre_active slave down" 133 check_active_slave "eth1" 134 ;; 135 esac 136 137 # Test changing bond slave prio 138 if [[ "$primary_reselect" == "0" ]];then 139 ip -n ${s_ns} link set eth0 type bond_slave prio 1000000 140 ip -n ${s_ns} link set eth1 type bond_slave prio 0 141 ip -n ${s_ns} link set eth2 type bond_slave prio -50 142 ip -n ${s_ns} -d link show eth0 | grep -q 'prio 1000000' 143 check_err $? "eth0 prio is not 1000000" 144 ip -n ${s_ns} -d link show eth1 | grep -q 'prio 0' 145 check_err $? "eth1 prio is not 0" 146 ip -n ${s_ns} -d link show eth2 | grep -q 'prio -50' 147 check_err $? "eth3 prio is not -50" 148 check_active_slave "eth1" 149 150 ip -n ${s_ns} link set $active_slave down 151 check_active_slave "eth0" 152 bond_check_connection "change slave prio" 153 fi 154} 155 156prio_miimon() 157{ 158 local primary_reselect 159 local mode=$1 160 161 for primary_reselect in 0 1 2; do 162 prio_test "mode $mode miimon 100 primary eth1 primary_reselect $primary_reselect" 163 log_test "prio" "$mode miimon primary_reselect $primary_reselect" 164 done 165} 166 167prio_arp() 168{ 169 local primary_reselect 170 local mode=$1 171 172 for primary_reselect in 0 1 2; do 173 prio_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} primary eth1 primary_reselect $primary_reselect" 174 log_test "prio" "$mode arp_ip_target primary_reselect $primary_reselect" 175 done 176} 177 178prio_ns() 179{ 180 local primary_reselect 181 local mode=$1 182 183 if skip_ns; then 184 log_test_skip "prio ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'." 185 return 0 186 fi 187 188 for primary_reselect in 0 1 2; do 189 prio_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} primary eth1 primary_reselect $primary_reselect" 190 log_test "prio" "$mode ns_ip6_target primary_reselect $primary_reselect" 191 done 192} 193 194prio() 195{ 196 local mode modes="active-backup balance-tlb balance-alb" 197 198 if skip_prio; then 199 log_test_skip "prio" "Current iproute or kernel doesn't support bond option 'prio'." 200 return 0 201 fi 202 203 for mode in $modes; do 204 prio_miimon $mode 205 done 206 prio_arp "active-backup" 207 prio_ns "active-backup" 208} 209 210wait_mii_up() 211{ 212 for i in $(seq 0 2); do 213 mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status") 214 [ ${mii_status} != "UP" ] && return 1 215 done 216 return 0 217} 218 219arp_validate_test() 220{ 221 local param="$1" 222 RET=0 223 224 # create bond 225 bond_reset "${param}" 226 227 bond_check_connection 228 [ $RET -ne 0 ] && log_test "arp_validate" "$retmsg" 229 230 # wait for a while to make sure the mii status stable 231 slowwait 5 wait_mii_up 232 for i in $(seq 0 2); do 233 mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status") 234 if [ ${mii_status} != "UP" ]; then 235 RET=1 236 log_test "arp_validate" "interface eth$i mii_status $mii_status" 237 fi 238 done 239} 240 241arp_validate_arp() 242{ 243 local mode=$1 244 local val 245 for val in $(seq 0 6); do 246 arp_validate_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} arp_validate $val" 247 log_test "arp_validate" "$mode arp_ip_target arp_validate $val" 248 done 249} 250 251arp_validate_ns() 252{ 253 local mode=$1 254 local val 255 256 if skip_ns; then 257 log_test_skip "arp_validate ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'." 258 return 0 259 fi 260 261 for val in $(seq 0 6); do 262 arp_validate_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} arp_validate $val" 263 log_test "arp_validate" "$mode ns_ip6_target arp_validate $val" 264 done 265} 266 267arp_validate() 268{ 269 arp_validate_arp "active-backup" 270 arp_validate_ns "active-backup" 271} 272 273garp_test() 274{ 275 local param="$1" 276 local active_slave exp_num real_num i 277 RET=0 278 279 # create bond 280 bond_reset "${param}" 281 282 bond_check_connection 283 [ $RET -ne 0 ] && log_test "num_grat_arp" "$retmsg" 284 285 286 # Add tc rules to count GARP number 287 for i in $(seq 0 2); do 288 tc -n ${g_ns} filter add dev s$i ingress protocol arp pref 1 handle 101 \ 289 flower skip_hw arp_op request arp_sip ${s_ip4} arp_tip ${s_ip4} action pass 290 done 291 292 # Do failover 293 active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave") 294 ip -n ${s_ns} link set ${active_slave} down 295 296 # wait for active link change 297 slowwait 2 active_slave_changed $active_slave 298 299 exp_num=$(echo "${param}" | cut -f6 -d ' ') 300 active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave") 301 slowwait_for_counter $((exp_num + 5)) $exp_num \ 302 tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}" 303 304 # check result 305 real_num=$(tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}") 306 if [ "${real_num}" -ne "${exp_num}" ]; then 307 echo "$real_num garp packets sent on active slave ${active_slave}" 308 RET=1 309 fi 310 311 for i in $(seq 0 2); do 312 tc -n ${g_ns} filter del dev s$i ingress 313 done 314} 315 316num_grat_arp() 317{ 318 local val 319 for val in 10 20 30; do 320 garp_test "mode active-backup miimon 10 num_grat_arp $val peer_notify_delay 100" 321 log_test "num_grat_arp" "active-backup miimon num_grat_arp $val" 322 done 323} 324 325trap cleanup EXIT 326 327setup_prepare 328setup_wait 329tests_run 330 331exit $EXIT_STATUS 332