1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Testing if bond lacp_strict works 5# 6# Partner (p_ns) 7# +--------------------------+ 8# | bond0 | 9# | + | 10# | eth0 | eth1 | 11# | +---+---+ | 12# | | | | 13# +--------------------------+ 14# | | eth0 | eth1 | 15# | | | | 16# |(br_ns) | br0 | br1 | 17# | | | | 18# | | eth2 | eth3 | 19# +--------------------------+ 20# | | | | 21# | +---+---+ | 22# | eth0 | eth1 | 23# | + | 24# | bond0 | 25# +--------------------------+ 26# Dut (d_ns) 27 28lib_dir=$(dirname "$0") 29# shellcheck disable=SC1090 30source "$lib_dir"/../../../net/lib.sh 31 32COLLECTING_DISTRIBUTING_MASK=48 33COLLECTING_DISTRIBUTING=48 34FAILED=0 35 36setup_links() 37{ 38 # shellcheck disable=SC2154 39 ip -n "${p_ns}" link add eth0 type veth peer name eth0 netns "${br_ns}" 40 ip -n "${p_ns}" link add eth1 type veth peer name eth1 netns "${br_ns}" 41 ip -n "${d_ns}" link add eth0 type veth peer name eth2 netns "${br_ns}" 42 ip -n "${d_ns}" link add eth1 type veth peer name eth3 netns "${br_ns}" 43 44 ip -n "${br_ns}" link add br0 type bridge 45 ip -n "${br_ns}" link add br1 type bridge 46 47 ip -n "${br_ns}" link set dev br0 type bridge stp_state 0 48 ip -n "${br_ns}" link set dev br1 type bridge stp_state 0 49 50 ip -n "${br_ns}" link set eth0 master br0 51 ip -n "${br_ns}" link set eth2 master br0 52 ip -n "${br_ns}" link set eth1 master br1 53 ip -n "${br_ns}" link set eth3 master br1 54 55 # Allow LACP trames forwarding on bridge ports 56 ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth0/group_fwd_mask" 57 ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth1/group_fwd_mask" 58 ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth2/group_fwd_mask" 59 ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth3/group_fwd_mask" 60 61 ip -n "${br_ns}" link set eth0 up 62 ip -n "${br_ns}" link set eth2 up 63 ip -n "${br_ns}" link set eth1 up 64 ip -n "${br_ns}" link set eth3 up 65 66 ip -n "${br_ns}" link set br0 up 67 ip -n "${br_ns}" link set br1 up 68 69 ip -n "${d_ns}" link add bond0 type bond mode 802.3ad miimon 100 \ 70 lacp_rate fast min_links 1 71 ip -n "${p_ns}" link add bond0 type bond mode 802.3ad miimon 100 \ 72 lacp_rate fast min_links 1 73 74 ip -n "${d_ns}" link set eth0 master bond0 75 ip -n "${d_ns}" link set eth1 master bond0 76 ip -n "${p_ns}" link set eth0 master bond0 77 ip -n "${p_ns}" link set eth1 master bond0 78 79 ip -n "${d_ns}" link set bond0 up 80 ip -n "${p_ns}" link set bond0 up 81} 82 83test_master_carrier() { 84 local expected=$1 85 local mode_name=$2 86 local carrier 87 88 carrier=$(ip netns exec "${d_ns}" cat /sys/class/net/bond0/carrier) 89 [ "$carrier" == "1" ] && carrier="up" || carrier="down" 90 91 [ "$carrier" == "$expected" ] && return 92 93 echo "FAIL: Expected carrier $expected in lacp_strict $mode_name mode, got $carrier" 94 95 RET=1 96 97} 98 99compare_state() { 100 local actual_state=$1 101 local expected_state=$2 102 local iface=$3 103 local last_attempt=$4 104 105 [ $((actual_state & COLLECTING_DISTRIBUTING_MASK)) -eq "$expected_state" ] \ 106 && return 0 107 108 [ "$last_attempt" -ne 1 ] && return 1 109 110 printf "FAIL: Expected LACP %s actor state to " "$iface" 111 if [ "$expected_state" -eq $COLLECTING_DISTRIBUTING ]; then 112 echo "be in Collecting/Distributing state" 113 else 114 echo "have neither Collecting nor Distributing set." 115 fi 116 117 return 1 118} 119 120_test_lacp_port_state() { 121 local interface=$1 122 local expected=$2 123 local last_attempt=$3 124 local eth0_actor_state eth1_actor_state 125 local ret=0 126 127 # shellcheck disable=SC2016 128 while IFS='=' read -r k v; do 129 printf -v "$k" '%s' "$v" 130 done < <( 131 ip netns exec "${d_ns}" awk ' 132 /^Slave Interface: / { iface=$3 } 133 /details actor lacp pdu:/ { ctx="actor" } 134 /details partner lacp pdu:/ { ctx="partner" } 135 /^[[:space:]]+port state: / { 136 if (ctx == "actor") { 137 gsub(":", "", iface) 138 printf "%s_%s_state=%s\n", iface, ctx, $3 139 } 140 } 141 ' /proc/net/bonding/bond0 142 ) 143 144 if [ "$interface" == "eth0" ] || [ "$interface" == "both" ]; then 145 compare_state "$eth0_actor_state" "$expected" eth0 "$last_attempt" || ret=1 146 fi 147 148 if [ "$interface" == "eth1" ] || [ "$interface" == "both" ]; then 149 compare_state "$eth1_actor_state" "$expected" eth1 "$last_attempt" || ret=1 150 fi 151 152 return $ret 153} 154 155test_lacp_port_state() { 156 local interface=$1 157 local expected=$2 158 local retry=$3 159 local last_attempt=0 160 local attempt=1 161 local ret=1 162 163 while [ $attempt -le $((retry + 1)) ]; do 164 [ $attempt -eq $((retry + 1)) ] && last_attempt=1 165 _test_lacp_port_state "$interface" "$expected" "$last_attempt" && return 166 ((attempt++)) 167 sleep 1 168 done 169 170 RET=1 171} 172 173 174trap cleanup_all_ns EXIT 175setup_ns d_ns p_ns br_ns 176setup_links 177 178# Initial state 179RET=0 180mode=off 181test_lacp_port_state both $COLLECTING_DISTRIBUTING 3 182test_master_carrier up $mode 183log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up" 184 185# partner eth0 down, eth1 up 186# (replicate eth0 state to dut eth0 by shutting a bridge port) 187RET=0 188ip -n "${p_ns}" link set eth0 down 189ip -n "${br_ns}" link set eth2 down 190test_lacp_port_state eth0 $FAILED 5 191test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1 192test_master_carrier up $mode 193log_test "bond LACP" "lacp_strict $mode - eth0 down" 194 195# partner eth0 and eth1 down 196RET=0 197ip -n "${p_ns}" link set eth1 down 198ip -n "${br_ns}" link set eth3 down 199test_lacp_port_state both $FAILED 5 200test_master_carrier down $mode # down because of min_links 201log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 down" 202 203# partner eth0 up, eth1 down 204RET=0 205ip -n "${p_ns}" link set eth0 up 206ip -n "${br_ns}" link set eth2 up 207test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60 208test_lacp_port_state eth1 $FAILED 1 209test_master_carrier up $mode 210log_test "bond LACP" "lacp_strict $mode - eth0 up, eth1 down" 211 212# partner eth0 and eth1 up 213RET=0 214ip -n "${p_ns}" link set eth1 up 215ip -n "${br_ns}" link set eth3 up 216test_lacp_port_state both $COLLECTING_DISTRIBUTING 60 217test_master_carrier up $mode 218log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up" 219 220# partner eth0 stops LACP and eth1 up 221RET=0 222ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth0/group_fwd_mask" 223ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth2/group_fwd_mask" 224test_lacp_port_state eth0 $FAILED 5 225test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1 226test_master_carrier up $mode 227log_test "bond LACP" "lacp_strict $mode - eth0 stopped sending LACP" 228 229# partner eth0 and eth1 stop LACP 230RET=0 231ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth1/group_fwd_mask" 232ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth3/group_fwd_mask" 233test_lacp_port_state both $FAILED 5 234test_master_carrier up $mode 235log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP" 236 237# switch to lacp_strict on 238RET=0 239mode=on 240ip -n "${d_ns}" link set dev bond0 type bond lacp_strict $mode 241test_lacp_port_state both $FAILED 1 242test_master_carrier down $mode 243log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP" 244 245# switch back to lacp_strict off mode 246RET=0 247mode=off 248ip -n "${d_ns}" link set dev bond0 type bond lacp_strict $mode 249test_lacp_port_state both $FAILED 1 250test_master_carrier up $mode 251log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP" 252 253# eth0 recovers LACP 254RET=0 255ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth0/group_fwd_mask" 256ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth2/group_fwd_mask" 257test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60 258test_lacp_port_state eth1 $FAILED 1 259test_master_carrier up $mode 260log_test "bond LACP" "lacp_strict $mode - eth0 recovered and eth1 stopped sending LACP" 261 262# eth1 recovers LACP 263RET=0 264ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth1/group_fwd_mask" 265ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth3/group_fwd_mask" 266test_lacp_port_state both $COLLECTING_DISTRIBUTING 60 267test_master_carrier up $mode 268log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 recovered LACP" 269 270# switch to lacp_strict on 271RET=0 272mode=on 273ip -n "${d_ns}" link set dev bond0 type bond lacp_strict $mode 274test_lacp_port_state both $COLLECTING_DISTRIBUTING 1 275test_master_carrier up $mode 276log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up" 277 278# partner eth0 down, eth1 up 279RET=0 280ip -n "${p_ns}" link set eth0 down 281ip -n "${br_ns}" link set eth2 down 282test_lacp_port_state eth0 $FAILED 5 283test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1 284test_master_carrier up $mode 285log_test "bond LACP" "lacp_strict $mode - eth0 down" 286 287# partner eth0 and eth1 down 288RET=0 289ip -n "${p_ns}" link set eth1 down 290ip -n "${br_ns}" link set eth3 down 291test_lacp_port_state both $FAILED 5 292test_master_carrier down $mode # down because of min_links 293log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 down" 294 295# partner eth0 up, eth1 down 296RET=0 297ip -n "${p_ns}" link set eth0 up 298ip -n "${br_ns}" link set eth2 up 299test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60 300test_lacp_port_state eth1 $FAILED 1 301test_master_carrier up $mode 302log_test "bond LACP" "lacp_strict $mode - eth0 up, eth1 down" 303 304# partner eth0 and eth1 up 305RET=0 306ip -n "${p_ns}" link set eth1 up 307ip -n "${br_ns}" link set eth3 up 308test_lacp_port_state both $COLLECTING_DISTRIBUTING 60 309test_master_carrier up $mode 310log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 up" 311 312# partner eth0 stops LACP and eth1 up 313RET=0 314ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth0/group_fwd_mask" 315ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br0/brif/eth2/group_fwd_mask" 316test_lacp_port_state eth0 $FAILED 5 317test_lacp_port_state eth1 $COLLECTING_DISTRIBUTING 1 318test_master_carrier up $mode 319log_test "bond LACP" "lacp_strict $mode - eth0 stopped sending LACP" 320 321# partner eth0 and eth1 stop LACP 322RET=0 323ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth1/group_fwd_mask" 324ip netns exec "${br_ns}" sh -c "echo 0 > /sys/class/net/br1/brif/eth3/group_fwd_mask" 325test_lacp_port_state both $FAILED 5 326test_master_carrier down $mode 327log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 stopped sending LACP" 328 329# eth0 recovers LACP 330RET=0 331ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth0/group_fwd_mask" 332ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br0/brif/eth2/group_fwd_mask" 333test_lacp_port_state eth0 $COLLECTING_DISTRIBUTING 60 334test_lacp_port_state eth1 $FAILED 1 335test_master_carrier up $mode 336log_test "bond LACP" "lacp_strict $mode - eth0 recovered and eth1 stopped sending LACP" 337 338# eth1 recovers LACP 339# shellcheck disable=SC2034 340RET=0 341ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth1/group_fwd_mask" 342ip netns exec "${br_ns}" sh -c "echo 4 > /sys/class/net/br1/brif/eth3/group_fwd_mask" 343test_lacp_port_state both $COLLECTING_DISTRIBUTING 60 344test_master_carrier up $mode 345log_test "bond LACP" "lacp_strict $mode - eth0 and eth1 recovered LACP" 346 347exit "${EXIT_STATUS}" 348