From: Michael Tremer Date: Wed, 20 Jun 2012 23:19:34 +0000 (+0000) Subject: pppoe: Rework hook. X-Git-Tag: 004~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=97cb552e711bdaf2b4d7dab6b465dcc99879cf7d;p=network.git pppoe: Rework hook. --- diff --git a/functions.config b/functions.config index 42c8b617..bc808c04 100644 --- a/functions.config +++ b/functions.config @@ -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} diff --git a/functions.ppp b/functions.ppp index 9c793b43..c2eba58d 100644 --- a/functions.ppp +++ b/functions.ppp @@ -19,6 +19,29 @@ # # ############################################################################### +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} +} diff --git a/functions.util b/functions.util index 0b646f7d..163888fd 100644 --- a/functions.util +++ b/functions.util @@ -19,6 +19,11 @@ # # ############################################################################### +# A simple print statement +function print() { + printf "$@\n" +} + # Print a pretty error message function error() { echo -e " ${COLOUR_ERROR}ERROR${COLOUR_NORMAL} : $@" >&2 diff --git a/header-zone b/header-zone index bbc2c0bc..8233f612 100644 --- a/header-zone +++ b/header-zone @@ -248,6 +248,12 @@ function _config_show() { _notimplemented _config_show } +function _ppp-write-config() { + _notimplemented _ppp_write_config + + # Arguments: +} + function _ppp-ip-pre-up() { local zone=${1} shift diff --git a/hooks/zones/pppoe.ports/ethernet b/helpers/pppd-config-helper old mode 100644 new mode 100755 similarity index 50% rename from hooks/zones/pppoe.ports/ethernet rename to helpers/pppd-config-helper index 46411a74..6f1dae95 --- a/hooks/zones/pppoe.ports/ethernet +++ b/helpers/pppd-config-helper @@ -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 # @@ -19,95 +19,36 @@ # # ############################################################################### -. /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} diff --git a/hooks/zones/pppoe b/hooks/zones/pppoe index 64d47814..1b737334 100755 --- a/hooks/zones/pppoe +++ b/hooks/zones/pppoe @@ -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 # @@ -21,93 +21,70 @@ . /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 <${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" "" + cli_print_fmt1 2 "Username" "${USERNAME}" + cli_print_fmt1 2 "Password" "" + 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 index 3857774a..00000000 --- a/hooks/zones/pppoe.ports/bonding +++ /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 index 3857774a..00000000 --- a/hooks/zones/pppoe.ports/virtual +++ /dev/null @@ -1 +0,0 @@ -ethernet \ No newline at end of file diff --git a/man/Makefile b/man/Makefile index eadee58d..52fcf2c8 100644 --- a/man/Makefile +++ b/man/Makefile @@ -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 index 00000000..470420d8 --- /dev/null +++ b/man/network-zone-pppoe.8.in @@ -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 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 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)