#!/bin/bash
###############################################################################
#                                                                             #
# IPFire.org - A linux based firewall                                         #
# Copyright (C) 2011  Michael Tremer & Christian Schmidt                      #
#                                                                             #
# 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/>.       #
#                                                                             #
###############################################################################

IN_HOTPLUG_EVENT=1

# Setup logging.
LOG_FACILITY="network-hotplug"

. /usr/lib/network/functions

# Read network settings
network_settings_read

log DEBUG "Called with SUBSYSTEM='${SUBSYSTEM}', ACTION='${ACTION}'"

# Check if the udev environment variables are properly set.
assert isset ACTION

case "${SUBSYSTEM}" in
	ieee80211)
		PHY="$(basename "${DEVPATH}")"
		if phy_exists "${PHY}"; then
			PHY_ADDRESS="$(phy_get_address "${PHY}")"
			log DEBUG "  PHY='${PHY}', PHY_ADDRESS='${PHY_ADDRESS}'"
		else
			PHY=""
		fi

		# Propagate the hotplug event to all configured port hooks
		hotplug_propagate_all_ports || exit ${EXIT_ERROR}
		;;

	net)
		assert isset INTERFACE

		# Don't do anything for zones
		if zone_exists "${INTERFACE}"; then
			exit ${EXIT_OK}
		fi

		# Get the internal type of the device for later processing
		TYPE="$(device_get_type "${INTERFACE}")"

		log DEBUG "  INTERFACE='${INTERFACE}', TYPE='${TYPE}'"

		# Stop processing rules for wireless monitoring devices
		if device_is_wireless_monitor "${INTERFACE}"; then
			exit ${EXIT_OK}
		fi

		# Handle special cases like removing automatically created
		# devices that we don't want
		case "${ACTION},${TYPE}" in
			# Bonding
			add,bonding)
				# Remove bonding devices without configuration
				if ! port_exists "${INTERFACE}"; then
					bonding_remove "${INTERFACE}"
					exit ${EXIT_OK}
				fi
				;;

			# dummy
			add,dummy)
				# Remove the by default created dummy device
				if [ "${INTERFACE}" = "dummy0" ]; then
					dummy_remove "${INTERFACE}"
					exit ${EXIT_OK}
				fi
				;;

			# Ethernet
			add,ethernet)
				# Create a default port for all ethernet devices
				if ! port_exists "${INTERFACE}"; then
					port_new "ethernet" "${INTERFACE}"
					exit ${EXIT_OK}
				fi
				;;

			# Wireless devices
			add,wireless)
				# Remove wireless devices without configuration
				if ! port_exists "${INTERFACE}"; then
					wireless_remove "${INTERFACE}"
					exit ${EXIT_OK}
				fi

				# Load regulatory domain for wireless devices
				wireless_init_reg_domain
				;;

			# Don't propagate removal events for ports that don't exist
			remove,*)
				if ! port_exists "${INTERFACE}"; then
					exit ${EXIT_OK}
				fi
				;;
		esac

		if ! port_exists "${INTERFACE}"; then
			log ERROR "Got to hotplug event for a port which does not exist: ${INTERFACE}"
			exit ${EXIT_ERROR}
		fi

		# Propagate the hotplug event to all configured port hooks
		hotplug_propagate_all_ports || exit ${EXIT_ERROR}

		# Propagate the hotplug event to all configured zones
		hotplug_propagate_all_zones || exit ${EXIT_ERROR}

		exit ${EXIT_OK}
		;;

	*)
		log ERROR "Called for an unsupported subsystem: ${SUBSYSTEM}"
		exit ${EXIT_ERROR}
		;;
esac

exit ${EXIT_NOT_HANDLED}
