]> git.ipfire.org Git - people/ms/network.git/blame - src/functions/functions.zone
zone: Send systemd updates on hotplug events
[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
22function zone_dir() {
23 local zone=${1}
24
d2a21d01 25 echo "${NETWORK_ZONE_DIR}/zones/${zone}"
1848564d
MT
26}
27
28function zone_exists() {
29 local zone=${1}
711ffac1
MT
30 assert isset zone
31
1848564d
MT
32 [ -d "$(zone_dir ${zone})" ]
33}
34
35function zone_match() {
36 local match
37
38 local i
39 for i in ${VALID_ZONES}; do
40 match="${match}|${i}[0-9]{1,5}"
41 done
42
43 echo "${match:1:${#match}}"
44}
45
46function zone_name_is_valid() {
47 local zone=${1}
4fedddef
MT
48
49 # Don't accept empty strings.
50 [ -z "${zone}" ] && return ${EXIT_FALSE}
711ffac1 51
1848564d
MT
52 [[ ${zone} =~ $(zone_match) ]]
53}
54
55function zone_is_local() {
56 local zone=${1}
57
7de0637a 58 [[ "${zone:0:${#ZONE_LOCAL}}" = "${ZONE_LOCAL}" ]]
5e42d659
MT
59}
60
61function zone_is_nonlocal() {
62 local zone=${1}
63
7de0637a 64 [[ "${zone:0:${#ZONE_NONLOCAL}}" = "${ZONE_NONLOCAL}" ]]
1848564d
MT
65}
66
67function zone_get_hook() {
68 local zone=${1}
711ffac1
MT
69 assert isset zone
70
1848564d
MT
71 config_get_hook $(zone_dir ${zone})/settings
72}
73
5bb2429a
MT
74function zone_start() {
75 # This function will bring up the zone
76 # 'asynchronously' with help of systemd.
77
78 local zone=${1}
79 assert zone_exists ${zone}
80
1d08b9b3 81 service_start "network@${zone}.service"
5bb2429a
MT
82}
83
84function zone_stop() {
85 # This function will bring down the zone
86 # 'asynchronously' with help of systemd.
87
88 local zone=${1}
89 assert zone_exists ${zone}
90
1d08b9b3 91 service_stop "network@${zone}.service"
5bb2429a
MT
92}
93
e6fd23fd
MT
94function zone_reload() {
95 local zone="${1}"
96 assert zone_exists "${zone}"
97
98 service_reload "network@${zone}.service"
99}
100
5c5b8e36
SS
101function zone_enable() {
102 # This function will enable the zone
103 # with help of systemd.
104
105 local zone="${1}"
106 assert zone_exists "${zone}"
107
108 # Enable service for the zone
109 service_enable "network@${zone}.service"
110 local ret=$?
111
112 if [ ${ret} -eq ${EXIT_OK} ]; then
113 log INFO "Auto-start enabled for zone ${zone}"
114 return ${EXIT_OK}
115 fi
116
117 log ERROR "Could not enable zone ${zone}: ${ret}"
118 return ${ret}
119}
120
121function zone_disable() {
122 # This function will disable the zone
123 # with help of systemd.
124
125 local zone="${1}"
126 assert zone_exists "${zone}"
127
128 # Disable service for the zone
129 service_disable "network@${zone}.service"
130 local ret=$?
131
132 if [ ${ret} -eq ${EXIT_OK} ]; then
133 log INFO "Auto-start disabled for zone ${zone}"
134 return ${EXIT_OK}
135 fi
136
137 log ERROR "Could not disable zone ${zone}: ${ret}"
138 return ${ret}
139}
140
141function zone_is_enabled() {
142 local zone="${1}"
143 assert isset zone
144
145 # Ask systemd if the zone is enabled.
146 if service_is_enabled "network@${zone}.service"; then
147 return ${EXIT_TRUE}
148 fi
149
150 return ${EXIT_FALSE}
151}
152
e6fd23fd
MT
153function zone_is_active() {
154 local zone="${1}"
155 assert isset zone
156
157 if service_is_active "network@${zone}.service"; then
158 return ${EXIT_TRUE}
159 fi
160
161 return ${EXIT_FALSE}
162}
163
1848564d
MT
164function zone_create() {
165 local zone=${1}
166 local hook=${2}
167 shift 2
168
169 if ! zone_name_is_valid ${zone}; then
170 error "Zone name '${zone}' is not valid."
171 return ${EXIT_ERROR}
172 fi
173
174 if zone_exists ${zone}; then
175 error "Zone '${zone}' does already exist."
176 return ${EXIT_ERROR}
177 fi
178
d61a01d4 179 if ! hook_zone_exists ${hook}; then
1848564d
MT
180 error "Hook '${hook}' does not exist."
181 return ${EXIT_ERROR}
182 fi
183
184 mkdir -p $(zone_dir ${zone})
185
a5ebb169
MT
186 # Create directories for configs and ports
187 mkdir -p $(zone_dir ${zone})/{configs,ports}
943e3f7e 188
d61a01d4 189 hook_zone_exec ${hook} create ${zone} $@
1848564d
MT
190 local ret=$?
191
192 # Maybe the zone create hook did not exit correctly.
193 # If this is the case we remove the created zone immediately.
194 if [ "${ret}" = "${EXIT_ERROR}" ]; then
69ace22b 195 zone_remove_now ${zone}
5c5b8e36 196 return ${EXIT_ERROR}
1848564d 197 fi
5c5b8e36
SS
198
199 # Automatically enable zone.
200 zone_enable "${zone}"
1848564d
MT
201}
202
203function zone_edit() {
204 local zone=${1}
205 shift
206
207 if ! zone_exists ${zone}; then
208 error "Zone '${zone}' does not exist."
209 return ${EXIT_ERROR}
210 fi
211
69ace22b
MT
212 # Check if the zone is tagged for removal.
213 if zone_has_remove_tag ${zone}; then
214 error "You cannot edit a zone that is tagged for removal."
215 return ${EXIT_ERROR}
216 fi
217
1848564d
MT
218 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
219
220 if [ -z "${hook}" ]; then
221 error "Config file did not provide any hook."
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
d61a01d4 230 hook_zone_exec ${hook} edit ${zone} $@
1848564d
MT
231}
232
69ace22b 233
1848564d
MT
234function zone_remove() {
235 local zone=${1}
69ace22b 236 assert zone_exists ${zone}
1848564d 237
69ace22b
MT
238 # Make the zone for removal.
239 touch $(zone_dir ${zone})/.remove
240
241 log INFO "Zone '${zone}' has been tagged for removal."
242}
243
244function zone_has_remove_tag() {
245 local zone=${1}
246 assert zone_exists ${zone}
247
248 [ -e "$(zone_dir ${zone})/.remove" ]
249}
250
251# This function will remove the given zone
252# RIGHT NOW. Use zone_remove to remove it
253# at the next status change.
254function zone_remove_now() {
255 local zone=${1}
256 assert zone_exists ${zone}
257
258 log INFO "Removing zone '${zone}' right now."
1848564d 259
69ace22b
MT
260 # Force the zone down.
261 zone_is_up ${zone} && zone_set_down ${zone}
1848564d 262
5c5b8e36
SS
263 # Disable zone.
264 zone_disable "${zone}"
265
1848564d
MT
266 rm -rf $(zone_dir ${zone})
267}
268
269function zone_up() {
270 local zone=${1}
271 shift
272
273 if ! zone_exists ${zone}; then
274 error "Zone '${zone}' does not exist."
275 return ${EXIT_ERROR}
276 fi
277
69ace22b
MT
278 # Check if a zone has got the remove tag.
279 if zone_has_remove_tag ${zone}; then
280 error "Cannot bring up any zone which is to be removed."
281 return ${EXIT_ERROR}
282 fi
283
1848564d
MT
284 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
285
286 if [ -z "${hook}" ]; then
287 error "Config file did not provide any hook."
288 return ${EXIT_ERROR}
289 fi
290
d61a01d4 291 if ! hook_zone_exists ${hook}; then
1848564d
MT
292 error "Hook '${hook}' does not exist."
293 return ${EXIT_ERROR}
294 fi
295
059469a8
MT
296 zone_db ${zone} starting
297
d61a01d4
MT
298 hook_zone_exec ${hook} up ${zone} $@
299
059469a8 300 zone_db ${zone} started
1848564d
MT
301}
302
303function zone_down() {
304 local zone=${1}
305 shift
306
307 if ! zone_exists ${zone}; then
308 error "Zone '${zone}' does not exist."
309 return ${EXIT_ERROR}
310 fi
311
312 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
313
314 if [ -z "${hook}" ]; then
315 error "Config file did not provide any hook."
316 return ${EXIT_ERROR}
317 fi
318
d61a01d4 319 if ! hook_zone_exists ${hook}; then
1848564d
MT
320 error "Hook '${hook}' does not exist."
321 return ${EXIT_ERROR}
322 fi
323
059469a8
MT
324 zone_db ${zone} stopping
325
d61a01d4 326 hook_zone_exec ${hook} down ${zone} $@
059469a8
MT
327
328 zone_db ${zone} stopped
69ace22b
MT
329
330 # Remove the zone, if it has got a remove tag.
331 if zone_has_remove_tag ${zone}; then
332 zone_remove_now ${zone}
333 fi
1848564d
MT
334}
335
336function zone_status() {
337 local zone=${1}
338 shift
339
340 if ! zone_exists ${zone}; then
341 error "Zone '${zone}' does not exist."
342 return ${EXIT_ERROR}
343 fi
344
345 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
346
347 if [ -z "${hook}" ]; then
348 error "Config file did not provide any hook."
349 return ${EXIT_ERROR}
350 fi
351
d61a01d4 352 if ! hook_zone_exists ${hook}; then
1848564d
MT
353 error "Hook '${hook}' does not exist."
354 return ${EXIT_ERROR}
355 fi
356
d61a01d4 357 hook_zone_exec ${hook} status ${zone} $@
69ace22b
MT
358
359 # Show that the zone it to be removed soon.
360 if zone_has_remove_tag ${zone}; then
361 warning "This zone is tagged for removal."
362 fi
1848564d
MT
363}
364
711ffac1
MT
365function zone_port() {
366 local zone=${1}
367 local action=${2}
368 shift 2
369
370 assert isset zone
371 assert isset action
372 assert zone_exists ${zone}
373
374 case "${action}" in
828eb94a 375 add|edit|remove)
943e3f7e
MT
376 zone_port_${action} ${zone} $@
377 ;;
378 *)
379 error "Unrecognized argument: ${action}"
380 cli_usage root-zone-port-subcommands
381 exit ${EXIT_ERROR}
382 ;;
383 esac
711ffac1
MT
384}
385
386function zone_port_add() {
828eb94a 387 local zone="${1}"
711ffac1
MT
388 assert isset zone
389
828eb94a
MT
390 local port="${2}"
391 assert isset port
392
393 shift 2
711ffac1 394
828eb94a
MT
395 # Check if the port actually exists.
396 if ! port_exists "${port}"; then
397 error "Cannot add port '${port}' which does not exist"
398 return ${EXIT_ERROR}
399 fi
400
401 # Check if the port is already connected to this or any other zone.
402 local z
403 for z in $(zones_get_all); do
404 if zone_has_port "${z}" "${port}"; then
405 error "Port '${port}' is already assigned to zone '${z}'"
406 return ${EXIT_ERROR}
407 fi
408 done
409
410 local hook=$(zone_get_hook "${zone}")
711ffac1
MT
411 assert isset hook
412
828eb94a 413 hook_zone_exec "${hook}" "port_add" "${zone}" "${port}" "$@"
711ffac1
MT
414}
415
416function zone_port_edit() {
828eb94a
MT
417 local zone="${1}"
418 assert isset zone
711ffac1 419
828eb94a
MT
420 local port="${2}"
421 assert isset port
711ffac1 422
828eb94a 423 shift 2
711ffac1 424
828eb94a
MT
425 # Check if the port actually exists.
426 if ! port_exists "${port}"; then
427 error "Port '${port}' does not exist"
428 return ${EXIT_ERROR}
429 fi
711ffac1 430
828eb94a
MT
431 # Check if the zone actually has this port.
432 if ! zone_has_port "${zone}" "${port}"; then
433 error "Port '${port}' is not attached to zone '${zone}'"
434 return ${EXIT_ERROR}
435 fi
711ffac1 436
828eb94a
MT
437 local hook=$(zone_get_hook "${zone}")
438 assert isset hook
711ffac1 439
828eb94a 440 hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
711ffac1
MT
441}
442
828eb94a
MT
443function zone_port_remove() {
444 local zone="${1}"
445 assert isset zone
446
447 local port="${2}"
448 assert isset port
449
450 shift 2
451
452 # Check if the zone actually has this port.
453 if ! zone_has_port "${zone}" "${port}"; then
454 error "Port '${port}' is not attached to zone '${zone}'"
455 return ${EXIT_ERROR}
456 fi
457
458 local hook=$(zone_get_hook "${zone}")
459 assert isset hook
711ffac1 460
828eb94a 461 hook_zone_exec "${hook}" "port_remove" "${zone}" "${port}" "$@"
711ffac1
MT
462}
463
464function zone_get_ports() {
465 local zone=${1}
466
467 assert isset zone
468
469 local port
943e3f7e 470 for port in $(zone_dir ${zone})/ports/*; do
711ffac1 471 port=$(basename ${port})
711ffac1
MT
472
473 if port_exists ${port}; then
474 echo "${port}"
475 fi
476 done
477}
478
529141df
MT
479function zone_get_ports_num() {
480 local zone="${1}"
481 assert isset zone
482
483 local counter=0
484 local port
485 for port in $(zone_dir "${zone}")/ports/*; do
486 port="$(basename "${port}")"
487
488 if port_exists "${port}"; then
489 counter=$(( ${counter} + 1 ))
490 fi
491 done
492
493 echo "${counter}"
494 return ${EXIT_OK}
495}
496
3a7fef62
MT
497function zone_has_port() {
498 # Check, if the given port is configured
499 # in this zone.
500
501 local zone=${1}
502 local port=${2}
503 shift 2
504
505 assert isset zone
506 assert isset port
507
508 [ -e "$(zone_dir ${zone})/ports/${port}" ]
509}
510
a5ebb169 511# XXX overwritten some lines below
1848564d
MT
512function zone_config() {
513 local zone=${1}
514 shift
515
516 if ! zone_exists ${zone}; then
517 error "Zone '${zone}' does not exist."
518 return ${EXIT_ERROR}
519 fi
520
521 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
522
523 if [ -z "${hook}" ]; then
524 error "Config file did not provide any hook."
525 return ${EXIT_ERROR}
526 fi
527
d61a01d4 528 if ! hook_zone_exists ${hook}; then
1848564d
MT
529 error "Hook '${hook}' does not exist."
530 return ${EXIT_ERROR}
531 fi
532
d61a01d4 533 hook_zone_exec ${hook} config ${zone} $@
1848564d
MT
534}
535
a5ebb169
MT
536function zone_config() {
537 local zone=${1}
538 local action=${2}
539 shift 2
540
541 assert isset zone
542 assert isset action
543 assert zone_exists ${zone}
544
545 # Aliases
546 case "${action}" in
547 del|delete|remove)
548 action="rem"
549 ;;
550 esac
551
552 case "${action}" in
553 create|edit|rem)
554 zone_config_${action} ${zone} $@
555 ;;
556 *)
557 error "Unrecognized argument: ${action}"
558 cli_usage root-zone-config-subcommands
559 exit ${EXIT_ERROR}
560 ;;
561 esac
562}
563
564function zone_config_create() {
e9df08ad 565 local zone="${1}"
a5ebb169 566 assert isset zone
e9df08ad 567 shift
a5ebb169 568
e9df08ad 569 local hook=$(zone_get_hook "${zone}")
a5ebb169
MT
570 assert isset hook
571
e9df08ad 572 hook_zone_exec "${hook}" "config_create" "${zone}" "$@"
a5ebb169
MT
573}
574
1848564d
MT
575function zone_show() {
576 local zone=${1}
577
578 echo "${zone}"
579 echo " Type: $(zone_get_hook ${zone})"
580 echo
581}
582
583function zones_show() {
584 local zone
585
586 for zone in $(zones_get $@); do
587 zone_show ${zone}
588 done
589}
590
591function zones_get_all() {
592 local zone
d61a01d4 593 for zone in $(zone_dir)/*; do
1848564d
MT
594 zone=$(basename ${zone})
595 zone_exists ${zone} || continue
596
597 echo "${zone}"
03170817 598 done
1848564d
MT
599}
600
601function zones_get_local() {
602 local zone
603 for zone in $(zones_get_all); do
604 zone_is_local ${zone} && echo "${zone}"
605 done
606}
607
608function zones_get_nonlocal() {
609 local zone
610 for zone in $(zones_get_all); do
5e42d659 611 zone_is_nonlocal ${zone} && echo "${zone}"
1848564d
MT
612 done
613}
614
615function zones_get() {
616 local local=1
617 local remote=1
618
619 local zones
620
621 while [ $# -gt 0 ]; do
622 case "${1}" in
623 --local-only)
624 local=1
625 remote=0
626 ;;
627 --remote-only)
628 local=0
629 remote=1
630 ;;
631 --all)
632 local=1
633 remote=1
634 ;;
635 *)
636 if zone_name_is_valid ${1}; then
637 zones="${zones} ${1}"
638 else
639 warning "Unrecognized argument '${1}'"
640 fi
641 ;;
642 esac
643 shift
644 done
645
646 if [ -n "${zones}" ]; then
647 local zone
648 for zone in ${zones}; do
649 zone_exists ${zone} && echo "${zone}"
650 done
651 exit ${EXIT_OK}
652 fi
653
654 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
655 zones_get_all
656 elif [ ${local} -eq 1 ]; then
657 zones_get_local
658 elif [ ${remote} -eq 1 ]; then
659 zones_get_nonlocal
660 fi
661}
662
663function zone_ports_list() {
664 local zone=${1}
665
666 local port
a5ebb169 667 for port in $(zone_dir ${zone})/ports/*; do
1848564d
MT
668 [ -e "${port}" ] || continue
669
670 echo $(basename ${port})
03170817 671 done
1848564d
MT
672}
673
674function zone_ports_cmd() {
675 local cmd=${1}
676 local zone=${2}
677 shift 2
678
711ffac1
MT
679 assert isset cmd
680 assert isset zone
1848564d 681
711ffac1 682 assert zone_exists ${zone}
1848564d 683
711ffac1
MT
684 local hook=$(zone_get_hook ${zone})
685
686 local port
687 for port in $(zone_get_ports ${zone}); do
711ffac1 688 hook_zone_exec ${hook} ${cmd} ${zone} ${port} $@
1848564d
MT
689 done
690}
691
692function zone_ports_up() {
711ffac1 693 zone_ports_cmd port_up $@
1848564d
MT
694}
695
696function zone_ports_down() {
711ffac1
MT
697 zone_ports_cmd port_down $@
698}
699
700function zone_ports_status() {
701 zone_ports_cmd port_status $@
1848564d
MT
702}
703
704function zone_configs_list() {
705 local zone=${1}
706
707 local config
a5ebb169 708 for config in $(zone_dir ${zone})/configs/*; do
1848564d
MT
709 [ -e "${config}" ] || continue
710
f41fa3d7 711 basename ${config}
03170817 712 done
1848564d
MT
713}
714
715function zone_configs_cmd() {
716 local cmd=${1}
717 local zone=${2}
718 shift 2
719
720 local hook_zone=$(config_get_hook $(zone_dir ${zone})/settings)
721
722 local hook_config
723 local config
724 for config in $(zone_configs_list ${zone}); do
a5ebb169 725 hook_config=$(config_get_hook $(zone_dir ${zone})/configs/${config})
1848564d 726
d61a01d4 727 hook_zone_config_exec ${hook_zone} ${hook_config} ${cmd} ${zone} ${config} $@
1848564d
MT
728 done
729}
730
731function zone_configs_up() {
732 zone_configs_cmd up $@
733}
734
735function zone_configs_down() {
736 zone_configs_cmd down $@
737}
738
a5ebb169
MT
739function zone_configs_status() {
740 zone_configs_cmd config_status $@
741}
742
38f61548
MT
743function zone_has_ip() {
744 device_has_ip $@
4231f419
MT
745}
746
059469a8
MT
747function zone_db() {
748 local zone=${1}
749 local action=${2}
750 shift 2
751
752 case "${action}" in
753 starting|started|stopping|stopped)
754 db_connection_update ${zone} ${action}
755 ;;
756 esac
757}
5e42d659
MT
758
759function zone_is_up() {
760 local zone=${1}
761
762 device_is_up ${zone}
763}
764
765function zone_is_down() {
766 ! zone_is_up $@
767}
711ffac1 768
a5ebb169 769function zone_get_supported_port_hooks() {
711ffac1
MT
770 local zone=${1}
771
772 local hook=$(zone_get_hook ${zone})
773
774 hook_zone_ports_get_all ${hook}
775}
776
a5ebb169
MT
777function zone_get_supported_config_hooks() {
778 local zone=${1}
779
780 local hook=$(zone_get_hook ${zone})
781
782 hook_zone_configs_get_all ${hook}
783}
784
711ffac1
MT
785function zone_file() {
786 local zone=${1}
787
788 assert isset zone
789
790 echo "$(zone_dir ${zone})/settings"
791}
792
e9df08ad 793function zone_settings_read() {
711ffac1
MT
794 local zone=${1}
795
796 assert isset zone
797
bfd6c282
MT
798 # Save the HOOK variable.
799 local hook="${HOOK}"
800
e9df08ad 801 settings_read $(zone_file ${zone})
bfd6c282
MT
802
803 # Restore hook.
804 HOOK="${hook}"
711ffac1
MT
805}
806
e9df08ad 807function zone_settings_write() {
711ffac1
MT
808 local zone=${1}
809
810 assert isset zone
811
e9df08ad 812 settings_write $(zone_file ${zone}) ${HOOK_SETTINGS}
711ffac1
MT
813}
814
e9df08ad 815function zone_settings_set() {
711ffac1
MT
816 local zone=${1}
817 shift
818 local args="$@"
819
820 assert isset zone
821
822 (
e9df08ad 823 zone_settings_read ${zone}
711ffac1
MT
824
825 for arg in ${args}; do
826 eval "${arg}"
827 done
828
e9df08ad 829 zone_settings_write ${zone}
711ffac1
MT
830 )
831}
6b3f9c85 832
e9df08ad 833function zone_settings_get() {
6b3f9c85
MT
834 local zone=${1}
835 local key=${2}
836
837 assert isset zone
838 assert isset key
839
840 (
e9df08ad 841 zone_settings_read ${zone}
6b3f9c85
MT
842
843 echo "${!key}"
844 )
845}
e9df08ad
MT
846
847function zone_config_settings_read() {
848 assert [ $# -gt 2 ]
849
850 local zone="${1}"
851 local config="${2}"
852 shift 2
853
854 local path="$(zone_dir "${zone}")/configs/${config}"
855 settings_read "${path}" "$@"
856}
857
858function zone_config_settings_write() {
859 assert [ $# -gt 2 ]
860
861 local zone="${1}"
862 local config="${2}"
863 shift 2
864
865 local path="$(zone_dir "${zone}")/configs/${config}"
866 settings_write "${path}" "$@"
867}
868
869function zone_port_settings_read() {
870 assert [ $# -gt 2 ]
871
872 local zone="${1}"
873 local port="${2}"
874 shift 2
875
876 local path="$(zone_dir "${zone}")/ports/${port}"
877 settings_read "${path}" "$@"
878}
879
880function zone_port_settings_write() {
881 assert [ $# -gt 2 ]
882
883 local zone="${1}"
884 local port="${2}"
885 shift 2
886
887 local path="$(zone_dir "${zone}")/ports/${port}"
888 settings_write "${path}" "$@"
889}
890
891function zone_port_settings_remove() {
892 assert [ $# -eq 2 ]
893
894 local zone="${1}"
895 local port="${2}"
896
897 local path="$(zone_dir "${zone}")/ports/${port}"
898 settings_remove "${path}"
899}