]> git.ipfire.org Git - network.git/commitdiff
pppoe: Rework hook.
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 20 Jun 2012 23:19:34 +0000 (23:19 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 20 Jun 2012 23:19:34 +0000 (23:19 +0000)
functions.config
functions.ppp
functions.util
header-zone
helpers/pppd-config-helper [moved from hooks/zones/pppoe.ports/ethernet with 50% similarity, mode: 0755]
hooks/zones/pppoe
hooks/zones/pppoe.ports/bonding [deleted symlink]
hooks/zones/pppoe.ports/virtual [deleted symlink]
man/Makefile
man/network-zone-pppoe.8.in [new file with mode: 0644]

index 42c8b6178ae253b5c127fba0adf8bc6c89b753a6..bc808c044bfbe7639fcb9a4dbfeff1fee9516e34 100644 (file)
@@ -68,6 +68,21 @@ function config_check() {
        [ -n "$(type -t _check)" ] && _check
 }
 
+function config_header() {
+       local what=${1}
+       assert isset what
+
+       # Print the header.
+       echo "#"
+       echo "# This is a ${what}."
+       echo "# THIS FILE IS AUTOMATICALLY GENERATED AND WILL OVERWRITE"
+       echo "# ANY CUSTOM CHANGES!"
+       echo "#"
+       echo "# $(date -u)"
+       echo "#"
+       echo
+}
+
 function config_hostname() {
        local hostname=${1}
 
index 9c793b43bcf4210a7704c5d11e247814761d237e..c2eba58dc9c46a87498f18ad7d62b4cd4b65bf6c 100644 (file)
 #                                                                             #
 ###############################################################################
 
+PPP_SUPPORTED_AUTH_METHODS="chap pap"
+
+function pppd_start() {
+       local interface=${1}
+       assert isset interface
+
+       service_start "pppd@${interface}"
+}
+
+function pppd_stop() {
+       local interface=${1}
+       assert isset interface
+
+       service_stop "pppd@${interface}"
+}
+
+function pppd_status() {
+       local interface=${1}
+       assert isset interface
+
+       service_status "pppd@${interface}"
+}
+
 function ppp_common_ip_pre_up() {
        local zone=${1}
        shift
@@ -153,3 +176,116 @@ function pppd_exec() {
 
        pppd $@ > /dev/null
 }
+
+function pppd_write_config() {
+       local file=${1}; shift
+       assert isset file
+
+       local auth
+       local interface
+       local linkname
+       local mtu mru
+       local plugin plugin_options
+       local user
+
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --auth=*)
+                               auth=$(cli_get_val ${1})
+                               ;;
+                       # The name of the created ppp interface.
+                       --interface=*)
+                               interface=$(cli_get_val ${1})
+                               ;;
+                       # Maximum Transmission Unit
+                       --mtu=*)
+                               mtu=$(cli_get_val ${1})
+                               ;;
+                       # Maximum Receive Unit
+                       --mru=*)
+                               mru=$(cli_get_val ${1})
+                               ;;
+                       --plugin=*)
+                               plugin=$(cli_get_val ${1})
+                               ;;
+                       --plugin-options=*)
+                               plugin_options=$(cli_get_val ${1})
+                               ;;
+                       --user=*)
+                               user=$(cli_get_val ${1})
+                               ;;
+                       *)
+                               log WARNING "Unhandled argument: ${1}"
+                               ;;
+               esac
+               shift
+       done
+
+       if [ -z "${interface}" ]; then
+               log ERROR "You need to set the interface name: ${interface}"
+               return ${EXIT_ERROR}
+       fi
+       linkname=${interface}
+
+       if isset auth; then
+               if ! isoneof ${auth} ${PPP_SUPPORTED_AUTH_METHODS}; then
+                       log ERROR "Unsupported auth method: ${auth}"
+                       return ${EXIT_ERROR}
+               fi
+       fi
+
+       # Write the configuration header.
+       mkdir -p $(dirname ${file}) 2>/dev/null
+       config_header "PPP daemon configuration file" > ${file}
+
+       # At first, set the name of the link.
+       print "name ${linkname}\nlinkname ${linkname}\n" >> ${file}
+
+       # Configure the interface name.
+       print "# Interface name\nifname ${interface}\n" >> ${file}
+
+       # Plugin settings
+       if isset plugin; then
+               (
+                       print "# Plugin settings"
+                       print "plugin ${plugin} ${plugin_options}"
+                       print
+               ) >> ${file}
+       fi
+
+       # User authentication
+       if isset user; then
+               (
+                       print "# User authentication"
+                       print "user ${user}"
+
+                       print "noauth"
+                       if isset auth; then
+                               print "require-${auth}"
+                       fi
+                       print
+               ) >> ${file}
+       fi
+
+       # MTU/MRU settings
+       if isset mtu; then
+               isset mru || mru=${mtu}
+
+               (
+                       print "# MTU/MRU settings"
+                       print "mtu ${mtu}"
+                       print "mru ${mru}"
+                       print
+               ) >> ${file}
+       fi
+
+       # Add the default settings.
+       (
+               print "# Disable the compression"
+               print "noccp noaccomp nodeflate nopcomp novj novjccomp nobsdcomp nomppe"
+
+               print "noipdefault nodetach debug"
+       ) >> ${file}
+
+       return ${EXIT_OK}
+}
index 0b646f7ddd610166845dcd30f1c589492c24a0ef..163888fdfb7941b37668934b0907af5a75909cf6 100644 (file)
 #                                                                             #
 ###############################################################################
 
+# A simple print statement
+function print() {
+       printf "$@\n"
+}
+
 # Print a pretty error message
 function error() {
        echo -e " ${COLOUR_ERROR}ERROR${COLOUR_NORMAL}  : $@" >&2
index bbc2c0bcbb4afa9e063eb96370dc673cea57844b..8233f61241fe092a97e2a897d5c37f3183cb2fa5 100644 (file)
@@ -248,6 +248,12 @@ function _config_show() {
        _notimplemented _config_show
 }
 
+function _ppp-write-config() {
+       _notimplemented _ppp_write_config
+
+       # Arguments: <zone> <filename>
+}
+
 function _ppp-ip-pre-up() {
        local zone=${1}
        shift
old mode 100644 (file)
new mode 100755 (executable)
similarity index 50%
rename from hooks/zones/pppoe.ports/ethernet
rename to helpers/pppd-config-helper
index 46411a7..6f1dae9
@@ -2,7 +2,7 @@
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2010  Michael Tremer & Christian Schmidt                      #
+# Copyright (C) 2012  IPFire Network Development Team                         #
 #                                                                             #
 # 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        #
 #                                                                             #
 ###############################################################################
 
-. /lib/network/header-port
+. /usr/lib/network/functions
 
-function _add() {
-       local zone=${1}
-       local port=${2}
-       shift 2
+action="${1}"
+assert isset action
 
-       assert isset zone
-       assert isset port
+zone="${2}"
+assert isset zone
+assert zone_exists ${zone}
 
-       if ! port_exists ${port}; then
-               error "Port '${port}' does not exist."
-               exit ${EXIT_ERROR}
-       fi
-
-       touch $(zone_dir ${zone})/ports/${port}
-
-       exit ${EXIT_OK}
-}
+config_file="${RUN_DIR}/ppp/${zone}/pppd.conf"
 
-function _edit() {
-       _add $@
-}
+case "${action}" in
+       create)
+               # Create the configuration file for this zone.
+               hook=$(zone_get_hook ${zone})
+               assert isset hook
 
-function _rem() {
-       local zone=${1}
-       local port=${2}
-       shift 2
+               hook_exec zone ${hook} ppp_write_config \
+                       ${zone} ${config_file}
+               exit $?
+               ;;
 
-       assert isset zone
-       assert isset port
+       remove)
+               rm -f ${config_file}
+               ;;
 
-       if ! listmatch ${port} $(zone_get_ports ${zone}); then
-               error "Port '${port}' does not belong to '${zone}'."
-               error "Won't remove anything."
+       *)
+               log ERROR "Unknown action passed: ${action}"
                exit ${EXIT_ERROR}
-       fi
-
-       warning "Removing port '${port}' from '${zone}' will shutdown the zone."
-
-       # Shut down this zone
-       zone_down ${zone}
-
-       rm -f $(zone_dir ${zone})/ports/${port}
-
-       exit ${EXIT_OK}
-}
-
-function _up() {
-       local zone=${1}
-       local port=${2}
-
-       assert isset zone
-       assert isset port
-
-       assert zone_exists ${zone}
-       assert port_exists ${port}
-
-       port_up ${port}
-
-       exit ${EXIT_OK}
-}
-
-function _down() {
-       local zone=${1}
-       local port=${2}
-
-       assert isset zone
-       assert isset port
-
-       assert zone_exists ${zone}
-       assert port_exists ${port}
-
-       port_down ${port}
-
-       exit ${EXIT_OK}
-}
-
-function _status() {
-       local zone=${1}
-       local port=${2}
-
-       printf "        %-10s - " "${port}"
-       if device_is_up ${port}; then
-               echo -ne "${COLOUR_UP}    UP    ${COLOUR_NORMAL}"
-       else
-               echo -ne "${COLOUR_DOWN}   DOWN   ${COLOUR_NORMAL}"
-       fi
-       echo
+               ;;
+esac
 
-       exit ${EXIT_OK}
-}
+exit ${EXIT_OK}
index 64d4781490e637a7910b47028cb5016ffb2edd19..1b73733428dde60dd8f6502f0d6a01352051684e 100755 (executable)
@@ -2,7 +2,7 @@
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2010  Michael Tremer & Christian Schmidt                      #
+# Copyright (C) 2012  IPFire Network Development Team                         #
 #                                                                             #
 # 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        #
 
 . /usr/lib/network/header-zone
 
-# TODO XXX AC name, service name, sync?
+HOOK_SETTINGS="HOOK ACCESS_CONCENTRATOR AUTH USERNAME PASSWORD"
+HOOK_SETTINGS="${HOOK_SETTINGS} SERVICE_NAME MTU PORT"
 
-HOOK_SETTINGS="HOOK AUTH LINKNAME USER SECRET PEERDNS DEFAULTROUTE MTU"
+# User credentials for the dialin.
+USERNAME=""
+PASSWORD=""
 
+# Set the authentication mechanism.
 AUTH=
-DEFAULTROUTE=1
-IPV6=1
-LINKNAME="$(uuid)"
+
+# 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
-PEERDNS=1
-SECRET=
-USER=
 
-PPPOE_ALLOWED_AUTHS="chap pap"
+# This hook can work with all authentication methods supported by pppd.
+PPPOE_ALLOWED_AUTH_METHODS="${PPP_ALLOWED_AUTH_METHODS}"
 PPPOE_PLUGIN="rp-pppoe.so"
 
-function pppd_pid() {
-       local zone=${1}
-       shift
+function _check() {
+       assert isset USERNAME
+       assert isset PASSWORD
 
-       cat /var/run/${zone}.pid 2>/dev/null
-}
+       isset AUTH && assert isoneof AUTH ${PPPOE_ALLOWED_AUTH_METHODS}
 
-function _check() {
-       assert isset USER
-       assert isset SECRET
-       assert isset LINKNAME
-       assert isset DEFAULTROUTE
-       assert isset PEERDNS
-       #assert isset DEVICE
-       #assert isset DEVICE_TYPE
-
-       assert isbool DEFAULTROUTE
-       assert isbool IPV6
-       assert isbool PEERDNS
-       #assert ismac DEVICE
-       #assert isoneof DEVICE_TYPE real virtual
-
-       local ports_num=$(listlength ${PORTS})
-       assert isoneof ports_num 0 1
-
-       isset AUTH && assert isoneof AUTH ${PPPOE_ALLOWED_AUTHS}
-       isset DEVICE_ID && assert isinteger DEVICE_VID
+       # Check for a valid port setting.
+       assert isset PORT
+       assert port_exists ${PORT}
 }
 
 function _parse_cmdline() {
-       local value
-
        while [ $# -gt 0 ]; do
-               case "$1" in
-                       --user=*)
-                               USER=${1#--user=}
+               case "${1}" in
+                       --access-concentrator=*)
+                               ACCESS_CONCENTRATOR=$(cli_get_val ${1})
                                ;;
-                       --secret=*)
-                               SECRET=${1#--secret=}
-                               ;;
-                       --linkname=*)
-                               LINKNAME=${1#--name=}
+                       --auth=*)
+                               AUTH=$(cli_get_val ${1})
                                ;;
                        --mtu=*)
-                               MTU=${1#--mtu=}
+                               MTU=$(cli_get_val ${1})
                                ;;
-                       --defaultroute=*)
-                               value=${1#--defaultroute=}
-                               if enabled value; then
-                                       DEFAULTROUTE=1
-                               else
-                                       DEFAULTROUTE=0
-                               fi
+                       --password=*)
+                               PASSWORD=$(cli_get_val ${1})
                                ;;
-                       --dns=*)
-                               value=${1#--dns=}
-                               if enabled value; then
-                                       PEERDNS=1
-                               else
-                                       PEERDNS=0
-                               fi
+                       --port=*)
+                               PORT=$(cli_get_val ${1})
                                ;;
-                       --auth=*)
-                               AUTH=${1#--auth=}
+                       --service-name=*)
+                               SERVICE_NAME=$(cli_get_val ${1})
                                ;;
-                       --ipv6=*)
-                               IPV6=${1#--ipv6=}
+                       --username=*)
+                               USERNAME=$(cli_get_val ${1})
                                ;;
                        *)
-                               echo "Unknown option: $1" >&2
-                               exit ${EXIT_ERROR}
+                               warning "Unknown argument: ${1}" >&2
                                ;;
                esac
                shift
@@ -116,94 +93,20 @@ function _parse_cmdline() {
 
 function _up() {
        local zone=${1}
-       shift
-
        assert isset zone
 
-       zone_config_read ${zone}
-
-       local port=$(zone_get_ports ${zone})
-
-       assert isset port
-
-       if ! port_exists ${port}; then
-               error_log "Parent device '${port}' does not exist. Cannot bring up zone '${zone}'."
-               exit ${EXIT_ERROR}
-       fi
-
-       # Creating necessary files
-       # XXX must be PPP_RUN
-       [ -d "${RED_RUN}/${LINKNAME}" ] || mkdir -p ${RED_RUN}/${LINKNAME}
-
-       # Setting up the device
-       zone_ports_up ${zone}
-
-       ppp_secret "${USER}" "${SECRET}"
-
-       # XXX AC and service on plugin command line
-
-       cat <<EOF >${RED_RUN}/${LINKNAME}/options
-# Naming options
-ifname ${zone}
-name ${LINKNAME}
-linkname ${LINKNAME}
-
-plugin ${PPPOE_PLUGIN} ${port}
-
-# Enable/disable IPv6
-$(enabled IPV6 && echo "+" || echo "-")ipv6
-
-# User configuration
-user ${USER}
-
-$(enabled PEERDNS && echo "usepeerdns")
-$(enabled DEFAULTROUTE && echo "defaultroute")
-
-noauth
-$(isset AUTH && echo "require-${AUTH}")
-
-noipdefault
-
-# Maximum transmission/receive unit
-mtu ${MTU}
-mru ${MTU}
-
-# Disable the compression
-noccp noaccomp nodeflate nopcomp novj novjccomp nobsdcomp nomppe
-
-updetach debug
-EOF
-
-       pppd_exec file ${RED_RUN}/${LINKNAME}/options
-
-       local ret=$?
+       # Start the ppp daemon.
+       pppd_start ${zone}
 
-       # Get exit code from ppp daemon and handle it:
-       case "${ret}" in
-               0)
-                       log DEBUG "pppd detached successfully"
-                       exit ${EXIT_OK}
-                       ;;
-               19)
-                       log ERROR "Authentication failed. Maybe user and/or secret is/are incorrect."
-                       exit ${EXIT_ERROR}
-                       ;;
-       esac
-
-       error_log "pppd exited with unknown exit code '${ret}'"
-
-       exit ${EXIT_ERROR}
+       exit ${EXIT_OK}
 }
 
 function _down() {
        local zone=${1}
-       shift
-
-       # Kill pppd
-       # XXX very ugly
-       kill $(pppd_pid ${zone}) &>/dev/null
+       assert isset zone
 
-       zone_ports_down ${zone}
+       # Stop the ppp daemon.
+       pppd_stop ${zone}
 
        exit ${EXIT_OK}
 }
@@ -247,21 +150,11 @@ function _status() {
        zone_config_read ${zone}
 
        cli_headline 2 "Configuration"
-       cli_print_fmt1 2 "User" "${USER}"
-       cli_print_fmt1 2 "Secret" "<hidden>"
+       cli_print_fmt1 2 "Username" "${USERNAME}"
+       cli_print_fmt1 2 "Password" "<hidden>"
+       cli_print_fmt1 2 "Port" "${PORT}"
        cli_space
 
-       enabled IPV6 &>/dev/null
-       local ipv6_enabled=$?
-       cli_print_fmt1 2 "IPv6?" "$(cli_print_bool ${ipv6_enabled})"
-
-       cli_headline 2 "Ports"
-       zone_ports_status ${zone}
-       if [ -z "$(zone_get_ports ${zone})" ]; then
-               cli_print_warning "No ports attached. Won't be able to start."
-               cli_space
-       fi
-
        # Exit if zone is down
        if ! zone_is_up ${zone}; then
                echo # Empty line
@@ -300,18 +193,69 @@ function _status() {
        exit ${EXIT_OK}
 }
 
-function _port_add() {
+function _ppp-ip-pre-up() {
        local zone=${1}
-       local port=${2}
-       shift 2
+       assert isset ${zone}
 
-       if [ $(listlength $(zone_get_ports ${zone})) -ge 1 ]; then
-               error "This hook only supports one port at a time."
-               error "Please remove any existant port(s) and try again."
-               exit ${EXIT_ERROR}
+       # Read the configuration.
+       zone_config_read ${zone}
+
+       # Bring up the port.
+       port_up ${PORT}
+
+       ppp_common_pre_ip_up ${zone}
+}
+
+function _ppp-ip-down() {
+       local zone=${1}
+       assert isset ${zone}
+
+       # Read the configuation.
+       zone_config_read ${zone}
+
+       # Bring down the port.
+       port_down ${PORT}
+
+       ppp_common_ip_down ${zone}
+}
+
+function _ppp_write_config() {
+       local zone=${1}
+       assert isset zone
+
+       local file=${2}
+       assert isset file
+
+       # Read in the configuration files.
+       zone_config_read ${zone}
+
+       # Set the user credentials.
+       ppp_secret "${USERNAME}" "${PASSWORD}"
+
+       # Prepare the command line options for the pppoe plugin.
+       local plugin_options
+
+       # Add the access concentrator (if any).
+       if isset ACCESS_CONCENTRATOR; then
+               plugin_options="${plugin_options} rp_pppoe_ac '${ACCESS_CONCENTRATOR}'"
        fi
 
-       _port_cmd add ${zone} ${port} $@
+       # Add the service name (if any).
+       if isset SERVICE_NAME; then
+               plugin_options="${plugin_options} rp_pppoe_service '${SERVICE_NAME}'"
+       fi
 
-       exit ${EXIT_OK}
+       # The last argument must be the interface.
+       plugin_options="${plugin_options} ${PORT}"
+
+       pppd_write_config ${file} \
+               --interface="${zone}" \
+               --user="${USERNAME}" \
+               --mtu="${MTU}" \
+               --auth="${AUTH}" \
+               \
+               --plugin="${PPPOE_PLUGIN}" \
+               --plugin-options="${plugin_options}"
+
+       return ${EXIT_OK}
 }
diff --git a/hooks/zones/pppoe.ports/bonding b/hooks/zones/pppoe.ports/bonding
deleted file mode 120000 (symlink)
index 3857774..0000000
+++ /dev/null
@@ -1 +0,0 @@
-ethernet
\ No newline at end of file
diff --git a/hooks/zones/pppoe.ports/virtual b/hooks/zones/pppoe.ports/virtual
deleted file mode 120000 (symlink)
index 3857774..0000000
+++ /dev/null
@@ -1 +0,0 @@
-ethernet
\ No newline at end of file
index eadee58d66f73194c3941308246fab6aff7da17e..52fcf2c837200d2cf37413138fab4aec3c890816 100644 (file)
@@ -30,7 +30,8 @@ MANPAGES8   = \
        network-config.8 \
        network-device.8 \
        network-zone.8 \
-       network-zone-bridge.8
+       network-zone-bridge.8 \
+       network-zone-pppoe.8
 
 .PHONY: all
 all: $(MANPAGES)
diff --git a/man/network-zone-pppoe.8.in b/man/network-zone-pppoe.8.in
new file mode 100644 (file)
index 0000000..470420d
--- /dev/null
@@ -0,0 +1,79 @@
+.TH network-zone-pppoe 8 "21 Jun 2012" "@VERSION@" "network man page"
+
+.SH NAME
+network-zone-pppoe \- Network Configuration Control Program
+
+.SH SYNOPSIS
+\fBnetwork [OPTIONS] zone create <zone> pppoe ...\fR
+.P
+All options may be edited on zones which have already been set up with the \fBpppoe\fR hook:
+.P
+\fBnetwork [OPTIONS] zone <zone> edit ...\fR
+
+.SH DESCRIPTION
+The pppoe hook creates a PPPoE connection to your ISP.
+.PP
+
+.SH OPTIONS
+The \fBpppoe\fR hook offers various configuration options:
+
+\fB--port\fR = ...
+.RS 4
+This options sets the port, pppd is using to connect to the modem.
+.PP
+This may be a normal ethernet or vlan interface.
+.RE
+.PP
+
+\fB--username\fR = ...
+.RS 4
+Sets the username for authentication.
+.RE
+.PP
+
+\fB--password\fR = ...
+.RS 4
+Sets the password for authentication.
+.PP
+Use the \fB--auth=\fR option to transmit it in a secure manner to the provider.
+.RE
+.PP
+
+\fB--mtu\fR = 1492
+.RS 4
+Sets the default MTU of the PPP connection. The default value is 1492 which is
+a common MTU used for DSL.
+.RE
+.PP
+
+\fB--auth\fR = [chap|pap]
+.RS 4
+Define the authentication method that is used to authenticate
+against your provider. The default is to use the provider's preference.
+.PP
+* \fBChallange-Handshake Authentication Protocol\fR (chap) is the preferred
+secure method.
+.PP
+* \fBPassword Authentication Protocol\fR (pap) sends the plaintext password
+to the authentication server which is the reason why it should be avoided
+to use PAP.
+.RE
+.PP
+
+\fB--access-concentrator\fR = ...
+.RS 4
+By this option, you may define the name of the access concentrator.
+.RE
+.PP
+
+\fB--service-name\fR = ...
+.RS 4
+By this option, you may define the service name.
+.RE
+.PP
+
+.SH SEE ALSO
+network(8), network-zone(8)
+
+.SH AUTHOR
+Michael Tremer (michael.tremer@ipfire.org)