]> git.ipfire.org Git - people/ms/network.git/commitdiff
Introduce triggers
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 13 Aug 2015 09:02:58 +0000 (11:02 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 13 Aug 2015 09:02:58 +0000 (11:02 +0200)
When the state of the network changes (i.e. a zone comes up, etc.)
a set of triggers will be called so that external applications can
adopt to these changes.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/functions/functions.constants
src/functions/functions.in
src/functions/functions.routing
src/functions/functions.triggers [new file with mode: 0644]
src/functions/functions.util
src/functions/functions.zone

index 2bb27e2f28cf55d11a892310e97d93d953cff8b0..9d8577480c74e2a12558a69897707094c081c276 100644 (file)
@@ -46,6 +46,8 @@ hooks_configsdir = $(hooksdir)/configs
 hooks_portsdir   = $(hooksdir)/ports
 hooks_zonesdir   = $(hooksdir)/zones
 
+triggersdir      = $(networkdir)/triggers
+
 CLEANFILES =
 DISTCLEANFILES =
 EXTRA_DIST =
@@ -145,6 +147,7 @@ dist_network_SCRIPTS = \
        src/functions/functions.settings \
        src/functions/functions.stp \
        src/functions/functions.sysctl \
+       src/functions/functions.triggers \
        src/functions/functions.usb \
        src/functions/functions.util \
        src/functions/functions.vlan \
@@ -309,6 +312,11 @@ dist_macros_DATA = \
 
 # ------------------------------------------------------------------------------
 
+INSTALL_DIRS = \
+       $(triggersdir)
+
+# ------------------------------------------------------------------------------
+
 MANPAGES = \
        man/firewall-settings.8 \
        man/network.8 \
index eb7fe7d4bfbe5ffa9a7aca033bf12038ded400ef..abf7812ec4585df9f34e42c1c8ff4dbcbf25c488 100644 (file)
@@ -33,6 +33,7 @@ NETWORK_CONFIG_DIR="/etc/network"
 NETWORK_DB_DIR="${RUN_DIR}/db"
 NETWORK_ZONE_DIR="${NETWORK_CONFIG_DIR}"
 NETWORK_HOOKS_DIR=/usr/lib/network/hooks
+NETWORK_TRIGGERS_DIR=/usr/lib/network/triggers
 
 # Network file configuration.
 NETWORK_SETTINGS_FILE=${NETWORK_CONFIG_DIR}/config
index 873b6beacab5a7e5e00f811a781a5c4eb8e1d41b..ba0f95e66c32e39da9c4d967ea91d693b4c7ab09 100644 (file)
@@ -34,6 +34,9 @@ init_run() {
        for init in ${INIT_FUNCTIONS}; do
                ${init}
        done
+
+       # Also execute all triggers
+       triggers_execute_all "init"
 }
 
 VERSION="@PACKAGE_VERSION@"
index 5bfbea0194e812b4c416f63adf54371a0563cc95..66346107c167f91d1d22428330c474910bc8b220 100644 (file)
@@ -81,18 +81,15 @@ routing_default_update() {
                routes=$(echo ${routes})
 
                # Remove all default routes.
-               while ${cmd} | grep -q "^default"; do
-                       ${cmd} del default
-               done
-
                if [ -z "${routes}" ]; then
+                       cmd ${cmd} del default
                        log INFO "Removed default route for ${proto}."
                        return ${EXIT_OK}
                fi
 
                log INFO "Setting default route for ${proto}: ${routes}"
 
-               cmd ${cmd} add default ${routes}
+               cmd ${cmd} replace default ${routes}
                assert [ $? -eq 0 ]
 
                case "${proto}" in
@@ -101,6 +98,8 @@ routing_default_update() {
                                radvd_update
                                ;;
                esac
+
+               triggers_execute_all "online"
        done
 }
 
diff --git a/src/functions/functions.triggers b/src/functions/functions.triggers
new file mode 100644 (file)
index 0000000..28a1396
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2015  IPFire Network Development Team                         #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+TRIGGER_ACTIONS="init up down online"
+
+trigger_execute() {
+       local trigger="$1"
+       shift
+
+       local environment=$@
+
+       if [ ! -x "${trigger}" ]; then
+               log WARNING "Trigger is not executable: ${trigger}"
+               return ${EXIT_ERROR}
+       fi
+
+       log DEBUG "Executing trigger ${trigger}..."
+       cmd_clean_environment ${environment} "${trigger}" &>/dev/null
+       local ret=${?}
+
+       if [ ${ret} -ne ${EXIT_OK} ]; then
+               log WARNING "Trigger ${trigger} exited with exit code: ${ret}"
+               log WARNING "  Environment: ${environment}"
+       fi
+
+       return ${ret}
+}
+
+triggers_execute_all() {
+       local action="${1}"
+       shift
+
+       # Check if the action is valid
+       assert list_match "${action}" ${TRIGGER_ACTIONS}
+
+       local environment=$@
+
+       # Check if the directory exists
+       [ -d "${NETWORK_TRIGGERS_DIR}" ] || return ${EXIT_ERROR}
+
+       local trigger
+       for trigger in ${NETWORK_TRIGGERS_DIR}/*; do
+               # Check if the trigger can be executed
+               if [ ! -x "${trigger}" ]; then
+                       log DEBUG "Trigger is not executable: ${trigger}"
+                       continue
+               fi
+
+               # Execute the trigger
+               trigger_execute "${trigger}" ${environment} ACTION="${action}"
+       done
+
+       return ${EXIT_OK}
+}
index d26f519f4a43e0b1d348c9b395437d8554a8f891..fdb2ce47b395df150d97096b1b7f091f44afe05c 100644 (file)
@@ -363,6 +363,19 @@ cmd_not_implemented() {
        assert false "not implemented"
 }
 
+# Runs a command in a clean environment so that no confidential information
+# is leaked to any untrusted commands.
+cmd_clean_environment() {
+       local cmd=$@
+
+       log DEBUG "Running command in a clean environment: ${cmd}"
+       env -i -- ${cmd}
+       local ret=${?}
+
+       log DEBUG "Returned with code '${ret}'"
+       return ${ret}
+}
+
 # Increase security of the read command
 read() {
        builtin read -r $@
index a41585a9fbde9cded4c0b27e3347b340a99b962b..c46cae94efedcd3941337cd91f45e52312c86f16 100644 (file)
@@ -351,6 +351,9 @@ zone_up() {
        hook_zone_exec ${hook} up ${zone} $@
 
        zone_db ${zone} started
+
+       # Execute all triggers after the zone got up
+       triggers_execute_all "up" ZONE="${zone}"
 }
 
 zone_down() {
@@ -379,6 +382,9 @@ zone_down() {
 
        zone_db ${zone} stopped
 
+       # Execute all triggers after the zone went down
+       triggers_execute_all "down" ZONE="${zone}"
+
        # Remove the zone, if it has got a remove tag.
        if zone_has_destroy_tag "${zone}"; then
                zone_destroy_now "${zone}"