Path: blob/master/tools/testing/selftests/drivers/net/bonding/bond_options.sh
29271 views
#!/bin/bash1# SPDX-License-Identifier: GPL-2.02#3# Test bonding options with mode 1,5,645ALL_TESTS="6prio7arp_validate8num_grat_arp9fail_over_mac10vlan_over_bond11"1213lib_dir=$(dirname "$0")14source ${lib_dir}/bond_topo_3d1c.sh15c_maddr="33:33:ff:00:00:10"16g_maddr="33:33:ff:00:02:54"1718skip_prio()19{20local skip=12122# check if iproute support prio option23ip -n ${s_ns} link set eth0 type bond_slave prio 1024[[ $? -ne 0 ]] && skip=02526# check if kernel support prio option27ip -n ${s_ns} -d link show eth0 | grep -q "prio 10"28[[ $? -ne 0 ]] && skip=02930return $skip31}3233skip_ns()34{35local skip=13637# check if iproute support ns_ip6_target option38ip -n ${s_ns} link add bond1 type bond ns_ip6_target ${g_ip6}39[[ $? -ne 0 ]] && skip=04041# check if kernel support ns_ip6_target option42ip -n ${s_ns} -d link show bond1 | grep -q "ns_ip6_target ${g_ip6}"43[[ $? -ne 0 ]] && skip=04445ip -n ${s_ns} link del bond14647return $skip48}4950active_slave=""51active_slave_changed()52{53local old_active_slave=$154local new_active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" \55".[].linkinfo.info_data.active_slave")56[ "$new_active_slave" != "$old_active_slave" -a "$new_active_slave" != "null" ]57}5859check_active_slave()60{61local target_active_slave=$162slowwait 5 active_slave_changed $active_slave63active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")64test "$active_slave" = "$target_active_slave"65check_err $? "Current active slave is $active_slave but not $target_active_slave"66}6768# Test bonding prio option69prio_test()70{71local param="$1"72RET=07374# create bond75bond_reset "${param}"76# set active_slave to primary eth1 specifically77ip -n ${s_ns} link set bond0 type bond active_slave eth17879# check bonding member prio value80ip -n ${s_ns} link set eth0 type bond_slave prio 081ip -n ${s_ns} link set eth1 type bond_slave prio 1082ip -n ${s_ns} link set eth2 type bond_slave prio 1183cmd_jq "ip -n ${s_ns} -d -j link show eth0" \84".[].linkinfo.info_slave_data | select (.prio == 0)" "-e" &> /dev/null85check_err $? "eth0 prio is not 0"86cmd_jq "ip -n ${s_ns} -d -j link show eth1" \87".[].linkinfo.info_slave_data | select (.prio == 10)" "-e" &> /dev/null88check_err $? "eth1 prio is not 10"89cmd_jq "ip -n ${s_ns} -d -j link show eth2" \90".[].linkinfo.info_slave_data | select (.prio == 11)" "-e" &> /dev/null91check_err $? "eth2 prio is not 11"9293bond_check_connection "setup"9495# active slave should be the primary slave96check_active_slave eth19798# active slave should be the higher prio slave99ip -n ${s_ns} link set $active_slave down100check_active_slave eth2101bond_check_connection "fail over"102103# when only 1 slave is up104ip -n ${s_ns} link set $active_slave down105check_active_slave eth0106bond_check_connection "only 1 slave up"107108# when a higher prio slave change to up109ip -n ${s_ns} link set eth2 up110bond_check_connection "higher prio slave up"111case $primary_reselect in112"0")113check_active_slave "eth2"114;;115"1")116check_active_slave "eth0"117;;118"2")119check_active_slave "eth0"120;;121esac122local pre_active_slave=$active_slave123124# when the primary slave change to up125ip -n ${s_ns} link set eth1 up126bond_check_connection "primary slave up"127case $primary_reselect in128"0")129check_active_slave "eth1"130;;131"1")132check_active_slave "$pre_active_slave"133;;134"2")135check_active_slave "$pre_active_slave"136ip -n ${s_ns} link set $active_slave down137bond_check_connection "pre_active slave down"138check_active_slave "eth1"139;;140esac141142# Test changing bond slave prio143if [[ "$primary_reselect" == "0" ]];then144ip -n ${s_ns} link set eth0 type bond_slave prio 1000000145ip -n ${s_ns} link set eth1 type bond_slave prio 0146ip -n ${s_ns} link set eth2 type bond_slave prio -50147ip -n ${s_ns} -d link show eth0 | grep -q 'prio 1000000'148check_err $? "eth0 prio is not 1000000"149ip -n ${s_ns} -d link show eth1 | grep -q 'prio 0'150check_err $? "eth1 prio is not 0"151ip -n ${s_ns} -d link show eth2 | grep -q 'prio -50'152check_err $? "eth3 prio is not -50"153check_active_slave "eth1"154155ip -n ${s_ns} link set $active_slave down156check_active_slave "eth0"157bond_check_connection "change slave prio"158fi159}160161prio_miimon()162{163local primary_reselect164local mode=$1165166for primary_reselect in 0 1 2; do167prio_test "mode $mode miimon 100 primary eth1 primary_reselect $primary_reselect"168log_test "prio" "$mode miimon primary_reselect $primary_reselect"169done170}171172prio_arp()173{174local primary_reselect175local mode=$1176177for primary_reselect in 0 1 2; do178prio_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} primary eth1 primary_reselect $primary_reselect"179log_test "prio" "$mode arp_ip_target primary_reselect $primary_reselect"180done181}182183prio_ns()184{185local primary_reselect186local mode=$1187188if skip_ns; then189log_test_skip "prio ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."190return 0191fi192193for primary_reselect in 0 1 2; do194prio_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6} primary eth1 primary_reselect $primary_reselect"195log_test "prio" "$mode ns_ip6_target primary_reselect $primary_reselect"196done197}198199prio()200{201local mode modes="active-backup balance-tlb balance-alb"202203if skip_prio; then204log_test_skip "prio" "Current iproute or kernel doesn't support bond option 'prio'."205return 0206fi207208for mode in $modes; do209prio_miimon $mode210done211prio_arp "active-backup"212prio_ns "active-backup"213}214215wait_mii_up()216{217for i in $(seq 0 2); do218mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")219[ ${mii_status} != "UP" ] && return 1220done221return 0222}223224arp_validate_test()225{226local param="$1"227RET=0228229# create bond230bond_reset "${param}"231232bond_check_connection233[ $RET -ne 0 ] && log_test "arp_validate" "$retmsg"234235# wait for a while to make sure the mii status stable236slowwait 5 wait_mii_up237for i in $(seq 0 2); do238mii_status=$(cmd_jq "ip -n ${s_ns} -j -d link show eth$i" ".[].linkinfo.info_slave_data.mii_status")239if [ ${mii_status} != "UP" ]; then240RET=1241log_test "arp_validate" "interface eth$i mii_status $mii_status"242fi243done244}245246# Testing correct multicast groups are added to slaves for ns targets247arp_validate_mcast()248{249RET=0250local arp_valid=$(cmd_jq "ip -n ${s_ns} -j -d link show bond0" ".[].linkinfo.info_data.arp_validate")251local active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")252253for i in $(seq 0 2); do254maddr_list=$(ip -n ${s_ns} maddr show dev eth${i})255256# arp_valid == 0 or active_slave should not join any maddrs257if { [ "$arp_valid" == "null" ] || [ "eth${i}" == ${active_slave} ]; } && \258echo "$maddr_list" | grep -qE "${c_maddr}|${g_maddr}"; then259RET=1260check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"261# arp_valid != 0 and backup_slave should join both maddrs262elif [ "$arp_valid" != "null" ] && [ "eth${i}" != ${active_slave} ] && \263( ! echo "$maddr_list" | grep -q "${c_maddr}" || \264! echo "$maddr_list" | grep -q "${m_maddr}"); then265RET=1266check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"267fi268done269270# Do failover271ip -n ${s_ns} link set ${active_slave} down272# wait for active link change273slowwait 2 active_slave_changed $active_slave274active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")275276for i in $(seq 0 2); do277maddr_list=$(ip -n ${s_ns} maddr show dev eth${i})278279# arp_valid == 0 or active_slave should not join any maddrs280if { [ "$arp_valid" == "null" ] || [ "eth${i}" == ${active_slave} ]; } && \281echo "$maddr_list" | grep -qE "${c_maddr}|${g_maddr}"; then282RET=1283check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"284# arp_valid != 0 and backup_slave should join both maddrs285elif [ "$arp_valid" != "null" ] && [ "eth${i}" != ${active_slave} ] && \286( ! echo "$maddr_list" | grep -q "${c_maddr}" || \287! echo "$maddr_list" | grep -q "${m_maddr}"); then288RET=1289check_err 1 "arp_valid $arp_valid active_slave $active_slave, eth$i has mcast group"290fi291done292}293294arp_validate_arp()295{296local mode=$1297local val298for val in $(seq 0 6); do299arp_validate_test "mode $mode arp_interval 100 arp_ip_target ${g_ip4} arp_validate $val"300log_test "arp_validate" "$mode arp_ip_target arp_validate $val"301done302}303304arp_validate_ns()305{306local mode=$1307local val308309if skip_ns; then310log_test_skip "arp_validate ns" "Current iproute or kernel doesn't support bond option 'ns_ip6_target'."311return 0312fi313314for val in $(seq 0 6); do315arp_validate_test "mode $mode arp_interval 100 ns_ip6_target ${g_ip6},${c_ip6} arp_validate $val"316log_test "arp_validate" "$mode ns_ip6_target arp_validate $val"317arp_validate_mcast318log_test "arp_validate" "join mcast group"319done320}321322arp_validate()323{324arp_validate_arp "active-backup"325arp_validate_ns "active-backup"326}327328garp_test()329{330local param="$1"331local active_slave exp_num real_num i332RET=0333334# create bond335bond_reset "${param}"336337bond_check_connection338[ $RET -ne 0 ] && log_test "num_grat_arp" "$retmsg"339340341# Add tc rules to count GARP number342for i in $(seq 0 2); do343tc -n ${g_ns} filter add dev s$i ingress protocol arp pref 1 handle 101 \344flower skip_hw arp_op request arp_sip ${s_ip4} arp_tip ${s_ip4} action pass345done346347# Do failover348active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")349ip -n ${s_ns} link set ${active_slave} down350351# wait for active link change352slowwait 2 active_slave_changed $active_slave353354exp_num=$(echo "${param}" | cut -f6 -d ' ')355active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")356slowwait_for_counter $((exp_num + 5)) $exp_num tc_rule_handle_stats_get \357"dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}" &> /dev/null358359# check result360real_num=$(tc_rule_handle_stats_get "dev s${active_slave#eth} ingress" 101 ".packets" "-n ${g_ns}")361if [ "${real_num}" -ne "${exp_num}" ]; then362echo "$real_num garp packets sent on active slave ${active_slave}"363RET=1364fi365366for i in $(seq 0 2); do367tc -n ${g_ns} filter del dev s$i ingress368done369}370371num_grat_arp()372{373local val374for val in 10 20 30; do375garp_test "mode active-backup miimon 10 num_grat_arp $val peer_notify_delay 100"376log_test "num_grat_arp" "active-backup miimon num_grat_arp $val"377done378}379380check_all_mac_same()381{382RET=0383# all slaves should have same mac address (with the first port's mac)384local bond_mac=$(ip -n "$s_ns" -j link show bond0 | jq -r '.[]["address"]')385local eth0_mac=$(ip -n "$s_ns" -j link show eth0 | jq -r '.[]["address"]')386local eth1_mac=$(ip -n "$s_ns" -j link show eth1 | jq -r '.[]["address"]')387local eth2_mac=$(ip -n "$s_ns" -j link show eth2 | jq -r '.[]["address"]')388if [ "$bond_mac" != "${mac[0]}" ] || [ "$eth0_mac" != "$bond_mac" ] || \389[ "$eth1_mac" != "$bond_mac" ] || [ "$eth2_mac" != "$bond_mac" ]; then390RET=1391fi392}393394check_bond_mac_same_with_first()395{396RET=0397# bond mac address should be same with the first added slave398local bond_mac=$(ip -n "$s_ns" -j link show bond0 | jq -r '.[]["address"]')399if [ "$bond_mac" != "${mac[0]}" ]; then400RET=1401fi402}403404check_bond_mac_same_with_active()405{406RET=0407# bond mac address should be same with active slave408local bond_mac=$(ip -n "$s_ns" -j link show bond0 | jq -r '.[]["address"]')409local active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")410local active_slave_mac=$(ip -n "$s_ns" -j link show "$active_slave" | jq -r '.[]["address"]')411if [ "$bond_mac" != "$active_slave_mac" ]; then412RET=1413fi414}415416check_backup_slave_mac_not_change()417{418RET=0419# backup slave's mac address is not changed420if ip -n "$s_ns" -d -j link show type bond_slave | jq -e '.[]421| select(.linkinfo.info_slave_data.state=="BACKUP")422| select(.address != .linkinfo.info_slave_data.perm_hwaddr)' &> /dev/null; then423RET=1424fi425}426427check_backup_slave_mac_inherit()428{429local backup_mac430RET=0431432# backup slaves should use mac[1] or mac[2]433local backup_macs=$(ip -n "$s_ns" -d -j link show type bond_slave | \434jq -r '.[] | select(.linkinfo.info_slave_data.state=="BACKUP") | .address')435for backup_mac in $backup_macs; do436if [ "$backup_mac" != "${mac[1]}" ] && [ "$backup_mac" != "${mac[2]}" ]; then437RET=1438fi439done440}441442check_first_slave_random_mac()443{444RET=0445# remove the first added slave and added it back446ip -n "$s_ns" link set eth0 nomaster447ip -n "$s_ns" link set eth0 master bond0448449# the first slave should use random mac address450eth0_mac=$(ip -n "$s_ns" -j link show eth0 | jq -r '.[]["address"]')451[ "$eth0_mac" = "${mac[0]}" ] && RET=1452log_test "bond fail_over_mac follow" "random first slave mac"453454# remove the first slave, the permanent MAC address should be restored back455ip -n "$s_ns" link set eth0 nomaster456eth0_mac=$(ip -n "$s_ns" -j link show eth0 | jq -r '.[]["address"]')457[ "$eth0_mac" != "${mac[0]}" ] && RET=1458}459460do_active_backup_failover()461{462local active_slave=$(cmd_jq "ip -n ${s_ns} -d -j link show bond0" ".[].linkinfo.info_data.active_slave")463ip -n ${s_ns} link set ${active_slave} down464slowwait 2 active_slave_changed $active_slave465ip -n ${s_ns} link set ${active_slave} up466}467468fail_over_mac()469{470# Bring down the first interface on the switch to force the bond to471# select another active interface instead of the first one that joined.472ip -n "$g_ns" link set s0 down473474# fail_over_mac none475bond_reset "mode active-backup miimon 100 fail_over_mac 0"476check_all_mac_same477log_test "fail_over_mac 0" "all slaves have same mac"478do_active_backup_failover479check_all_mac_same480log_test "fail_over_mac 0" "failover: all slaves have same mac"481482# fail_over_mac active483bond_reset "mode active-backup miimon 100 fail_over_mac 1"484check_bond_mac_same_with_active485log_test "fail_over_mac 1" "bond mac is same with active slave mac"486check_backup_slave_mac_not_change487log_test "fail_over_mac 1" "backup slave mac is not changed"488do_active_backup_failover489check_bond_mac_same_with_active490log_test "fail_over_mac 1" "failover: bond mac is same with active slave mac"491check_backup_slave_mac_not_change492log_test "fail_over_mac 1" "failover: backup slave mac is not changed"493494# fail_over_mac follow495bond_reset "mode active-backup miimon 100 fail_over_mac 2"496check_bond_mac_same_with_first497log_test "fail_over_mac 2" "bond mac is same with first slave mac"498check_bond_mac_same_with_active499log_test "fail_over_mac 2" "bond mac is same with active slave mac"500check_backup_slave_mac_inherit501log_test "fail_over_mac 2" "backup slave mac inherit"502do_active_backup_failover503check_bond_mac_same_with_first504log_test "fail_over_mac 2" "failover: bond mac is same with first slave mac"505check_bond_mac_same_with_active506log_test "fail_over_mac 2" "failover: bond mac is same with active slave mac"507check_backup_slave_mac_inherit508log_test "fail_over_mac 2" "failover: backup slave mac inherit"509check_first_slave_random_mac510log_test "fail_over_mac 2" "first slave mac random"511}512513vlan_over_bond_arp()514{515local mode="$1"516RET=0517518bond_reset "mode $mode arp_interval 100 arp_ip_target 192.0.3.10"519ip -n "${s_ns}" link add bond0.3 link bond0 type vlan id 3520ip -n "${s_ns}" link set bond0.3 up521ip -n "${s_ns}" addr add 192.0.3.1/24 dev bond0.3522ip -n "${s_ns}" addr add 2001:db8::3:1/64 dev bond0.3523524slowwait_for_counter 5 5 tc_rule_handle_stats_get \525"dev eth0.3 ingress" 101 ".packets" "-n ${c_ns}" &> /dev/null || RET=1526log_test "vlan over bond arp" "$mode"527}528529vlan_over_bond_ns()530{531local mode="$1"532RET=0533534if skip_ns; then535log_test_skip "vlan_over_bond ns" "$mode"536return 0537fi538539bond_reset "mode $mode arp_interval 100 ns_ip6_target 2001:db8::3:10"540ip -n "${s_ns}" link add bond0.3 link bond0 type vlan id 3541ip -n "${s_ns}" link set bond0.3 up542ip -n "${s_ns}" addr add 192.0.3.1/24 dev bond0.3543ip -n "${s_ns}" addr add 2001:db8::3:1/64 dev bond0.3544545slowwait_for_counter 5 5 tc_rule_handle_stats_get \546"dev eth0.3 ingress" 102 ".packets" "-n ${c_ns}" &> /dev/null || RET=1547log_test "vlan over bond ns" "$mode"548}549550vlan_over_bond()551{552# add vlan 3 for client553ip -n "${c_ns}" link add eth0.3 link eth0 type vlan id 3554ip -n "${c_ns}" link set eth0.3 up555ip -n "${c_ns}" addr add 192.0.3.10/24 dev eth0.3556ip -n "${c_ns}" addr add 2001:db8::3:10/64 dev eth0.3557558# Add tc rule to check the vlan pkts559tc -n "${c_ns}" qdisc add dev eth0.3 clsact560tc -n "${c_ns}" filter add dev eth0.3 ingress protocol arp \561handle 101 flower skip_hw arp_op request \562arp_sip 192.0.3.1 arp_tip 192.0.3.10 action pass563tc -n "${c_ns}" filter add dev eth0.3 ingress protocol ipv6 \564handle 102 flower skip_hw ip_proto icmpv6 \565type 135 src_ip 2001:db8::3:1 action pass566567vlan_over_bond_arp "active-backup"568vlan_over_bond_ns "active-backup"569}570571trap cleanup EXIT572573setup_prepare574setup_wait575tests_run576577exit $EXIT_STATUS578579580