From: Michael Tremer Date: Mon, 8 Oct 2012 12:49:14 +0000 (+0000) Subject: bonding: Update bonding drivers. X-Git-Tag: 006~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1e71061055d50282bc65a0c55adb1f46f52e05c;p=network.git bonding: Update bonding drivers. Nothing new. Just the old stuff reloaded and twice as awesome. --- diff --git a/functions.bonding b/functions.bonding index 87ce5d76..247d37ca 100644 --- a/functions.bonding +++ b/functions.bonding @@ -19,6 +19,10 @@ # # ############################################################################### +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} } diff --git a/functions.cli b/functions.cli index 9e291e41..c24c9e94 100644 --- a/functions.cli +++ b/functions.cli @@ -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 } diff --git a/hooks/ports/bonding b/hooks/ports/bonding index 892e8840..3d8b987e 100755 --- a/hooks/ports/bonding +++ b/hooks/ports/bonding @@ -21,16 +21,15 @@ . /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} -}