]> git.ipfire.org Git - people/ms/network.git/blame - src/functions/functions.zone
device: Refactor check for device type
[people/ms/network.git] / src / functions / functions.zone
CommitLineData
1848564d
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
1c6a4e30 22zone_exists() {
1848564d 23 local zone=${1}
711ffac1
MT
24 assert isset zone
25
04c27fe9 26 [ -d "${NETWORK_ZONES_DIR}/${zone}" ]
1848564d
MT
27}
28
1c6a4e30 29zone_match() {
1848564d
MT
30 local match
31
32 local i
33 for i in ${VALID_ZONES}; do
34 match="${match}|${i}[0-9]{1,5}"
35 done
36
37 echo "${match:1:${#match}}"
38}
39
1c6a4e30 40zone_name_is_valid() {
1848564d 41 local zone=${1}
4fedddef
MT
42
43 # Don't accept empty strings.
44 [ -z "${zone}" ] && return ${EXIT_FALSE}
711ffac1 45
1848564d
MT
46 [[ ${zone} =~ $(zone_match) ]]
47}
48
1c6a4e30 49zone_is_local() {
1848564d
MT
50 local zone=${1}
51
7de0637a 52 [[ "${zone:0:${#ZONE_LOCAL}}" = "${ZONE_LOCAL}" ]]
5e42d659
MT
53}
54
1c6a4e30 55zone_is_nonlocal() {
5e42d659
MT
56 local zone=${1}
57
7de0637a 58 [[ "${zone:0:${#ZONE_NONLOCAL}}" = "${ZONE_NONLOCAL}" ]]
1848564d
MT
59}
60
1c6a4e30 61zone_get_hook() {
1848564d 62 local zone=${1}
711ffac1
MT
63 assert isset zone
64
04c27fe9 65 config_get_hook "${NETWORK_ZONES_DIR}/${zone}/settings"
1848564d
MT
66}
67
1c6a4e30 68zone_start() {
5bb2429a
MT
69 # This function will bring up the zone
70 # 'asynchronously' with help of systemd.
71
72 local zone=${1}
73 assert zone_exists ${zone}
74
1d08b9b3 75 service_start "network@${zone}.service"
5bb2429a
MT
76}
77
1c6a4e30 78zone_start_auto() {
2a969c27
MT
79 local zone="${1}"
80 assert zone_exists "${zone}"
81
82 # If the zone has already been started, we
83 # will reload it so the current configuration
84 # is re-applied.
85 if zone_is_active "${zone}"; then
86 zone_reload "${zone}"
87 return ${?}
88
89 # If the zone is still down, but in auto-start mode,
90 # we will start it.
91 elif zone_is_enabled "${zone}"; then
92 zone_start "${zone}"
93 return ${?}
94 fi
95
96 # Otherwise, nothing will be done.
97 return ${EXIT_OK}
98}
99
1c6a4e30 100zone_stop() {
5bb2429a
MT
101 # This function will bring down the zone
102 # 'asynchronously' with help of systemd.
103
104 local zone=${1}
105 assert zone_exists ${zone}
106
1d08b9b3 107 service_stop "network@${zone}.service"
5bb2429a
MT
108}
109
1c6a4e30 110zone_reload() {
e6fd23fd
MT
111 local zone="${1}"
112 assert zone_exists "${zone}"
113
114 service_reload "network@${zone}.service"
115}
116
1c6a4e30 117zone_hotplug_event() {
fb8c7c92 118 local zone="${1}"
2a969c27 119 assert isset zone
fb8c7c92 120
2a969c27 121 hotplug_assert_in_hotplug_event
fb8c7c92 122
2a969c27 123 zone_cmd "hotplug" "${zone}"
fb8c7c92
MT
124}
125
1c6a4e30 126zone_enable() {
5c5b8e36
SS
127 # This function will enable the zone
128 # with help of systemd.
129
130 local zone="${1}"
131 assert zone_exists "${zone}"
132
133 # Enable service for the zone
134 service_enable "network@${zone}.service"
135 local ret=$?
136
137 if [ ${ret} -eq ${EXIT_OK} ]; then
138 log INFO "Auto-start enabled for zone ${zone}"
139 return ${EXIT_OK}
140 fi
141
142 log ERROR "Could not enable zone ${zone}: ${ret}"
143 return ${ret}
144}
145
1c6a4e30 146zone_disable() {
5c5b8e36
SS
147 # This function will disable the zone
148 # with help of systemd.
149
150 local zone="${1}"
151 assert zone_exists "${zone}"
152
153 # Disable service for the zone
154 service_disable "network@${zone}.service"
155 local ret=$?
156
157 if [ ${ret} -eq ${EXIT_OK} ]; then
158 log INFO "Auto-start disabled for zone ${zone}"
159 return ${EXIT_OK}
160 fi
161
162 log ERROR "Could not disable zone ${zone}: ${ret}"
163 return ${ret}
164}
165
1c6a4e30 166zone_is_enabled() {
5c5b8e36
SS
167 local zone="${1}"
168 assert isset zone
169
170 # Ask systemd if the zone is enabled.
171 if service_is_enabled "network@${zone}.service"; then
172 return ${EXIT_TRUE}
173 fi
174
175 return ${EXIT_FALSE}
176}
177
1c6a4e30 178zone_is_active() {
e6fd23fd
MT
179 local zone="${1}"
180 assert isset zone
181
182 if service_is_active "network@${zone}.service"; then
183 return ${EXIT_TRUE}
184 fi
185
186 return ${EXIT_FALSE}
187}
188
1c6a4e30 189zone_is_enabled_or_active() {
2a969c27
MT
190 local zone="${1}"
191 assert isset zone
192
193 zone_is_enabled "${zone}" || zone_is_active "${zone}"
194}
195
1c6a4e30 196zone_cmd() {
2a969c27
MT
197 local cmd="${1}"
198 local port="${2}"
199 shift 2
200
201 assert isset cmd
202 assert isset zone
203
204 local hook="$(zone_get_hook ${zone})"
205 assert isset hook
206
2212045f 207 hook_exec zone "${hook}" "${cmd}" "${zone}" "$@"
2a969c27
MT
208}
209
1c6a4e30 210zone_new() {
1848564d
MT
211 local zone=${1}
212 local hook=${2}
213 shift 2
214
215 if ! zone_name_is_valid ${zone}; then
216 error "Zone name '${zone}' is not valid."
217 return ${EXIT_ERROR}
218 fi
219
220 if zone_exists ${zone}; then
221 error "Zone '${zone}' does already exist."
222 return ${EXIT_ERROR}
223 fi
224
d61a01d4 225 if ! hook_zone_exists ${hook}; then
1848564d
MT
226 error "Hook '${hook}' does not exist."
227 return ${EXIT_ERROR}
228 fi
229
a5ebb169 230 # Create directories for configs and ports
04c27fe9
MT
231 local what
232 for what in configs ports; do
233 make_directory "${NETWORK_ZONES_DIR}/${zone}/${what}"
234 done
943e3f7e 235
2212045f 236 hook_zone_exec "${hook}" "new" "${zone}" "$@"
1848564d
MT
237 local ret=$?
238
cf0fc8ab 239 # Maybe the zone new hook did not exit correctly.
1848564d 240 # If this is the case we remove the created zone immediately.
a63e51c6 241 if [ "${ret}" != "${EXIT_OK}" ]; then
285f779f 242 zone_destroy "${zone}"
5c5b8e36 243 return ${EXIT_ERROR}
1848564d 244 fi
5c5b8e36
SS
245
246 # Automatically enable zone.
247 zone_enable "${zone}"
ac694a6a
MT
248
249 # Bring up the zone immediately after
250 zone_start "${zone}"
1848564d
MT
251}
252
1c6a4e30 253zone_edit() {
1848564d
MT
254 local zone=${1}
255 shift
256
257 if ! zone_exists ${zone}; then
258 error "Zone '${zone}' does not exist."
259 return ${EXIT_ERROR}
260 fi
261
2472e0ea 262 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
263 if [ -z "${hook}" ]; then
264 error "Config file did not provide any hook."
265 return ${EXIT_ERROR}
266 fi
267
d61a01d4 268 if ! hook_zone_exists ${hook}; then
1848564d
MT
269 error "Hook '${hook}' does not exist."
270 return ${EXIT_ERROR}
271 fi
272
2212045f 273 hook_zone_exec ${hook} edit ${zone} "$@"
1848564d
MT
274}
275
2bb20bbd
SS
276zone_rename() {
277 assert [ $# -eq 2 ]
278
279 local zone="${1}"
280 local name="${2}"
281
282 assert zone_exists "${zone}"
2bb20bbd
SS
283 assert not zone_exists "${name}"
284
285 # The zone must be shut down before, is then renamed and
286 # potentially brought up again
287
288 # Save if the zone is running right now
289 zone_is_active "${zone}"
290 local zone_was_active="${?}"
291
292 # Save if the zone is enabled (i.e. auto-start)
293 zone_is_enabled "${zone}"
294 local zone_was_enabled="${?}"
295
296 # Stop the zone
297 zone_stop "${zone}"
298
299 # Disable the zone
300 zone_disable "${zone}"
301
302 # Rename the configuration files
04c27fe9 303 mv -f "${NETWORK_ZONES_DIR}/${zone}" "${NETWORK_ZONES_DIR}/${name}"
2bb20bbd
SS
304
305 # Enable the zone if it was enabled before
306 [ ${zone_was_enabled} -eq ${EXIT_TRUE} ] && zone_enable "${name}"
307
308 # Start the zone if it was up before
309 [ ${zone_was_active} -eq ${EXIT_TRUE} ] && zone_start "${name}"
310
311 log INFO "Zone ${zone} was renamed to ${name}"
312 return ${EXIT_OK}
313}
314
69ace22b 315
1c6a4e30 316zone_destroy() {
cf0fc8ab 317 local zone="${1}"
69ace22b 318
285f779f
MT
319 # Cannot delete a zone that does not exist
320 if ! zone_exists "${zone}"; then
321 log ERROR "Zone ${zone} does not exist"
322 return ${EXIT_ERROR}
323 fi
69ace22b 324
69ace22b 325 # Force the zone down.
d5c9bd17 326 zone_is_active "${zone}" && zone_stop "${zone}"
1848564d 327
285f779f 328 # Disable zone auto-start
5c5b8e36
SS
329 zone_disable "${zone}"
330
8707df4b
MT
331 if ! rm -rf "${NETWORK_ZONES_DIR}/${zone}"; then
332 log ERROR "Could not destroy zone ${zone}"
333 return ${EXIT_ERROR}
334 fi
335
336 log INFO "Destroyed zone ${zone}"
337 return ${EXIT_OK}
1848564d
MT
338}
339
1c6a4e30 340zone_up() {
1848564d
MT
341 local zone=${1}
342 shift
343
344 if ! zone_exists ${zone}; then
345 error "Zone '${zone}' does not exist."
346 return ${EXIT_ERROR}
347 fi
348
2472e0ea 349 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
350 if [ -z "${hook}" ]; then
351 error "Config file did not provide any hook."
352 return ${EXIT_ERROR}
353 fi
354
d61a01d4 355 if ! hook_zone_exists ${hook}; then
1848564d
MT
356 error "Hook '${hook}' does not exist."
357 return ${EXIT_ERROR}
358 fi
359
059469a8
MT
360 zone_db ${zone} starting
361
2212045f 362 hook_zone_exec ${hook} up ${zone} "$@"
d61a01d4 363
059469a8 364 zone_db ${zone} started
de3cecef
MT
365
366 # Execute all triggers after the zone got up
367 triggers_execute_all "up" ZONE="${zone}"
1848564d
MT
368}
369
1c6a4e30 370zone_down() {
1848564d
MT
371 local zone=${1}
372 shift
373
374 if ! zone_exists ${zone}; then
375 error "Zone '${zone}' does not exist."
376 return ${EXIT_ERROR}
377 fi
378
2472e0ea 379 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
380 if [ -z "${hook}" ]; then
381 error "Config file did not provide any hook."
382 return ${EXIT_ERROR}
383 fi
384
d61a01d4 385 if ! hook_zone_exists ${hook}; then
1848564d
MT
386 error "Hook '${hook}' does not exist."
387 return ${EXIT_ERROR}
388 fi
389
059469a8
MT
390 zone_db ${zone} stopping
391
2212045f 392 hook_zone_exec ${hook} down ${zone} "$@"
059469a8
MT
393
394 zone_db ${zone} stopped
69ace22b 395
de3cecef
MT
396 # Execute all triggers after the zone went down
397 triggers_execute_all "down" ZONE="${zone}"
1848564d
MT
398}
399
1c6a4e30 400zone_status() {
2472e0ea
MT
401 local zone="${1}"
402 assert isset zone
1848564d
MT
403 shift
404
2472e0ea 405 if ! zone_exists "${zone}"; then
1848564d
MT
406 error "Zone '${zone}' does not exist."
407 return ${EXIT_ERROR}
408 fi
409
2472e0ea 410 local hook="$(zone_get_hook "${zone}")"
1848564d
MT
411 if [ -z "${hook}" ]; then
412 error "Config file did not provide any hook."
413 return ${EXIT_ERROR}
414 fi
415
2472e0ea 416 if ! hook_zone_exists "${hook}"; then
1848564d
MT
417 error "Hook '${hook}' does not exist."
418 return ${EXIT_ERROR}
419 fi
420
2472e0ea 421 hook_zone_exec "${hook}" "status" "${zone}" "$@"
1848564d
MT
422}
423
f5ee091e
MT
424zone_identify() {
425 assert [ $# -ge 1 ]
426
427 local zone="${1}"
428 shift
429
430 assert zone_exists "${zone}"
431
432 log INFO "Identifying zone ${zone}"
433 local pids
434
435 local pid
436 local port
437 for port in $(zone_get_ports "${zone}"); do
438 # Identify all the ports
2212045f 439 port_identify "${port}" --background "$@"
f5ee091e
MT
440
441 # Save the PIDs of the subprocesses
442 list_append pids "$(cmd_background_get_pid)"
443 done
444
445 # Wait until all port_identfy processes have finished
446 for pid in ${pids}; do
447 cmd_background_result "${pid}"
448 done
449
450 return ${EXIT_OK}
451}
452
1c6a4e30 453zone_get_ports() {
711ffac1
MT
454 local zone=${1}
455
456 assert isset zone
457
458 local port
04c27fe9 459 for port in $(list_directory "${NETWORK_ZONES_DIR}/${zone}/ports"); do
60b1f378 460 if port_exists "${port}"; then
711ffac1
MT
461 echo "${port}"
462 fi
463 done
464}
465
1c6a4e30 466zone_get_ports_num() {
529141df
MT
467 local zone="${1}"
468 assert isset zone
469
470 local counter=0
471 local port
04c27fe9 472 for port in $(list_directory "${NETWORK_ZONES_DIR}/${zone}/ports"); do
529141df
MT
473 if port_exists "${port}"; then
474 counter=$(( ${counter} + 1 ))
475 fi
476 done
477
478 echo "${counter}"
479 return ${EXIT_OK}
480}
481
1c6a4e30 482zone_has_port() {
3a7fef62
MT
483 # Check, if the given port is configured
484 # in this zone.
485
486 local zone=${1}
487 local port=${2}
488 shift 2
489
490 assert isset zone
491 assert isset port
492
04c27fe9 493 [ -e "${NETWORK_ZONES_DIR}/${zone}/ports/${port}" ]
3a7fef62
MT
494}
495
1c6a4e30 496zone_config() {
ea699552
MT
497 local zone="${1}"
498 local cmd="${2}"
a5ebb169
MT
499 shift 2
500
501 assert isset zone
ea699552
MT
502 assert isset cmd
503 assert zone_exists "${zone}"
a5ebb169 504
ea699552 505 case "${cmd}" in
2a6b2397
MT
506 new)
507 zone_config_new "${zone}" "$@"
508 ;;
509 destroy)
e9582016
JS
510 # usually ${1} is a valid hid
511 local hid=${1}
512 shift 1
513
514 # We convert the hid into an id
515 local id=$(zone_config_convert_hid_to_id ${zone} ${hid})
516
517 # If id isset the hid is valid and we can go on with the id
518 if isset id; then
519 zone_config_destroy "${zone}" "${id}" "$@"
520
521 # If we can't get a valid hid we check if we got a valid id
ea37ec0b 522 else
e9582016
JS
523 if zone_config_id_is_valid ${zone} ${hid}; then
524 zone_config_destroy "${zone}" ${hid} "$@"
525 else
526 log ERROR "${id} is not a valid id or hid"
527 fi
ea37ec0b 528 fi
a5ebb169 529 ;;
a5d2c758
JS
530 list)
531 zone_config_list "${zone}" "$@"
532 ;;
a5ebb169 533 *)
e9582016
JS
534 # usually ${1} is a valid hid
535 local hid=${cmd}
536 local cmd=${1}
537 shift 1
538
539 local id=$(zone_config_convert_hid_to_id ${zone} ${hid})
540
541 # If id isset the hid is valid and we can go on with the id
542 if isset id && [[ ${cmd} == "edit" ]]; then
543 zone_config_edit "${zone}" "${id}" "$@"
e6a03d56 544
e9582016 545 # If we didn't get a valid hid we check if we got a valid id
e6a03d56 546 else
e9582016
JS
547 if zone_config_id_is_valid ${zone} ${id} && [[ ${cmd} == "edit" ]]; then
548 shift 1
549 zone_config_edit "${zone}" "${id}" "$@"
550 else
551 # in ${hid} is saved the command after network zone ${zone} config
552 error "Unrecognized argument: ${hid}"
553 cli_usage root-zone-config-subcommands
554 exit ${EXIT_ERROR}
555 fi
e6a03d56 556 fi
a5ebb169
MT
557 ;;
558 esac
559}
560
1c6a4e30 561zone_config_cmd() {
ea699552 562 assert [ $# -gt 2 ]
a5ebb169 563
ea699552
MT
564 local cmd="${1}"
565 local zone="${2}"
566 shift 2
567
568 local hook="$(zone_get_hook "${zone}")"
a5ebb169
MT
569 assert isset hook
570
ea699552
MT
571 hook_zone_exec "${hook}" "config_${cmd}" "${zone}" "$@"
572}
573
2a6b2397 574zone_config_new() {
44b8ade9
SS
575 local zone="${1}"
576 shift
577
578 # Create a new configuration, but exit when that was
579 # not successful.
580 zone_config_cmd "new" "${zone}" "$@" || return ${?}
581
582 # If the config could be created, we will try to bring
583 # it up if the zone is up, too.
584 if zone_is_up "${zone}"; then
585 zone_configs_up "${zone}"
586 fi
ea699552
MT
587}
588
2a6b2397
MT
589zone_config_destroy() {
590 zone_config_cmd "destroy" "$@"
ea699552
MT
591}
592
2a6b2397
MT
593zone_config_edit() {
594 zone_config_cmd "edit" "$@"
ea699552
MT
595}
596
a5d2c758
JS
597zone_config_list() {
598 # This function list in an nice way all configs of a zone
599 local zone=${1}
600 assert isset zone
601
602 # Print a nice header
fc36aaf4
JS
603 local format="%-3s %-20s %-20s"
604 print "${format}" "ID" "HOOK" "HID"
a5d2c758
JS
605
606 local config
607 local hook
608 local id
fc36aaf4 609 local hid
a5d2c758
JS
610
611 # Print for all config:
612 # id and hook
a5d2c758
JS
613 for config in $(zone_configs_list "${zone}"); do
614 id=${config##*.}
615 hook=$(zone_config_get_hook "${zone}" "${config}")
fc36aaf4 616 hid=$(zone_config_get_hid "${zone}" "${config}")
a5d2c758 617 assert isset hook
fc36aaf4 618 print "${format}" "${id}" "${hook}" "${hid}"
a5d2c758
JS
619 done
620}
621
1c6a4e30 622zone_config_show() {
ea699552 623 zone_config_cmd "show" "$@"
a5ebb169
MT
624}
625
d2998dc2
JS
626# Returns a list of all used ids for a zone
627zone_config_list_ids() {
628 assert [ $# -eq 1 ]
629
630 local zone=${1}
631 local config
632 local ids
633
634 for config in $(zone_configs_list ${zone}); do
635 list_append ids "$(config_get_id_from_config ${config})"
636 done
637
638 echo ${ids}
639}
640
450afe05
JS
641# List all hids of a zone
642zone_config_list_hids() {
643 assert [ $# -eq 1 ]
644
645 local zone=${1}
646
647 local config
648 for config in $(zone_configs_list ${zone}); do
649 zone_config_get_hid "${zone}" "${config}"
650 done
651}
652
653# get the hid from a given config
654zone_config_get_hid() {
655 assert [ $# -eq 2 ]
656
657 local zone=${1}
658 local config=${2}
659
660 local hook="$(zone_config_get_hook "${zone}" "${config}")"
661
662 hook_exec "config" "${hook}" "hid" "${zone}" "${config}"
663}
664
665# Checks if a hid is valid for a given zone
666zone_config_hid_is_valid() {
667 assert [ $# -eq 2]
668
669 local zone=${1}
670 local hid=${2}
671
672 local _hid
673 for _hid in $(zone_config_list_hids "${zone}"); do
674 if [[ ${_hid} = ${hid} ]]; then
675 return ${EXIT_TRUE}
676 fi
677 done
678
679 return ${EXIT_FALSE}
680}
681
682# This function converts a hid to a id
683zone_config_convert_hid_to_id() {
684 assert [ $# -eq 2 ]
685
686 local zone=${1}
687 local hid=${2}
688
689 local config
690 for config in $(zone_configs_list ${zone}); do
691 # Get hook from config
692 local hook="$(zone_config_get_hook "${zone}" "${config}")"
693
694 if [[ "$(hook_exec "config" "${hook}" "hid" "${zone}" "${config}")" == "${hid}" ]]; then
695 config_get_id_from_config "${config}"
696 return ${EXIT_TRUE}
697 fi
698 done
699
700 return ${EXIT_FALSE}
701}
702
1c6a4e30 703zones_get_all() {
1848564d 704 local zone
04c27fe9 705 for zone in $(list_directory "${NETWORK_ZONES_DIR}"); do
60b1f378
MT
706 if zone_exists ${zone}; then
707 echo "${zone}"
708 fi
03170817 709 done
1848564d
MT
710}
711
1ca5fe9f
JS
712zones_get_next_free() {
713 # This function return the next free zones.
714 # Example net0 upl0 upl1 are configured so the next free zones are:
715 # net1 upl2
716 local i
717 local zone_name
718 for zone_name in ${VALID_ZONES}; do
719 i=0
720
721 while true; do
722 local zone="${zone_name}${i}"
723 if ! zone_exists ${zone}; then
724 echo "${zone}"
725 break
726 fi
727 i=$(( i + 1 ))
728 done
729 done
730}
731
1c6a4e30 732zones_get_local() {
1848564d
MT
733 local zone
734 for zone in $(zones_get_all); do
735 zone_is_local ${zone} && echo "${zone}"
736 done
737}
738
1c6a4e30 739zones_get_nonlocal() {
1848564d
MT
740 local zone
741 for zone in $(zones_get_all); do
5e42d659 742 zone_is_nonlocal ${zone} && echo "${zone}"
1848564d
MT
743 done
744}
745
1c6a4e30 746zones_get() {
1848564d
MT
747 local local=1
748 local remote=1
749
750 local zones
751
752 while [ $# -gt 0 ]; do
753 case "${1}" in
754 --local-only)
755 local=1
756 remote=0
757 ;;
758 --remote-only)
759 local=0
760 remote=1
761 ;;
762 --all)
763 local=1
764 remote=1
765 ;;
766 *)
767 if zone_name_is_valid ${1}; then
768 zones="${zones} ${1}"
769 else
770 warning "Unrecognized argument '${1}'"
771 fi
772 ;;
773 esac
774 shift
775 done
776
777 if [ -n "${zones}" ]; then
778 local zone
779 for zone in ${zones}; do
780 zone_exists ${zone} && echo "${zone}"
781 done
782 exit ${EXIT_OK}
783 fi
784
785 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
786 zones_get_all
787 elif [ ${local} -eq 1 ]; then
788 zones_get_local
789 elif [ ${remote} -eq 1 ]; then
790 zones_get_nonlocal
791 fi
792}
793
1c6a4e30 794zone_ports_list() {
1848564d
MT
795 local zone=${1}
796
04c27fe9 797 list_directory "${NETWORK_ZONES_DIR}/${zone}/ports"
1848564d
MT
798}
799
1c6a4e30 800zone_port_attach() {
ac694a6a
MT
801 local zone="${1}"
802 assert isset zone
803
804 local port="${2}"
805 assert isset port
806
807 shift 2
808
809 # Check if the port actually exists.
810 if ! port_exists "${port}"; then
811 error "Cannot attach port '${port}' which does not exist"
812 return ${EXIT_ERROR}
813 fi
814
815 # Check if the port is already connected to this or any other zone.
816 local z
817 for z in $(zones_get_all); do
818 if zone_has_port "${z}" "${port}"; then
819 error "Port '${port}' is already attached to zone '${z}'"
820 return ${EXIT_ERROR}
821 fi
822 done
823
824 local hook="$(zone_get_hook "${zone}")"
825 assert isset hook
826
f5ee091e 827 # Make the port briefly flash if supported
01a079e0
MT
828 if device_exists ${port}; then
829 port_identify "${port}" --background
830 fi
f5ee091e 831
ac694a6a
MT
832 hook_zone_exec "${hook}" "port_attach" "${zone}" "${port}" "$@"
833 local ret="${?}"
834
835 case "${ret}" in
836 ${EXIT_OK})
837 log INFO "${port} has been attached to ${zone}"
838
839 # Automatically connect the port
abba34c1 840 zone_port_start "${zone}" "${port}"
ac694a6a
MT
841 ;;
842 *)
843 log CRITICAL "${port} could not be attached to ${zone}"
844 ;;
845 esac
846
847 return ${ret}
848}
849
1c6a4e30 850zone_port_edit() {
ac694a6a
MT
851 local zone="${1}"
852 assert isset zone
853
854 local port="${2}"
855 assert isset port
856
857 shift 2
858
859 # Check if the port actually exists.
860 if ! port_exists "${port}"; then
861 error "Port '${port}' does not exist"
862 return ${EXIT_ERROR}
863 fi
864
865 # Check if the zone actually has this port.
866 if ! zone_has_port "${zone}" "${port}"; then
867 error "Port '${port}' is not attached to zone '${zone}'"
868 return ${EXIT_ERROR}
869 fi
870
871 local hook=$(zone_get_hook "${zone}")
872 assert isset hook
873
874 hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
875}
876
1c6a4e30 877zone_port_detach() {
ac694a6a
MT
878 local zone="${1}"
879 assert isset zone
880
881 local port="${2}"
882 assert isset port
883
1848564d
MT
884 shift 2
885
ac694a6a
MT
886 # Check if the zone actually has this port.
887 if ! zone_has_port "${zone}" "${port}"; then
888 error "Port '${port}' is not attached to zone '${zone}'"
889 return ${EXIT_ERROR}
890 fi
891
892 local hook=$(zone_get_hook "${zone}")
893 assert isset hook
894
f5ee091e
MT
895 # Make the port briefly flash if supported
896 port_identify "${port}" --background
897
ac694a6a
MT
898 hook_zone_exec "${hook}" "port_detach" "${zone}" "${port}" "$@"
899 local ret="${?}"
900
901 case "${ret}" in
902 ${EXIT_OK})
903 log INFO "${port} has been detached from ${zone}"
904
905 # Bring down the port if needed
abba34c1 906 zone_port_stop "${zone}" "${port}"
ac694a6a
MT
907 ;;
908 *)
909 log CRITICAL "${port} could not be detached from ${zone}"
910 ;;
911 esac
912
913 return ${ret}
914}
915
1c6a4e30 916zone_port_cmd() {
ac694a6a 917 local cmd="${1}"
711ffac1 918 assert isset cmd
ac694a6a
MT
919
920 local zone="${2}"
711ffac1 921 assert isset zone
1848564d 922
ac694a6a
MT
923 local port="${3}"
924 assert isset port
1848564d 925
ac694a6a
MT
926 shift 3
927
928 local hook="$(zone_get_hook "${zone}")"
929 assert isset hook
930
931 # Dispatch command to hook
2212045f 932 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" "$@"
ac694a6a
MT
933}
934
1c6a4e30 935zone_port_create() {
2212045f 936 zone_port_cmd "port_create" "$@"
ac694a6a
MT
937}
938
1c6a4e30 939zone_port_remove() {
2212045f 940 zone_port_cmd "port_remove" "$@"
ac694a6a
MT
941}
942
1c6a4e30 943zone_port_up() {
2212045f 944 zone_port_cmd "port_up" "$@"
ac694a6a
MT
945}
946
1c6a4e30 947zone_port_down() {
2212045f 948 zone_port_cmd "port_down" "$@"
ac694a6a
MT
949}
950
abba34c1
MT
951# The next two functions automagically bring up and down
952# port that are attached to a bridge or similar.
953# The problem that is tried to overcome here is that there
954# are ports which exist all the time (like ethernet ports)
955# and therefore do not dispatch a hotplug event when
956# port_create is called.
957
1c6a4e30 958zone_port_start() {
abba34c1
MT
959 local zone="${1}"
960 local port="${2}"
961
962 if zone_is_active "${zone}"; then
963 if device_exists "${port}"; then
964 zone_port_up "${zone}" "${port}"
965 return ${?}
966 else
967 zone_port_create "${zone}" "${port}"
968 return ${?}
969 fi
970 fi
971
972 return ${EXIT_OK}
973}
974
1c6a4e30 975zone_port_stop() {
abba34c1
MT
976 local zone="${1}"
977 local port="${2}"
978
979 # Shut down the port if necessary
980 if zone_is_active "${zone}" && port_is_up "${port}"; then
981 zone_port_down "${zone}" "${port}"
982 fi
983
984 # Remove the port
985 zone_port_remove "${zone}" "${port}"
986}
987
1c6a4e30 988zone_port_status() {
2212045f 989 zone_port_cmd "port_status" "$@"
ac694a6a
MT
990}
991
1c6a4e30 992zone_ports_cmd() {
ac694a6a
MT
993 local cmd="${1}"
994 assert isset cmd
995
996 local zone="${2}"
997 assert isset zone
998
999 shift 2
1000
1001 local hook="$(zone_get_hook "${zone}")"
711ffac1
MT
1002
1003 local port
1004 for port in $(zone_get_ports ${zone}); do
2212045f 1005 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" "$@"
1848564d
MT
1006 done
1007}
1008
1c6a4e30 1009zone_ports_create() {
2212045f 1010 zone_ports_cmd "port_create" "$@"
1ba6a2bb
MT
1011}
1012
1c6a4e30 1013zone_ports_remove() {
2212045f 1014 zone_ports_cmd "port_remove" "$@"
1ba6a2bb
MT
1015}
1016
1c6a4e30 1017zone_ports_up() {
2212045f 1018 zone_ports_cmd "port_up" "$@"
1848564d
MT
1019}
1020
1c6a4e30 1021zone_ports_down() {
2212045f 1022 zone_ports_cmd "port_down" "$@"
711ffac1
MT
1023}
1024
1c6a4e30 1025zone_ports_status() {
2212045f 1026 zone_ports_cmd "port_status" "$@"
1848564d
MT
1027}
1028
1c6a4e30 1029zone_configs_cmd() {
2472e0ea 1030 assert [ $# -ge 2 ]
ea699552
MT
1031
1032 local cmd="${1}"
1033 local zone="${2}"
1848564d
MT
1034 shift 2
1035
ea699552 1036 assert zone_exists "${zone}"
1848564d 1037
1848564d 1038 local config
2472e0ea
MT
1039 for config in $(zone_configs_list "${zone}"); do
1040 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1041 assert isset config_hook
1042
2212045f 1043 hook_config_exec "${config_hook}" "${cmd}" "${zone}" "${config}" "$@"
1848564d
MT
1044 done
1045}
1046
1c6a4e30 1047zone_configs_up() {
2212045f 1048 zone_configs_cmd "up" "$@"
1848564d
MT
1049}
1050
1c6a4e30 1051zone_configs_down() {
2212045f 1052 zone_configs_cmd "down" "$@"
1848564d
MT
1053}
1054
1c6a4e30 1055zone_configs_status() {
2212045f 1056 zone_configs_cmd "status" "$@"
ea699552
MT
1057}
1058
1c6a4e30 1059zone_configs_list() {
ea699552
MT
1060 local zone=${1}
1061
04c27fe9 1062 list_directory "${NETWORK_ZONES_DIR}/${zone}/configs"
a5ebb169
MT
1063}
1064
0afedf0d
JS
1065zone_config_get_new_id() {
1066 # This functions returns the next free id for a zone
1067
1068 assert [ $# -eq 1 ]
1069 local zone=${1}
1070
04c27fe9 1071 local zone_path="${NETWORK_ZONES_DIR}/${zone}"
0afedf0d
JS
1072 local i=0
1073
1074 while true; do
1075 if [ ! -f ${zone_path}/configs/*.${i} ]; then
1076 echo "${i}"
1077 return ${EXIT_OK}
1078 fi
1079 (( i++ ))
1080 done
1081}
1082
6727e4be
JS
1083zone_config_check_same_setting() {
1084 # This functions checks if a config hook
1085 # with the same setting is already configured for this zone.
1086 # Returns True when yes and False when no.
1087
320f1fda 1088 assert [ $# -eq 5 ]
6727e4be
JS
1089
1090 local zone=${1}
1091 local hook=${2}
320f1fda
JS
1092 local id=${3}
1093 local key=${4}
1094 local value=${5}
6727e4be
JS
1095
1096 # The key should be local for this function
1097 local ${key}
1098 local config
1099
1100 for config in $(zone_configs_list ${zone}); do
320f1fda
JS
1101 # Check if the config is eqal with the config we want to edit, when continue
1102 if [[ "${config}" = "${hook}.${id}" ]]; then
1103 continue
1104 fi
1105
6727e4be
JS
1106 # Check if the config is from the given hook, when not continue
1107 if [[ $(zone_config_get_hook "${zone}" "${config}") != ${hook} ]]; then
1108 continue
1109 fi
320f1fda 1110
6727e4be
JS
1111 # Get the value of the key for a given function
1112 zone_config_settings_read "${zone}" "${config}" \
1113 --ignore-superfluous-settings "${key}"
1114 # Check if the value of the config and the passed value are eqal
1115 if [[ "${value}" == "${!key}" ]]; then
1116 return ${EXIT_TRUE}
1117 fi
1118 done
1119
1120 return ${EXIT_FALSE}
1121}
1122
1c6a4e30 1123zone_config_get_hook() {
2472e0ea
MT
1124 assert [ $# -eq 2 ]
1125
1126 local zone="${1}"
1127 assert isset zone
1128
1129 local config="${2}"
1130 assert isset config
1131
1132 local HOOK
1133 zone_config_settings_read "${zone}" "${config}" \
1134 --ignore-superfluous-settings HOOK
1135
1136 print "${HOOK}"
1137}
1138
41f8233d
JS
1139zone_config_hook_is_configured() {
1140 # Checks if a zone has already at least one config with the given hook.
1141 # Returns True when yes and False when no
1142
1143 assert [ $# -eq 2 ]
1144 local zone=${1}
1145 local hook=${2}
1146
1147 local config
1148 for config in $(zone_configs_list "${zone}"); do
1149 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1150 assert isset config_hook
1151 if [[ ${hook} == ${config_hook} ]]; then
1152 return ${EXIT_TRUE}
1153 fi
1154
1155 done
1156
1157 # If we get here the zone has no config with the given hook
1158 return ${EXIT_FALSE}
1159}
1160
f158dc66
JS
1161zone_config_id_is_valid() {
1162 # This function checks if a given id is valid for a zone
1163 # Return True when yes and false when no
1164
1165 assert [ $# -eq 2 ]
1166 local zone=${1}
1167 local id=${2}
1168
04c27fe9 1169 local zone_path="${NETWORK_ZONES_DIR}/${zone}"
f158dc66
JS
1170
1171 [ -f ${zone_path}/configs/*.${id} ];
1172}
1173
450afe05
JS
1174# This function checks if a given hid is valid for a zone
1175# Return True when yes and false when no
1176zone_config_hid_is_valid() {
1177 assert [ $# -eq 2 ]
1178 local zone=${1}
1179 local hid=${2}
1180
1181 local _hid
1182 for _hid in $(zone_config_list_hids ${zone}); do
1183 if [[ ${_hid} == ${hid} ]]; then
1184 return ${EXIT_TRUE}
1185 fi
1186 done
1187
1188 return ${EXIT_FALSE}
1189}
1190
cdf4266d
JS
1191zone_config_get_hook_from_id() {
1192 # Returns the hook for a given id
1193 assert [ $# -eq 2 ]
1194 local zone=${1}
1195 local id=${2}
1196
1197 local config
1198 for config in $(zone_configs_list "${zone}"); do
1199 if [[ ${config} == *.${id} ]]; then
1200 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1201 assert isset config_hook
1202 print "${config_hook}"
1203 return "${EXIT_OK}"
1204 fi
1205 done
1206
1207 # If we get here the zone has no config with the given id
1208 return ${EXIT_ERROR}
1209}
1210
1c6a4e30 1211zone_has_ip() {
2212045f 1212 device_has_ip "$@"
4231f419
MT
1213}
1214
1c6a4e30 1215zone_db() {
059469a8
MT
1216 local zone=${1}
1217 local action=${2}
1218 shift 2
1219
1220 case "${action}" in
1221 starting|started|stopping|stopped)
1222 db_connection_update ${zone} ${action}
1223 ;;
1224 esac
1225}
5e42d659 1226
1c6a4e30 1227zone_is_up() {
5e42d659
MT
1228 local zone=${1}
1229
1230 device_is_up ${zone}
1231}
1232
1c6a4e30 1233zone_is_down() {
2212045f 1234 ! zone_is_up "$@"
5e42d659 1235}
711ffac1 1236
1c6a4e30 1237zone_get_supported_port_hooks() {
711ffac1
MT
1238 local zone=${1}
1239
1240 local hook=$(zone_get_hook ${zone})
1241
1242 hook_zone_ports_get_all ${hook}
1243}
1244
1c6a4e30 1245zone_get_supported_config_hooks() {
ea699552 1246 hook_config_get_all
a5ebb169
MT
1247}
1248
1c6a4e30 1249zone_settings_read() {
711ffac1 1250 local zone=${1}
711ffac1 1251 assert isset zone
52acd25f
MT
1252 shift
1253
1254 local args
1255 if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS}" ]; then
1256 list_append args ${HOOK_SETTINGS}
1257 else
2212045f 1258 list_append args "$@"
52acd25f 1259 fi
711ffac1 1260
bfd6c282
MT
1261 # Save the HOOK variable.
1262 local hook="${HOOK}"
1263
04c27fe9 1264 settings_read "${NETWORK_ZONES_DIR}/${zone}/settings" ${args}
bfd6c282
MT
1265
1266 # Restore hook.
1267 HOOK="${hook}"
711ffac1
MT
1268}
1269
1c6a4e30 1270zone_settings_write() {
1e6f187e 1271 local zone="${1}"
711ffac1
MT
1272 assert isset zone
1273
1e6f187e
MT
1274 local args
1275 if function_exists "hook_check_settings"; then
1276 list_append args "--check=\"hook_check_settings\""
1277 fi
1278 list_append args ${HOOK_SETTINGS}
1279
04c27fe9 1280 settings_write "${NETWORK_ZONES_DIR}/${zone}/settings" ${args}
711ffac1
MT
1281}
1282
1c6a4e30 1283zone_settings_set() {
711ffac1
MT
1284 local zone=${1}
1285 shift
1286 local args="$@"
1287
1288 assert isset zone
1289
1290 (
e9df08ad 1291 zone_settings_read ${zone}
711ffac1
MT
1292
1293 for arg in ${args}; do
1294 eval "${arg}"
1295 done
1296
e9df08ad 1297 zone_settings_write ${zone}
711ffac1
MT
1298 )
1299}
6b3f9c85 1300
1c6a4e30 1301zone_settings_get() {
6b3f9c85
MT
1302 local zone=${1}
1303 local key=${2}
1304
1305 assert isset zone
1306 assert isset key
1307
1308 (
1e6f187e
MT
1309 zone_settings_read "${zone}" "${key}" \
1310 --ignore-superfluous-settings
6b3f9c85
MT
1311
1312 echo "${!key}"
1313 )
1314}
e9df08ad 1315
1c6a4e30 1316zone_config_settings_read() {
c8132752 1317 assert [ $# -ge 2 ]
e9df08ad
MT
1318
1319 local zone="${1}"
1320 local config="${2}"
1321 shift 2
1322
c8132752
MT
1323 local args
1324 if [ $# -eq 0 ] && [ -n "${HOOK_CONFIG_SETTINGS}" ]; then
1325 list_append args ${HOOK_CONFIG_SETTINGS}
1326 else
2212045f 1327 list_append args "$@"
c8132752
MT
1328 fi
1329
04c27fe9 1330 local path="${NETWORK_ZONES_DIR}/${zone}/configs/${config}"
c8132752 1331 settings_read "${path}" ${args}
e9df08ad
MT
1332}
1333
1c6a4e30 1334zone_config_settings_write() {
c8132752 1335 assert [ $# -ge 2 ]
e9df08ad
MT
1336
1337 local zone="${1}"
0959b0b9
JS
1338 local hook="${2}"
1339 local id=${3}
1340
320f1fda 1341 assert isset id
e9df08ad 1342
c8132752
MT
1343 local args
1344 if function_exists "hook_check_config_settings"; then
1345 list_append args "--check=\"hook_check_config_settings\""
1346 fi
1347 list_append args ${HOOK_CONFIG_SETTINGS}
1348
04c27fe9 1349 local path="${NETWORK_ZONES_DIR}/${zone}/configs/${hook}.${id}"
c8132752 1350 settings_write "${path}" ${args}
e9df08ad
MT
1351}
1352
ea96cf52
JS
1353zone_config_settings_destroy() {
1354 # This function deletes the config file for a given zone and config
1355 assert [ $# -ge 2 ]
1356 local zone="${1}"
1357 local config="${2}"
1358
04c27fe9 1359 local path="${NETWORK_ZONES_DIR}/${zone}/configs/${config}"
ea96cf52
JS
1360
1361 # Check if path is valid
1362 if [ ! -f ${path} ]; then
1363 log ERROR "Path: '${path}' is not valid"
1364 return ${EXIT_ERROR}
1365 fi
1366
1367 log DEBUG "Deleting config file ${path}"
1368 rm -f "${path}"
1369
1370}
79b2155d
MT
1371
1372zone_config_find_by_hook() {
1373 local zone="${1}"
1374 assert isset zone
1375
1376 local hook="${2}"
1377 assert isset hook
1378
1379 local config
1380 for config in $(zone_configs_list "${zone}"); do
1381 local h="$(zone_config_get_hook "${zone}" "${config}")"
1382
1383 [[ "${hook}" = "${h}" ]] && echo "${config}"
1384 done
1385
1386 return ${EXIT_OK}
1387}
1388
1389zone_config_settings_read_by_hook() {
1390 local zone="${1}"
1391 assert isset zone
1392
1393 local hook="${2}"
1394 assert isset hook
1395
1396 local config
1397 for config in $(zone_config_find_by_hook "${zone}" "${hook}"); do
1398 zone_config_settings_read "${zone}" "${config}"
1399 done
1400
1401 return ${EXIT_OK}
1402}
1403
1c6a4e30 1404zone_port_settings_read() {
ac694a6a 1405 assert [ $# -ge 2 ]
e9df08ad
MT
1406
1407 local zone="${1}"
1408 local port="${2}"
1409 shift 2
1410
ac694a6a
MT
1411 local args
1412 if [ $# -eq 0 ] && [ -n "${HOOK_PORT_SETTINGS}" ]; then
1413 list_append args ${HOOK_PORT_SETTINGS}
1414 else
2212045f 1415 list_append args "$@"
ac694a6a
MT
1416 fi
1417
04c27fe9 1418 local path="${NETWORK_ZONES_DIR}/${zone}/ports/${port}"
ac694a6a 1419 settings_read "${path}" ${args}
e9df08ad
MT
1420}
1421
1c6a4e30 1422zone_port_settings_write() {
02236ca6 1423 assert [ $# -ge 2 ]
e9df08ad
MT
1424
1425 local zone="${1}"
1426 local port="${2}"
1427 shift 2
1428
1e6f187e
MT
1429 local args
1430 if function_exists "hook_check_port_settings"; then
1431 list_append args "--check=\"hook_check_port_settings\""
1432 fi
ac694a6a 1433 list_append args ${HOOK_PORT_SETTINGS}
1e6f187e 1434
04c27fe9 1435 local path="${NETWORK_ZONES_DIR}/${zone}/ports/${port}"
1e6f187e 1436 settings_write "${path}" ${args}
e9df08ad
MT
1437}
1438
1c6a4e30 1439zone_port_settings_remove() {
e9df08ad
MT
1440 assert [ $# -eq 2 ]
1441
1442 local zone="${1}"
1443 local port="${2}"
1444
04c27fe9 1445 local path="${NETWORK_ZONES_DIR}/${zone}/ports/${port}"
e9df08ad
MT
1446 settings_remove "${path}"
1447}
410d2e85
JS
1448
1449zone_get_color() {
1450 # This function return the color of a zone
1451 assert [ $# -eq 1 ]
1452
1453 local name=${1}
1454 color_read "zone" ${name}
1455}
5de34b4c
JS
1456
1457zone_get_description_title() {
1458 assert [ $# -eq 1 ]
1459
1460 local name=${1}
1461 description_title_read $(description_format_filename "zone" "${name}")
1462}