1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Test the protodown mechanism. Verify basic protodown toggling, protodown 5# reasons, operational state when the lower device carrier changes, and correct 6# operational state when the lower device has no carrier. 7 8# shellcheck disable=SC1091,SC2034,SC2154,SC2317 9source lib.sh 10 11require_command jq 12 13ALL_TESTS=" 14 protodown_basic_macvlan 15 protodown_basic_vxlan 16 protodown_reasons 17 protodown_lower_toggle 18 protodown_lower_down 19" 20 21operstate_get() 22{ 23 local ns=$1; shift 24 local dev=$1; shift 25 26 ip -n "$ns" -j link show dev "$dev" | jq -r '.[].operstate' 27} 28 29operstate_check() 30{ 31 local ns=$1; shift 32 local dev=$1; shift 33 local expected=$1; shift 34 35 local current 36 current=$(operstate_get "$ns" "$dev") 37 38 [ "$current" = "$expected" ] 39} 40 41setup_prepare() 42{ 43 setup_ns NS 44 defer cleanup_all_ns 45 46 ip -n "$NS" link add name dummy0 up type dummy 47 48 ip -n "$NS" link add name macvlan0 link dummy0 up type macvlan mode bridge 49 50 ip -n "$NS" link add name vxlan0 up type vxlan id 10010 dstport 4789 51} 52 53protodown_basic() 54{ 55 local dev=$1; shift 56 57 ip -n "$NS" link set dev "$dev" protodown on 58 check_err $? "Failed to set protodown on" 59 60 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" "$dev" DOWN 61 check_err $? "Operational state is not DOWN after setting protodown" 62 63 ip -n "$NS" link set dev "$dev" protodown off 64 check_err $? "Failed to set protodown off" 65 66 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" "$dev" UP 67 check_err $? "Operational state is not UP after clearing protodown" 68} 69 70protodown_basic_macvlan() 71{ 72 RET=0 73 74 protodown_basic macvlan0 75 76 log_test "Basic protodown on/off with macvlan" 77} 78 79protodown_basic_vxlan() 80{ 81 RET=0 82 83 protodown_basic vxlan0 84 85 log_test "Basic protodown on/off with vxlan" 86} 87 88protodown_reasons() 89{ 90 RET=0 91 92 ip -n "$NS" link set dev macvlan0 protodown on 93 94 ip -n "$NS" link set dev macvlan0 protodown_reason 0 on 95 check_err $? "Failed to set protodown reason bit 0" 96 97 # Cannot clear protodown while reasons are active. 98 ip -n "$NS" link set dev macvlan0 protodown off 2>/dev/null 99 check_fail $? "Clearing protodown succeeded with active reasons" 100 101 ip -n "$NS" link set dev macvlan0 protodown_reason 0 off 102 check_err $? "Failed to clear protodown reason bit 0" 103 104 # Can clear protodown when no reasons are active. 105 ip -n "$NS" link set dev macvlan0 protodown off 106 check_err $? "Failed to clear protodown with no active reasons" 107 108 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 UP 109 check_err $? "Operational state is not UP after clearing protodown" 110 111 log_test "Protodown reasons" 112} 113 114protodown_lower_toggle() 115{ 116 RET=0 117 118 ip -n "$NS" link set dev macvlan0 protodown on 119 120 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 DOWN 121 check_err $? "Operational state is not DOWN after setting protodown" 122 123 # Toggle carrier on the lower device. The macvlan should stay DOWN 124 # because protodown is on. 125 ip -n "$NS" link set dev dummy0 carrier off 126 ip -n "$NS" link set dev dummy0 carrier on 127 128 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" dummy0 UP 129 check_err $? "Lower device is not UP after carrier on" 130 131 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 DOWN 132 check_err $? "Macvlan operational state is not DOWN despite protodown" 133 134 # Clear protodown and verify the macvlan comes back up. 135 ip -n "$NS" link set dev macvlan0 protodown off 136 137 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 UP 138 check_err $? "Operational state is not UP after clearing protodown" 139 140 log_test "Protodown with lower device toggled" 141} 142 143protodown_lower_down() 144{ 145 RET=0 146 147 # Bring the lower device carrier down first. 148 ip -n "$NS" link set dev dummy0 carrier off 149 150 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 LOWERLAYERDOWN 151 check_err $? "Macvlan is not LOWERLAYERDOWN with lower carrier off" 152 153 # Toggle protodown on and off while lower has no carrier. The macvlan 154 # should not transition to UP. 155 ip -n "$NS" link set dev macvlan0 protodown on 156 157 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 LOWERLAYERDOWN 158 check_err $? "Macvlan is not LOWERLAYERDOWN after setting protodown" 159 160 ip -n "$NS" link set dev macvlan0 protodown off 161 162 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 LOWERLAYERDOWN 163 check_err $? "Macvlan is not LOWERLAYERDOWN after clearing protodown" 164 165 # Bring the lower device carrier up. The macvlan should transition to 166 # UP. 167 ip -n "$NS" link set dev dummy0 carrier on 168 169 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" dummy0 UP 170 check_err $? "Lower device is not UP after carrier on" 171 172 busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 UP 173 check_err $? "Macvlan is not UP after lower device is UP" 174 175 log_test "Protodown with lower device down" 176} 177 178trap defer_scopes_cleanup EXIT 179setup_prepare 180tests_run 181 182exit "$EXIT_STATUS" 183