Project: IPFire
Code Location: git://git.ipfire.org/network.gitmaster
Browse
/
Download File
functions.bridge
#!/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 <http://www.gnu.org/licenses/>.       #
#                                                                             #
###############################################################################

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}
}