]> git.ipfire.org Git - people/ms/network.git/blobdiff - src/hooks/ports/bonding
hooks: Automatically set defaults for all port hooks
[people/ms/network.git] / src / hooks / ports / bonding
index 817f6d0e0020196e32541cc7e1bc6fb4f68efefb..f0572c3f5b496f45b3df8b33d55549bf412ae34b 100644 (file)
 
 . /usr/lib/network/header-port
 
-HOOK_SETTINGS="HOOK ADDRESS MIIMON MODE SLAVES"
+HOOK_SETTINGS="ADDRESS MIIMON MODE OFFLOADING SLAVES"
 
-ADDRESS=$(mac_generate)
-SLAVES=""
-MIIMON=100
-MODE="balance-rr"
+DEFAULT_MIIMON=100
+DEFAULT_MODE="balance-rr"
 
-function hook_check() {
+hook_check_settings() {
        assert isset ADDRESS
        assert ismac ADDRESS
 
@@ -36,29 +34,54 @@ function hook_check() {
        assert isinteger MIIMON
 }
 
-function hook_new() {
-       hook_edit $@
-}
-
-function hook_edit() {
-       local port=${1}
-       assert isset port
-       shift
-
+hook_parse_cmdline() {
        while [ $# -gt 0 ]; do
                case "${1}" in
                        --address=*)
-                               ADDRESS=$(cli_get_val ${1})
+                               ADDRESS="$(cli_get_val "${1}")"
+
+                               if ! mac_is_valid "${ADDRESS}"; then
+                                       error "Invalid MAC address: ${ADDRESS}"
+                                       return ${EXIT_ERROR}
+                               fi
                                ;;
+
                        --miimon=*)
-                               MIIMON=$(cli_get_val ${1})
+                               MIIMON=$(cli_get_val "${1}")
                                ;;
                        --mode=*)
-                               MODE=$(cli_get_val ${1})
+                               MODE=$(cli_get_val "${1}")
+                               ;;
+                       --offloading=*)
+                               OFFLOADING="$(cli_get_val "${1}")"
+
+                               if enabled OFFLOADING; then
+                                       OFFLOADING="on"
+                               elif disabled OFFLOADING; then
+                                       OFFLOADING="off"
+                               else
+                                       error "Invalid value for offloading: ${OFFLOADING}"
+                                       return ${EXIT_ERROR}
+                               fi
                                ;;
-                       --slave=*)
-                               slave=$(cli_get_val ${1})
-                               SLAVES="${SLAVES} ${slave}"
+                       +*)
+                               local slave=$(cli_get_val "${1:1}")
+
+                               if port_exists "${slave}"; then
+                                       if list_match "${slave}" ${SLAVES}; then
+                                               warning "Port ${slave} is already enslaved"
+                                       else
+                                               list_append SLAVES "${slave}"
+                                       fi
+                               else
+                                       warning "Port ${slave} does not exist"
+                               fi
+                               ;;
+                       -*)
+                               local slave=$(cli_get_val "${1:1}")
+                               if ! list_remove SLAVES "${slave}"; then
+                                       warning "Port ${slave} is not a slave of this bonding device"
+                               fi
                                ;;
                        *)
                                warning "Unknown argument '${1}'"
@@ -67,36 +90,72 @@ function hook_edit() {
                shift
        done
 
-       DEVICE=${port}
+       if isset ADDRESS; then
+               if ! ismac ADDRESS; then
+                       error "The given MAC address is invalid: ${ADDRESS}"
+                       return ${EXIT_ERROR}
+               fi
+       else
+               ADDRESS=$(mac_generate)
+       fi
+}
+
+hook_new() {
+       if ! hook_parse_cmdline "$@"; then
+               return ${EXIT_ERROR}
+       fi
+
+       # Find a new name
+       local port=$(port_find_free ${BONDING_PORT_PATTERN})
+       assert isset port
 
-       # XXX think this must move to _check()
-       if ! isset DEVICE; then
-               error "You must set a device name."
-               exit ${EXIT_ERROR}
+       # Save configuration
+       if port_settings_write "${port}" ${HOOK_SETTINGS}; then
+               log INFO "New port ${port} has been created"
+       else
+               error "Could not save configuration for ${port}"
+               return ${EXIT_ERROR}
        fi
 
-       if ! isset SLAVES; then
-               error "You need to specify at least one slave port (e.g. --slave=port0)."
-               exit ${EXIT_ERROR}
+       return ${EXIT_OK}
+}
+
+hook_edit() {
+       local port=${1}
+
+       if ! hook_default_edit "$@"; then
+               return ${EXIT_ERROR}
        fi
 
-       local slave
-       for slave in $(unquote ${SLAVES}); do
-               if ! device_is_ethernet ${slave}; then
-                       error "Slave device '${slave}' is not an ethernet device."
-                       exit ${EXIT_ERROR}
+       # If the master device is up, make sure that all
+       # slaves are up, too
+       if device_exists "${port}"; then
+               # Setting the mode requires us to destroy the device
+               # and to recreate it again.
+               local mode=$(bonding_get_mode "${port}")
+               if [ "${mode}" != "${MODE}" ]; then
+                       port_restart "${port}"
+                       return ${EXIT_OK}
                fi
-       done
 
-       # Remove any whitespace
-       SLAVES=$(echo ${SLAVES})
+               # Set address
+               device_set_address "${port}" "${ADDRESS}"
 
-       port_settings_write "${port}" ${HOOK_SETTINGS}
+               # Set miimon
+               bonding_set_miimon "${port}" "${MIIMON}"
 
-       exit ${EXIT_OK}
+               local slave
+               for slave in ${SLAVES}; do
+                       if device_exists "${slave}"; then
+                               bonding_enslave_device "${port}" "${slave}"
+                       else
+                               port_create "${slave}"
+                       fi
+               done
+       fi
 }
 
-function hook_create() {
+hook_create() {
        local port="${1}"
        assert isset port
 
@@ -115,7 +174,7 @@ function hook_create() {
        exit ${EXIT_OK}
 }
 
-function hook_remove() {
+hook_remove() {
        local port="${1}"
        assert isset port
 
@@ -127,12 +186,19 @@ function hook_remove() {
        fi
 }
 
-function hook_up() {
+hook_up() {
        local port="${1}"
        assert isset port
 
        port_settings_read "${port}" ${HOOK_SETTINGS}
 
+       # Auto-enable or disable hardware offloading
+       if ! isset OFFLOADING || enabled OFFLOADING; then
+               offloading_auto "${port}"
+       else
+               offloading_disable_all "${port}"
+       fi
+
        # Execute the default action
        hook_default_up "${port}"
 
@@ -143,7 +209,7 @@ function hook_up() {
        done
 }
 
-function hook_down() {
+hook_down() {
        local port="${1}"
        assert isset port
 
@@ -159,7 +225,7 @@ function hook_down() {
        hook_default_down "${port}"
 }
 
-function hook_hotplug() {
+hook_hotplug() {
        local port="${1}"
        assert isset port