]> git.ipfire.org Git - people/ms/network.git/commitdiff
network: Magnificent changes on code.
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 9 Jul 2010 19:37:47 +0000 (21:37 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 9 Jul 2010 19:37:47 +0000 (21:37 +0200)
21 files changed:
functions.bonding
functions.cli
functions.constants
functions.device
functions.ethernet [new file with mode: 0644]
functions.hook
functions.ports [new file with mode: 0644]
functions.ppp
functions.util
functions.zone
header-device [new file with mode: 0644]
hooks/ports/bonding [new file with mode: 0755]
hooks/ports/ethernet [new file with mode: 0755]
hooks/ports/virtual [new file with mode: 0755]
hooks/zones/bridge
hooks/zones/bridge.ports/bonding [changed from file to symlink]
hooks/zones/bridge.ports/ethernet
hooks/zones/bridge.ports/virtual [changed from file to symlink]
hooks/zones/pppoe
network
ppp/ip-updown

index 8a04a91a954afc2e6b02e2066ee0ce361a6a5f42..a63289269a8d169aad4ad85b8dafbb93679a1954 100644 (file)
 #                                                                             #
 ###############################################################################
 
+function bonding_init() {
+       if ! grep -q "^bonding" /proc/modules; then
+               modprobe bonding
+
+               bonding_remove bond0
+       fi
+}
+
 function bonding_create() {
        local device=${1}
        local mac=${2}
 
+       # Make sure the bonding is initialized
+       bonding_init
+
        [ -z "${mac}" ] && mac=$(mac_generate)
 
        log INFO "Creating bonding device '${device}' (${mac})."
 
        echo "+${device}" > /sys/class/net/bonding_masters
-       device_set_address ${mac}
+       device_set_address ${device} ${mac}
        device_set_up ${device}
 }
 
 function bonding_remove() {
        local device=$(devicify ${1})
 
+       assert isset device
+
        log INFO "Remove bonding device '${device}'."
 
        device_set_down ${device}
@@ -50,13 +63,79 @@ function bonding_set_mode() {
        echo "${mode}" > /sys/class/net/${device}/bonding/mode
 }
 
+function bonding_get_mode() {
+       local device=${1}
+
+       local mode mode_num
+       read mode mode_num < ${SYS_CLASS_NET}/${device}/bonding/mode
+       echo "${mode}"
+}
+
 function bonding_enslave_device() {
        local device=$(devicify ${1})
        local slave=$(devicify ${2})
        shift 2
 
+       assert isset device
+       assert isset slave
+
        log INFO "Enslaving slave '${slave}' to '${device}'."
 
        device_set_down ${slave}
        echo "+${slave}" > /sys/class/net/${device}/bonding/slaves
 }
+
+function bonding_get_slaves() {
+       local device=${1}
+
+       cat ${SYS_CLASS_NET}/${device}/bonding/slaves
+}
+
+function bonding_get_active_slave() {
+       local device=${1}
+
+       cat ${SYS_CLASS_NET}/${device}/bonding/active_slave
+}
+
+# XXX function bonding_get_lacp_rate?
+
+function bonding_get_miimon() {
+       local device=${1}
+
+       cat ${SYS_CLASS_NET}/${device}/bonding/miimon
+}
+
+function bonding_set_miimon() {
+       local device=${1}
+       local miimon=${2}
+
+       echo "${miimon}" > ${SYS_CLASS_NET}/${device}/bonding/miimon
+}
+
+function bonding_device_print() {
+       local device=${1}
+
+       ethernet_device_print ${device}
+
+       echo # Empty line
+
+       printf "${DEVICE_PRINT_LINE1}" "Mode:" "$(bonding_get_mode ${device})"
+       printf "${DEVICE_PRINT_LINE1}" "Slaves:" "$(bonding_get_slaves ${device})"
+}
+
+function bonding_slave_get_master() {
+       local slave=${1}
+
+       assert isset slave
+       assert device_is_bonded ${slave}
+
+       local device
+       for device in $(devices_get_all); do
+               if device_is_bonding ${device} && listmatch ${slave} $(bonding_get_slaves ${device}); then
+                       echo "${device}"
+                       return ${EXIT_OK}
+               fi
+       done
+
+       return ${EXIT_ERROR}
+}
index b6435bcd0cb90de4690d6e4ae780c950bae244f3..56db94c054b145a4c31ae545f1292fcad26d8a10 100644 (file)
@@ -33,47 +33,44 @@ function cli_config() {
 }
 
 function cli_device() {
-       local action=${1}
-       shift
-
-       local device
-       local devices=$@
-
-       if [ -z "${devices}" ]; then
-               devices=$(devices_get_all)
-       fi
+       if device_config_exists ${1}; then
+               local device=${1}
+               local action=${2}
+               shift 2
 
-       case "${action}" in
-               discover)
-                       echo "# XXX need to implement --raw here"
-                       for device in ${devices}; do
-                               cli_device_discover ${device} $@
-                       done
-                       ;;
+               case "${action}" in
+                       down|up)
+                               device_${action} ${device} $@
+                               ;;
+               esac
+       else
+               local action=${1}
+               shift
 
-               show|"")
-                       for device in ${devices}; do
-                               cli_device_print ${device}
-                       done
-                       ;;
-               *)
-                       cli_usage device
-                       ;;                              
-       esac
-}
+               case "${action}" in
+                       create)
+                               device_${action} $@
+                               ;;
 
-function cli_device_print() {
-       local device=${1}
+                       discover)
+                               echo "# XXX need to implement --raw here"
+                               local device
+                               for device in ${devices}; do
+                                       cli_device_discover ${device} $@
+                               done
+                               ;;
 
-       if ! device_exists ${device}; then
-               error "Device '${device}' does not exist."
-               return ${EXIT_ERROR}
+                       show|"")
+                               local device
+                               for device in $(device_get $@); do
+                                       device_print ${device}
+                               done
+                               ;;
+                       *)
+                               cli_usage device
+                               ;;                              
+               esac
        fi
-
-       echo "${device}"
-       echo "  Type: $(device_get_type ${device})"
-       echo "  Addr: $(device_get_address ${device})"
-       echo
 }
 
 function cli_device_discover() {
@@ -147,6 +144,58 @@ function cli_device_discover() {
        [ "${up}" = "1" ] || device_set_down ${device}
 }
 
+function cli_port() {
+       if cli_help_requested $@; then
+               cli_usage root-port
+               exit ${EXIT_OK}
+       fi
+
+       local action
+       local port
+
+       if port_exists ${1}; then
+               port=${1}
+               action=${2}
+               shift 2
+
+               # Action aliases
+               case "${action}" in
+                       start)
+                               action="up"
+                               ;;
+                       stop)
+                               action="down"
+                               ;;
+                       show)
+                               action="status"
+                               ;;
+               esac
+
+               case "${action}" in
+                       edit|up|down|status)
+                               port_${action} ${port} $@
+                               ;;
+                       *)
+                               error "Unrecognized argument: ${action}"
+                               exit ${EXIT_ERROR}
+                               ;;
+               esac
+       else
+               action=${1}
+               shift
+
+               case "${action}" in
+                       create|destroy)
+                               port_${action} $@
+                               ;;
+                       *)
+                               error "Unrecognized argument: ${action}"
+                               exit ${EXIT_ERROR}
+                               ;;
+               esac
+       fi
+}
+
 function cli_zone() {
        if cli_help_requested $@; then
                cli_usage root-zone
@@ -161,8 +210,21 @@ function cli_zone() {
                action=${2}
                shift 2
 
+               # Action aliases
+               case "${action}" in
+                       start)
+                               action="up"
+                               ;;
+                       stop)
+                               action="down"
+                               ;;
+                       show)
+                               action="status"
+                               ;;
+               esac
+
                case "${action}" in
-                       config|down|edit|port|show|status|up)
+                       config|down|edit|port|status|up)
                                zone_${action} ${zone} $@
                                ;;
                        *)
index 62c023c4d8d6a508d719a5bc228b7173e85ddb0e..75ad577952a7c800badbac160ff5ffb5bf698d47 100644 (file)
@@ -43,9 +43,19 @@ DB_CONNECTION_FILE="${LOG_DIR}/connections.db"
 EXIT_OK=0
 EXIT_ERROR=1
 EXIT_CONF_ERROR=2
+EXIT_ERROR_ASSERT=3 # XXX needs check 
 
 STATUS_UP=0
 STATUS_DOWN=1
+STATUS_NOCARRIER=2
+
+STATUS_TEXT[${STATUS_UP}]="UP"
+STATUS_TEXT[${STATUS_DOWN}]="DOWN"
+STATUS_TEXT[${STATUS_NOCARRIER}]="NO CARRIER"
+
+STATUS_COLOUR[${STATUS_UP}]=${COLOUR_GREEN}
+STATUS_COLOUR[${STATUS_DOWN}]=${COLOUR_RED}
+STATUS_COLOUR[${STATUS_NOCARRIER}]=${COLOUR_YELLOW}
 
 DISCOVER_OK=0
 DISCOVER_ERROR=1
@@ -58,3 +68,5 @@ SYS_CLASS_NET="/sys/class/net"
 
 # Timeout values
 TIMEOUT_RESTART=2
+
+DEVICE_PRINT_LINE1="    %-20s %s\n"
index 67453c741059343ca661ac1fbff5b95f35b0e1db..54e4d6e64e8e53285fdb5bf86b25b439e9850f2f 100644 (file)
@@ -22,6 +22,8 @@
 function devicify() {
        local device=${1}
 
+       assert isset device
+
        if device_exists ${device}; then
                echo "${device}"
                return ${EXIT_OK}
@@ -41,6 +43,8 @@ function devicify() {
 function macify() {
        local device=${1}
 
+       assert isset device
+
        if mac_is_valid ${device}; then
                echo "${device}"
                return ${EXIT_OK}
@@ -80,20 +84,9 @@ function device_is_bonding() {
 
 # Check if the device bonded in a bonding device
 function device_is_bonded() {
-       local dev
-       for dev in /sys/class/net/*; do
-               # Skip crappy files
-               [ -d "${dev}" ] || continue
-
-               # Continue if not a bonding device
-               device_is_bonding "${dev##*/}" || continue
-
-               if grep -q "\<${1}\>" ${dev}/bonding/slaves; then
-                       return 0
-               fi
-       done
+       local device=${1}
 
-       return 1
+       [ -d "${SYS_CLASS_NET}/${device}/master" ]
 }
 
 # Check if the device is a bridge
@@ -196,6 +189,26 @@ function device_get_type() {
        fi
 }
 
+function device_get_status() {
+       local device=${1}
+
+       assert isset device
+
+       local status=${STATUS_UNKNOWN}
+
+       if ! device_has_carrier ${device}; then
+               status=${STATUS_NOCARRIER}
+       elif device_is_up ${device}; then
+               status=${STATUS_UP}
+       elif device_is_down ${device}; then
+               status=${STATUS_DOWN}
+       fi
+
+       assert isset status
+
+       echo "${status}"
+}
+
 function device_get_address() {
        local device=${1}
 
@@ -233,11 +246,40 @@ function device_set_address() {
        return ${ret}
 }
 
+function device_get() {
+       local from_config
+
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --from-config)
+                               from_config=1
+                               ;;
+                       --no-config)
+                               from_config=0
+                               ;;
+               esac
+               shift
+       done
+
+       local devices
+
+       if [ "${from_config}" != "0" ]; then
+               devices="${devices} $(device_config_list)"
+       fi
+
+       if [ "${from_config}" != "1" ]; then
+               local device
+               for device in ${SYS_CLASS_NET}/*; do
+                       devices="${devices} $(basename ${device})"
+               done
+       fi
+
+       echo ${devices}
+       return ${EXIT_OK}
+}
+
 function devices_get_all() {
-       local device
-       for device in ${SYS_CLASS_NET}/*; do
-               echo "$(basename ${device})"
-       done | sort
+       device_get
 }
 
 # Check if a device has a cable plugged in
@@ -333,6 +375,9 @@ function device_set_name() {
 function device_set_up() {
        local device=$(devicify ${1})
 
+       # Silently fail if device was not found
+       [ -z "${device}" ] && return ${EXIT_ERROR}
+
        # Do nothing if device is already up
        device_is_up ${device} && return ${EXIT_OK}
 
@@ -469,7 +514,7 @@ function device_virtual_create() {
        local vid=${2}
        local mac=${3}
        local newport=${port}v${vid}
-       
+
        if [ -z "${mac}" ]; then
                mac=$(mac_generate)
        fi
@@ -585,6 +630,9 @@ function device_virtual_get_by_parent_and_vid() {
        local parent=${1}
        local vid=${2}
 
+       assert isset parent
+       assert isset vid
+
        local v_port
        local v_id
        local v_parent
@@ -603,15 +651,16 @@ function device_virtual_get_by_parent_and_vid() {
 function bridge_attach_device() {
        local bridge=${1}
        local device=${2}
-       
-       if ! device_exists ${bridge}; then
-               error "Bridge '${bridge}' does not exist."
-               return ${EXIT_ERROR}
-       fi
 
-       if ! device_exists ${device}; then
-               error "Device '${device}' does not exist."
-               return ${EXIT_ERROR}
+       assert isset bridge
+       assert isset device
+
+       assert device_exists ${bridge}
+       assert device_exists ${device}
+
+       # If device is already attached, exit silently
+       if listmatch ${device} $(bridge_get_members ${bridge}); then
+               return ${EXIT_OK}
        fi
 
        log INFO "Attaching device '${device}' to bridge '${bridge}'."
@@ -625,6 +674,9 @@ function bridge_detach_device() {
        local bridge=${1}
        local device=${2}
 
+       assert isset bridge
+       assert isset device
+       
        if ! device_exists ${bridge}; then
                error "Bridge '${bridge}' does not exist."
                return ${EXIT_ERROR}
@@ -639,7 +691,21 @@ function bridge_detach_device() {
 
        brctl delif ${bridge} ${device}
 
-       device_set_down ${device}
+       #device_set_down ${device}
+}
+
+function bridge_get_members() {
+       local bridge=${1}
+
+       assert isset bridge
+
+       local member
+       for member in ${SYS_CLASS_NET}/${bridge}/brif/*; do
+               member=$(basename ${master})
+               if device_exists ${member}; then
+                       echo "${member}"
+               fi
+       done
 }
 
 function bridge_is_forwarding() {
@@ -709,3 +775,148 @@ function device_has_ipv6() {
 
        ip addr show ${device} | grep -q "inet6 ${addr}"
 }
+
+function device_config_list() {
+       local device
+       for device in ${CONFIG_DIR}/devices/*; do
+               device=$(basename ${device})
+               if device_config_exists ${device}; then
+                       echo "${device}"
+               fi
+       done
+}
+
+function device_config_exists() {
+       local device=${1}
+
+       [ -e "${CONFIG_DIR}/devices/${device}" ]
+}
+
+function device_config_write() {
+       local device=${1}
+       shift
+
+       config_write ${CONFIG_DIR}/devices/${device} $@
+}
+
+function device_config_read() {
+       local device=${1}
+
+       config_read ${CONFIG_DIR}/devices/${device}
+}
+
+function device_create() {
+       local hook=${1}
+       shift
+
+       if ! hook_exists device ${hook}; then
+               error "Hook '${hook}' does not exist."
+               return ${EXIT_ERROR}
+       fi
+
+       hook_exec device ${hook} create $@
+}
+
+# XXX to be fixed
+function device_up() {
+       local device=${1}
+       shift
+
+       if ! device_config_exists ${device}; then
+               error "Device '${device}' does not exist."
+               return ${EXIT_ERROR}
+       fi
+
+       local hook=$(config_get_hook ${CONFIG_DIR}/devices/${device})
+
+       if ! hook_exists device ${hook}; then
+               error "Hook '${hook}' does not exist."
+               return ${EXIT_ERROR}
+       fi
+
+       hook_exec device ${hook} up ${device} $@
+}
+
+# XXX to be fixed
+function device_down() {
+       local device=${1}
+       shift
+
+       if ! device_config_exists ${device}; then
+                error "Device '${device}' does not exist."
+                return ${EXIT_ERROR}
+        fi
+
+       local hook=$(config_get_hook ${CONFIG_DIR}/devices/${device})
+
+       if ! hook_exists device ${hook}; then
+               error "Hook '${hook}' does not exist."
+               return ${EXIT_ERROR}
+       fi
+
+       hook_exec device ${hook} down ${device} $@
+}
+
+function device_print() {
+       local device=${1}
+       local type=$(device_get_type ${device})
+
+       echo "${device}"
+       printf "${DEVICE_PRINT_LINE1}" "Type:" "${type}"
+
+       #device_config_exists ${device}
+       #local has_config=$?
+
+       # XXX need something is_function() method here
+       if [ -n "$(type -t ${type}_device_print)" ]; then
+               ${type}_device_print ${device}
+       fi
+
+       echo # Empty line
+}
+
+function __device_get_file() {
+       local device=${1}
+       local file=${2}
+
+       assert isset device
+       assert isset file
+
+       cat ${SYS_CLASS_NET}/${device}/${file}
+}
+
+function device_get_rx_bytes() {
+       local device=${1}
+
+       __device_get_file ${device} statistics/rx_bytes
+}
+
+function device_get_tx_bytes() {
+       local device=${1}
+
+       __device_get_file ${device} statistics/tx_bytes
+}
+
+function device_get_rx_packets() {
+       local device=${1}
+
+       __device_get_file ${device} statistics/rx_packets
+}
+
+function device_get_tx_packets() {
+       local device=${1}
+
+       __device_get_file ${device} statistics/tx_packets
+}
+
+function device_get_rx_errors() {
+       local device=${1}
+
+       __device_get_file ${device} statistics/rx_errors
+}
+
+function device_get_tx_errors() {
+       local device=${1}
+
+       __device_get_file ${device} statistics/tx_errors
+}
diff --git a/functions.ethernet b/functions.ethernet
new file mode 100644 (file)
index 0000000..f0bfbc0
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash
+# XXX header missing
+
+function ethernet_device_print() {
+       local device=${1}
+
+       printf "${DEVICE_PRINT_LINE1}" "Address:" "$(device_get_address ${device})"
+       printf "${DEVICE_PRINT_LINE1}" "MTU:"     "$(device_get_mtu ${device})"
+}
+
+function real_device_print() {
+       warning_log "Deprecated function called: real_device_print"
+
+       ethernet_device_print $@
+}
index 481d3cc51fbf926492729f3a312189a838b57346..57b5389eeea0ba6c7041027550598d705e240633 100644 (file)
@@ -46,7 +46,7 @@ function hook_exec() {
                return ${EXIT_ERROR}
        fi
 
-       ${SHELL} $(hook_dir ${type})/${hook} $@
+       exec_cmd $(hook_dir ${type})/${hook} $@
 }
 
 function config_get_hook() {
@@ -88,6 +88,10 @@ function hook_zone_has_ports() {
        [ -d "$(hook_dir zone)/${hook}.ports" ]
 }
 
+function hook_zone_port_exists() {
+       : # XXX WANTED
+}
+
 function hook_zone_has_configs() {
        local hook=${1}
 
@@ -113,7 +117,7 @@ function hook_zone_port_exec() {
                return ${EXIT_ERROR}
        fi
 
-       ${SHELL} $(hook_dir zone)/${hook_zone}.ports/${hook_port} $@
+       exec_cmd $(hook_dir zone)/${hook_zone}.ports/${hook_port} $@
 }
 
 function hook_zone_config_exec() {
@@ -131,7 +135,7 @@ function hook_zone_config_exec() {
                return ${EXIT_ERROR}
        fi
 
-       ${SHELL} $(hook_dir zone)/${hook_zone}.configs/${hook_config} $@
+       exec_cmd $(hook_dir zone)/${hook_zone}.configs/${hook_config} $@
 }
 
 function hook_zone_get_all() {
@@ -152,10 +156,14 @@ function hook_zone_ports_get_all() {
                return ${EXIT_ERROR}
        fi
 
-       local hook
-       for hook in $(hook_dir zone)/${zone}.ports/*; do
-               hook=$(basename ${hook})
+       local h
+       for h in $(hook_dir zone)/${hook}.ports/*; do
+               h=$(basename ${h})
                ## XXX executeable?
-               echo "${hook}"
+               echo "${h}"
        done | sort
 }
+
+function hook_device_exists() {
+       hook_exists device $@
+}
diff --git a/functions.ports b/functions.ports
new file mode 100644 (file)
index 0000000..25ce046
--- /dev/null
@@ -0,0 +1,130 @@
+#!/bin/bash
+# XXX header missing
+
+function port_dir() {
+       echo "${CONFIG_DIR}/ports"
+}
+
+function port_file() {
+       local port=${1}
+
+       assert isset port
+
+       echo "$(port_dir)/${port}"
+}
+
+function port_exists() {
+       local port=${1}
+
+       [ -f "${CONFIG_DIR}/ports/${port}" ]
+}
+
+function port_get_hook() {
+       local port=${1}
+
+       assert isset port
+
+       config_get_hook $(port_file ${port})
+}
+
+function port_is_attached() {
+       local port=${1}
+       shift
+
+       assert isset port
+
+       local zone
+       for zone in $(zones_get_all); do
+
+               assert isset zone
+               assert zone_exists ${zone}
+
+               if listmatch ${port} $(zone_get_ports ${zone}); then
+                       echo "${zone}"
+                       return ${EXIT_OK}
+               fi
+       done
+
+       return ${EXIT_ERROR}
+}
+
+function port_create() {
+       #local port=${1}
+       #shift
+       #
+       #if port_exists ${port}; then
+       #       error "Port '${port}' does already exist."
+       #       return ${EXIT_ERROR}
+       #fi
+
+       local hook=${1}
+       shift
+
+       if ! hook_exists port ${hook}; then
+               error "Port hook '${hook}' does not exist."
+               return ${EXIT_ERROR}
+       fi
+
+       #port_edit ${port} ${hook} $@
+       #
+       #if [ $? -ne ${EXIT_OK} ]; then
+       #       port_destroy ${port}
+       #fi
+
+       hook_exec port ${hook} create $@
+}
+
+function port_destroy() {
+       local port=${1}
+
+       assert isset port
+
+       port_exists ${port} || return ${EXIT_OK}
+
+       local attached_zone=$(port_is_attached ${port})
+
+       if [ -n "${attached_zone}" ]; then
+               error "Cannot destroy port '${port}' which is attached to zone '${attached_zone}'."
+               return ${EXIT_ERROR}
+       fi
+
+       port_down ${port}
+
+       rm -f $(port_file ${port})
+}
+
+function port_edit() {
+       port_cmd edit $@
+}
+
+# XXX? Compatibility function
+function port_show() {
+       port_status $@
+}
+
+function port_up() {
+       port_cmd up $@
+}
+
+function port_down() {
+       port_cmd down $@
+}
+
+function port_status() {
+       port_cmd status $@
+}
+
+function port_cmd() {
+       local cmd=${1}
+       local port=${2}
+       shift 2
+
+       assert isset cmd
+       assert isset port
+
+       local hook=$(port_get_hook ${port})
+
+       assert isset hook
+
+       hook_exec port ${hook} ${cmd} ${port} $@
+}
index 7c8d3414d9e7d4c848f64f868705eaa103d32193..c1c5dae5787581844c2214d60050cd72b5c49e0f 100644 (file)
 #                                                                             #
 ###############################################################################
 
+function ppp_init() {
+       mkdir -p /var/run/ppp 2>/dev/null
+}
+
 function ppp_common_ip_pre_up() {
        local zone=${1}
        shift
@@ -98,3 +102,11 @@ function ppp_accounting() {
        db_ppp_update ${zone} --duration="${CONNECT_TIME}" \
                --rcvd="${BYTES_RCVD}" --sent="${BYTES_SENT}"
 }
+
+function pppd_exec() {
+       ppp_init
+
+       log DEBUG "Running pppd with parameters '$@'."
+
+       pppd $@ > /dev/null
+}
index 8705726ca1b557f0b919a5112309c8c29121ba55..83ec302c9812c8c24a141635ac8fa600cd7c0726 100644 (file)
@@ -39,6 +39,7 @@ function warning_log() {
        log WARNING "$@"
 }
 
+# XXX uses tr
 function listsort() {
        local i
        for i in $@; do
@@ -46,6 +47,31 @@ function listsort() {
        done | sort | tr "\n" " "
 }
 
+function listmatch() {
+       local match=${1}
+       shift
+
+       assert isset match
+
+       local i
+       for i in $@; do
+               [ "${match}" = "${i}" ] && return ${EXIT_OK}
+       done
+
+       return ${EXIT_ERROR}
+}
+
+function listlength() {
+       local length=0
+
+       local i
+       for i in $@; do
+               length=$(( ${length} + 1 ))
+       done
+
+       echo "${length}"
+}
+
 function config_read() {
        local config_file=${1}
 
@@ -219,17 +245,51 @@ function ismac() {
        mac_is_valid ${mac}
 }
 
+function backtrace() {
+       local start=1
+
+       echo # Empty line
+       error_log "Backtrace (most recent call in first line):"
+
+       local i
+       for i in $(seq ${start} ${#BASH_SOURCE[*]}); do
+               [ -z "${FUNCNAME[${i}]}" ] && continue
+               [ "${FUNCNAME[${i}]}" == "main" ] && continue
+
+               error_log "  $(printf "%20s" "'${FUNCNAME[${i}]}'") called from ${BASH_SOURCE[$(( ${i} + 1 ))]}:${BASH_LINENO[${i}]}"
+       done
+}
+
 function assert() {
        local assertion="$@"
 
        if ! ${assertion}; then
                error_log "Assertion '${assertion}' failed."
+               backtrace
                exit ${EXIT_ERROR}
        fi
 
        return ${EXIT_OK}
 }
 
+function exec_cmd() {
+       local cmd=$@
+
+       log DEBUG "Running command: ${cmd}"
+
+       ${SHELL} ${cmd}
+       local ret=$?
+
+       #log DEBUG "Returned with code '${ret}'"
+
+       if [ ${ret} -eq ${EXIT_ERROR_ASSERT} ]; then
+               error_log "Stopping parent process due to assertion error in child process: ${cmd}"
+               exit ${EXIT_ERROR_ASSERT}
+       fi
+
+       return ${ret}
+}
+
 function uppercase() {
        local input
        read input
@@ -275,3 +335,16 @@ function beautify_time() {
 
        echo "${value}${unit}"
 }
+
+function beautify_bytes() {
+       local value=${1}
+
+       local unit
+       local limit=1024
+       for unit in B k M G T; do
+               [ ${value} -lt ${limit} ] && break
+               value=$(( ${value} / ${limit} ))
+       done
+
+       echo "${value}${unit}"
+}
index 1fc631c05303d48a6fb40f9fb3b66a572ec55ad6..981c8e27e5535226b3a70df7ba7b7db8b5f96091 100644 (file)
 function zone_dir() {
        local zone=${1}
 
+       #assert isset zone
+
        echo "${ZONE_DIR}/zones/${zone}"
 }
 
 function zone_exists() {
        local zone=${1}
 
+       assert isset zone
+
        [ -d "$(zone_dir ${zone})" ]
 }
 
@@ -45,6 +49,8 @@ function zone_match() {
 function zone_name_is_valid() {
        local zone=${1}
 
+       assert isset zone
+
        [[ ${zone} =~ $(zone_match) ]]
 }
 
@@ -57,12 +63,16 @@ function zone_is_local() {
 function zone_is_nonlocal() {
        local zone=${1}
 
+       assert isset zone
+
        [[ ${zone} =~ ^red[0-9]{1,5} ]]
 }
 
 function zone_get_hook() {
        local zone=${1}
 
+       assert isset zone
+
        config_get_hook $(zone_dir ${zone})/settings
 }
 
@@ -216,6 +226,7 @@ function zone_status() {
        hook_zone_exec ${hook} status ${zone} $@
 }
 
+# XXX deprecated
 function zone_port() {
        local zone=${1}
        shift
@@ -240,6 +251,130 @@ function zone_port() {
        hook_zone_exec ${hook} port ${zone} $@
 }
 
+function zone_port() {
+       local zone=${1}
+       local action=${2}
+       shift 2
+
+       assert isset zone
+       assert isset action
+       assert zone_exists ${zone}
+
+       case "${action}" in
+               add|remove|edit)
+                       zone_port_${action} ${zone} $@
+                       ;;
+       esac
+}
+
+function zone_port_add() {
+       local zone=${1}
+       local port=${2}
+       shift 2
+
+       assert isset zone
+       assert isset port
+       assert zone_exists ${zone}
+
+       local hook_port=$(port_get_hook ${port})
+
+       assert isset hook_port
+
+       if ! listmatch ${hook_port} $(zone_get_supported_hooks ${zone}); then
+               error "Zone '${zone}' does not support ports with hook '${hook_port}'."
+               return ${EXIT_ERROR}
+       fi
+
+       # XXX does this already exist?
+
+       # XXX I would rather like a relative symlink
+       ln -sf $(port_file ${port}) $(zone_dir ${zone})/port.${port}
+}
+
+function zone_port_add() {
+       local zone=${1}
+       shift
+
+       assert isset zone
+
+       local hook=$(zone_get_hook ${zone})
+
+       assert isset hook
+
+       hook_zone_exec ${hook} port_add ${zone} $@
+}
+
+function zone_port_edit() {
+       local zone=${1}
+       local port=${2}
+       shift 2
+
+       assert isset zone
+       assert isset port
+
+       port_edit ${port} $@
+}
+
+function zone_port_remove() {
+       local zone=${1}
+       local port=${2}
+       shift 2
+
+       assert isset zone
+       assert isset port
+
+       rm -f $(zone_dir ${zone})/port.${port}
+}
+
+function zone_port_cmd() {
+       local cmd=${1}
+       local zone=${2}
+       local port=${3}
+       shift 3
+
+       assert isset zone
+       assert isset port
+
+       local hook_zone=$(zone_get_hook ${zone})
+       local hook_port=$(port_get_hook ${port})
+
+       assert isset hook_zone
+       assert isset hook_port
+
+       assert hook_zone_port_exists ${hook_zone} ${hook_port}
+
+       hook_zone_port_exec ${hook_zone} ${hook_port} ${cmd} ${zone} ${port} $@
+}
+
+function zone_port_cmd() {
+       error_log "UNSUPPORTED FUNCTION CALLED: zone_port_cmd"
+       backtrace
+}
+
+function zone_port_up() {
+       zone_port_cmd up $@
+}
+
+function zone_port_down() {
+       zone_port_cmd down $@
+}
+
+function zone_get_ports() {
+       local zone=${1}
+
+       assert isset zone
+
+       local port
+       for port in $(zone_dir ${zone})/port.*; do
+               port=$(basename ${port})
+               port=${port#port.}
+
+               if port_exists ${port}; then
+                       echo "${port}"
+               fi
+       done
+}
+
 function zone_config() {
        local zone=${1}
        shift
@@ -368,23 +503,30 @@ function zone_ports_cmd() {
        local zone=${2}
        shift 2
 
-       local hook_zone=$(config_get_hook $(zone_dir ${zone})/settings)
+       assert isset cmd
+       assert isset zone
 
-       local hook_port
-       local port
-       for port in $(zone_ports_list ${zone}); do
-               hook_port=$(config_get_hook $(zone_dir ${zone})/${port})
+       assert zone_exists ${zone}
 
-               hook_zone_port_exec ${hook_zone} ${hook_port} ${cmd} ${zone} ${port} $@
+       local hook=$(zone_get_hook ${zone})
+
+       local port
+       for port in $(zone_get_ports ${zone}); do
+               #zone_port_cmd ${cmd} ${zone} ${port} $@
+               hook_zone_exec ${hook} ${cmd} ${zone} ${port} $@
        done
 }
 
 function zone_ports_up() {
-       zone_ports_cmd up $@
+       zone_ports_cmd port_up $@
 }
 
 function zone_ports_down() {
-       zone_ports_cmd down $@
+       zone_ports_cmd port_down $@
+}
+
+function zone_ports_status() {
+       zone_ports_cmd port_status $@
 }
 
 function zone_configs_list() {
@@ -451,3 +593,53 @@ function zone_is_up() {
 function zone_is_down() {
        ! zone_is_up $@
 }
+
+function zone_get_supported_hooks() {
+       local zone=${1}
+
+       local hook=$(zone_get_hook ${zone})
+
+       hook_zone_ports_get_all ${hook}
+}
+
+function zone_file() {
+       local zone=${1}
+
+       assert isset zone
+
+       echo "$(zone_dir ${zone})/settings"
+}
+
+function zone_config_read() {
+       local zone=${1}
+
+       assert isset zone
+
+       config_read $(zone_file ${zone})
+}
+
+function zone_config_write() {
+       local zone=${1}
+
+       assert isset zone
+
+       config_write $(zone_file ${zone}) ${HOOK_SETTINGS}
+}
+
+function zone_config_set() {
+       local zone=${1}
+       shift
+       local args="$@"
+
+       assert isset zone
+
+       (
+               zone_config_read ${zone}
+
+               for arg in ${args}; do
+                       eval "${arg}"
+               done
+       
+               zone_config_write ${zone}
+       )
+}
diff --git a/header-device b/header-device
new file mode 100644 (file)
index 0000000..ab2fb18
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2010  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/>.       #
+#                                                                             #
+###############################################################################
+
+. /lib/network/functions
+
+HOOK=$(basename ${0})
+
+while [ $# -gt 0 ]; do
+       case "${1}" in
+               -*)
+                       error "Unrecognized option: ${1}"
+                       exit ${EXIT_ERROR}
+                       ;;
+               *)
+                       action=${1}
+                       ;;
+       esac
+       shift
+       [ -n "${action}" ] && break
+done
+
+function run() {
+       case "${action}" in
+               create|rem|up|down|status)
+                       _${action} $@
+                       ;;
+       esac
+
+       error "Port hook '${HOOK}' didn't exit properly."
+       exit ${EXIT_ERROR}
+}
diff --git a/hooks/ports/bonding b/hooks/ports/bonding
new file mode 100755 (executable)
index 0000000..9e04435
--- /dev/null
@@ -0,0 +1,203 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2010  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/>.       #
+#                                                                             #
+###############################################################################
+
+. /lib/network/header-port
+
+HOOK_SETTINGS="HOOK DEVICE_MAC MIIMON MODE SLAVES"
+
+DEVICE_MAC=$(mac_generate)
+MIIMON=100
+
+function _check() {
+       assert isset DEVICE_MAC
+       assert ismac DEVICE_MAC
+
+       #assert isset SLAVES
+       assert isinteger MIIMON
+}
+
+function _create() {
+       _edit $@
+}
+
+function _edit() {
+       local port=${1}
+       shift
+
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --mac=*)
+                               DEVICE_MAC=${1#--mac=}
+                               ;;
+                       --miimon=*)
+                               MIIMON=${1#--miimon=}
+                               ;;
+                       --mode=*)
+                               MODE=${1#--mode=}
+                               ;;
+                       --slave=*)
+                               slave=${1#--slave=}
+                               SLAVES="${SLAVES} $(macify ${slave})"
+                               ;;
+                       *)
+                               warning "Unknown argument '${1}'"
+                               ;;
+               esac
+               shift
+       done
+
+       DEVICE=${port}
+
+       # XXX think this must move to _check()
+       if ! isset DEVICE; then
+               error "You must set a device name."
+               exit ${EXIT_ERROR}
+       fi
+
+       if ! isset SLAVES; then
+               error "You need to specify at least one slave port (e.g. --slave=port0)."
+               exit ${EXIT_ERROR}
+       fi
+
+       local slave
+       for slave in ${SLAVES}; do
+               if ! device_is_real $(devicify ${slave}); then
+                       error "Slave device '${slave}' is not an ethernet device."
+                       exit ${EXIT_ERROR}
+               fi
+       done
+
+       # Remove any whitespace
+       SLAVES=$(echo ${SLAVES})
+
+       config_write $(port_file ${port}) ${HOOK_SETTINGS}
+
+       exit ${EXIT_OK}
+}
+
+function _up() {
+       local device=${1}
+
+       config_read $(port_file ${device})
+
+       if device_exists ${device}; then
+               log DEBUG "Bonding device '${device}' does already exist."
+
+               device_set_address ${DEVICE_MAC}
+               device_set_up ${device}
+
+               exit ${EXIT_OK}
+       fi
+
+       bonding_create ${device} ${DEVICE_MAC}
+
+       if [ -n "${MODE}" ]; then
+               bonding_set_mode ${device} ${MODE}
+       fi
+
+       bonding_set_miimon ${device} ${MIIMON}
+
+       local slave
+       for slave in ${SLAVES}; do
+               if ! device_exists $(devicify ${slave}); then
+                       warning_log "${device}: configured slave '${slave}' is not available."
+                       continue
+               fi
+               
+               slave=$(devicify ${slave})
+               assert isset slave
+
+               bonding_enslave_device ${device} ${slave}
+       done
+
+       exit ${EXIT_OK}
+}
+
+function _down() {
+       local device=${1}
+
+       bonding_remove ${device}
+
+       local slave
+       for slave in ${SLAVES}; do
+               device_set_down ${slave}
+       done
+
+       exit ${EXIT_OK}
+}
+
+function _status() {
+        local port=${1}
+        shift
+
+        assert isset port
+
+        echo "${port}"
+
+        local status=$(device_get_status ${port})
+        printf "${DEVICE_PRINT_LINE1}" "Status:" "$(echo -ne ${STATUS_COLOUR[${status}]}${STATUS_TEXT[${status}]}${COLOUR_NORMAL})"
+
+        cli_headline "  Ethernet information:"
+        printf "${DEVICE_PRINT_LINE1}" "Address:" $(device_get_address ${port})
+        printf "${DEVICE_PRINT_LINE1}" "MTU:" $(device_get_mtu ${port})
+        printf "${DEVICE_PRINT_LINE1}" "Promisc mode:" $(device_is_promisc ${port} && echo "yes" || echo "no")
+
+        if device_is_bonded ${port}; then
+                cli_headline "  Bonding information:"
+
+                local master=$(bonding_slave_get_master ${port})
+                printf "${DEVICE_PRINT_LINE1}" "Master:" "${master}"
+
+                local active
+                if [ "$(bonding_get_active_slave ${master})" = "${port}" ]; then
+                        active="yes"
+                else
+                        active="no"
+                fi
+                printf "${DEVICE_PRINT_LINE1}" "Active slave:" "${active}"
+        fi
+
+       if device_is_bonding ${port}; then
+               cli_headline "  Bonding information:"
+
+               printf "${DEVICE_PRINT_LINE1}" "Mode:" "$(bonding_get_mode ${port})"
+               # XXX lacp rate
+               echo
+
+               local slave
+               local slave_active=$(bonding_get_active_slave ${port})
+               for slave in $(bonding_get_slaves ${port}); do
+                       printf "${DEVICE_PRINT_LINE1}" "Slave$([ "${slave}" = "${slave_active}" ] && echo " (active)"):" "${slave}"
+               done
+       fi
+
+        cli_headline "  Statistics:"
+        printf "${DEVICE_PRINT_LINE1}" "Received:" \
+                "$(beautify_bytes $(device_get_rx_bytes ${port})) ($(device_get_rx_packets ${port}) packets)"
+        printf "${DEVICE_PRINT_LINE1}" "Sent:" \
+                "$(beautify_bytes $(device_get_tx_bytes ${port})) ($(device_get_tx_packets ${port}) packets)"
+
+        echo
+
+        exit ${EXIT_OK}
+}
+
+run $@
diff --git a/hooks/ports/ethernet b/hooks/ports/ethernet
new file mode 100755 (executable)
index 0000000..2d49f49
--- /dev/null
@@ -0,0 +1,105 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2010  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/>.       #
+#                                                                             #
+###############################################################################
+
+. /lib/network/header-port
+
+HOOK_SETTINGS="HOOK DEVICE_MAC"
+
+function _check() {
+       assert ismac DEVICE_MAC
+}
+
+function _create() {
+       local port=${1}
+       shift
+
+       assert isset port
+
+       DEVICE_MAC=$(device_get_address ${port})
+
+       config_write $(port_file ${port}) ${HOOK_SETTINGS}
+
+       exit ${EXIT_OK}
+}
+
+function _up() {
+       local port=${1}
+
+       assert isset port
+
+       device_set_up ${port}
+
+       exit ${EXIT_OK}
+}
+
+function _down() {
+       local port=${1}
+
+       assert isset port
+
+       device_set_down ${port}
+
+       exit ${EXIT_OK}
+}
+
+function _status() {
+       local port=${1}
+       shift
+
+       assert isset port
+
+       echo "${port}"
+
+       local status=$(device_get_status ${port})
+       printf "${DEVICE_PRINT_LINE1}" "Status:" "$(echo -ne ${STATUS_COLOUR[${status}]}${STATUS_TEXT[${status}]}${COLOUR_NORMAL})"
+
+       cli_headline "  Ethernet information:"
+       printf "${DEVICE_PRINT_LINE1}" "Address:" $(device_get_address ${port})
+       printf "${DEVICE_PRINT_LINE1}" "MTU:" $(device_get_mtu ${port})
+       printf "${DEVICE_PRINT_LINE1}" "Promisc mode:" $(device_is_promisc ${port} && echo "yes" || echo "no")
+
+       if device_is_bonded ${port}; then
+               cli_headline "  Bonding information:"
+
+               local master=$(bonding_slave_get_master ${port})
+               printf "${DEVICE_PRINT_LINE1}" "Master:" "${master}"
+
+               local active
+               if [ "$(bonding_get_active_slave ${master})" = "${port}" ]; then
+                       active="yes"
+               else
+                       active="no"
+               fi
+               printf "${DEVICE_PRINT_LINE1}" "Active slave:" "${active}"
+       fi
+
+       cli_headline "  Statistics:"
+       printf "${DEVICE_PRINT_LINE1}" "Received:" \
+               "$(beautify_bytes $(device_get_rx_bytes ${port})) ($(device_get_rx_packets ${port}) packets)"
+       printf "${DEVICE_PRINT_LINE1}" "Sent:" \
+               "$(beautify_bytes $(device_get_tx_bytes ${port})) ($(device_get_tx_packets ${port}) packets)"
+
+       echo
+
+       exit ${EXIT_OK}
+}
+
+run $@
diff --git a/hooks/ports/virtual b/hooks/ports/virtual
new file mode 100755 (executable)
index 0000000..4c35ebc
--- /dev/null
@@ -0,0 +1,152 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2010  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/>.       #
+#                                                                             #
+###############################################################################
+
+. /lib/network/header-port
+
+HOOK_SETTINGS="HOOK DEVICE DEVICE_MAC DEVICE_VID"
+
+DEVICE_MAC=$(mac_generate)
+
+function _check() {
+       assert isset DEVICE
+       assert ismac DEVICE_MAC
+       assert isinteger DEVICE_VID
+
+       if [ ${DEVICE_VID} -gt 4096 ]; then
+               error "DEVICE_VID is greater than 4096."
+               exit ${EXIT_ERROR}
+       fi
+
+       local reserved
+       for reserved in 0 4095; do
+               if [ "${DEVICE_VID}" = "${reserved}" ]; then
+                       error "DEVICE_VID=${reserved} is reserved."
+                       exit ${EXIT_ERROR}
+               fi
+       done
+}
+
+function _create() {
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --device=*)
+                               DEVICE=${1#--device=}
+                               ;;
+                       --mac=*)
+                               DEVICE_MAC=${1#--mac=}
+                               ;;
+                       --id=*)
+                               DEVICE_VID=${1#--id=}
+                               ;;
+                       *)
+                               warning "Unknown argument '${1}'"
+                               ;;
+               esac
+               shift
+       done
+
+       local port="${DEVICE}v${DEVICE_VID}"
+
+       config_write $(port_file ${port}) ${HOOK_SETTINGS}
+
+       exit ${EXIT_OK}
+}
+
+function _edit() {
+       local port=${1}
+       shift
+
+       assert isset port
+
+       config_read $(port_file ${port})
+
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --mac=*)
+                               DEVICE_MAC=${1#--mac=}
+                               ;;
+                       *)
+                               warning "Unknown argument '${1}'"
+                               ;;
+               esac
+               shift
+       done
+
+       config_write $(port_file ${port}) ${HOOK_SETTINGS}
+
+       exit ${EXIT_OK} 
+}
+
+function _up() {
+       local port=${1}
+
+       assert isset port
+
+       config_read $(port_file ${port})
+
+       if ! device_exists ${port}; then
+               device_virtual_create ${DEVICE} ${DEVICE_VID} ${DEVICE_MAC}
+       fi
+
+       exit ${EXIT_OK}
+}
+
+function _down() {
+       local port=${1}
+
+       assert isset port
+
+       config_read $(port_file ${port})
+
+       if ! device_exists ${port}; then
+               exit ${EXIT_OK}
+       fi
+
+       device_virtual_remove ${port}
+
+       exit ${EXIT_OK}
+}
+
+function _status() {
+       local zone=${1}
+       local port=${2}
+
+config_read $(zone_dir ${zone})/${port}
+
+       local device=$(devicify ${DEVICE_MAC})
+
+       printf "        %-10s - " "${device}"
+       if ! device_is_up ${device}; then
+               echo -ne "${COLOUR_DOWN}   DOWN   ${COLOUR_NORMAL}"
+       else
+               local state=$(stp_port_state ${zone} ${device})
+               local colour="COLOUR_STP_${state}"
+               printf "${!colour}%10s${COLOUR_NORMAL}" ${state}
+       fi
+
+       echo -n " - DSR: $(stp_port_designated_root ${zone} ${device})"
+       echo -n " - Cost: $(stp_port_pathcost ${zone} ${device})"
+       echo
+
+       exit ${EXIT_OK}
+}
+
+run $@
index e4bc1f7b4fbc6d9bf09218e0667cd78197532a31..1108bb2a0d1d010eb776583fd37962d98dd324cb 100755 (executable)
@@ -114,8 +114,6 @@ function _up() {
        zone_configs_up ${zone}
 
        event_interface_up ${zone}
-
-       exit $?
 }
 
 function _down() {
@@ -164,7 +162,7 @@ function _status() {
        printf "        Topology change count : %6s\n" $(stp_topology_change_count ${zone})
 
        cli_headline "    Ports:"
-       zone_ports_cmd status ${zone}
+       zone_ports_status ${zone}
 
        cli_headline "    Configurations:"
        zone_configs_cmd status ${zone}
@@ -173,17 +171,4 @@ function _status() {
        exit ${EXIT_OK}
 }
 
-function _addport() {
-       local zone=${1}
-       local hook=${2}
-       shift 2
-
-       if ! port_hook_exists ${hook}; then
-               error "Hook does not exist '${hook}'"
-               exit ${EXIT_ERROR}
-       fi
-
-       port_hook ${hook} add ${zone}
-}
-
 run $@
deleted file mode 100755 (executable)
index 2680d56216a95784ccf78f18d1124724a5b4d89b..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/bin/bash
-###############################################################################
-#                                                                             #
-# IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2010  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/>.       #
-#                                                                             #
-###############################################################################
-
-. /lib/network/header-port
-
-HOOK_SETTINGS="HOOK DEVICE_MAC DEVICE_NAME MODE SLAVES"
-
-DEVICE_NAME="bond0" # XXX DEVICE_NAME must be unique
-DEVICE_MAC=$(mac_generate)
-
-function _check() {
-       assert isset DEVICE_MAC
-       assert ismac DEVICE_MAC
-       assert isset DEVICE_NAME
-
-       assert isset SLAVES
-}
-
-function _create() {
-       local zone=${1}
-       shift
-
-       local
-
-       while [ $# -gt 0 ]; do
-               case "${1}" in
-                       --mac=*)
-                               DEVICE_MAC=${1#--mac=}
-                               ;;
-                       --mode=*)
-                               MODE=${1#--mode=}
-                               ;;
-                       --slave=*)
-                               slave=${1#--slave=}
-                               SLAVES="${SLAVES} $(macify ${slave})"
-                               ;;
-                       *)
-                               warning "Unknown argument '${1}'"
-                               ;;
-               esac
-               shift
-       done
-
-       # Remove any whitespace
-       SLAVES=$(echo ${SLAVES})
-
-       _check
-
-       config_write $(zone_dir ${zone})/port.${HOOK}.$(device_hash ${DEVICE_MAC}) ${HOOK_SETTINGS}
-
-       exit ${EXIT_OK}
-}
-
-function _up() {
-       local zone=${1}
-       local port=${2}
-
-       config_read $(zone_dir ${zone})/${port}
-
-       if ! device_exists $(devicify ${DEVICE_MAC}); then
-               device_virtual_create ${DEVICE} ${DEVICE_VID} ${DEVICE_MAC}
-       fi
-
-       local device=$(devicify ${DEVICE_MAC})
-
-       # Set same MTU to device that the bridge has got
-       device_set_mtu ${device} $(device_get_mtu ${zone})
-
-       bridge_attach_device ${zone} ${device}
-
-       exit ${EXIT_OK}
-}
-
-run $@
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..3857774abcff9e4c36abf3b1d399afd4f65ea037
--- /dev/null
@@ -0,0 +1 @@
+ethernet
\ No newline at end of file
index d25448854bf9a69505b456078d1b93db466e866b..0b8fd78e45b64546bccc40aca42ffe6a1639b161 100755 (executable)
@@ -24,8 +24,8 @@
 HOOK_SETTINGS="HOOK DEVICE"
 
 function _check() {
-       assert isset DEVICE
-       assert ismac DEVICE
+       assert isset DEVICE_MAC
+       assert ismac DEVICE_MAC
 }
 
 function _create() {
@@ -53,21 +53,18 @@ function _up() {
        local zone=${1}
        local port=${2}
 
-       config_read $(zone_dir ${zone})/${port}
+       assert isset zone
+       assert isset port
 
-       local device=$(devicify ${DEVICE})
+       assert zone_exists ${zone}
+       assert port_exists ${port}
 
-       if ! device_exists ${device}; then
-               warning "Device '${DEVICE}' does not exist."
-               exit ${EXIT_ERROR}
-       fi
+       port_up ${port}
 
        # Set same MTU to device that the bridge has got
-       device_set_mtu ${device} $(device_get_mtu ${zone})
+       device_set_mtu ${port} $(device_get_mtu ${zone})
 
-       device_set_up ${device}
-
-       bridge_attach_device ${zone} ${device}
+       bridge_attach_device ${zone} ${port}
 
        exit ${EXIT_OK}
 }
@@ -76,18 +73,15 @@ function _down() {
        local zone=${1}
        local port=${2}
 
-       config_read $(zone_dir ${zone})/${port}
-
-       local device=$(devicify ${DEVICE})
+       assert isset zone
+       assert isset port
 
-       if ! device_exists ${device}; then
-               warning "Device '${DEVICE}' does not exist."
-               exit ${EXIT_ERROR}
-       fi
+       assert zone_exists ${zone}
+       assert port_exists ${port}
 
-       bridge_detach_device ${zone} ${device}
+       bridge_detach_device ${zone} ${port}
 
-       device_set_down ${device}
+       port_down ${port}
 
        exit ${EXIT_OK}
 }
@@ -96,21 +90,18 @@ function _status() {
        local zone=${1}
        local port=${2}
 
-       config_read $(zone_dir ${zone})/${port}
-
-       local device=$(devicify ${DEVICE})
-
-       printf "        %-10s - " "${device}"
-       if ! device_is_up ${device}; then
+       printf "        %-10s - " "${port}"
+       if ! device_is_up ${port}; then
                echo -ne "${COLOUR_DOWN}   DOWN   ${COLOUR_NORMAL}"
        else
-               local state=$(stp_port_state ${zone} ${device})
+               local state=$(stp_port_state ${zone} ${port})
                local colour="COLOUR_STP_${state}"
                printf "${!colour}%10s${COLOUR_NORMAL}" ${state}
+
+               echo -n " - DSR: $(stp_port_designated_root ${zone} ${port})"
+               echo -n " - Cost: $(stp_port_pathcost ${zone} ${port})"
        fi
-       
-       echo -n " - DSR: $(stp_port_designated_root ${zone} ${device})"
-       echo -n " - Cost: $(stp_port_pathcost ${zone} ${device})"
+
        echo
 
        exit ${EXIT_OK}
deleted file mode 100755 (executable)
index 0e350bbb8379a9e496dffddfccd6190c3e330a23..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/bin/bash
-###############################################################################
-#                                                                             #
-# IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2010  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/>.       #
-#                                                                             #
-###############################################################################
-
-. /lib/network/header-port
-
-HOOK_SETTINGS="HOOK DEVICE DEVICE_MAC DEVICE_VID"
-
-DEVICE_MAC=$(mac_generate)
-
-function _check() {
-       assert ismac DEVICE
-       assert ismac DEVICE_MAC
-
-       assert isinteger DEVICE_VID
-
-       if [ ${DEVICE_VID} -gt 4096 ]; then
-               error "DEVICE_VID is greater than 4096."
-               exit ${EXIT_ERROR}
-       fi
-
-       local reserved
-       for reserved in 0 4095; do
-               if [ "${DEVICE_VID}" = "${reserved}" ]; then
-                       error "DEVICE_VID=${reserved} is reserved."
-                       exit ${EXIT_ERROR}
-               fi
-       done
-}
-
-function _create() {
-       local zone=${1}
-       local device=${2}
-       shift 2
-
-       while [ $# -gt 0 ]; do
-               case "${1}" in
-                       --mac=*)
-                               DEVICE_MAC=${1#--mac=}
-                               ;;
-                       --id=*)
-                               DEVICE_VID=${1#--id=}
-                               ;;
-                       *)
-                               warning "Unknown argument '${1}'"
-                               ;;                      
-               esac
-               shift
-       done
-
-       DEVICE=$(macify ${device})
-
-       _check
-
-       config_write $(zone_dir ${zone})/port.${HOOK}.$(device_hash ${device}).${DEVICE_VID} ${HOOK_SETTINGS}
-
-       exit ${EXIT_OK} 
-}
-
-function _edit() {
-       local zone=${1}
-
-       error "TODO - edit mac addres"
-
-       exit ${EXIT_ERROR}
-}
-
-function _up() {
-       local zone=${1}
-       local port=${2}
-
-       config_read $(zone_dir ${zone})/${port}
-
-       if ! device_exists $(devicify ${DEVICE_MAC}); then
-               device_virtual_create ${DEVICE} ${DEVICE_VID} ${DEVICE_MAC}
-       fi
-
-       local device=$(devicify ${DEVICE_MAC})
-
-       # Set same MTU to device that the bridge has got
-       device_set_mtu ${device} $(device_get_mtu ${zone})
-
-       bridge_attach_device ${zone} ${device}
-
-       exit ${EXIT_OK}
-}
-
-function _down() {
-       local zone=${1}
-       local port=${2}
-
-       config_read $(zone_dir ${zone})/${port}
-
-       local device=$(devicify ${DEVICE_MAC})
-
-       if ! device_exists ${device}; then
-               error "Device '${DEVICE_MAC}' does not exist."
-               exit ${EXIT_ERROR}
-       fi
-
-       bridge_detach_device ${zone} ${device}
-
-       device_virtual_remove ${device}
-
-       exit ${EXIT_OK}
-}
-
-function _status() {
-       local zone=${1}
-       local port=${2}
-
-       config_read $(zone_dir ${zone})/${port}
-
-       local device=$(devicify ${DEVICE_MAC})
-
-       printf "        %-10s - " "${device}"
-       if ! device_is_up ${device}; then
-               echo -ne "${COLOUR_DOWN}   DOWN   ${COLOUR_NORMAL}"
-       else
-               local state=$(stp_port_state ${zone} ${device})
-               local colour="COLOUR_STP_${state}"
-               printf "${!colour}%10s${COLOUR_NORMAL}" ${state}
-       fi
-
-       echo -n " - DSR: $(stp_port_designated_root ${zone} ${device})"
-       echo -n " - Cost: $(stp_port_pathcost ${zone} ${device})"
-       echo
-
-       exit ${EXIT_OK}
-}
-
-run $@
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..3857774abcff9e4c36abf3b1d399afd4f65ea037
--- /dev/null
@@ -0,0 +1 @@
+ethernet
\ No newline at end of file
index a3a1688068d4ae2af9e6a5e5628039b244f19612..3cf4877b4b681dfa305496969209da91bf8f3a5a 100755 (executable)
@@ -23,8 +23,7 @@
 
 # TODO AC name, service name, sync?
 
-HOOK_SETTINGS="HOOK AUTH LINKNAME USER SECRET PEERDNS DEFAULTROUTE MTU"
-HOOK_SETTINGS="${HOOK_SETTINGS} DEVICE DEVICE_VID DEVICE_TYPE"
+HOOK_SETTINGS="HOOK AUTH LINKNAME USER SECRET PEERDNS DEFAULTROUTE MTU PORTS"
 
 AUTH=
 DEFAULTROUTE=1
@@ -35,19 +34,9 @@ SECRET=
 USER=
 
 PPPOE_ALLOWED_AUTHS="chap pap"
+PPPOE_ALLOWED_PORTS="bonding ethernet virtual"
 PPPOE_PLUGIN="rp-pppoe.so"
 
-function _pppoe_real_device() {
-       local device
-       if [ -n "${DEVICE_VID}" ]; then
-               device="${DEVICE_MAC}"
-       else
-               device="${DEVICE}"
-       fi
-
-       devicify ${device}
-}
-
 function pppd_pid() {
        local zone=${1}
        shift
@@ -61,19 +50,24 @@ function _check() {
        assert isset LINKNAME
        assert isset DEFAULTROUTE
        assert isset PEERDNS
-       assert isset DEVICE
-       assert isset DEVICE_TYPE
+       #assert isset DEVICE
+       #assert isset DEVICE_TYPE
 
        assert isbool DEFAULTROUTE
        assert isbool PEERDNS
-       assert ismac DEVICE
-       assert isoneof DEVICE_TYPE real virtual
+       #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
 }
 
 function _parse_cmdline() {
+       local value
+
        while [ $# -gt 0 ]; do
                case "$1" in
                        --user=*)
@@ -88,21 +82,25 @@ function _parse_cmdline() {
                        --mtu=*)
                                MTU=${1#--mtu=}
                                ;;
-                       --no-defaultroute)
-                               DEFAULTROUTE=0
+                       --defaultroute=*)
+                               value=${1#--defaultroute=}
+                               if enabled value; then
+                                       DEFAULTROUTE=1
+                               else
+                                       DEFAULTROUTE=0
+                               fi
                                ;;
-                       --no-dns)
-                               PEERDNS=0
+                       --dns=*)
+                               value=${1#--dns=}
+                               if enabled value; then
+                                       PEERDNS=1
+                               else
+                                       PEERDNS=0
+                               fi
                                ;;
                        --auth=*)
                                AUTH=${1#--auth=}
                                ;;
-                       --device=*)
-                               DEVICE=${1#--device=}
-                               ;;
-                       --device-vid=*)
-                               DEVICE_VID=${1#--device-vid=}
-                               ;;
                        *)
                                echo "Unknown option: $1" >&2
                                exit ${EXIT_ERROR}
@@ -110,46 +108,39 @@ function _parse_cmdline() {
                esac
                shift
        done
-
-       if ! device_exists $(devicify ${DEVICE}); then
-               error "Device '${DEVICE}' does not exist."
-               exit ${EXIT_ERROR}
-       fi
-
-       DEVICE=$(macify ${DEVICE})
-
-       if isset DEVICE_VID; then
-               DEVICE_TYPE="virtual"
-       else
-               DEVICE_TYPE="real"
-       fi
 }
 
 function _up() {
        local zone=${1}
        shift
 
-       config_read ${ZONE_DIR}/${zone}/settings
+       assert isset zone
+
+       zone_config_read ${zone}
+
+       if ! isset PORTS || ! port_exists ${PORTS}; then
+               error_log "Parent device '${PORTS}' 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
-       if [ -n "${DEVICE_VID}" ]; then
-               device_create_virtual ${DEVICE} ${DEVICE_VID} ${DEVICE_MAC}
-       else
-               device_set_up ${DEVICE}
-       fi
+       port_up ${PORTS}
 
        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} $(_pppoe_real_device)
+plugin ${PPPOE_PLUGIN} ${PORTS}
 
 # User configuration
 user ${USER}
@@ -172,7 +163,7 @@ noccp noaccomp nodeflate nopcomp novj novjccomp nobsdcomp nomppe
 updetach debug
 EOF
 
-       pppd file ${RED_RUN}/${LINKNAME}/options >/dev/null
+       pppd_exec file ${RED_RUN}/${LINKNAME}/options
 
        local ret=$?
 
@@ -193,17 +184,13 @@ function _down() {
        local zone=${1}
        shift
 
-       config_read ${ZONE_DIR}/${zone}/settings
+       zone_config_read ${zone}
 
        # Kill pppd
+       # XXX very ugly
        kill $(pppd_pid ${zone}) &>/dev/null
 
-       # Pull down device or remove virtual one
-       if [ -n "${DEVICE_VID}" ]; then
-               device_remove_virtual ${DEVICE_MAC}
-       else
-               device_set_down ${DEVICE}
-       fi
+       port_down ${PORTS}
 
        exit ${EXIT_OK}
 }
@@ -241,14 +228,30 @@ function _discover() {
 function _status() {
        local zone=${1}
 
+       assert isset zone
+
        cli_status_headline ${zone}
 
+       zone_config_read ${zone}
+
+       cli_headline "  Configuration:"
+       printf "${DEVICE_PRINT_LINE1}" "User:" "${USER}"
+       printf "${DEVICE_PRINT_LINE1}" "Secret:" "<hidden>"
+       echo
+       printf "${DEVICE_PRINT_LINE1}" "MTU:" "${MTU}"
+       printf "${DEVICE_PRINT_LINE1}" "Use default route?" "$(enabled DEFAULTROUTE && echo "enabled" || echo "disabled")"
+       printf "${DEVICE_PRINT_LINE1}" "Use peer DNS?" "$(enabled PEERDNS && echo "enabled" || echo "disabled")"
+       echo
+       printf "${DEVICE_PRINT_LINE1}" "Port:" "${PORTS:-none}"
+
        # Exit if zone is down
        if ! zone_is_up ${zone}; then
                echo # Empty line
                exit ${EXIT_ERROR}
        fi
 
+       # XXX display time since connection started
+
        cli_headline "    Point-to-Point-over-Ethernet protocol:"
        echo "        IP-Address            : $(red_db_get ${zone} local-ip-address)"
        echo "        Gateway               : $(red_db_get ${zone} remote-ip-address)"
@@ -261,4 +264,31 @@ function _status() {
        exit ${EXIT_OK}
 }
 
+function _port_add() {
+       local zone=${1}
+       local port=${2}
+       shift 2
+
+       assert isset zone
+       assert isset port
+       assert port_exists ${port}
+
+       zone_config_read ${zone}
+
+       if isset PORTS; then
+               warning "There is already a port defined: '${PORTS}'."
+               warning "Will overwrite current configuration."
+       fi
+
+       if ! listmatch $(port_get_hook ${port}) ${PPPOE_ALLOWED_PORTS}; then
+               error "You can only add ports to this hook that are of type '${PPPOE_ALLOWED_PORTS}'."
+               exit ${EXIT_ERROR}
+       fi
+
+       PORTS="${port}"
+       zone_config_write ${zone}
+
+       exit ${EXIT_OK}
+}
+
 run $@
diff --git a/network b/network
index c683da69e2e64773821642c983cd8f3e4a03e080..e315b19ada70208e9a026fa16953ef6c15208051 100755 (executable)
--- a/network
+++ b/network
@@ -38,7 +38,7 @@ done
 
 # Process the given action
 case "${action}" in
-       config|device|zone|start|stop|restart|status)
+       config|port|device|zone|start|stop|restart|status)
                cli_${action} $@
                ;;
 
index d03e9321668dc396553cb80be54df73359ea76e5..cc746a13f7032718203f962e48124fd731b32cb1 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
 umask 022
 export PATH=/usr/sbin:/sbin:/usr/bin:/bin
 
+exec &>/tmp/network.$(basename $0)
+
+# Give the variables we get passed by pppd an own namespace
+for i in IFNAME IPLOCAL IPREMOTE DNS1 DNS2 MACREMOTE; do
+       export PPP_${i}=${!i}
+       unset ${i}
+done
+
 . /lib/network/functions
 
 # Zone equals IFNAME
-ZONE=${IFNAME}
+ZONE=${PPP_IFNAME}
+
+assert isset ZONE
 
 if ! zone_exists ${ZONE}; then
        error "Zone '${ZONE}' does not exist."
        exit ${EXIT_ERROR}
 fi
 
-HOOK=$(config_get_hook $(zone_dir ${ZONE})/settings)
+HOOK=$(zone_get_hook ${ZONE})
+
+assert isset HOOK
 
-if ! hook_exists ${HOOK}; then
+if ! hook_zone_exists ${HOOK}; then
        error "Hook '${HOOK}' does not exist."
        exit ${EXIT_ERROR}
 fi
 
-hook_exec ${HOOK} ppp-$(basename ${0}) ${ZONE}
+hook_zone_exec ${HOOK} ppp-$(basename ${0}) ${ZONE}