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