done
}
+function hotplug_propagate_all_zones() {
+ hotplug_assert_in_hotplug_event
+
+ local zone
+ for zone in $(zones_get_all); do
+ zone_hotplug_event "${zone}"
+ local ret="${?}"
+
+ # Log warning for crashed hooks
+ case "${ret}" in
+ ${EXIT_OK}|${EXIT_NOT_HANDLED})
+ : # do nothing
+ ;;
+ *)
+ log WARNING "Unknown exit code for zone '${zone}': ${ret}"
+ ;;
+ esac
+ done
+}
+
function hotplug_event_port_is_interface() {
hotplug_assert_in_hotplug_event
[ "${port}" = "${INTERFACE}" ]
}
-function hotplug_event_port_is_slave() {
+function hotplug_event_interface_is_slave_of_port() {
hotplug_assert_in_hotplug_event
local port="${1}"
isset INTERFACE || return ${EXIT_FALSE}
local slaves="$(port_get_slaves "${port}")"
- list_match "${INTERFACE}" ${SLAVES}
+ list_match "${INTERFACE}" ${slaves}
+}
+
+function hotplug_event_interface_is_port_of_zone() {
+ hotplug_assert_in_hotplug_event
+
+ local zone="${1}"
+ assert isset zone
+
+ # Return false if INTERFACE is not set
+ isset INTERFACE || return ${EXIT_FALSE}
+
+ local ports="$(zone_get_ports "${zone}")"
+ list_match "${INTERFACE}" ${ports}
}
function hotplug_event_port_uses_phy() {
service_start "network@${zone}.service"
}
+function zone_start_auto() {
+ local zone="${1}"
+ assert zone_exists "${zone}"
+
+ # If the zone has already been started, we
+ # will reload it so the current configuration
+ # is re-applied.
+ if zone_is_active "${zone}"; then
+ zone_reload "${zone}"
+ return ${?}
+
+ # If the zone is still down, but in auto-start mode,
+ # we will start it.
+ elif zone_is_enabled "${zone}"; then
+ zone_start "${zone}"
+ return ${?}
+ fi
+
+ # Otherwise, nothing will be done.
+ return ${EXIT_OK}
+}
+
function zone_stop() {
# This function will bring down the zone
# 'asynchronously' with help of systemd.
function zone_hotplug_event() {
local zone="${1}"
- assert zone_exists "${zone}"
-
- # If the zone has already been started, we
- # will reload it so the current configuration
- # is re-applied.
- if zone_is_active "${zone}"; then
- zone_reload "${zone}"
- return ${?}
+ assert isset zone
- # If the zone is still down, but in auto-start mode,
- # we will start it.
- elif zone_is_enabled "${zone}"; then
- zone_start "${zone}"
- return ${?}
- fi
+ hotplug_assert_in_hotplug_event
- # Otherwise, nothing will be done.
- return ${EXIT_OK}
+ zone_cmd "hotplug" "${zone}"
}
function zone_enable() {
return ${EXIT_FALSE}
}
+function zone_is_enabled_or_active() {
+ local zone="${1}"
+ assert isset zone
+
+ zone_is_enabled "${zone}" || zone_is_active "${zone}"
+}
+
+function zone_cmd() {
+ local cmd="${1}"
+ local port="${2}"
+ shift 2
+
+ assert isset cmd
+ assert isset zone
+
+ local hook="$(zone_get_hook ${zone})"
+ assert isset hook
+
+ hook_exec zone "${hook}" "${cmd}" "${zone}" $@
+}
+
function zone_create() {
local zone=${1}
local hook=${2}
zone_settings_read "${zone}" ${HOOK_SETTINGS}
# 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 up all ports
+ zone_ports_up "${zone}"
+
+ # Bring up all configurations
+ zone_configs_up "${zone}"
+
+ exit ${EXIT_OK}
+}
+
+function hook_hotplug() {
+ local zone="${1}"
+ assert isset zone
- # Bring all ports up
- zone_ports_up ${zone}
- zone_configs_up ${zone}
+ case "$(hotplug_action)" in
+ add)
+ # Handle ports of this zone that have just been added
+ if hotplug_event_interface_is_port_of_zone "${zone}"; then
+ # Bring up the zone if it is enabled but not active, yet.
+ if zone_is_enabled "${zone}" && ! zone_is_active "${zone}"; then
+ zone_start "${zone}"
+ fi
+
+ hook_port_up "${zone}" "${INTERFACE}"
+ fi
+ ;;
+ remove)
+ # Handle ports of this zone that have just been removed
+ if hotplug_event_interface_is_port_of_zone "${zone}"; then
+ hook_port_down "${zone}" "${INTERFACE}"
+ fi
+ ;;
+ *)
+ exit ${EXIT_NOT_HANDLED}
+ ;;
+ esac
exit ${EXIT_OK}
}
function hook_down() {
- local zone=${1}
+ local zone="${1}"
assert isset zone
- if ! device_is_up ${zone}; then
+ 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}"
- 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}
+ 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
+ if stp_is_enabled "${zone}"; then
local proto=$(stp_bridge_get_protocol ${zone})
cli_print_fmt1 2 "Version" "$(stp_get_name ${proto})"
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}
local zone="${1}"
local port="${2}"
- # Try bringing up the port
- port_up "${port}"
-
- # If the port could not be brought up, we will
- # log an error message and exit.
+ # 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
- log WARNING "Port '${port}' cannot be attached to zone '${zone}' as it does not exist"
+ port_up "${port}"
+
exit ${EXIT_OK}
fi
# TODO Apply priority (#10609)
+ # Make sure that the port is up
+ device_set_up "${port}"
+
exit ${EXIT_OK}
}
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}
}