]> git.ipfire.org Git - people/stevee/network.git/blobdiff - src/hooks/zones/pppoe
Convert HOOK_SETTINGS into an array
[people/stevee/network.git] / src / hooks / zones / pppoe
index ee89346487b53a219e6304be4d8704b7e4aaf25f..4f7ae51596d41e7bfdd8c74b76ab3d0c10c4f299 100644 (file)
 
 . /usr/lib/network/header-zone
 
-HOOK_SETTINGS="HOOK ACCESS_CONCENTRATOR AUTH USERNAME PASSWORD"
-HOOK_SETTINGS="${HOOK_SETTINGS} SERVICE_NAME MTU PORT IPV6 PREFIX_DELEGATION"
-
-# User credentials for the dialin.
-USERNAME=""
-PASSWORD=""
-
-# Set the authentication mechanism.
-AUTH=
-
-# The physical ethernet port the modem is connected to.
-PORT=""
-
-# Access Concentrator.
-ACCESS_CONCENTRATOR=""
-
-# Service name.
-SERVICE_NAME=""
-
-# Maximum Transmission Unit.
-# 1492 is a very common value for that.
-MTU=1492
+HOOK_SETTINGS=(
+       "ACCESS_CONCENTRATOR"
+       "AUTH"
+       "USERNAME"
+       "PASSWORD"
+       "SERVICE_NAME"
+       "MTU"
+       "IPV6"
+       "PREFIX_DELEGATION"
+)
 
 # This hook can work with all authentication methods supported by pppd.
 PPPOE_SUPPORTED_AUTH_METHODS="${PPP_SUPPORTED_AUTH_METHODS}"
 PPPOE_PLUGIN="rp-pppoe.so"
 
 # Request an IPv6 address.
-IPV6="true"
+DEFAULT_IPV6="true"
 
 # Use IPv6 prefix delegation.
-PREFIX_DELEGATION="false"
+DEFAULT_PREFIX_DELEGATION="true"
 
-function hook_check() {
+hook_check_settings() {
        assert isset USERNAME
        assert isset PASSWORD
 
        isset AUTH && assert isoneof AUTH ${PPPOE_SUPPORTED_AUTH_METHODS}
 
-       # Check for a valid port setting.
-       assert isset PORT
-       assert port_exists ${PORT}
-
        assert isset IPV6
        assert isset PREFIX_DELEGATION
 }
 
-function hook_parse_cmdline() {
+hook_parse_cmdline() {
        while [ $# -gt 0 ]; do
                case "${1}" in
                        --access-concentrator=*)
-                               ACCESS_CONCENTRATOR=$(cli_get_val ${1})
+                               ACCESS_CONCENTRATOR=$(cli_get_val "${1}")
                                ;;
                        --auth=*)
-                               AUTH=$(cli_get_val ${1})
+                               AUTH=$(cli_get_val "${1}")
                                ;;
                        --ipv6=*)
                                local value="$(cli_get_val "${1}")"
@@ -86,22 +70,19 @@ function hook_parse_cmdline() {
                                fi
                                ;;
                        --mtu=*)
-                               MTU=$(cli_get_val ${1})
+                               MTU=$(cli_get_val "${1}")
                                ;;
                        --password=*)
-                               PASSWORD=$(cli_get_val ${1})
-                               ;;
-                       --port=*)
-                               PORT=$(cli_get_val ${1})
+                               PASSWORD=$(cli_get_val "${1}")
                                ;;
                        --prefix-delegation=*)
                                PREFIX_DELEGATION="$(cli_get_bool "${1}")"
                                ;;
                        --service-name=*)
-                               SERVICE_NAME=$(cli_get_val ${1})
+                               SERVICE_NAME=$(cli_get_val "${1}")
                                ;;
                        --username=*)
-                               USERNAME=$(cli_get_val ${1})
+                               USERNAME=$(cli_get_val "${1}")
                                ;;
                        *)
                                warning "Unknown argument: ${1}" >&2
@@ -111,15 +92,26 @@ function hook_parse_cmdline() {
        done
 }
 
-function hook_up() {
+hook_up() {
        local zone=${1}
        assert isset zone
 
-       zone_config_read ${zone}
+       # If this zone's port is not set, we will return
+       # with EXIT_OK so that this zone will remain active,
+       # but we cannot start pppd.
+       local port=$(__hook_get_port "${zone}")
+       if ! isset port || ! port_exists "${port}"; then
+               log WARNING "Could not bring up zone '${zone}' because no port is attached"
+               exit ${EXIT_OK}
+       fi
+
+       zone_settings_read "${zone}"
+
+       # Load the pppoe kernel module
+       module_load "pppoe"
 
        # Bring up the port.
-       log DEBUG "Bringing up port '${PORT}'."
-       port_up ${PORT}
+       port_up "${port}"
 
        # Start the ppp daemon.
        pppd_start ${zone}
@@ -127,26 +119,57 @@ function hook_up() {
        exit ${EXIT_OK}
 }
 
-function hook_down() {
+hook_down() {
        local zone=${1}
        assert isset zone
 
-       zone_config_read ${zone}
+       zone_settings_read "${zone}"
 
        # Stop the ppp daemon.
        pppd_stop ${zone}
 
        # Bring down the port.
-       log DEBUG "Bringing down port '${PORT}'."
-       port_down ${PORT}
+       local port=$(__hook_get_port "${zone}")
+       if isset port; then
+               log DEBUG "Bringing down port '${port}'"
+               port_down "${port}"
+       fi
 
        exit ${EXIT_OK}
 }
 
-function hook_discover() {
+hook_hotplug() {
+       local zone="${1}"
+
+       case "$(hotplug_action)" in
+               add)
+                       if hotplug_event_interface_is_port_of_zone "${zone}"; then
+                               # Bring up the zone if it is enabled but not active, yet.
+                               zone_start_auto "${zone}"
+
+                               exit ${EXIT_OK}
+                       fi
+                       ;;
+               remove)
+                       # PPPoE cannot work if the ethernet device has been removed
+                       if hotplug_event_interface_is_port_of_zone "${zone}"; then
+                               if zone_is_active "${zone}"; then
+                                       zone_stop "${zone}"
+                               fi
+
+                               exit ${EXIT_OK}
+                       fi
+                       ;;
+       esac
+
+       exit ${EXIT_NOT_HANDLED}
+}
+
+hook_discover() {
        local device=${1}
 
-       if [ "$(device_get_type ${device})" != "real" ]; then
+       # This obviously only works on ethernet (or compatible) devices
+       if ! device_is_ethernet_compatible "${device}"; then
                exit ${EXIT_ERROR}
        fi
 
@@ -173,18 +196,22 @@ function hook_discover() {
        exit ${DISCOVER_OK}
 }
 
-function hook_status() {
+hook_status() {
        local zone=${1}
        assert isset zone
 
        cli_device_headline ${zone}
 
-       zone_config_read ${zone}
+       zone_settings_read "${zone}"
 
        cli_headline 2 "Configuration"
        cli_print_fmt1 2 "Username" "${USERNAME}"
        cli_print_fmt1 2 "Password" "<hidden>"
-       cli_print_fmt1 2 "Port" "${PORT}"
+
+       local port=$(__hook_get_port "${zone}")
+       if isset port; then
+               cli_print_fmt1 2 "Port" "${port}"
+       fi
        cli_space
 
        # Exit if zone is down
@@ -196,9 +223,12 @@ function hook_status() {
        # XXX display time since connection started
 
        cli_headline 2 "Point-to-Point-over-Ethernet protocol"
+       cli_print_fmt1 2 "MAC-Remote"  "$(db_get "${zone}/remote-address")"
+       cli_space
+
        local proto
        for proto in ${IP_SUPPORTED_PROTOCOLS}; do
-               routing_db_exists ${zone} ${proto} || continue
+               db_exists "${zone}/${proto}" || continue
 
                local headline
                case "${proto}" in
@@ -214,18 +244,16 @@ function hook_status() {
                esac
                cli_headline 3 "${headline}"
 
-               cli_print_fmt1 3 "IP address"  "$(routing_db_get ${zone} ${proto} local-ip-address)"
-               cli_print_fmt1 3 "Gateway"     "$(routing_db_get ${zone} ${proto} remote-ip-address)"
-               cli_print_fmt1 3 "DNS servers" "$(routing_db_get ${zone} ${proto} dns)"
-               cli_space
-               cli_print_fmt1 3 "MAC-Remote"  "$(routing_db_get ${zone} ${proto} remote-address)"
+               cli_print_fmt1 3 "IP address"  "$(db_get "${zone}/${proto}/local-ip-address")"
+               cli_print_fmt1 3 "Gateway"     "$(db_get "${zone}/${proto}/remote-ip-address")"
+               cli_print_fmt1 3 "DNS servers" "$(db_get "${zone}/${proto}/domain-name-servers")"
                cli_space
        done
 
        exit ${EXIT_OK}
 }
 
-function hook_ppp_write_config() {
+hook_ppp_write_config() {
        local zone=${1}
        assert isset zone
 
@@ -233,7 +261,14 @@ function hook_ppp_write_config() {
        assert isset file
 
        # Read in the configuration files.
-       zone_config_read ${zone}
+       zone_settings_read "${zone}"
+
+       # A port has to be assigned for this action
+       local port=$(__hook_get_port "${zone}")
+       if ! isset port; then
+               error "No port assigned to pppoe hook of zone '${zone}'"
+               exit ${EXIT_ERROR}
+       fi
 
        # Prepare the command line options for the pppoe plugin.
        local plugin_options
@@ -249,7 +284,7 @@ function hook_ppp_write_config() {
        fi
 
        # The last argument must be the interface.
-       plugin_options="${plugin_options} ${PORT}"
+       plugin_options="${plugin_options} ${port}"
 
        pppd_write_config ${file} \
                --interface="${zone}" \
@@ -264,3 +299,118 @@ function hook_ppp_write_config() {
 
        exit ${EXIT_OK}
 }
+
+__hook_get_port() {
+       local zone="${1}"
+
+       local port
+       for port in $(zone_get_ports "${zone}"); do
+               echo "${port}"
+               return ${EXIT_OK}
+       done
+
+       return ${EXIT_ERROR}
+}
+
+hook_port_attach() {
+       # Excepting at least two arguments here
+       assert [ $# -ge 2 ]
+
+       local zone="${1}"
+       local port="${2}"
+       shift 2
+
+       # PPPoE can only use one port
+       local ports_num="$(zone_get_ports_num "${zone}")"
+       if [ ${ports_num} -ge 1 ]; then
+               local ports="$(zone_get_ports "${zone}")"
+               error "The pppoe zone hook only supports assigning one port"
+               error "  port '${ports}' has already been assigned to zone '${zone}'"
+               return ${EXIT_ERROR}
+       fi
+
+       if ! zone_port_settings_write "${zone}" "${port}"; then
+               exit ${EXIT_ERROR}
+       fi
+
+       exit ${EXIT_OK}
+}
+
+hook_port_detach() {
+       assert [ $# -eq 2 ]
+
+       local zone="${1}"
+       local port="${2}"
+
+       # Shut down the entire zone here, because it cannot
+       # run without a port any way and removing the port would
+       # create a hotplug event which will be processed after the
+       # port has already been detached...
+       zone_stop "${zone}"
+
+       if ! zone_port_settings_remove "${zone}" "${port}"; then
+               exit ${EXIT_ERROR}
+       fi
+
+       exit ${EXIT_OK}
+}
+
+hook_port_up() {
+       assert [ $# -eq 2 ]
+
+       local zone="${1}"
+       local port="${2}"
+
+       # Try bringing up the port if it has not been brought up before
+       if ! device_exists "${port}"; then
+               port_create "${port}"
+       fi
+
+       # Make sure that the port is up
+       port_up "${port}"
+
+       exit ${EXIT_OK}
+}
+
+hook_port_down() {
+       assert [ $# -eq 2 ]
+
+       local zone="${1}"
+       local port="${2}"
+
+       if device_exists "${port}"; then
+               port_down "${port}"
+       fi
+
+       exit ${EXIT_OK}
+}
+
+hook_ppp_ipv6_up() {
+       local zone="${1}"
+
+       ppp_common_ipv6_up "${zone}"
+
+       # Read configuration
+       zone_settings_read "${zone}"
+
+       if enabled PREFIX_DELEGATION; then
+               dhclient_start "${zone}" ipv6
+       fi
+
+       exit ${EXIT_OK}
+}
+
+hook_ppp_ipv6_down() {
+       local zone="${1}"
+
+       ppp_common_ipv6_down "${zone}"
+
+       # Read configuration
+       zone_settings_read "${zone}"
+
+       if enabled PREFIX_DELEGATION; then
+               dhclient_stop "${zone}" ipv6
+       fi
+
+       exit ${EXIT_OK}
+}