HOOK_MANPAGE="network-zone-bridge"
-HOOK_SETTINGS="HOOK STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE STP_MODE"
+HOOK_SETTINGS="HOOK STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE"
HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MAC MTU"
HOOK_PORT_SETTINGS="COST PRIORITY"
# Default values
-MAC=$(mac_generate)
+MAC=""
MTU=1500
STP="on"
-STP_MODE="rstp"
STP_FORWARD_DELAY=0
STP_HELLO=2
STP_MAXAGE=20
STP_PRIORITY=512
-function hook_check() {
+hook_check_settings() {
assert ismac MAC
assert isbool STP
- assert isoneof STP_MODE stp rstp
assert isinteger STP_HELLO
assert isinteger STP_FORWARD_DELAY
assert isinteger STP_PRIORITY
assert isinteger MTU
}
-function hook_parse_cmdline() {
+hook_parse_cmdline() {
while [ $# -gt 0 ]; do
case "${1}" in
--stp=*)
STP=${1#--stp=}
;;
- --stp-mode=*)
- STP_MODE=${1#--stp-mode=}
- ;;
--stp-hello=*)
STP_HELLO=${1#--stp-hello=}
;;
esac
shift
done
+
+ # Generate a random MAC address if the user passed no one
+ isset MAC || MAC="$(mac_generate)"
}
-function hook_up() {
+hook_up() {
local zone=${1}
assert isset zone
- zone_config_read ${zone}
+ zone_settings_read "${zone}"
# Create the bridge if it does not already exist.
- if ! device_exists ${zone}; then
- bridge_create ${zone} \
- --address=${MAC} --mtu=${MTU}
-
- # Adjust MAC address and MTU if needed.
- else
- device_set_address ${zone} ${MAC}
- device_set_mtu ${zone} ${MTU}
+ if ! device_exists "${zone}"; then
+ bridge_create "${zone}" \
+ --address="${MAC}" \
+ --mtu="${MTU}"
fi
# Enable STP
if enabled STP; then
- stp_enable ${zone}
+ stp_enable "${zone}"
- if [ -n "${STP_FORWARD_DELAY}" ]; then
- stp_bridge_set_forward_delay ${zone} ${STP_FORWARD_DELAY}
+ if isset STP_FORWARD_DELAY; then
+ stp_bridge_set_forward_delay "${zone}" "${STP_FORWARD_DELAY}"
fi
- if [ -n "${STP_HELLO}" ]; then
- stp_bridge_set_hello_time ${zone} ${STP_HELLO}
+ if isset STP_HELLO; then
+ stp_bridge_set_hello_time "${zone}" "${STP_HELLO}"
fi
- if [ -n "${STP_MAXAGE}" ]; then
- stp_bridge_set_max_age ${zone} ${STP_MAXAGE}
+ if isset STP_MAXAGE; then
+ stp_bridge_set_max_age "${zone}" "${STP_MAXAGE}"
fi
- if [ -n "${STP_PRIORITY}" ]; then
- stp_bridge_set_priority ${zone} ${STP_PRIORITY}
+ if isset STP_PRIORITY; then
+ stp_bridge_set_priority "${zone}" "${STP_PRIORITY}"
fi
else
- stp_disable ${zone}
+ stp_disable "${zone}"
fi
- device_set_up ${zone}
+ device_set_up "${zone}"
# XXX Currently, there is a bug (in the linux kernel?) that we need to
# set our bridges to promisc mode.
- device_set_promisc ${zone} on
+ device_set_promisc "${zone}" on
- # Bring all ports up
- zone_ports_up ${zone}
- zone_configs_up ${zone}
+ # Bring up all configurations
+ zone_configs_up "${zone}"
exit ${EXIT_OK}
}
-function hook_down() {
- local zone=${1}
+hook_hotplug() {
+ local zone="${1}"
assert isset zone
- if ! device_is_up ${zone}; then
+ case "$(hotplug_action)" in
+ add)
+ # Attach all ports when zone is coming up
+ if hotplug_event_interface_is_zone "${zone}"; then
+ # Bring up all ports
+ local port
+ for port in $(zone_get_ports "${zone}"); do
+ log DEBUG "Trying to attach port ${port} to ${zone}"
+
+ hook_port_up "${zone}" "${port}"
+ done
+
+ # Handle ports of this zone that have just been added
+ elif hotplug_event_interface_is_port_of_zone "${zone}"; then
+ # Attach the device if the parent bridge is up
+ if zone_is_active "${zone}"; then
+ hook_port_up "${zone}" "${INTERFACE}"
+ fi
+ fi
+ ;;
+ remove)
+ if hotplug_event_interface_is_zone "${zone}"; then
+ # Bring down/destroy all ports
+ local port
+ for port in $(zone_get_ports "${zone}"); do
+ log DEBUG "Trying to detach port ${port} from ${zone}"
+
+ hook_port_down "${zone}" "${port}"
+ done
+
+ # Handle ports of this zone that have just been removed
+ elif hotplug_event_interface_is_port_of_zone "${zone}"; then
+ hook_port_down "${zone}" "${INTERFACE}"
+ fi
+ ;;
+ *)
+ exit ${EXIT_NOT_HANDLED}
+ ;;
+ esac
+
+ exit ${EXIT_OK}
+}
+
+hook_down() {
+ local zone="${1}"
+ assert isset zone
+
+ if ! device_is_up "${zone}"; then
warning "Zone '${zone}' is not up"
exit ${EXIT_OK}
fi
- zone_configs_down ${zone}
- zone_ports_down ${zone}
+ # Stop all the configs.
+ zone_configs_down "${zone}"
- # XXX See remark in _up().
- device_set_promisc ${zone} off
+ # Bring down all the ports.
+ zone_ports_down "${zone}"
+ zone_ports_remove "${zone}"
- device_set_down ${zone}
- bridge_delete ${zone}
+ # Remove the bridge.
+ device_set_down "${zone}"
+ bridge_delete "${zone}"
exit ${EXIT_OK}
}
-function hook_status() {
- local zone=${1}
+hook_status() {
+ local zone="${1}"
assert isset zone
# Print the default header.
- cli_device_headline ${zone}
+ cli_device_headline "${zone}"
# Exit if zone is down
- if ! zone_is_up ${zone}; then
+ if ! zone_is_up "${zone}"; then
echo # Empty line
exit ${EXIT_ERROR}
fi
cli_headline 2 "Spanning Tree Protocol information"
- if stp_is_enabled ${zone}; then
- local proto=$(stp_bridge_get_protocol ${zone})
-
- cli_print_fmt1 2 "Version" "$(stp_get_name ${proto})"
+ if stp_is_enabled "${zone}"; then
cli_print_fmt1 2 "ID" "$(stp_bridge_get_id ${zone})"
cli_print_fmt1 2 "Priority" "$(stp_bridge_get_priority ${zone})"
fi
cli_headline 2 "Ports"
- zone_ports_status ${zone}
+ zone_ports_status "${zone}"
cli_space
cli_headline 2 "Configurations"
- zone_configs_cmd status ${zone}
+ zone_configs_cmd status "${zone}"
cli_space
exit ${EXIT_OK}
}
-function __parse_cmdline_args() {
- while [ $# -gt 0 ]; do
- case "${1}" in
- --priority=*)
- PRIORITY="$(cli_get_val ${1})"
- ;;
- --cost=*)
- COST="$(cli_get_val ${1})"
- ;;
- esac
- shift
- done
+hook_check_port_settings() {
+ if isset COST; then
+ assert isinteger COST
+ fi
- return ${EXIT_OK}
+ if isset PRIORITY; then
+ assert isinteger PRIORITY
+ fi
}
-function hook_port_add() {
+hook_port_attach() {
# Excepting at least two arguments here
assert [ $# -ge 2 ]
local port="${2}"
shift 2
- __parse_cmdline_args "$@"
- [ $? -eq ${EXIT_OK} ] || return ${EXIT_ERROR}
-
- config_write "$(zone_dir "${zone}")/ports/${port}" ${HOOK_PORT_SETTINGS}
-
- log INFO "Port '${port}' has been added to zone '${zone}'"
-
- exit ${EXIT_OK}
-}
-
-function hook_port_edit() {
- assert [ $# -ge 2 ]
-
- local zone="${1}"
- local port="${2}"
- shift 2
-
- config_read "$(zone_dir "${zone}")/ports/${port}" ${HOOK_PORT_SETTINGS}
-
- __parse_cmdline_args "$@"
- [ $? -eq ${EXIT_OK} ] || return ${EXIT_ERROR}
+ if zone_has_port "${zone}" "${port}"; then
+ zone_port_settings_read "${zone}" "${port}"
+ fi
- config_write "$(zone_dir "${zone}")/ports/${port}" ${HOOK_PORT_SETTINGS}
+ local arg
+ local val
+ while read arg; do
+ case "${arg}" in
+ --cost=*)
+ COST="$(cli_get_val "${arg}")"
+ ;;
+ --priority=*)
+ PRIORITY="$(cli_get_val "${arg}")"
+ ;;
+ esac
+ done <<< "$(args "$@")"
- log INFO "Port '${port}' (member of zone '${zone}') has been edited"
+ if ! zone_port_settings_write "${zone}" "${port}"; then
+ exit ${EXIT_ERROR}
+ fi
exit ${EXIT_OK}
}
-function hook_port_remove() {
+hook_port_detach() {
assert [ $# -eq 2 ]
local zone="${1}"
# Shut down the port (if possible)
port_down "${port}"
- log INFO "Port '${port}' has been removed from zone '${zone}'"
- config_remove "$(zone_dir "${zone}")/ports/${port}"
+ if ! zone_port_settings_remove "${zone}" "${port}"; then
+ exit ${EXIT_ERROR}
+ fi
exit ${EXIT_OK}
}
-function hook_port_up() {
+hook_port_edit() {
+ hook_port_attach "$@"
+}
+
+hook_port_up() {
assert [ $# -eq 2 ]
local zone="${1}"
local port="${2}"
- port_up "${port}"
+ # Try bringing up the port if it has not been
+ # brought up before.
+ # We will get here as soon as the port device has
+ # been created and will then connect it with the bridge.
+ if ! device_exists "${port}"; then
+ port_create "${port}"
+
+ return ${EXIT_OK}
+ fi
+
+ # Read configuration values
+ zone_port_settings_read "${zone}" "${port}" ${HOOK_PORT_SETTINGS}
- # Set same MTU to device that the bridge has got
- device_set_mtu "${port}" $(device_get_mtu "${zone}")
+ # Make sure that the port is up
+ port_up "${port}"
+ # Attach the port to the bridge
bridge_attach_device "${zone}" "${port}"
- # XXX must set cost and prio here
+ # Set STP configuration
+ if isset COST; then
+ stp_port_set_cost "${zone}" "${port}" "${COST}"
+ fi
+
+ if isset PRIORITY; then
+ stp_port_set_priority "${zone}" "${port}" "${PRIORITY}"
+ fi
- exit ${EXIT_OK}
+ return ${EXIT_OK}
}
-function hook_port_down() {
+hook_port_down() {
assert [ $# -eq 2 ]
local zone="${1}"
local port="${2}"
- bridge_detach_device "${zone}" "${port}"
+ if device_exists "${port}"; then
+ bridge_detach_device "${zone}" "${port}"
- port_down "${port}"
+ port_down "${port}"
+ fi
- exit ${EXIT_OK}
+ return ${EXIT_OK}
}
-function hook_port_status() {
+hook_port_status() {
assert [ $# -eq 2 ]
local zone="${1}"