blob: c8e343fcdd6aa5b36802565006244981b20d96b4 [file] [log] [blame]
Jordan Halterman4d32a582017-05-26 19:14:30 -07001#!/bin/bash
2# ---------------------------------
3# Disrupts links between ONOS nodes
4# ---------------------------------
5
6[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7. $ONOS_ROOT/tools/build/envDefaults
8
9function print_usage {
10 command_name=`basename $0`
11 echo "Disrupts links between ONOS nodes."
12 echo
13 echo "Usage: $command_name [<HOST>] <COMMAND> <ARGS>"
14 echo
15 echo "Options:"
16 echo " HOST The host on which to run the command"
17 echo " COMMAND The command to run"
18 echo " ARGS The command arguments"
19 echo " [-h | --help] Print this help"
20 echo
21 echo "COMMAND: <crash | partition | partition-halves | partition-bridge | heal | delay | drop | reorder | duplicate | corrupt | restore>"
22 echo
23 echo " crash Crashes the given host using \"kill -9\""
24 echo
25 echo " Syntax:"
26 echo " $command_name <HOST> crash"
27 echo
28 echo " Examples:"
29 echo " $command_name 10.127.10.111 crash"
30 echo
Jordan Haltermanddc2b182017-07-23 01:27:47 -070031 echo " recover Recovers the given host"
32 echo
33 echo " Syntax:"
34 echo " $command_name <host> recover"
35 echo
36 echo " Examples:"
37 echo " $command_name 10.127.10.111 recover"
38 echo
Jordan Halterman4d32a582017-05-26 19:14:30 -070039 echo " partition Partitions the given host from a list of source host or all ONOS hosts if no sources are specified"
40 echo
41 echo " Syntax:"
42 echo " $command_name <HOST> partition [<SOURCE> [<SOURCE>...]]"
43 echo
44 echo " Examples:"
45 echo " $command_name 10.127.10.111 partition"
46 echo " $command_name 10.127.10.111 partition 10.127.10.111"
47 echo " $command_name 10.127.10.111 partition 10.127.10.112 10.127.10.113"
48 echo
49 echo " partition-halves Splits the cluster into two partitions - this is only recommended for clusters with an odd number of nodes"
50 echo
51 echo " Syntax:"
52 echo " $command_name partition-halves"
53 echo
54 echo " Examples:"
55 echo " $command_name partition-halves"
56 echo
57 echo " partition-bridge Creates a bridge partition where the cluster is partitioned into two halves and the target host is connected to both halves"
58 echo
59 echo " Syntax:"
Jordan Haltermanddc2b182017-07-23 01:27:47 -070060 echo " $command_name <HOST> partition-bridge"
Jordan Halterman4d32a582017-05-26 19:14:30 -070061 echo
62 echo " Examples:"
Jordan Haltermanddc2b182017-07-23 01:27:47 -070063 echo " $command_name 10.127.10.111 partition-bridge"
Jordan Halterman4d32a582017-05-26 19:14:30 -070064 echo
65 echo " heal Heals a partition on the given host"
66 echo
67 echo " Syntax:"
68 echo " $command_name [<HOST>] heal"
69 echo
70 echo " Examples:"
71 echo " $command_name heal"
72 echo " $command_name 10.127.10.111 heal"
73 echo
74 echo " delay Delays packets incoming to the given host by an optional LATENCY, JITTER, CORRELATION, and DISTRIBUTION"
75 echo
76 echo " Syntax:"
77 echo " $command_name [<HOST>] delay [<LATENCY> [<JITTER> [<CORRELATION> [<DISTRIBUTION>]]]]"
78 echo
79 echo " Examples:"
80 echo " $command_name delay"
81 echo " $command_name delay 50ms"
82 echo " $command_name delay 50ms 10ms"
83 echo " $command_name delay 50ms 10ms 75%"
84 echo " $command_name delay 50ms 10ms 75% normal"
85 echo " $command_name 10.127.10.111 delay"
86 echo " $command_name 10.127.10.111 delay 50ms"
87 echo " $command_name 10.127.10.111 delay 50ms 10ms"
88 echo " $command_name 10.127.10.111 delay 50ms 10ms 75%"
89 echo " $command_name 10.127.10.111 delay 50ms 10ms 75% normal"
90 echo
91 echo " drop Drops packets incoming to the given host by an optional PROBABILITY and CORRELATION"
92 echo
93 echo " Syntax:"
94 echo " $command_name [<HOST>] drop [<PROBABILITY> [<CORRELATION>]]"
95 echo
96 echo " Examples:"
97 echo " $command_name drop"
98 echo " $command_name drop 2%"
99 echo " $command_name drop 2% 25%"
100 echo " $command_name 10.127.10.111 drop"
101 echo " $command_name 10.127.10.111 drop 2%"
102 echo " $command_name 10.127.10.111 drop 2% 25%"
103 echo
104 echo " reorder Reorders packets incoming to the given host by an optional PROBABILITY and CORRELATION"
105 echo
106 echo " Syntax:"
107 echo " $command_name [<HOST>] reorder [<PROBABILITY> [<CORRELATION>]]"
108 echo
109 echo " Examples:"
110 echo " $command_name reorder"
111 echo " $command_name reorder 2%"
112 echo " $command_name reorder 2% 50%"
113 echo " $command_name 10.127.10.111 reorder"
114 echo " $command_name 10.127.10.111 reorder 2%"
115 echo " $command_name 10.127.10.111 reorder 2% 50%"
116 echo
117 echo " duplicate Duplicates packets incoming to the given host by an optional PROBABILITY and CORRELATION"
118 echo
119 echo " Syntax:"
120 echo " $command_name [<HOST>] duplicate [<PROBABILITY> [<CORRELATION>]]"
121 echo
122 echo " Examples:"
123 echo " $command_name duplicate"
124 echo " $command_name duplicate 0.5%"
125 echo " $command_name duplicate 0.5% 5%"
126 echo " $command_name 10.127.10.111 duplicate"
127 echo " $command_name 10.127.10.111 duplicate 0.5%"
128 echo " $command_name 10.127.10.111 duplicate 0.5% 5%"
129 echo
130 echo " corrupt Corrupts packets incoming to the given host by an optional PROBABILITY"
131 echo
132 echo " Syntax:"
133 echo " $command_name [<HOST>] corrupt [<PROBABILITY>]"
134 echo
135 echo " Examples:"
136 echo " $command_name corrupt"
137 echo " $command_name corrupt 0.1%"
138 echo " $command_name 10.127.10.111 corrupt"
139 echo " $command_name 10.127.10.111 corrupt 0.1%"
140 echo
141 echo " restore Restores the given host from all delay/drop/reorder/duplicate/corrupt states"
142 echo
143 echo " Syntax:"
144 echo " $command_name [<HOST>] restore"
145 echo
146 echo " Examples:"
147 echo " $command_name restore"
148 echo " $command_name 10.127.10.111 restore"
149 echo
150}
151
152# Print usage
153if [ "${1}" = "-h" -o "${1}" = "--help" ]; then
154 print_usage
155 exit 0
156fi
157
158# Converts an argument into a milliseconds string unless it's already in the correct format.
159function to_millis() {
160 if [[ ${1: -2} != "ms" ]]; then
161 echo "${1}ms"
162 else
163 echo ${1}
164 fi
165}
166
167function onos_nodes() {
168 echo $(env | sort | egrep "^OC[0-9]+" | cut -d= -f2)
169}
170
171function partition() {
172 local=${1}
173 remote=${2}
174 echo "Severing link ${remote}->${local}"
175 ssh $ONOS_USER@${local} "sudo iptables -A INPUT -s ${remote} -j DROP -w"
176}
177
178function heal() {
179 local=${1}
180 remote=${2}
181 echo "Restoring link ${remote}->${local}"
182 ssh $ONOS_USER@${local} "sudo iptables -D INPUT -s ${remote} -j DROP -w" &>/dev/null
183}
184
185function delay() {
186 host=${1}
187 latency=$(to_millis ${2:-"50ms"})
188 jitter=$(to_millis ${3:-"10ms"})
189 correlation=${4:-"75%"}
190 distribution=${5:-"normal"}
191 echo "Delaying packets for ${host} (latency: ${latency}, jitter: ${jitter}, correlation: ${correlation}, distribution: ${distribution})"
192 ssh $ONOS_USER@${host} "sudo tc qdisc add dev eth0 root netem delay ${latency} ${jitter} ${correlation} distribution ${distribution}"
193}
194
195function drop() {
196 host=${1}
197 probability=${2:-"2%"}
198 correlation=${3:-"25%"}
199 echo "Dropping packets for ${host} (probability: ${probability}, correlation: ${correlation})"
200 ssh $ONOS_USER@${host} "sudo tc qdisc add dev eth0 root netem loss ${probability} ${correlation}"
201}
202
203function reorder() {
204 host=${1}
205 probability=${2:-"2%"}
206 correlation=${3:-"50%"}
207 echo "Reordering packets for ${host} (probability: ${probability}, correlation: ${correlation})"
208 ssh $ONOS_USER@${host} "sudo tc qdisc add dev eth0 root netem reorder ${probability} ${correlation}"
209}
210
211function duplicate() {
212 host=${1}
213 probability=${2:-"0.5%"}
214 correlation=${3:-"5%"}
215 echo "Duplicating packets for ${host} (probability: ${probability}, correlation: ${correlation})"
216 ssh $ONOS_USER@${host} "sudo tc qdisc add dev eth0 root netem duplicate ${probability} ${correlation}"
217}
218
219function corrupt() {
220 host=${1}
221 probability=${2:-"0.1%"}
222 echo "Corrupting packets for ${host} (probability: ${probability})"
223 ssh $ONOS_USER@${host} "sudo tc qdisc add dev eth0 root netem corrupt ${probability}"
224}
225
226function restore() {
227 host=${1}
228 echo "Restoring packets for ${host}"
229 ssh $ONOS_USER@${host} "sudo tc qdisc del dev eth0 root" &>/dev/null
230}
231
232cmd=${1} && shift
233
234case $cmd in
235
236# Partitions the cluster into two halves.
237partition-halves)
238 # Get the list of ONOS nodes.
239 nodes=($(onos_nodes))
240
241 # Use a nested loop to split the network into two halves using index mod 2.
242 for i in "${!nodes[@]}"; do
243 if [[ $((i % 2)) == 0 ]]; then
244 for j in "${!nodes[@]}"; do
245 if [[ $i != $j ]] && [[ $((j % 2)) == 1 ]]; then
246 partition ${nodes[i]} ${nodes[j]}
247 partition ${nodes[j]} ${nodes[i]}
248 fi
249 done
250 fi
251 done
252 ;;
253
254# Heals all partitions on all nodes.
255heal)
256 # Get the list of ONOS nodes and heal partitions between each node in both directions.
257 nodes=$(onos_nodes)
258 for lnode in ${nodes}; do
259 for rnode in ${nodes}; do
260 if [[ ${lnode} != ${rnode} ]]; then
261 heal ${lnode} ${rnode}
262 fi
263 done
264 done
265 ;;
266
267*)
268 # If a function with the command name exists, iterate through all ONOS nodes and call the function for each node.
269 if [ -n "$(type -t $cmd)" ] && [ "$(type -t $cmd)" = function ]; then
270 nodes=$(onos_nodes)
271 for node in ${nodes}; do
272 ${cmd} ${node} "${@}"
273 done
274 exit 0
275 fi
276
277 host=$cmd
278 cmd="$1" && shift
279
280 case $cmd in
281
282 # Kills a node.
283 crash)
284 onos-kill "${host}"
285 ;;
286
Jordan Haltermanddc2b182017-07-23 01:27:47 -0700287 # Recovers a crashed node
288 recover)
289 onos-service "${host}" start
290 onos-wait-for-start "${host}"
291 ;;
292
Jordan Halterman4d32a582017-05-26 19:14:30 -0700293 # Creates a partition between the source node and a set of destination nodes.
294 partition)
295
296 # Default to ONOS nodes.
297 if [ -z "${1}" ]; then
298 nodes=$(onos_nodes)
299 else
300 nodes="${*}"
301 fi
302
303 # Iterate through all provided nodes and create partitions.
304 for node in $nodes; do
305 partition ${host} ${node}
306 done
307 ;;
308
309 # Splits the cluster into two halves, preserving the provided host as a bridge between the two halves.
310 partition-bridge)
311
312 # Get the list of ONOS nodes.
313 nodes=($(onos_nodes))
314
315 # Use a nested loop and split the network into two halves using index mod 2. Exclude
316 # the indicated host to ensure it can communicate with both sides of the partition.
317 for i in "${!nodes[@]}"; do
318 if [[ $((i % 2)) == 0 ]] && [[ ${nodes[i]} != ${host} ]]; then
319 for j in "${!nodes[@]}"; do
320 if [[ $i != $j ]] && [[ $((j % 2)) == 1 ]] && [[ ${nodes[j]} != ${host} ]]; then
321 partition ${nodes[i]} ${nodes[j]}
322 partition ${nodes[j]} ${nodes[i]}
323 fi
324 done
325 fi
326 done
327 ;;
328
329 # Heals a partition between the provided host and a set of ONOS nodes.
330 heal)
331
332 # Default to ONOS nodes.
333 if [ -z "${1}" ]; then
334 nodes=$(onos_nodes)
335 else
336 nodes="${*}"
337 fi
338
339 # Iterate through all provided nodes and heal partitions.
340 for node in $nodes; do
341 heal ${host} ${node}
342 done
343 ;;
344
345 # If we made it this far, use the command name variable to call the associated function.
346 *)
347 ${cmd} ${host} "${@}"
348 ;;
349
350 esac
351 ;;
352
353esac