#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2012 IPFire Network Development Team # # # # 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 . # # # ############################################################################### function bridge_create() { local bridge=${1} assert isset bridge shift local address local mtu while [ $# -gt 0 ]; do case "${1}" in --address=*) address=$(cli_get_val ${1}) ;; --mtu=*) mtu=$(cli_get_val ${1}) ;; *) error "Unrecognized argument: ${1}" return ${EXIT_ERROR} ;; esac shift done if device_exists ${bridge}; then log ERROR "bridge: bridge '${bridge}' does already exist" return ${EXIT_ERROR} fi # Build the ip command. local command="ip link add name ${bridge}" # Add address, if we know it. if ismac address; then command="${command} address ${address}" fi # Add MTU if it has been set. if isinteger mtu; then command="${command} mtu ${mtu}" fi # Last argument is the device type. command="${command} type bridge" # Run the command. cmd_quiet ${command} local ret=$? if [ ${ret} -eq ${EXIT_OK} ]; then log DEBUG "bridge: bridge '${bridge}' has been created" else log ERROR "bridge: Could not create bridge '${bridge}': ${ret}" fi return ${ret} } function bridge_delete() { local bridge=${1} assert isset bridge device_delete ${bridge} } function bridge_attach_device() { local bridge=${1} assert isset bridge local device=${2} assert isset device # Check if bridge exists. if ! device_exists ${bridge}; then log ERROR "bridge: bridge '${bridge}' does not exist to attach devices to" return ${EXIT_ERROR} fi # Check if device exists. if ! device_exists ${device}; then log ERROR "bridge: could not attach '${device}' to '${bridge}' because device does not exist" return ${EXIT_ERROR} fi # If device is already attached, exit silently. if listmatch ${device} $(bridge_get_members ${bridge}); then return ${EXIT_OK} fi # Actually connect bridge and device. cmd_quiet ip link set ${device} master ${bridge} local ret=$? if [ ${ret} -eq ${EXIT_OK} ]; then log DEBUG "bridge: device '${device}' has been attached to bridge '${bridge}'" else log ERROR "bridge: could not attach device '${device}' to bridge '${bridge}': ${ret}" fi return ${ret} } function bridge_detach_device() { local bridge=${1} assert isset bridge local device=${2} assert isset device # Check if bridge exists. if ! device_exists ${bridge}; then log ERROR "bridge: bridge '${bridge}' does not exist to detach devices from" return ${EXIT_ERROR} fi # Check if device exists. if ! device_exists ${device}; then log ERROR "bridge: could not detach '${device}' from '${bridge}' because device does not exist" return ${EXIT_ERROR} fi # If device is not attched, exit silently. if ! listmatch ${device} $(bridge_get_members ${bridge}); then return ${EXIT_OK} fi cmd_quiet ip link set ${device} nomaster local ret=$? if [ ${ret} -eq ${EXIT_OK} ]; then log DEBUG "bridge: device '${device}' has been detached from bridge '${bridge}'" else log ERROR "bridge: could not detach device '${device}' from bridge '${bridge}': ${ret}" fi return ${ret} } function bridge_get_members() { local bridge=${1} assert isset bridge local member for member in ${SYS_CLASS_NET}/${bridge}/brif/*; do member=$(basename ${member}) if device_exists ${member}; then echo "${member}" fi done } function bridge_is_forwarding() { local seconds=45 local zone=${1} bridge_has_carrier ${zone} || return ${EXIT_ERROR} local device while [ ${seconds} -gt 0 ]; do for device in ${SYS_CLASS_NET}/${zone}/brif/*; do [ -e "${device}/state" ] || continue if [ "$(<${device}/state)" = "3" ]; then return ${EXIT_OK} fi done sleep 1 seconds=$((${seconds} - 1)) done return ${EXIT_ERROR} } function bridge_has_carrier() { local zone=${1} local has_carrier=${EXIT_ERROR} local device for device in ${SYS_CLASS_NET}/${zone}/brif/*; do device=$(basename ${device}) device_exists ${device} || continue device_has_carrier ${device} && has_carrier=${EXIT_OK} done return ${has_carrier} }