1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4NAMESPACES="" 5 6# Test that a link aggregation device (bonding, team) removes the hardware 7# addresses that it adds on its underlying devices. 8test_LAG_cleanup() 9{ 10 local driver=$1 11 local mode=$2 12 local ucaddr="02:00:00:12:34:56" 13 local addr6="fe80::78:9abc/64" 14 local mcaddr="33:33:ff:78:9a:bc" 15 local name 16 17 ip link add dummy1 type dummy 18 ip link add dummy2 type dummy 19 if [ "$driver" = "bonding" ]; then 20 name="bond1" 21 ip link add "$name" up type bond mode "$mode" 22 ip link set dev dummy1 master "$name" 23 ip link set dev dummy2 master "$name" 24 elif [ "$driver" = "team" ]; then 25 name="team0" 26 teamd -d -c ' 27 { 28 "device": "'"$name"'", 29 "runner": { 30 "name": "'"$mode"'" 31 }, 32 "ports": { 33 "dummy1": 34 {}, 35 "dummy2": 36 {} 37 } 38 } 39 ' 40 ip link set dev "$name" up 41 else 42 check_err 1 43 log_test test_LAG_cleanup ": unknown driver \"$driver\"" 44 return 45 fi 46 47 # Used to test dev->uc handling 48 ip link add mv0 link "$name" up address "$ucaddr" type macvlan 49 # Used to test dev->mc handling 50 ip address add "$addr6" dev "$name" 51 52 # Check that addresses were added as expected 53 (grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy1 || 54 grep_bridge_fdb "$ucaddr" bridge fdb show dev dummy2) >/dev/null 55 check_err $? "macvlan unicast address not found on a slave" 56 57 # mcaddr is added asynchronously by addrconf_dad_work(), use busywait 58 (busywait 10000 grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy1 || 59 grep_bridge_fdb "$mcaddr" bridge fdb show dev dummy2) >/dev/null 60 check_err $? "IPv6 solicited-node multicast mac address not found on a slave" 61 62 ip link set dev "$name" down 63 ip link del "$name" 64 65 not grep_bridge_fdb "$ucaddr" bridge fdb show >/dev/null 66 check_err $? "macvlan unicast address still present on a slave" 67 68 not grep_bridge_fdb "$mcaddr" bridge fdb show >/dev/null 69 check_err $? "IPv6 solicited-node multicast mac address still present on a slave" 70 71 cleanup 72 73 log_test "$driver cleanup mode $mode" 74} 75 76# Build a generic 2 node net namespace with 2 connections 77# between the namespaces 78# 79# +-----------+ +-----------+ 80# | node1 | | node2 | 81# | | | | 82# | | | | 83# | eth0 +-------+ eth0 | 84# | | | | 85# | eth1 +-------+ eth1 | 86# | | | | 87# +-----------+ +-----------+ 88lag_setup2x2() 89{ 90 local state=${1:-down} 91 local namespaces="lag_node1 lag_node2" 92 93 # create namespaces 94 for n in ${namespaces}; do 95 ip netns add ${n} 96 done 97 98 # wire up namespaces 99 ip link add name lag1 type veth peer name lag1-end 100 ip link set dev lag1 netns lag_node1 $state name eth0 101 ip link set dev lag1-end netns lag_node2 $state name eth0 102 103 ip link add name lag1 type veth peer name lag1-end 104 ip link set dev lag1 netns lag_node1 $state name eth1 105 ip link set dev lag1-end netns lag_node2 $state name eth1 106 107 NAMESPACES="${namespaces}" 108} 109 110# cleanup all lag related namespaces and remove the bonding module 111lag_cleanup() 112{ 113 for n in ${NAMESPACES}; do 114 ip netns delete ${n} >/dev/null 2>&1 || true 115 done 116 modprobe -r bonding 117} 118 119SWITCH="lag_node1" 120CLIENT="lag_node2" 121CLIENTIP="172.20.2.1" 122SWITCHIP="172.20.2.2" 123 124lag_setup_network() 125{ 126 lag_setup2x2 "down" 127 128 # create switch 129 ip netns exec ${SWITCH} ip link add br0 up type bridge 130 ip netns exec ${SWITCH} ip link set eth0 master br0 up 131 ip netns exec ${SWITCH} ip link set eth1 master br0 up 132 ip netns exec ${SWITCH} ip addr add ${SWITCHIP}/24 dev br0 133} 134 135lag_reset_network() 136{ 137 ip netns exec ${CLIENT} ip link del bond0 138 ip netns exec ${SWITCH} ip link set eth0 up 139 ip netns exec ${SWITCH} ip link set eth1 up 140} 141 142create_bond() 143{ 144 # create client 145 ip netns exec ${CLIENT} ip link set eth0 down 146 ip netns exec ${CLIENT} ip link set eth1 down 147 148 ip netns exec ${CLIENT} ip link add bond0 type bond $@ 149 ip netns exec ${CLIENT} ip link set eth0 master bond0 150 ip netns exec ${CLIENT} ip link set eth1 master bond0 151 ip netns exec ${CLIENT} ip link set bond0 up 152 ip netns exec ${CLIENT} ip addr add ${CLIENTIP}/24 dev bond0 153} 154 155test_bond_recovery() 156{ 157 RET=0 158 159 create_bond $@ 160 161 # verify connectivity 162 ip netns exec ${CLIENT} ping ${SWITCHIP} -c 2 >/dev/null 2>&1 163 check_err $? "No connectivity" 164 165 # force the links of the bond down 166 ip netns exec ${SWITCH} ip link set eth0 down 167 sleep 2 168 ip netns exec ${SWITCH} ip link set eth0 up 169 ip netns exec ${SWITCH} ip link set eth1 down 170 171 # re-verify connectivity 172 ip netns exec ${CLIENT} ping ${SWITCHIP} -c 2 >/dev/null 2>&1 173 174 local rc=$? 175 check_err $rc "Bond failed to recover" 176 log_test "$1 ($2) bond recovery" 177 lag_reset_network 178} 179