]> git.ipfire.org Git - people/ms/network.git/commitdiff
bonding: Update bonding drivers.
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 8 Oct 2012 12:49:14 +0000 (12:49 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 8 Oct 2012 12:49:14 +0000 (12:49 +0000)
Nothing new. Just the old stuff reloaded and twice
as awesome.

functions.bonding
functions.cli
hooks/ports/bonding

index 87ce5d76124ab73653f71b4b0a3e15114e8e1a0c..247d37caa15d0f64f80a9196eef773f6b77a75a6 100644 (file)
 #                                                                             #
 ###############################################################################
 
+BONDING_ALLOWED_MODES="balance-rr active-backup balance-xor broadcast 802.3ad \
+       balance-tlb balance-alb"
+BONDING_MASTERS="/sys/class/net/bonding_masters"
+
 function bonding_init() {
        if ! grep -q "^bonding" /proc/modules; then
                modprobe bonding
@@ -29,112 +33,201 @@ function bonding_init() {
 
 function bonding_create() {
        local device=${1}
-       local mac=${2}
+       assert isset device
+       shift
+
+       local address
+       local mode="balance-rr"
+
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --address=*)
+                               address=$(cli_get_val ${1})
+                               ;;
+                       --mode=*)
+                               mode=$(cli_get_val ${1})
+                               ;;
+                       *)
+                               error "Unrecognized argument: ${1}"
+                               return ${EXIT_ERROR}
+                               ;;
+               esac
+               shift
+       done
 
-       [ -z "${mac}" ] && mac=$(mac_generate)
+       if isset address; then
+               if ! ismac address; then
+                       log ERROR "Invalid mac address: ${address}"
+                       return ${EXIT_ERROR}
+               fi
+       fi
+
+       if ! list_match "${mode}" ${BONDING_ALLOWED_MODES}; then
+               log ERROR "Bonding mode is not supported: ${mode}"
+               log ERROR "Valid modes are: ${BONDING_ALLOWED_MODES}"
+               return ${EXIT_ERROR}
+       fi
 
        # Initialize the bonding driver just
        # when we need it.
        bonding_init
 
-       log INFO "Creating bonding device '${device}' (${mac})."
+       # Create the bonding device.
+       print "+${device}" > ${BONDING_MASTERS}
+       local ret=$?
 
-       echo "+${device}" > /sys/class/net/bonding_masters
-       device_set_address ${device} ${mac}
+       if [ ${ret} -eq ${EXIT_OK} ]; then
+               log DEBUG "Successfully created bonding device '${device}'"
+       else
+               log ERROR "Could not create bonding device '${device}'"
+               return ${EXIT_ERROR}
+       fi
+
+       # Set the mode of the bonding device.
+       print "${mode}" > ${SYS_CLASS_NET}/${device}/bonding/mode
+       local ret=$?
+
+       if [ ${ret} -ne ${EXIT_OK} ]; then
+               log ERROR "Could not set mode of bonding device '${device}': ${Mmode}"
+               return ${EXIT_ERROR}
+       fi
+
+       if isset address; then
+               device_set_address ${device} ${address}
+       fi
+
+       return ${EXIT_OK}
 }
 
 function bonding_remove() {
        local device=${1}
        assert isset device
 
-       log INFO "Remove bonding device '${device}'."
+       if ! device_exists ${device}; then
+               return ${EXIT_ERROR}
+       fi
 
+       # Set device down if not already done.
        device_set_down ${device}
-       echo "-${device}" > /sys/class/net/bonding_masters
-}
 
-function bonding_set_mode() {
-       local device=${1}
-       local mode=${2}
+       # Remove the device.
+       print "-${device}" > ${BONDING_MASTERS}
+       local ret=$?
 
-       log INFO "Setting bonding mode on '${device}' '${mode}'."
+       if [ ${ret} -eq ${EXIT_OK} ]; then
+               log DEBUG "Successfully removed bonding device '${device}'"
+       else
+               log ERROR "Could not remove bonding device '${device}'"
+               return ${EXIT_ERROR}
+       fi
 
-       echo "${mode}" > /sys/class/net/${device}/bonding/mode
+       return ${EXIT_OK}
 }
 
 function bonding_get_mode() {
        local device=${1}
+       assert isset device
 
        local mode mode_num
        read mode mode_num < ${SYS_CLASS_NET}/${device}/bonding/mode
-       echo "${mode}"
+       print "${mode}"
 }
 
 function bonding_enslave_device() {
        local device=${1}
+       assert isset device
+
        local slave=${2}
+       assert isset slave
+
        shift 2
 
-       assert isset device
-       assert isset slave
+       # Slave must be down to be enslaved.
+       device_set_down ${device}
+
+       if device_is_up ${device}; then
+               log ERROR "Cannot enslave '${slave}' because it cannot be set down."
+               return ${EXIT_ERROR}
+       fi
 
-       log INFO "Enslaving slave '${slave}' to '${device}'."
+       # Add it.
+       print "+${slave}" > ${SYS_CLASS_NET}/${device}/bonding/slaves
+       local ret=$?
 
-       device_set_down ${slave}
-       echo "+${slave}" > /sys/class/net/${device}/bonding/slaves
+       if [ ${ret} -eq ${EXIT_OK} ]; then
+               log DEBUG "Successfully enslaved '${slave}' to '${device}'."
+       else
+               log ERROR "Could not enslave '${slave}' to '${device}'."
+               return ${EXIT_ERROR}
+       fi
+
+       return ${EXIT_OK}
 }
 
 function bonding_get_slaves() {
        local device=${1}
+       assert isset device
+       shift
+
+       local file="slaves"
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --active)
+                               file="active_slave"
+                               ;;
+                       *)
+                               error "Unrecognized argument: ${1}"
+                               return ${EXIT_ERROR}
+                               ;;
+               esac
+               shift
+       done
 
-       cat ${SYS_CLASS_NET}/${device}/bonding/slaves
+       fread ${SYS_CLASS_NET}/${device}/bonding/${file}
+
+       return ${EXIT_OK}
 }
 
-function bonding_get_active_slave() {
+function bonding_get_lacp_rate() {
        local device=${1}
+       assert isset device
 
-       cat ${SYS_CLASS_NET}/${device}/bonding/active_slave
-}
+       local rate rateno
+       read -r rate rateno \
+               < ${SYS_CLASS_NET}/${device}/bonding/lacp_rate
 
-# XXX function bonding_get_lacp_rate?
+       print "${rate}"
+       return ${EXIT_OK}
+}
 
 function bonding_get_miimon() {
        local device=${1}
+       assert isset device
 
-       cat ${SYS_CLASS_NET}/${device}/bonding/miimon
+       fread ${SYS_CLASS_NET}/${device}/bonding/miimon
 }
 
 function bonding_set_miimon() {
        local device=${1}
-       local miimon=${2}
-
-       echo "${miimon}" > ${SYS_CLASS_NET}/${device}/bonding/miimon
-}
-
-function bonding_device_print() {
-       local device=${1}
-
-       ethernet_device_print ${device}
+       assert isset device
 
-       echo # Empty line
+       local miimon=${2}
+       assert isset miimon
 
-       printf "${DEVICE_PRINT_LINE1}" "Mode:" "$(bonding_get_mode ${device})"
-       printf "${DEVICE_PRINT_LINE1}" "Slaves:" "$(bonding_get_slaves ${device})"
+       print "${miimon}" > ${SYS_CLASS_NET}/${device}/bonding/miimon
 }
 
 function bonding_slave_get_master() {
        local slave=${1}
-
        assert isset slave
-       assert device_is_bonded ${slave}
 
-       local device
-       for device in $(devices_get_all); do
-               if device_is_bonding ${device} && listmatch ${slave} $(bonding_get_slaves ${device}); then
-                       echo "${device}"
-                       return ${EXIT_OK}
-               fi
-       done
+       device_is_bonded ${slave} || return ${EXIT_ERROR}
+
+       local master=$(fread ${SYS_CLASS_NET}/${slave}/master/ifindex)
+       if isset master; then
+               device_ifindex_to_name ${master}
+               return ${EXIT_OK}
+       fi
 
        return ${EXIT_ERROR}
 }
index 9e291e41f9119e933c8222ba3bc70cdc16dd5976..c24c9e948bbaa932f948de836724b6accacbd8d7 100644 (file)
@@ -172,30 +172,60 @@ function cli_device_bonded() {
        local master=$(bonding_slave_get_master ${port})
        cli_print_fmt1 2 "Master" "${master}"
 
-       local active
-       [ "$(bonding_get_active_slave ${master})" = "${port}" ]
-       cli_print_fmt1 2 "Active slave" "$(cli_print_yesno $?)"
+       local mode=$(bonding_get_mode ${master})
+       if [ "${mode}" = "active-backup" ]; then
+               local active_slaves=$(bonding_get_slaves ${master} --active)
+               local active="false"
+               if list_match "${device}" ${active_slaves}; then
+                       active="true"
+               fi
+               cli_print_fmt1 2 "Active slave" "$(cli_print_yesno ${active})"
+       fi
+
        cli_space
 }
 
 function cli_device_bonding() {
        local device=${1}
+       assert isset device
 
        cli_headline 2 "Bonding information"
 
-       cli_print_fmt1 2 "Mode" "$(bonding_get_mode ${port})"
-       # XXX lacp rate
+       local mode=$(bonding_get_mode ${device})
+
+       cli_print_fmt1 2 "Mode" "${mode}"
+       if [ "${mode}" = "802.3ad" ]; then
+               local lacp_rate=$(bonding_get_lacp_rate ${device})
+               cli_print_fmt1 2 "LACP rate" "${lacp_rate}"
+       fi
        cli_space
 
-       local slave slave_prefix
-       local slave_active=$(bonding_get_active_slave ${device})
+       local slave slave_suffix
+       local active_slaves=$(bonding_get_slaves ${device} --active)
        for slave in $(bonding_get_slaves ${device}); do
-               if [ "${slave_active}" = "${slave}" ]; then
-                       slave_prefix="Slave (active)"
+               # Print the device status.
+               local status
+               case "$(device_get_status ${slave})" in
+                       ${STATUS_UP})
+                               status=${MSG_DEVICE_STATUS_UP}
+                               ;;
+                       ${STATUS_DOWN})
+                               status=${MSG_DEVICE_STATUS_DOWN}
+                               ;;
+                       ${STATUS_NOCARRIER})
+                               status=${MSG_DEVICE_STATUS_NOCARRIER}
+                               ;;
+                       *)
+                               status=${MSG_DEVICE_STATUS_UNKNOWN}
+                               ;;
+               esac
+
+               if list_match "${slave}" ${active_slaves}; then
+                       slave_suffix="(active)"
                else
-                       slave_prefix="Slave"
+                       slave_suffix=""
                fi
-               cli_print_fmt1 2 "${slave_prefix}" "${slave}"
+               cli_print_fmt1 2 "Slave ${slave}" "${status} ${slave_suffix}"
        done
        cli_space
 }
index 892e884039553ab49777837c1457458d51599415..3d8b987e2e8ac0eceff780a00c92d5c7334759b1 100755 (executable)
 
 . /usr/lib/network/header-port
 
-HOOK_SETTINGS="HOOK DEVICE_MAC MIIMON MODE SLAVES"
+HOOK_SETTINGS="HOOK ADDRESS MIIMON MODE SLAVES"
 
-PORT_CHILDREN_VAR="SLAVES"
-
-DEVICE_MAC=$(mac_generate)
+ADDRESS=$(mac_generate)
+SLAVES=""
 MIIMON=100
 
 function _check() {
-       assert isset DEVICE_MAC
-       assert ismac DEVICE_MAC
+       assert isset ADDRESS
+       assert ismac ADDRESS
 
        #assert isset SLAVES
        assert isinteger MIIMON
@@ -42,22 +41,23 @@ function _create() {
 
 function _edit() {
        local port=${1}
+       assert isset port
        shift
 
        while [ $# -gt 0 ]; do
                case "${1}" in
-                       --mac=*)
-                               DEVICE_MAC=${1#--mac=}
+                       --address=*)
+                               ADDRESS=$(cli_get_val ${1})
                                ;;
                        --miimon=*)
-                               MIIMON=${1#--miimon=}
+                               MIIMON=$(cli_get_val ${1})
                                ;;
                        --mode=*)
-                               MODE=${1#--mode=}
+                               MODE=$(cli_get_val ${1})
                                ;;
                        --slave=*)
-                               slave=${1#--slave=}
-                               SLAVES="${SLAVES} $(macify ${slave})"
+                               slave=$(cli_get_val ${1})
+                               SLAVES="${SLAVES} ${slave}"
                                ;;
                        *)
                                warning "Unknown argument '${1}'"
@@ -80,8 +80,8 @@ function _edit() {
        fi
 
        local slave
-       for slave in ${SLAVES}; do
-               if ! device_is_ethernet $(devicify ${slave}); then
+       for slave in $(unquote ${SLAVES}); do
+               if ! device_is_ethernet ${slave}; then
                        error "Slave device '${slave}' is not an ethernet device."
                        exit ${EXIT_ERROR}
                fi
@@ -90,48 +90,47 @@ function _edit() {
        # Remove any whitespace
        SLAVES=$(echo ${SLAVES})
 
-       config_write $(port_file ${port}) ${HOOK_SETTINGS}
+       port_config_write ${port} ${HOOK_SETTINGS}
 
        exit ${EXIT_OK}
 }
 
 function _up() {
        local device=${1}
+       assert isset device
 
-       config_read $(port_file ${device})
+       port_config_read ${device}
 
        if device_exists ${device}; then
                log DEBUG "Bonding device '${device}' does already exist."
 
-               device_set_address ${DEVICE_MAC}
+               device_set_address ${device} ${ADDRESS}
                device_set_up ${device}
 
                exit ${EXIT_OK}
        fi
 
-       bonding_create ${device} ${DEVICE_MAC}
-       assert device_exists ${device}
+       bonding_create ${device} --address="${ADDRESS}" --mode="${MODE}"
+       local ret=$?
 
-       if [ -n "${MODE}" ]; then
-               bonding_set_mode ${device} ${MODE}
-       fi
+       [ ${ret} -eq ${EXIT_OK} ] || exit ${EXIT_ERROR}
 
        bonding_set_miimon ${device} ${MIIMON}
        device_set_up ${device}
 
        local slave
-       for slave in ${SLAVES}; do
-               if ! device_exists $(devicify ${slave}); then
+       for slave in $(unquote ${SLAVES}); do
+               if ! device_exists ${slave}; then
                        warning_log "${device}: configured slave '${slave}' is not available."
                        continue
                fi
-               
-               slave=$(devicify ${slave})
-               assert isset slave
 
                bonding_enslave_device ${device} ${slave}
        done
 
+       # Bring up the device.
+       device_set_up ${device}
+
        exit ${EXIT_OK}
 }
 
@@ -147,60 +146,3 @@ function _down() {
 
        exit ${EXIT_OK}
 }
-
-function _status() {
-        local port=${1}
-        shift
-
-        assert isset port
-
-        echo "${port}"
-
-        local status=$(device_get_status ${port})
-       # XXX STATUS_COLOUR AND STATUS_TEXT DO NOT EXIST ANYMORE
-        printf "${DEVICE_PRINT_LINE1}" "Status:" "$(echo -ne ${STATUS_COLOUR[${status}]}${STATUS_TEXT[${status}]}${COLOUR_NORMAL})"
-
-        cli_headline "  Ethernet information:"
-        printf "${DEVICE_PRINT_LINE1}" "Address:" $(device_get_address ${port})
-        printf "${DEVICE_PRINT_LINE1}" "MTU:" $(device_get_mtu ${port})
-        printf "${DEVICE_PRINT_LINE1}" "Promisc mode:" $(device_is_promisc ${port} && echo "yes" || echo "no")
-
-        if device_is_bonded ${port}; then
-                cli_headline "  Bonding information:"
-
-                local master=$(bonding_slave_get_master ${port})
-                printf "${DEVICE_PRINT_LINE1}" "Master:" "${master}"
-
-                local active
-                if [ "$(bonding_get_active_slave ${master})" = "${port}" ]; then
-                        active="yes"
-                else
-                        active="no"
-                fi
-                printf "${DEVICE_PRINT_LINE1}" "Active slave:" "${active}"
-        fi
-
-       if device_is_bonding ${port}; then
-               cli_headline "  Bonding information:"
-
-               printf "${DEVICE_PRINT_LINE1}" "Mode:" "$(bonding_get_mode ${port})"
-               # XXX lacp rate
-               echo
-
-               local slave
-               local slave_active=$(bonding_get_active_slave ${port})
-               for slave in $(bonding_get_slaves ${port}); do
-                       printf "${DEVICE_PRINT_LINE1}" "Slave$([ "${slave}" = "${slave_active}" ] && echo " (active)"):" "${slave}"
-               done
-       fi
-
-        cli_headline "  Statistics:"
-        printf "${DEVICE_PRINT_LINE1}" "Received:" \
-                "$(beautify_bytes $(device_get_rx_bytes ${port})) ($(device_get_rx_packets ${port}) packets)"
-        printf "${DEVICE_PRINT_LINE1}" "Sent:" \
-                "$(beautify_bytes $(device_get_tx_bytes ${port})) ($(device_get_tx_packets ${port}) packets)"
-
-        echo
-
-        exit ${EXIT_OK}
-}