2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
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. #
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. #
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/>. #
20 ###############################################################################
25 echo "${NETWORK_ZONE_DIR}/zones/${zone}"
32 [ -d "$(zone_dir ${zone})" ]
39 for i
in ${VALID_ZONES}; do
40 match
="${match}|${i}[0-9]{1,5}"
43 echo "${match:1:${#match}}"
46 zone_name_is_valid
() {
49 # Don't accept empty strings.
50 [ -z "${zone}" ] && return ${EXIT_FALSE}
52 [[ ${zone} =~ $
(zone_match
) ]]
58 [[ "${zone:0:${#ZONE_LOCAL}}" = "${ZONE_LOCAL}" ]]
64 [[ "${zone:0:${#ZONE_NONLOCAL}}" = "${ZONE_NONLOCAL}" ]]
71 config_get_hook $
(zone_dir
${zone})/settings
75 # This function will bring up the zone
76 # 'asynchronously' with help of systemd.
79 assert zone_exists
${zone}
81 service_start
"network@${zone}.service"
86 assert zone_exists
"${zone}"
88 # If the zone has already been started, we
89 # will reload it so the current configuration
91 if zone_is_active
"${zone}"; then
95 # If the zone is still down, but in auto-start mode,
97 elif zone_is_enabled
"${zone}"; then
102 # Otherwise, nothing will be done.
107 # This function will bring down the zone
108 # 'asynchronously' with help of systemd.
111 assert zone_exists
${zone}
113 service_stop
"network@${zone}.service"
118 assert zone_exists
"${zone}"
120 service_reload
"network@${zone}.service"
123 zone_hotplug_event
() {
127 hotplug_assert_in_hotplug_event
129 zone_cmd
"hotplug" "${zone}"
133 # This function will enable the zone
134 # with help of systemd.
137 assert zone_exists
"${zone}"
139 # Enable service for the zone
140 service_enable
"network@${zone}.service"
143 if [ ${ret} -eq ${EXIT_OK} ]; then
144 log INFO
"Auto-start enabled for zone ${zone}"
148 log ERROR
"Could not enable zone ${zone}: ${ret}"
153 # This function will disable the zone
154 # with help of systemd.
157 assert zone_exists
"${zone}"
159 # Disable service for the zone
160 service_disable
"network@${zone}.service"
163 if [ ${ret} -eq ${EXIT_OK} ]; then
164 log INFO
"Auto-start disabled for zone ${zone}"
168 log ERROR
"Could not disable zone ${zone}: ${ret}"
176 # Ask systemd if the zone is enabled.
177 if service_is_enabled
"network@${zone}.service"; then
188 if service_is_active
"network@${zone}.service"; then
195 zone_is_enabled_or_active
() {
199 zone_is_enabled
"${zone}" || zone_is_active
"${zone}"
210 local hook
="$(zone_get_hook ${zone})"
213 hook_exec zone
"${hook}" "${cmd}" "${zone}" $@
221 if ! zone_name_is_valid
${zone}; then
222 error
"Zone name '${zone}' is not valid."
226 if zone_exists
${zone}; then
227 error
"Zone '${zone}' does already exist."
231 if ! hook_zone_exists
${hook}; then
232 error
"Hook '${hook}' does not exist."
236 mkdir
-p $
(zone_dir
${zone})
238 # Create directories for configs and ports
239 mkdir
-p $
(zone_dir
${zone})/{configs
,ports
}
241 hook_zone_exec
"${hook}" "new" "${zone}" $@
244 # Maybe the zone new hook did not exit correctly.
245 # If this is the case we remove the created zone immediately.
246 if [ "${ret}" = "${EXIT_ERROR}" ]; then
247 zone_destroy_now
"${zone}"
251 # Automatically enable zone.
252 zone_enable
"${zone}"
254 # Bring up the zone immediately after
262 if ! zone_exists
${zone}; then
263 error
"Zone '${zone}' does not exist."
267 # Check if the zone is tagged for removal.
268 if zone_has_destroy_tag
${zone}; then
269 error
"You cannot edit a zone that is tagged for removal."
273 local hook
="$(zone_get_hook "${zone}")"
274 if [ -z "${hook}" ]; then
275 error
"Config file did not provide any hook."
279 if ! hook_zone_exists
${hook}; then
280 error
"Hook '${hook}' does not exist."
284 hook_zone_exec
${hook} edit
${zone} $@
290 assert zone_exists
"${zone}"
292 # Make the zone for removal.
293 touch "$(zone_dir "${zone}")/.destroy"
295 log INFO
"Zone '${zone}' has been tagged for removal."
298 zone_has_destroy_tag
() {
300 assert zone_exists
"${zone}"
302 [ -e "$(zone_dir "${zone}")/.destroy" ]
305 # This function will remove the given zone
306 # RIGHT NOW. Use zone_destroy to remove it
307 # at the next status change.
310 assert zone_exists
"${zone}"
312 log INFO
"Removing zone '${zone}' right now."
314 # Force the zone down.
315 zone_is_active
"${zone}" && zone_stop
"${zone}"
318 zone_disable
"${zone}"
320 rm -rf "$(zone_dir "${zone}")"
327 if ! zone_exists
${zone}; then
328 error
"Zone '${zone}' does not exist."
332 # Check if a zone has got the remove tag.
333 if zone_has_destroy_tag
${zone}; then
334 error
"Cannot bring up any zone which is to be removed."
338 local hook
="$(zone_get_hook "${zone}")"
339 if [ -z "${hook}" ]; then
340 error
"Config file did not provide any hook."
344 if ! hook_zone_exists
${hook}; then
345 error
"Hook '${hook}' does not exist."
349 zone_db
${zone} starting
351 hook_zone_exec
${hook} up
${zone} $@
353 zone_db
${zone} started
360 if ! zone_exists
${zone}; then
361 error
"Zone '${zone}' does not exist."
365 local hook
="$(zone_get_hook "${zone}")"
366 if [ -z "${hook}" ]; then
367 error
"Config file did not provide any hook."
371 if ! hook_zone_exists
${hook}; then
372 error
"Hook '${hook}' does not exist."
376 zone_db
${zone} stopping
378 hook_zone_exec
${hook} down
${zone} $@
380 zone_db
${zone} stopped
382 # Remove the zone, if it has got a remove tag.
383 if zone_has_destroy_tag
"${zone}"; then
384 zone_destroy_now
"${zone}"
393 if ! zone_exists
"${zone}"; then
394 error
"Zone '${zone}' does not exist."
398 local hook
="$(zone_get_hook "${zone}")"
399 if [ -z "${hook}" ]; then
400 error
"Config file did not provide any hook."
404 if ! hook_zone_exists
"${hook}"; then
405 error
"Hook '${hook}' does not exist."
409 hook_zone_exec
"${hook}" "status" "${zone}" "$@"
411 # Show that the zone it to be removed soon.
412 if zone_has_destroy_tag
${zone}; then
413 warning
"This zone is tagged for removal."
423 for port
in $
(zone_dir
${zone})/ports
/*; do
424 port
=$
(basename ${port})
426 if port_exists
${port}; then
432 zone_get_ports_num
() {
438 for port
in $
(zone_dir
"${zone}")/ports
/*; do
439 port
="$(basename "${port}")"
441 if port_exists
"${port}"; then
442 counter
=$
(( ${counter} + 1 ))
451 # Check, if the given port is configured
461 [ -e "$(zone_dir ${zone})/ports/${port}" ]
471 assert zone_exists
"${zone}"
475 zone_config_create
"${zone}" "$@"
478 zone_config_edit
"${zone}" "$@"
481 zone_config_remove
"${zone}" "$@"
484 error
"Unrecognized argument: ${cmd}"
485 cli_usage root-zone-config-subcommands
498 local hook
="$(zone_get_hook "${zone}")"
501 hook_zone_exec
"${hook}" "config_${cmd}" "${zone}" "$@"
504 zone_config_create
() {
505 zone_config_cmd
"create" "$@"
509 zone_config_cmd
"edit" "$@"
512 zone_config_remove
() {
513 zone_config_cmd
"remove" "$@"
517 zone_config_cmd
"show" "$@"
524 echo " Type: $(zone_get_hook ${zone})"
531 for zone
in $
(zones_get $@
); do
538 for zone
in $
(zone_dir
)/*; do
539 zone
=$
(basename ${zone})
540 zone_exists
${zone} ||
continue
548 for zone
in $
(zones_get_all
); do
549 zone_is_local
${zone} && echo "${zone}"
553 zones_get_nonlocal
() {
555 for zone
in $
(zones_get_all
); do
556 zone_is_nonlocal
${zone} && echo "${zone}"
566 while [ $# -gt 0 ]; do
581 if zone_name_is_valid
${1}; then
582 zones
="${zones} ${1}"
584 warning
"Unrecognized argument '${1}'"
591 if [ -n "${zones}" ]; then
593 for zone
in ${zones}; do
594 zone_exists
${zone} && echo "${zone}"
599 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
601 elif [ ${local} -eq 1 ]; then
603 elif [ ${remote} -eq 1 ]; then
612 for port
in $
(zone_dir
${zone})/ports
/*; do
613 [ -e "${port}" ] ||
continue
615 echo $
(basename ${port})
628 # Check if the port actually exists.
629 if ! port_exists
"${port}"; then
630 error
"Cannot attach port '${port}' which does not exist"
634 # Check if the port is already connected to this or any other zone.
636 for z
in $
(zones_get_all
); do
637 if zone_has_port
"${z}" "${port}"; then
638 error
"Port '${port}' is already attached to zone '${z}'"
643 local hook
="$(zone_get_hook "${zone}")"
646 hook_zone_exec
"${hook}" "port_attach" "${zone}" "${port}" "$@"
651 log INFO
"${port} has been attached to ${zone}"
653 # Automatically connect the port
654 zone_port_start
"${zone}" "${port}"
657 log CRITICAL
"${port} could not be attached to ${zone}"
673 # Check if the port actually exists.
674 if ! port_exists
"${port}"; then
675 error
"Port '${port}' does not exist"
679 # Check if the zone actually has this port.
680 if ! zone_has_port
"${zone}" "${port}"; then
681 error
"Port '${port}' is not attached to zone '${zone}'"
685 local hook
=$
(zone_get_hook
"${zone}")
688 hook_zone_exec
"${hook}" "port_edit" "${zone}" "${port}" "$@"
700 # Check if the zone actually has this port.
701 if ! zone_has_port
"${zone}" "${port}"; then
702 error
"Port '${port}' is not attached to zone '${zone}'"
706 local hook
=$
(zone_get_hook
"${zone}")
709 hook_zone_exec
"${hook}" "port_detach" "${zone}" "${port}" "$@"
714 log INFO
"${port} has been detached from ${zone}"
716 # Bring down the port if needed
717 zone_port_stop
"${zone}" "${port}"
720 log CRITICAL
"${port} could not be detached from ${zone}"
739 local hook
="$(zone_get_hook "${zone}")"
742 # Dispatch command to hook
743 hook_zone_exec
"${hook}" "${cmd}" "${zone}" "${port}" $@
747 zone_port_cmd
"port_create" $@
751 zone_port_cmd
"port_remove" $@
755 zone_port_cmd
"port_up" $@
759 zone_port_cmd
"port_down" $@
762 # The next two functions automagically bring up and down
763 # port that are attached to a bridge or similar.
764 # The problem that is tried to overcome here is that there
765 # are ports which exist all the time (like ethernet ports)
766 # and therefore do not dispatch a hotplug event when
767 # port_create is called.
773 if zone_is_active
"${zone}"; then
774 if device_exists
"${port}"; then
775 zone_port_up
"${zone}" "${port}"
778 zone_port_create
"${zone}" "${port}"
790 # Shut down the port if necessary
791 if zone_is_active
"${zone}" && port_is_up
"${port}"; then
792 zone_port_down
"${zone}" "${port}"
796 zone_port_remove
"${zone}" "${port}"
800 zone_port_cmd
"port_status" $@
812 local hook
="$(zone_get_hook "${zone}")"
815 for port
in $
(zone_get_ports
${zone}); do
816 hook_zone_exec
"${hook}" "${cmd}" "${zone}" "${port}" $@
820 zone_ports_create
() {
821 zone_ports_cmd
"port_create" $@
824 zone_ports_remove
() {
825 zone_ports_cmd
"port_remove" $@
829 zone_ports_cmd
"port_up" $@
833 zone_ports_cmd
"port_down" $@
836 zone_ports_status
() {
837 zone_ports_cmd
"port_status" $@
847 assert zone_exists
"${zone}"
850 for config
in $
(zone_configs_list
"${zone}"); do
851 local config_hook
="$(zone_config_get_hook "${zone}" "${config}")"
852 assert isset config_hook
854 hook_config_exec
"${config_hook}" "${cmd}" "${zone}" "${config}" $@
859 zone_configs_cmd
"up" $@
862 zone_configs_down
() {
863 zone_configs_cmd
"down" $@
866 zone_configs_status
() {
867 zone_configs_cmd
"status" $@
870 zone_configs_list
() {
874 for config
in $
(zone_dir
${zone})/configs
/*; do
875 [ -e "${config}" ] ||
continue
881 zone_config_get_hook
() {
891 zone_config_settings_read
"${zone}" "${config}" \
892 --ignore-superfluous-settings HOOK
907 starting|started|stopping|stopped
)
908 db_connection_update
${zone} ${action}
923 zone_get_supported_port_hooks
() {
926 local hook
=$
(zone_get_hook
${zone})
928 hook_zone_ports_get_all
${hook}
931 zone_get_supported_config_hooks
() {
940 echo "$(zone_dir ${zone})/settings"
943 zone_settings_read
() {
949 if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS}" ]; then
950 list_append args
${HOOK_SETTINGS}
955 # Save the HOOK variable.
958 settings_read
"$(zone_file "${zone}")" ${args}
964 zone_settings_write
() {
969 if function_exists
"hook_check_settings"; then
970 list_append args
"--check=\"hook_check_settings\""
972 list_append args
${HOOK_SETTINGS}
974 settings_write
"$(zone_file ${zone})" ${args}
977 zone_settings_set
() {
985 zone_settings_read
${zone}
987 for arg
in ${args}; do
991 zone_settings_write
${zone}
995 zone_settings_get
() {
1003 zone_settings_read
"${zone}" "${key}" \
1004 --ignore-superfluous-settings
1010 zone_config_settings_read
() {
1018 if [ $# -eq 0 ] && [ -n "${HOOK_CONFIG_SETTINGS}" ]; then
1019 list_append args
${HOOK_CONFIG_SETTINGS}
1024 local path
="$(zone_dir "${zone}")/configs/${config}"
1025 settings_read
"${path}" ${args}
1028 zone_config_settings_write
() {
1036 if function_exists
"hook_check_config_settings"; then
1037 list_append args
"--check=\"hook_check_config_settings\""
1039 list_append args
${HOOK_CONFIG_SETTINGS}
1041 local path
="$(zone_dir "${zone}")/configs/${config}"
1042 settings_write
"${path}" ${args}
1045 zone_port_settings_read
() {
1053 if [ $# -eq 0 ] && [ -n "${HOOK_PORT_SETTINGS}" ]; then
1054 list_append args
${HOOK_PORT_SETTINGS}
1059 local path
="$(zone_dir "${zone}")/ports/${port}"
1060 settings_read
"${path}" ${args}
1063 zone_port_settings_write
() {
1071 if function_exists
"hook_check_port_settings"; then
1072 list_append args
"--check=\"hook_check_port_settings\""
1074 list_append args
${HOOK_PORT_SETTINGS}
1076 local path
="$(zone_dir "${zone}")/ports/${port}"
1077 settings_write
"${path}" ${args}
1080 zone_port_settings_remove
() {
1086 local path
="$(zone_dir "${zone}")/ports/${port}"
1087 settings_remove
"${path}"