xref: /openbmc/linux/tools/testing/selftests/drivers/net/bonding/lag_lib.sh (revision 87832e937c808a7ebc41254b408362e3255c87c9)
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