###############################################################################
# #
# IPFire.org - A linux based firewall #
-# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
+# 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 #
# #
###############################################################################
-function bridge_attach_device() {
+function bridge_create() {
local bridge=${1}
- local device=${2}
+ 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
- assert device_exists ${bridge}
+ # 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 WARN "Could not attach '${device}' to '${bridge}' becase device does not exist."
+ 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 device is already attached, exit silently.
if listmatch ${device} $(bridge_get_members ${bridge}); then
return ${EXIT_OK}
fi
- log INFO "Attaching device '${device}' to bridge '${bridge}'."
+ # 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
- brctl addif ${bridge} ${device}
+ return ${ret}
}
function bridge_detach_device() {
local bridge=${1}
- local device=${2}
-
assert isset bridge
+
+ local device=${2}
assert isset device
-
+
+ # Check if bridge exists.
if ! device_exists ${bridge}; then
- error "Bridge '${bridge}' does not exist."
+ 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
- return ${EXIT_OK}
+ log ERROR "bridge: could not detach '${device}' from '${bridge}' because device does not exist"
+ return ${EXIT_ERROR}
fi
- # If device is not attached, exit silently
+ # If device is not attched, exit silently.
if ! listmatch ${device} $(bridge_get_members ${bridge}); then
return ${EXIT_OK}
fi
- log INFO "Detaching device '${device}' from bridge '${bridge}'."
+ cmd_quiet ip link set ${device} nomaster
+ locat 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
- brctl delif ${bridge} ${device}
+ return ${ret}
}
function bridge_get_members() {
serial_exists ${device}
}
+function device_delete() {
+ local device=${1}
+ assert isset device
+
+ # Nothing to do, it device does not exist.
+ device_exists ${device} || return ${EXIT_OK}
+
+ # Delete the device.
+ cmd_quiet ip link delete ${device}
+ local ret=$?
+
+ if [ ${ret} -ne ${EXIT_OK} ]; then
+ log ERROR "device: Could not delete device '${device}': ${ret}"
+ return ${EXIT_ERROR}
+ fi
+
+ return ${ret}
+}
+
function device_has_flag() {
local device=${1}
local flag=${2}
device_has_flag ${device} 0x1
}
+function device_ifindex_to_name() {
+ local idx=${1}
+ assert isset idx
+
+ local device device_idx
+ for device in ${SYS_CLASS_NET}/*; do
+ device=$(basename ${device})
+ device_exists ${device} || continue
+
+ device_idx=$(device_get_ifindex ${device})
+
+ if [ "${device_idx}" = "${idx}" ]; then
+ print "${device}"
+ return ${EXIT_OK}
+ fi
+ done
+
+ return ${EXIT_ERROR}
+}
+
+function device_get_ifindex() {
+ local device=${1}
+ assert isset device
+
+ local path="${SYS_CLASS_NET}/${1}/ifindex"
+
+ # Check if file can be read.
+ [ -r "${path}" ] || return ${EXIT_ERROR}
+
+ print "$(<${path})"
+}
+
# Check if the device is a bonding device
function device_is_bonding() {
[ -d "/sys/class/net/${1}/bonding" ]
[ -d "${SYS_CLASS_NET}/${device}/brport" ]
}
+function device_get_bridge() {
+ local device=${1}
+ assert isset device
+
+ # Check if device is attached to a bridge.
+ device_is_bridge_attached ${device} || return ${EXIT_ERROR}
+
+ local ifindex_path="${SYS_CLASS_NET}/${device}/brport/bridge/ifindex"
+ [ -r "${ifindex_path}" ] || return ${EXIT_ERROR}
+
+ local ifindex=$(<${ifindex_path})
+ assert isset ifindex
+
+ device_ifindex_to_name ${ifindex}
+}
+
# Check if the device is a virtual device
function device_is_virtual() {
local device=${1}
function _up() {
local zone=${1}
- shift
+ assert isset zone
zone_config_read ${zone}
+ # Create the bridge if it does not already exist.
if ! device_exists ${zone}; then
- brctl addbr ${zone}
- fi
+ bridge_create ${zone} \
+ --address=${MAC} --mtu=${MTU}
- [ -n "${MAC}" ] && device_set_address ${zone} ${MAC}
- [ -n "${MTU}" ] && device_set_mtu ${zone} ${MTU}
+ # Adjust MAC address and MTU if needed.
+ else
+ device_set_address ${zone} ${MAC}
+ device_set_mtu ${zone} ${MTU}
+ fi
# Enable STP
if enabled STP; then
zone_ports_up ${zone}
zone_configs_up ${zone}
- event_interface_up ${zone}
-
exit ${EXIT_OK}
}
function _down() {
local zone=${1}
- shift
+ assert isset zone
if ! device_is_up ${zone}; then
warning "Zone '${zone}' is not up"
exit ${EXIT_OK}
fi
- event_interface_down ${zone}
-
zone_configs_down ${zone}
zone_ports_down ${zone}
device_set_promisc ${zone} off
device_set_down ${zone}
- brctl delbr ${zone}
+ bridge_delete ${zone}
exit ${EXIT_OK}
}