+ # Check if the port actually exists.
+ if ! port_exists "${port}"; then
+ error "Cannot attach port '${port}' which does not exist"
+ return ${EXIT_ERROR}
+ fi
+
+ # Check if the port is already connected to this or any other zone.
+ local z
+ for z in $(zones_get_all); do
+ if zone_has_port "${z}" "${port}"; then
+ error "Port '${port}' is already attached to zone '${z}'"
+ return ${EXIT_ERROR}
+ fi
+ done
+
+ local hook="$(zone_get_hook "${zone}")"
+ assert isset hook
+
+ # Make the port briefly flash if supported
+ if device_exists ${port}; then
+ port_identify "${port}" --background
+ fi
+
+ hook_zone_exec "${hook}" "port_attach" "${zone}" "${port}" "$@"
+ local ret="${?}"
+
+ case "${ret}" in
+ ${EXIT_OK})
+ log INFO "${port} has been attached to ${zone}"
+
+ # Automatically connect the port
+ zone_port_start "${zone}" "${port}"
+ ;;
+ *)
+ log CRITICAL "${port} could not be attached to ${zone}"
+ ;;
+ esac
+
+ return ${ret}
+}
+
+zone_port_edit() {
+ local zone="${1}"
+ assert isset zone
+
+ local port="${2}"
+ assert isset port
+
+ shift 2
+
+ # Check if the port actually exists.
+ if ! port_exists "${port}"; then
+ error "Port '${port}' does not exist"
+ return ${EXIT_ERROR}
+ fi
+
+ # Check if the zone actually has this port.
+ if ! zone_has_port "${zone}" "${port}"; then
+ error "Port '${port}' is not attached to zone '${zone}'"
+ return ${EXIT_ERROR}
+ fi
+
+ local hook=$(zone_get_hook "${zone}")
+ assert isset hook
+
+ hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
+}
+
+zone_port_detach() {
+ local zone="${1}"
+ assert isset zone
+
+ local port="${2}"
+ assert isset port
+
+ shift 2
+
+ # Check if the zone actually has this port.
+ if ! zone_has_port "${zone}" "${port}"; then
+ error "Port '${port}' is not attached to zone '${zone}'"
+ return ${EXIT_ERROR}
+ fi
+
+ local hook=$(zone_get_hook "${zone}")
+ assert isset hook
+
+ # Make the port briefly flash if supported
+ port_identify "${port}" --background
+
+ hook_zone_exec "${hook}" "port_detach" "${zone}" "${port}" "$@"
+ local ret="${?}"
+
+ case "${ret}" in
+ ${EXIT_OK})
+ log INFO "${port} has been detached from ${zone}"
+
+ # Bring down the port if needed
+ zone_port_stop "${zone}" "${port}"
+ ;;
+ *)
+ log CRITICAL "${port} could not be detached from ${zone}"
+ ;;
+ esac
+
+ return ${ret}
+}
+
+zone_port_cmd() {
+ local cmd="${1}"