#!/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 . # # # ############################################################################### 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 bonding_remove bond0 fi } function bonding_create() { local device=${1} 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 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 # Create the bonding device. print "+${device}" > ${BONDING_MASTERS} local ret=$? 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 if ! device_exists ${device}; then return ${EXIT_ERROR} fi # Set device down if not already done. device_set_down ${device} # Remove the device. print "-${device}" > ${BONDING_MASTERS} local ret=$? 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 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 print "${mode}" } function bonding_enslave_device() { local device=${1} assert isset device local slave=${2} assert isset slave shift 2 # 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 # Add it. print "+${slave}" > ${SYS_CLASS_NET}/${device}/bonding/slaves local ret=$? 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 fread ${SYS_CLASS_NET}/${device}/bonding/${file} return ${EXIT_OK} } function bonding_get_lacp_rate() { local device=${1} assert isset device local rate rateno read -r rate rateno \ < ${SYS_CLASS_NET}/${device}/bonding/lacp_rate print "${rate}" return ${EXIT_OK} } function bonding_get_miimon() { local device=${1} assert isset device fread ${SYS_CLASS_NET}/${device}/bonding/miimon } function bonding_set_miimon() { local device=${1} assert isset device local miimon=${2} assert isset miimon print "${miimon}" > ${SYS_CLASS_NET}/${device}/bonding/miimon } function bonding_slave_get_master() { local slave=${1} assert isset slave 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} }