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