blob: 02ef0ee02d6a414daa24026b78d98d7c9a478326 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
test_dir="$(dirname "$0")"
export REQUIRE_MZ=no
export NUM_NETIFS=0
# shellcheck disable=SC1091
source "${test_dir}/../../../net/forwarding/lib.sh"
TCP_PORT="43434"
# Create a team interface inside of a given network namespace with a given
# mode, members, and IP address.
# Arguments:
# namespace - Network namespace to put the team interface into.
# team - The name of the team interface to setup.
# mode - The team mode of the interface.
# ip_address - The IP address to assign to the team interface.
# prefix_length - The prefix length for the IP address subnet.
# $@ - members - The member interfaces of the aggregation.
setup_team()
{
local namespace=$1
local team=$2
local mode=$3
local ip_address=$4
local prefix_length=$5
shift 5
local members=("$@")
# Prerequisite: team must have no members
for member in "${members[@]}"; do
ip -n "${namespace}" link set "${member}" nomaster
done
# Prerequisite: team must have no address in order to set it
# shellcheck disable=SC2086
ip -n "${namespace}" addr del "${ip_address}/${prefix_length}" \
${NODAD} dev "${team}"
echo "Setting team in ${namespace} to mode ${mode}"
if ! ip -n "${namespace}" link set "${team}" down; then
echo "Failed to bring team device down"
return 1
fi
if ! ip netns exec "${namespace}" teamnl "${team}" setoption mode \
"${mode}"; then
echo "Failed to set ${team} mode to '${mode}'"
return 1
fi
# Aggregate the members into teams.
for member in "${members[@]}"; do
ip -n "${namespace}" link set "${member}" master "${team}"
done
# Bring team devices up and give them addresses.
if ! ip -n "${namespace}" link set "${team}" up; then
echo "Failed to set ${team} up"
return 1
fi
# shellcheck disable=SC2086
if ! ip -n "${namespace}" addr add "${ip_address}/${prefix_length}" \
${NODAD} dev "${team}"; then
echo "Failed to give ${team} IP address in ${namespace}"
return 1
fi
}
# This is global used to keep track of the sender's iperf3 process, so that it
# can be terminated.
declare sender_pid
# Start sending and receiving TCP traffic with iperf3.
# Globals:
# sender_pid - The process ID of the iperf3 sender process. Used to kill it
# later.
start_listening_and_sending()
{
ip netns exec "${NS2}" iperf3 -s -p "${TCP_PORT}" --logfile /dev/null &
# Wait for server to become reachable before starting client.
slowwait 5 ip netns exec "${NS1}" iperf3 -c "${NS2_IP}" -p \
"${TCP_PORT}" -t 1 --logfile /dev/null
ip netns exec "${NS1}" iperf3 -c "${NS2_IP}" -p "${TCP_PORT}" -b 1M -l \
1K -t 0 --logfile /dev/null &
sender_pid=$!
}
# Stop sending TCP traffic with iperf3.
# Globals:
# sender_pid - The process ID of the iperf3 sender process.
stop_sending_and_listening()
{
kill "${sender_pid}" && wait "${sender_pid}" 2>/dev/null || true
}
# Monitor for TCP traffic with Tcpdump, save results to temp files.
# Arguments:
# namespace - The network namespace to run tcpdump inside of.
# $@ - interfaces - The interfaces to listen to.
save_tcpdump_outputs()
{
local namespace=$1
shift 1
local interfaces=("$@")
for interface in "${interfaces[@]}"; do
tcpdump_start "${interface}" "${namespace}"
done
sleep 1
for interface in "${interfaces[@]}"; do
tcpdump_stop_nosleep "${interface}"
done
}
clear_tcpdump_outputs()
{
local interfaces=("$@")
for interface in "${interfaces[@]}"; do
tcpdump_cleanup "${interface}"
done
}
# Read Tcpdump output, determine packet counts.
# Arguments:
# interface - The name of the interface to count packets for.
# ip_address - The destination IP address.
did_interface_receive()
{
local interface="$1"
local ip_address="$2"
local packet_count
packet_count=$(tcpdump_show "$interface" | grep -c \
"> ${ip_address}.${TCP_PORT}")
echo "Packet count for ${interface} was ${packet_count}"
if [[ "${packet_count}" -gt 0 ]]; then
true
else
false
fi
}
# Return true if the given interface in the given namespace does NOT receive
# traffic over a 1 second period.
# Arguments:
# interface - The name of the interface.
# ip_address - The destination IP address.
# namespace - The name of the namespace that the interface is in.
check_no_traffic()
{
local interface="$1"
local ip_address="$2"
local namespace="$3"
local rc
save_tcpdump_outputs "${namespace}" "${interface}"
did_interface_receive "${interface}" "${ip_address}"
rc=$?
clear_tcpdump_outputs "${interface}"
if [[ "${rc}" -eq 0 ]]; then
return 1
else
return 0
fi
}
|