From: Michael Tremer Date: Sun, 31 Aug 2014 15:04:38 +0000 (+0200) Subject: Remove port hooks as subhooks for zones. X-Git-Tag: 007~102 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=828eb94a9973f64c459a1e3c704cfc5d21c8d96a;p=network.git Remove port hooks as subhooks for zones. All port hooks handle ethernet-like devices which doesn't make it necessary to duplicate them over and over again. --- diff --git a/src/functions/functions.config b/src/functions/functions.config index 3854742e..a625c0fd 100644 --- a/src/functions/functions.config +++ b/src/functions/functions.config @@ -132,6 +132,18 @@ function config_write() { done } +function config_remove() { + local config_file="${1}" + + local abspath="$(readlink -e "${config_file}")" + if [ "${config_file}" != "${abspath}" ]; then + log ERROR "Can only handle absolute paths" + return ${EXIT_ERROR} + fi + + rm -f "${config_file}" +} + function config_print() { local param diff --git a/src/functions/functions.constants b/src/functions/functions.constants index 01848841..3f570ea5 100644 --- a/src/functions/functions.constants +++ b/src/functions/functions.constants @@ -51,6 +51,7 @@ NETWORK_CONFIG_ROUTES_PARAMS="network gateway unreachable prohibit blackhole mtu EXIT_OK=0 EXIT_ERROR=1 EXIT_CONF_ERROR=2 +EXIT_NOT_SUPPORTED=3 EXIT_COMMAND_NOT_FOUND=127 EXIT_ERROR_ASSERT=128 diff --git a/src/functions/functions.hook b/src/functions/functions.hook index 4b1e1106..bebe99d0 100644 --- a/src/functions/functions.hook +++ b/src/functions/functions.hook @@ -111,8 +111,9 @@ function hook_exec() { local ret=$? case "${ret}" in - ${EXIT_COMMAND_NOT_FOUND}) - log ERROR "Hook command not implemented: ${hook_command} ($@)" + ${EXIT_COMMAND_NOT_FOUND}|${EXIT_NOT_SUPPORTED}) + log ERROR "Hook '${hook}' does not implement the method '${cmd}':" + log ERROR " arguments: $@" exit ${EXIT_COMMAND_NOT_FOUND} ;; ${EXIT_ERROR_ASSERT}) @@ -140,13 +141,6 @@ function hook_zone_exists() { hook_exists zone $@ } -function hook_zone_port_exists() { - local hook_zone=${1} - local hook_port=${2} - - hook_exists zone "${hook_zone}.ports/${hook_port}" -} - function hook_zone_config_exists() { local hook_zone=${1} local hook_config=${2} @@ -154,12 +148,6 @@ function hook_zone_config_exists() { hook_exists zone "${hook_zone}.configs/${hook_config}" } -function hook_zone_has_ports() { - local hook=${1} - - [ -d "${NETWORK_HOOKS_DIR_ZONES}/${hook}.ports" ] -} - function hook_zone_has_configs() { local hook=${1} @@ -170,14 +158,6 @@ function hook_zone_exec() { hook_exec zone $@ } -function hook_zone_port_exec() { - local hook_zone=${1} - local hook_port=${2} - shift 2 - - hook_zone_exec "${hook_zone}.ports/${hook_port}" $@ -} - function hook_zone_config_exec() { local hook_zone=${1} local hook_port=${2} @@ -196,28 +176,6 @@ function hook_zone_get_all() { done } -function hook_zone_ports_get_all() { - local hook=${1} - - if ! hook_exists zone ${hook}; then - error "Hook '${hook}' does not exist." - return ${EXIT_ERROR} - fi - - # If the zone hook has got no ports we exit silently - if ! hook_zone_has_ports ${hook}; then - return ${EXIT_OK} - fi - - local h - for h in $(hook_dir zone)/${hook}.ports/*; do - h=$(basename ${h}) - if hook_zone_port_exists ${hook} ${h}; then - echo "${h}" - fi - done -} - function hook_zone_configs_get_all() { local hook=${1} diff --git a/src/functions/functions.zone b/src/functions/functions.zone index b18d4548..75ee70eb 100644 --- a/src/functions/functions.zone +++ b/src/functions/functions.zone @@ -353,15 +353,8 @@ function zone_port() { assert isset action assert zone_exists ${zone} - # Aliases - case "${action}" in - del|delete|remove) - action="rem" - ;; - esac - case "${action}" in - add|edit|rem) + add|edit|remove) zone_port_${action} ${zone} $@ ;; *) @@ -373,50 +366,81 @@ function zone_port() { } function zone_port_add() { - local zone=${1} - shift - + local zone="${1}" assert isset zone - local hook=$(zone_get_hook ${zone}) + local port="${2}" + assert isset port + + shift 2 + + # Check if the port actually exists. + if ! port_exists "${port}"; then + error "Cannot add port '${port}' which does not exist" + return ${EXIT_ERROR} + fi + # Check if the port is already connected to this or any other zone. + local z + for z in $(zones_get_all); do + if zone_has_port "${z}" "${port}"; then + error "Port '${port}' is already assigned to zone '${z}'" + return ${EXIT_ERROR} + fi + done + + local hook=$(zone_get_hook "${zone}") assert isset hook - hook_zone_exec ${hook} port_add ${zone} $@ + hook_zone_exec "${hook}" "port_add" "${zone}" "${port}" "$@" } function zone_port_edit() { - zone_port_cmd edit $@ -} + local zone="${1}" + assert isset zone -function zone_port_rem() { - zone_port_cmd rem $@ -} + local port="${2}" + assert isset port -function zone_port_cmd() { - local cmd=${1} - local zone=${2} - local port=${3} - shift 3 + shift 2 - assert isset zone - assert isset port + # Check if the port actually exists. + if ! port_exists "${port}"; then + error "Port '${port}' does not exist" + return ${EXIT_ERROR} + fi - local hook_zone=$(zone_get_hook ${zone}) - local hook_port=$(port_get_hook ${port}) + # Check if the zone actually has this port. + if ! zone_has_port "${zone}" "${port}"; then + error "Port '${port}' is not attached to zone '${zone}'" + return ${EXIT_ERROR} + fi - assert isset hook_zone - assert isset hook_port + local hook=$(zone_get_hook "${zone}") + assert isset hook - hook_zone_port_exec ${hook_zone} ${hook_port} ${cmd} ${zone} ${port} $@ + hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@" } -function zone_port_up() { - zone_port_cmd up $@ -} +function zone_port_remove() { + local zone="${1}" + assert isset zone + + local port="${2}" + assert isset port + + shift 2 + + # Check if the zone actually has this port. + if ! zone_has_port "${zone}" "${port}"; then + error "Port '${port}' is not attached to zone '${zone}'" + return ${EXIT_ERROR} + fi + + local hook=$(zone_get_hook "${zone}") + assert isset hook -function zone_port_down() { - zone_port_cmd down $@ + hook_zone_exec "${hook}" "port_remove" "${zone}" "${port}" "$@" } function zone_get_ports() { diff --git a/src/header-zone b/src/header-zone index fe556717..eaebd1b6 100644 --- a/src/header-zone +++ b/src/header-zone @@ -108,15 +108,15 @@ function hook_port() { } function hook_port_add() { - hook_port_cmd add "$@" + return ${EXIT_NOT_SUPPORTED} } function hook_port_edit() { - hook_port_cmd edit "$@" + return ${EXIT_NOT_SUPPORTED} } -function hook_port_rem() { - hook_port_cmd remove "$@" +function hook_port_remove() { + return ${EXIT_NOT_SUPPORTED} } function hook_port_show() { @@ -124,42 +124,15 @@ function hook_port_show() { } function hook_port_status() { - hook_port_cmd status "$@" -} - -function hook_port_cmd() { - local cmd="${1}" - assert isset cmd - - local zone="${2}" - assert isset zone - - local port="${3}" - assert isset port - - shift 3 - - local hook_zone="$(zone_get_hook ${zone})" - assert isset hook_zone - - local hook_port="$(port_get_hook ${port})" - assert isset hook_port - - if ! listmatch "${hook_port}" $(zone_get_supported_port_hooks ${zone}); then - log ERROR "Zone '${zone}' does not support port of type '${hook_port}'." - exit ${EXIT_ERROR} - fi - - hook_zone_port_exec "${hook_zone}" "${hook_port}" "${cmd}" "${zone}" "${port}" "$@" - exit $? + return ${EXIT_NOT_SUPPORTED} } function hook_port_up() { - hook_port_cmd up "$@" + cmd_not_implemented } function hook_port_down() { - hook_port_cmd down "$@" + cmd_not_implemented } function hook_config() { diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge index a534871b..872f4767 100644 --- a/src/hooks/zones/bridge +++ b/src/hooks/zones/bridge @@ -26,6 +26,8 @@ HOOK_MANPAGE="network-zone-bridge" HOOK_SETTINGS="HOOK STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE STP_MODE" HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MAC MTU" +HOOK_PORT_SETTINGS="COST PRIORITY" + # Default values MAC=$(mac_generate) MTU=1500 @@ -206,3 +208,137 @@ function hook_status() { exit ${EXIT_OK} } + +function __parse_cmdline_args() { + while [ $# -gt 0 ]; do + case "${1}" in + --priority=*) + PRIORITY="$(cli_get_val ${1})" + ;; + --cost=*) + COST="$(cli_get_val ${1})" + ;; + esac + shift + done + + return ${EXIT_OK} +} + +function hook_port_add() { + # Excepting at least two arguments here + assert [ $# -ge 2 ] + + local zone="${1}" + local port="${2}" + shift 2 + + __parse_cmdline_args "$@" + [ $? -eq ${EXIT_OK} ] || return ${EXIT_ERROR} + + config_write "$(zone_dir "${zone}")/ports/${port}" ${HOOK_PORT_SETTINGS} + + log INFO "Port '${port}' has been added to zone '${zone}'" + + exit ${EXIT_OK} +} + +function hook_port_edit() { + assert [ $# -ge 2 ] + + local zone="${1}" + local port="${2}" + shift 2 + + config_read "$(zone_dir "${zone}")/ports/${port}" ${HOOK_PORT_SETTINGS} + + __parse_cmdline_args "$@" + [ $? -eq ${EXIT_OK} ] || return ${EXIT_ERROR} + + config_write "$(zone_dir "${zone}")/ports/${port}" ${HOOK_PORT_SETTINGS} + + log INFO "Port '${port}' (member of zone '${zone}') has been edited" + + exit ${EXIT_OK} +} + +function hook_port_remove() { + assert [ $# -eq 2 ] + + local zone="${1}" + local port="${2}" + + # Shut down the port (if possible) + port_down "${port}" + + log INFO "Port '${port}' has been removed from zone '${zone}'" + config_remove "$(zone_dir "${zone}")/ports/${port}" + + exit ${EXIT_OK} +} + +function hook_port_up() { + assert [ $# -eq 2 ] + + local zone="${1}" + local port="${2}" + + port_up "${port}" + + # Set same MTU to device that the bridge has got + device_set_mtu "${port}" $(device_get_mtu "${zone}") + + bridge_attach_device "${zone}" "${port}" + + # XXX must set cost and prio here + + exit ${EXIT_OK} +} + +function hook_port_down() { + assert [ $# -eq 2 ] + + local zone="${1}" + local port="${2}" + + bridge_detach_device "${zone}" "${port}" + + port_down "${port}" + + exit ${EXIT_OK} +} + +function hook_port_status() { + assert [ $# -eq 2 ] + + local zone="${1}" + local port="${2}" + + # Do nothing for devices which are not up and running. + device_exists "${port}" || exit ${EXIT_OK} + + local status + + # Check if the device is down. + if ! device_is_up "${port}"; then + status="${MSG_DEVICE_STATUS_DOWN}" + + # Check if the device has no carrier. + elif ! device_has_carrier "${port}"; then + status="${MSG_DEVICE_STATUS_NOCARRIER}" + + # Check for STP information. + elif stp_is_enabled "${zone}"; then + local state="$(stp_port_get_state "${zone}" "${port}")" + state="MSG_STP_${state}" + status="${!state}" + + status="${status} - DSR: $(stp_port_get_designated_root "${zone}" "${port}")" + status="${status} - Cost: $(stp_port_get_cost "${zone}" "${port}")" + else + status="${MSG_DEVICE_STATUS_UP}" + fi + cli_statusline 3 "${port}" "${status}" + + exit ${EXIT_OK} +} diff --git a/src/hooks/zones/bridge.ports/batman-adv b/src/hooks/zones/bridge.ports/batman-adv deleted file mode 120000 index 3857774a..00000000 --- a/src/hooks/zones/bridge.ports/batman-adv +++ /dev/null @@ -1 +0,0 @@ -ethernet \ No newline at end of file diff --git a/src/hooks/zones/bridge.ports/bonding b/src/hooks/zones/bridge.ports/bonding deleted file mode 120000 index 3857774a..00000000 --- a/src/hooks/zones/bridge.ports/bonding +++ /dev/null @@ -1 +0,0 @@ -ethernet \ No newline at end of file diff --git a/src/hooks/zones/bridge.ports/dummy b/src/hooks/zones/bridge.ports/dummy deleted file mode 120000 index 3857774a..00000000 --- a/src/hooks/zones/bridge.ports/dummy +++ /dev/null @@ -1 +0,0 @@ -ethernet \ No newline at end of file diff --git a/src/hooks/zones/bridge.ports/ethernet b/src/hooks/zones/bridge.ports/ethernet deleted file mode 100644 index 1b7d92b1..00000000 --- a/src/hooks/zones/bridge.ports/ethernet +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/bash -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2010 Michael Tremer & Christian Schmidt # -# # -# 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 . # -# # -############################################################################### - -. /usr/lib/network/header-port - -HOOK_SETTINGS="COST PRIORITY" - -function hook_check() { - local i - for i in COST PRIORITY; do - if isset ${i}; then - assert isinteger ${i} - fi - done -} - -function hook_add() { - local zone=${1} - local port=${2} - shift 2 - - assert isset zone - assert isset port - - if ! port_exists ${port}; then - error "Port '${port}' does not exist." - exit ${EXIT_ERROR} - fi - - config_read $(zone_dir ${zone})/ports/${port} - - while [ $# -gt 0 ]; do - case "${1}" in - --priority=*) - PRIORITY=${1#--priority=} - ;; - --cost=*) - COST=${1#--cost=} - ;; - esac - shift - done - - config_write $(zone_dir ${zone})/ports/${port} ${HOOK_SETTINGS} - - exit ${EXIT_OK} -} - -function hook_edit() { - hook_add $@ -} - -function hook_remove() { - local zone=${1} - local port=${2} - - assert isset zone - assert isset port - - assert zone_exists ${zone} - - if ! listmatch ${port} $(zone_get_ports ${zone}); then - error "Port '${port}' does not belong to '${zone}'." - error "Won't remove anything." - exit ${EXIT_ERROR} - fi - - if port_exists ${port}; then - ( _down ${zone} ${port} ) - fi - - rm -f $(zone_dir ${zone})/ports/${port} - - exit ${EXIT_OK} -} - -function hook_up() { - local zone=${1} - local port=${2} - - assert isset zone - assert isset port - - assert zone_exists ${zone} - assert port_exists ${port} - - port_up ${port} - - # Set same MTU to device that the bridge has got - device_set_mtu ${port} $(device_get_mtu ${zone}) - - bridge_attach_device ${zone} ${port} - - # XXX must set cost and prio here - - exit ${EXIT_OK} -} - -function hook_down() { - local zone=${1} - local port=${2} - - assert isset zone - assert isset port - - assert zone_exists ${zone} - assert port_exists ${port} - - bridge_detach_device ${zone} ${port} - - port_down ${port} - - exit ${EXIT_OK} -} - -function hook_status() { - local zone=${1} - local port=${2} - - # Do nothing for devices which are not up and running. - device_exists ${port} || exit ${EXIT_OK} - - local status - - # Check if the device is down. - if ! device_is_up ${port}; then - status=${MSG_DEVICE_STATUS_DOWN} - - # Check if the device has no carrier. - elif ! device_has_carrier ${port}; then - status=${MSG_DEVICE_STATUS_NOCARRIER} - - # Check for STP information. - elif stp_is_enabled ${zone}; then - local state=$(stp_port_get_state ${zone} ${port}) - state="MSG_STP_${state}" - status="${!state}" - - status="${status} - DSR: $(stp_port_get_designated_root ${zone} ${port})" - status="${status} - Cost: $(stp_port_get_cost ${zone} ${port})" - else - status=${MSG_DEVICE_STATUS_UP} - fi - cli_statusline 3 "${port}" "${status}" - - exit ${EXIT_OK} -} diff --git a/src/hooks/zones/bridge.ports/macvlan b/src/hooks/zones/bridge.ports/macvlan deleted file mode 120000 index 3857774a..00000000 --- a/src/hooks/zones/bridge.ports/macvlan +++ /dev/null @@ -1 +0,0 @@ -ethernet \ No newline at end of file diff --git a/src/hooks/zones/bridge.ports/vlan b/src/hooks/zones/bridge.ports/vlan deleted file mode 120000 index 3857774a..00000000 --- a/src/hooks/zones/bridge.ports/vlan +++ /dev/null @@ -1 +0,0 @@ -ethernet \ No newline at end of file diff --git a/src/hooks/zones/bridge.ports/wireless-ap b/src/hooks/zones/bridge.ports/wireless-ap deleted file mode 120000 index 3857774a..00000000 --- a/src/hooks/zones/bridge.ports/wireless-ap +++ /dev/null @@ -1 +0,0 @@ -ethernet \ No newline at end of file