ctdb:tests: in the stub "ip link show" command use echo instead of cat
[Samba/wip.git] / ctdb / tests / eventscripts / stubs / ip
blobd852cf861d526afa7f91163117e79e66ee4b62e1
1 #!/bin/sh
3 not_implemented ()
5 echo "ip stub command: \"$1\" not implemented"
6 exit 127
9 ######################################################################
11 ip_link ()
13 case "$1" in
14 set)
15 shift
16 # iface="$1"
17 case "$2" in
18 up) ip_link_set_up "$1" ;;
19 down) ip_link_down_up "$1" ;;
20 *) not_implemented "\"$2\" in \"$orig_args\"" ;;
21 esac
23 show) shift ; ip_link_show "$@" ;;
24 del*) shift ; ip_link_delete "$@" ;;
25 *) not_implemented "$*" ;;
26 esac
29 ip_link_delete ()
31 mkdir -p "${FAKE_IP_STATE}/interfaces-deleted"
32 touch "${FAKE_IP_STATE}/interfaces-deleted/$1"
35 ip_link_set_up ()
37 rm -f "${FAKE_IP_STATE}/interfaces-down/$1"
38 rm -f "${FAKE_IP_STATE}/interfaces-deleted/$1"
41 ip_link_set_down ()
43 rm -f "${FAKE_IP_STATE}/interfaces-deleted/$1"
44 mkdir -p "${FAKE_IP_STATE}/interfaces-down"
45 touch "${FAKE_IP_STATE}/interfaces-down/$1"
48 ip_link_show ()
50 dev="$1"
51 if [ "$dev" = "dev" -a -n "$2" ] ; then
52 dev="$2"
55 if [ -e "${FAKE_IP_STATE}/interfaces-deleted/$dev" ] ; then
56 echo "Device \"${dev}\" does not exist." >&2
57 exit 255
60 mac=$(echo $dev | md5sum | sed -r -e 's@(..)(..)(..)(..)(..)(..).*@\1:\2:\3:\4:\5:\6@')
61 _state="UP"
62 _flags=",UP,LOWER_UP"
63 if [ -e "${FAKE_IP_STATE}/interfaces-down/$dev" ] ; then
64 _state="DOWN"
65 _flags=""
67 echo "${n}: ${dev}: <BROADCAST,MULTICAST${_flags}> mtu 1500 qdisc pfifo_fast state ${_state} qlen 1000"
68 echo " link/ether ${mac} brd ff:ff:ff:ff:ff:ff"
71 # This is incomplete because it doesn't actually look up table ids in
72 # /etc/iproute2/rt_tables. The rules/routes are actually associated
73 # with the name instead of the number. However, we include a variable
74 # to fake a bad table id.
75 [ -n "$IP_ROUTE_BAD_TABLE_ID" ] || IP_ROUTE_BAD_TABLE_ID=false
77 ip_check_table ()
79 _cmd="$1"
81 [ -n "$_table" ] || not_implemented "ip rule/route without \"table\""
83 # Only allow tables names from 13.per_ip_routing. This is a cheap
84 # way of avoiding implementing the default/main/local tables.
85 case "$_table" in
86 ctdb.*)
87 if $IP_ROUTE_BAD_TABLE_ID ; then
88 # Ouch. Simulate inconsistent errors from ip. :-(
89 case "$_cmd" in
90 route)
91 echo "Error: argument "${_table}" is wrong: table id value is invalid" >&2
95 echo "Error: argument "${_table}" is wrong: invalid table ID" >&2
96 esac
97 exit 255
100 *) not_implemented "table=${_table} ${orig_args}" ;;
101 esac
104 ######################################################################
106 ip_addr ()
108 case "$1" in
109 show|list|"") shift ; ip_addr_show "$@" ;;
110 add*) shift ; ip_addr_add "$@" ;;
111 del*) shift ; ip_addr_del "$@" ;;
112 *) not_implemented "\"$1\" in \"$orig_args\"" ;;
113 esac
116 ip_addr_show ()
118 dev=""
119 primary=true
120 secondary=true
121 _to=""
122 while [ -n "$1" ] ; do
123 case "$1" in
124 dev)
125 dev="$2" ; shift 2
127 # Do stupid things and stupid things will happen!
128 primary)
129 primary=true ; secondary=false ; shift
131 secondary)
132 secondary=true ; primary=false ; shift
135 _to="$2" ; shift 2
138 # Assume an interface name
139 dev="$1" ; shift 1
140 esac
141 done
142 devices="$dev"
143 if [ -z "$devices" ] ; then
144 # No device specified? Get all the primaries...
145 devices=$(ls "${FAKE_IP_STATE}/addresses/"*-primary 2>/dev/null | \
146 sed -e 's@.*/@@' -e 's@-primary$@@')
148 calc_brd ()
150 case "${local#*/}" in
152 brd="${local%.*}.255"
155 not_implemented "list ... fake bits other than 24: ${local#*/}"
156 esac
158 show_iface()
160 pf="${FAKE_IP_STATE}/addresses/${dev}-primary"
161 sf="${FAKE_IP_STATE}/addresses/${dev}-secondary"
162 ip_link_show "$dev"
163 if $primary && [ -r "$pf" ] ; then
164 read local <"$pf"
165 if [ -z "$_to" -o "${_to%/*}" = "${local%/*}" ] ; then
166 calc_brd
167 echo " inet ${local} brd ${brd} scope global ${dev}"
170 if $secondary && [ -r "$sf" ] ; then
171 while read local ; do
172 if [ -z "$_to" -o "${_to%/*}" = "${local%/*}" ] ; then
173 calc_brd
174 echo " inet ${local} brd ${brd} scope global secondary ${dev}"
176 done <"$sf"
178 if [ -z "$_to" ] ; then
179 echo " valid_lft forever preferred_lft forever"
183 for dev in $devices ; do
184 if [ -z "$_to" ] || \
185 grep -F "${_to%/*}/" "${FAKE_IP_STATE}/addresses/${dev}-"* >/dev/null ; then
186 show_iface
188 n=$(($n + 1))
189 done
192 ip_addr_add ()
194 local=""
195 dev=""
196 brd=""
197 while [ -n "$1" ] ; do
198 case "$1" in
199 *.*.*.*/*)
200 local="$1" ; shift
202 local)
203 local="$2" ; shift 2
205 broadcast|brd)
206 # For now assume this is always '+'.
207 if [ "$2" != "+" ] ; then
208 not_implemented "addr add ... brd $2 ..."
210 shift 2
212 dev)
213 dev="$2" ; shift 2
216 not_implemented "$@"
217 esac
218 done
219 if [ -z "$dev" ] ; then
220 not_implemented "addr add (without dev)"
222 mkdir -p "${FAKE_IP_STATE}/addresses"
223 pf="${FAKE_IP_STATE}/addresses/${dev}-primary"
224 sf="${FAKE_IP_STATE}/addresses/${dev}-secondary"
225 # We could lock here... but we should be the only ones playing
226 # around here with these stubs.
227 if [ ! -f "$pf" ] ; then
228 echo "$local" >"$pf"
229 elif grep -Fq "$local" "$pf" ; then
230 echo "RTNETLINK answers: File exists" >&2
231 exit 254
232 elif [ -f "$sf" ] && grep -Fq "$local" "$sf" ; then
233 echo "RTNETLINK answers: File exists" >&2
234 exit 254
235 else
236 echo "$local" >>"$sf"
240 ip_addr_del ()
242 local=""
243 dev=""
244 while [ -n "$1" ] ; do
245 case "$1" in
246 *.*.*.*/*)
247 local="$1" ; shift
249 local)
250 local="$2" ; shift 2
252 dev)
253 dev="$2" ; shift 2
256 not_implemented "addr del ... $1 ..."
257 esac
258 done
259 if [ -z "$dev" ] ; then
260 not_implemented "addr del (without dev)"
262 mkdir -p "${FAKE_IP_STATE}/addresses"
263 pf="${FAKE_IP_STATE}/addresses/${dev}-primary"
264 sf="${FAKE_IP_STATE}/addresses/${dev}-secondary"
265 # We could lock here... but we should be the only ones playing
266 # around here with these stubs.
267 if [ ! -f "$pf" ] ; then
268 echo "RTNETLINK answers: Cannot assign requested address" >&2
269 exit 254
270 elif grep -Fq "$local" "$pf" ; then
271 # Remove primaries AND SECONDARIES.
272 rm -f "$pf" "$sf"
273 elif [ -f "$sf" ] && grep -Fq "$local" "$sf" ; then
274 grep -Fv "$local" "$sf" >"${sf}.new"
275 mv "${sf}.new" "$sf"
276 else
277 echo "RTNETLINK answers: Cannot assign requested address" >&2
278 exit 254
282 ######################################################################
284 ip_rule ()
286 case "$1" in
287 show|list|"") shift ; ip_rule_show "$@" ;;
288 add) shift ; ip_rule_add "$@" ;;
289 del*) shift ; ip_rule_del "$@" ;;
290 *) not_implemented "$1 in \"$orig_args\"" ;;
291 esac
295 # All non-default rules are in $FAKE_IP_STATE_RULES/rules. As with
296 # the real version, rules can be repeated. Deleting just deletes the
297 # 1st match.
299 ip_rule_show ()
301 ip_rule_show_1 ()
303 _pre="$1"
304 _table="$2"
305 _selectors="$3"
306 # potentially more options
308 printf "%d:\t%s lookup %s \n" $_pre "$_selectors" "$_table"
311 ip_rule_show_some ()
313 _min="$1"
314 _max="$2"
316 [ -f "${FAKE_IP_STATE}/rules" ] || return
318 while read _pre _table _selectors ; do
319 # Only print those in range
320 [ $_min -le $_pre -a $_pre -le $_max ] || continue
322 ip_rule_show_1 $_pre "$_table" "$_selectors"
323 done <"${FAKE_IP_STATE}/rules"
326 ip_rule_show_1 0 "local" "from all"
328 ip_rule_show_some 1 32765
330 ip_rule_show_1 32766 "main" "from all"
331 ip_rule_show_1 32767 "default" "from all"
333 ip_rule_show_some 32768 2147483648
336 ip_rule_common ()
338 _from=""
339 _pre=""
340 _table=""
341 while [ -n "$1" ] ; do
342 case "$1" in
343 from) _from="$2" ; shift 2 ;;
344 pref) _pre="$2" ; shift 2 ;;
345 table) _table="$2" ; shift 2 ;;
346 *) not_implemented "$1 in \"$orig_args\"" ;;
347 esac
348 done
350 [ -n "$_pre" ] || not_implemented "ip rule without \"pref\""
351 ip_check_table "rule"
352 # Relax this if more selectors added later...
353 [ -n "$_from" ] || not_implemented "ip rule without \"from\""
356 ip_rule_add ()
358 ip_rule_common "$@"
360 _f="${FAKE_IP_STATE}/rules"
361 touch "$_f"
363 flock 0
364 # Filter order must be consistent with the comparison in ip_rule_del()
365 echo "$_pre $_table${_from:+ from }$_from" >>"$_f"
366 ) <"$_f"
369 ip_rule_del ()
371 ip_rule_common "$@"
373 _f="${FAKE_IP_STATE}/rules"
374 touch "$_f"
376 flock 0
377 _tmp="$(mktemp)"
378 _found=false
379 while read _p _t _s ; do
380 if ! $_found && \
381 [ "$_p" = "$_pre" -a "$_t" = "$_table" -a \
382 "$_s" = "${_from:+from }$_from" ] ; then
383 # Found. Skip this one but not future ones.
384 _found=true
385 else
386 echo "$_p $_t $_s" >>"$_tmp"
388 done
389 if cmp -s "$_tmp" "$_f" ; then
390 # No changes, must not have found what we wanted to delete
391 echo "RTNETLINK answers: No such file or directory" >&2
392 rm -f "$_tmp"
393 exit 2
394 else
395 mv "$_tmp" "$_f"
397 ) <"$_f" || exit $?
400 ######################################################################
402 ip_route ()
404 case "$1" in
405 show|list) shift ; ip_route_show "$@" ;;
406 flush) shift ; ip_route_flush "$@" ;;
407 add) shift ; ip_route_add "$@" ;;
408 *) not_implemented "$1 in \"ip route\"" ;;
409 esac
412 ip_route_common ()
414 [ "$1" = table ] || not_implemented "$1 in \"$orig_args\""
415 _table="$2"
417 ip_check_table "route"
420 # Routes are in a file per table in the directory
421 # $FAKE_IP_STATE/routes. These routes just use the table ID
422 # that is passed and don't do any lookup. This could be "improved" if
423 # necessary.
425 ip_route_show ()
427 ip_route_common "$@"
429 # Missing file is just an empty table
430 cat "$FAKE_IP_STATE/routes/${_table}" 2>/dev/null || true
433 ip_route_flush ()
435 ip_route_common "$@"
437 rm -f "$FAKE_IP_STATE/routes/${_table}"
440 ip_route_add ()
442 _prefix=""
443 _dev=""
444 _gw=""
445 _table=""
447 while [ -n "$1" ] ; do
448 case "$1" in
449 *.*.*.*/*|*.*.*.*) _prefix="$1" ; shift 1 ;;
450 local) _prefix="$2" ; shift 2 ;;
451 dev) _dev="$2" ; shift 2 ;;
452 via) _gw="$2" ; shift 2 ;;
453 table) _table="$2" ; shift 2 ;;
454 *) not_implemented "$1 in \"$orig_args\"" ;;
455 esac
456 done
458 ip_check_table "route"
459 [ -n "$_prefix" ] || not_implemented "ip route without inet prefix in \"$orig_args\""
460 [ -n "$_dev" ] || not_implemented "ip route without \"dev\" in \"$orig_args\""
462 # Alias or add missing bits
463 case "$_prefix" in
464 0.0.0.0/0) _prefix="default" ;;
465 */*) : ;;
466 *) _prefix="${_prefix}/32" ;;
467 esac
469 _f="$FAKE_IP_STATE/routes/${_table}"
470 mkdir -p "$FAKE_IP_STATE/routes"
471 touch "$_f"
474 flock 0
476 if [ -n "$_gw" ] ; then
477 echo "${_prefix} via ${_gw} dev ${_dev} "
478 else
479 echo "${_prefix} dev ${_dev} scope link "
480 fi >>"$_f"
481 ) <"$_f"
485 ######################################################################
487 orig_args="$*"
489 case "$1" in
490 link) shift ; ip_link "$@" ;;
491 addr*) shift ; ip_addr "$@" ;;
492 rule) shift ; ip_rule "$@" ;;
493 route) shift ; ip_route "$@" ;;
494 *) not_implemented "$1" ;;
495 esac
497 exit 0