]> git.ipfire.org Git - people/ms/network.git/blobdiff - src/hooks/zones/bridge
Cleanup code that deletes ports/zones
[people/ms/network.git] / src / hooks / zones / bridge
index 872f4767285535c97f94e5d8bc841131b9e96a0f..38b2b5f885c8aff7f50b0f28841624bf563cf02e 100644 (file)
 
 HOOK_MANPAGE="network-zone-bridge"
 
-HOOK_SETTINGS="HOOK STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE STP_MODE"
+HOOK_SETTINGS="HOOK STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE"
 HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MAC MTU"
 
 HOOK_PORT_SETTINGS="COST PRIORITY"
 
 # Default values
-MAC=$(mac_generate)
+MAC=""
 MTU=1500
 STP="on"
-STP_MODE="rstp"
 STP_FORWARD_DELAY=0
 STP_HELLO=2
 STP_MAXAGE=20
 STP_PRIORITY=512
 
-function hook_check() {
+hook_check_settings() {
        assert ismac MAC
        assert isbool STP
-       assert isoneof STP_MODE stp rstp
        assert isinteger STP_HELLO
        assert isinteger STP_FORWARD_DELAY
        assert isinteger STP_PRIORITY
        assert isinteger MTU
 }
 
-function hook_parse_cmdline() {
+hook_parse_cmdline() {
        while [ $# -gt 0 ]; do
                case "${1}" in
                        --stp=*)
                                STP=${1#--stp=}
                                ;;
-                       --stp-mode=*)
-                               STP_MODE=${1#--stp-mode=}
-                               ;;
                        --stp-hello=*)
                                STP_HELLO=${1#--stp-hello=}
                                ;;
@@ -78,100 +73,144 @@ function hook_parse_cmdline() {
                esac
                shift
        done
+
+       # Generate a random MAC address if the user passed no one
+       isset MAC || MAC="$(mac_generate)"
 }
 
-function hook_up() {
+hook_up() {
        local zone=${1}
        assert isset zone
 
-       zone_config_read ${zone}
+       zone_settings_read "${zone}"
 
        # Create the bridge if it does not already exist.
-       if ! device_exists ${zone}; then
-               bridge_create ${zone} \
-                       --address=${MAC} --mtu=${MTU}
-
-       # Adjust MAC address and MTU if needed.
-       else
-               device_set_address ${zone} ${MAC}
-               device_set_mtu ${zone} ${MTU}
+       if ! device_exists "${zone}"; then
+               bridge_create "${zone}" \
+                       --address="${MAC}" \
+                       --mtu="${MTU}"
        fi
 
        # Enable STP
        if enabled STP; then
-               stp_enable ${zone}
+               stp_enable "${zone}"
 
-               if [ -n "${STP_FORWARD_DELAY}" ]; then
-                       stp_bridge_set_forward_delay ${zone} ${STP_FORWARD_DELAY}
+               if isset STP_FORWARD_DELAY; then
+                       stp_bridge_set_forward_delay "${zone}" "${STP_FORWARD_DELAY}"
                fi
 
-               if [ -n "${STP_HELLO}" ]; then
-                       stp_bridge_set_hello_time ${zone} ${STP_HELLO}
+               if isset STP_HELLO; then
+                       stp_bridge_set_hello_time "${zone}" "${STP_HELLO}"
                fi
 
-               if [ -n "${STP_MAXAGE}" ]; then
-                       stp_bridge_set_max_age ${zone} ${STP_MAXAGE}
+               if isset STP_MAXAGE; then
+                       stp_bridge_set_max_age "${zone}" "${STP_MAXAGE}"
                fi
 
-               if [ -n "${STP_PRIORITY}" ]; then
-                       stp_bridge_set_priority ${zone} ${STP_PRIORITY}
+               if isset STP_PRIORITY; then
+                       stp_bridge_set_priority "${zone}" "${STP_PRIORITY}"
                fi
        else
-               stp_disable ${zone}
+               stp_disable "${zone}"
        fi
 
-       device_set_up ${zone}
+       device_set_up "${zone}"
 
        # XXX Currently, there is a bug (in the linux kernel?) that we need to
        # set our bridges to promisc mode.
-       device_set_promisc ${zone} on
+       device_set_promisc "${zone}" on
 
-       # Bring all ports up
-       zone_ports_up ${zone}
-       zone_configs_up ${zone}
+       # Bring up all configurations
+       zone_configs_up "${zone}"
 
        exit ${EXIT_OK}
 }
 
-function hook_down() {
-       local zone=${1}
+hook_hotplug() {
+       local zone="${1}"
        assert isset zone
 
-       if ! device_is_up ${zone}; then
+       case "$(hotplug_action)" in
+               add)
+                       # Attach all ports when zone is coming up
+                       if hotplug_event_interface_is_zone "${zone}"; then
+                               # Bring up all ports
+                               local port
+                               for port in $(zone_get_ports "${zone}"); do
+                                       log DEBUG "Trying to attach port ${port} to ${zone}"
+
+                                       hook_port_up "${zone}" "${port}"
+                               done
+
+                       # Handle ports of this zone that have just been added
+                       elif hotplug_event_interface_is_port_of_zone "${zone}"; then
+                               # Attach the device if the parent bridge is up
+                               if zone_is_active "${zone}"; then
+                                       hook_port_up "${zone}" "${INTERFACE}"
+                               fi
+                       fi
+                       ;;
+               remove)
+                       if hotplug_event_interface_is_zone "${zone}"; then
+                               # Bring down/destroy all ports
+                               local port
+                               for port in $(zone_get_ports "${zone}"); do
+                                       log DEBUG "Trying to detach port ${port} from ${zone}"
+
+                                       hook_port_down "${zone}" "${port}"
+                               done
+
+                       # Handle ports of this zone that have just been removed
+                       elif hotplug_event_interface_is_port_of_zone "${zone}"; then
+                               hook_port_down "${zone}" "${INTERFACE}"
+                       fi
+                       ;;
+               *)
+                       exit ${EXIT_NOT_HANDLED}
+                       ;;
+       esac
+
+       exit ${EXIT_OK}
+}
+
+hook_down() {
+       local zone="${1}"
+       assert isset zone
+
+       if ! device_is_up "${zone}"; then
                warning "Zone '${zone}' is not up"
                exit ${EXIT_OK}
        fi
 
-       zone_configs_down ${zone}
-       zone_ports_down ${zone}
+       # Stop all the configs.
+       zone_configs_down "${zone}"
 
-       # XXX See remark in _up().
-       device_set_promisc ${zone} off
+       # Bring down all the ports.
+       zone_ports_down "${zone}"
+       zone_ports_remove "${zone}"
 
-       device_set_down ${zone}
-       bridge_delete ${zone}
+       # Remove the bridge.
+       device_set_down "${zone}"
+       bridge_delete "${zone}"
 
        exit ${EXIT_OK}
 }
 
-function hook_status() {
-       local zone=${1}
+hook_status() {
+       local zone="${1}"
        assert isset zone
 
        # Print the default header.
-       cli_device_headline ${zone}
+       cli_device_headline "${zone}"
 
        # Exit if zone is down
-       if ! zone_is_up ${zone}; then
+       if ! zone_is_up "${zone}"; then
                echo # Empty line
                exit ${EXIT_ERROR}
        fi
 
        cli_headline 2 "Spanning Tree Protocol information"
-       if stp_is_enabled ${zone}; then
-               local proto=$(stp_bridge_get_protocol ${zone})
-
-               cli_print_fmt1 2 "Version"      "$(stp_get_name ${proto})"
+       if stp_is_enabled "${zone}"; then
                cli_print_fmt1 2 "ID"           "$(stp_bridge_get_id ${zone})"
                cli_print_fmt1 2 "Priority"     "$(stp_bridge_get_priority ${zone})"
 
@@ -199,33 +238,27 @@ function hook_status() {
        fi
 
        cli_headline 2 "Ports"
-       zone_ports_status ${zone}
+       zone_ports_status "${zone}"
        cli_space
 
        cli_headline 2 "Configurations"
-       zone_configs_cmd status ${zone}
+       zone_configs_cmd status "${zone}"
        cli_space
 
        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
+hook_check_port_settings() {
+       if isset COST; then
+               assert isinteger COST
+       fi
 
-       return ${EXIT_OK}
+       if isset PRIORITY; then
+               assert isinteger PRIORITY
+       fi
 }
 
-function hook_port_add() {
+hook_port_attach() {
        # Excepting at least two arguments here
        assert [ $# -ge 2 ]
 
@@ -233,36 +266,31 @@ function hook_port_add() {
        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}
+       if zone_has_port "${zone}" "${port}"; then
+               zone_port_settings_read "${zone}" "${port}"
+       fi
 
-       config_write "$(zone_dir "${zone}")/ports/${port}" ${HOOK_PORT_SETTINGS}
+       local arg
+       local val
+       while read arg; do
+               case "${arg}" in
+                       --cost=*)
+                               COST="$(cli_get_val "${arg}")"
+                               ;;
+                       --priority=*)
+                               PRIORITY="$(cli_get_val "${arg}")"
+                               ;;
+               esac
+       done <<< "$(args "$@")"
 
-       log INFO "Port '${port}' (member of zone '${zone}') has been edited"
+       if ! zone_port_settings_write "${zone}" "${port}"; then
+               exit ${EXIT_ERROR}
+       fi
 
        exit ${EXIT_OK}
 }
 
-function hook_port_remove() {
+hook_port_detach() {
        assert [ $# -eq 2 ]
 
        local zone="${1}"
@@ -271,44 +299,70 @@ function hook_port_remove() {
        # 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}"
+       if ! zone_port_settings_remove "${zone}" "${port}"; then
+               exit ${EXIT_ERROR}
+       fi
 
        exit ${EXIT_OK}
 }
 
-function hook_port_up() {
+hook_port_edit() {
+       hook_port_attach "$@"
+}
+
+hook_port_up() {
        assert [ $# -eq 2 ]
 
        local zone="${1}"
        local port="${2}"
 
-       port_up "${port}"
+       # Try bringing up the port if it has not been
+       # brought up before.
+       # We will get here as soon as the port device has
+       # been created and will then connect it with the bridge.
+       if ! device_exists "${port}"; then
+               port_create "${port}"
+
+               return ${EXIT_OK}
+       fi
+
+       # Read configuration values
+       zone_port_settings_read "${zone}" "${port}" ${HOOK_PORT_SETTINGS}
 
-       # Set same MTU to device that the bridge has got
-       device_set_mtu "${port}" $(device_get_mtu "${zone}")
+       # Make sure that the port is up
+       port_up "${port}"
 
+       # Attach the port to the bridge
        bridge_attach_device "${zone}" "${port}"
 
-       # XXX must set cost and prio here
+       # Set STP configuration
+       if isset COST; then
+               stp_port_set_cost "${zone}" "${port}" "${COST}"
+       fi
+
+       if isset PRIORITY; then
+               stp_port_set_priority "${zone}" "${port}" "${PRIORITY}"
+       fi
 
-       exit ${EXIT_OK}
+       return ${EXIT_OK}
 }
 
-function hook_port_down() {
+hook_port_down() {
        assert [ $# -eq 2 ]
 
        local zone="${1}"
        local port="${2}"
 
-       bridge_detach_device "${zone}" "${port}"
+       if device_exists "${port}"; then
+               bridge_detach_device "${zone}" "${port}"
 
-       port_down "${port}"
+               port_down "${port}"
+       fi
 
-       exit ${EXIT_OK}
+       return ${EXIT_OK}
 }
 
-function hook_port_status() {
+hook_port_status() {
        assert [ $# -eq 2 ]
 
        local zone="${1}"