From: Michael Tremer Date: Fri, 9 Jul 2010 19:37:47 +0000 (+0200) Subject: network: Magnificent changes on code. X-Git-Tag: 001~63 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=711ffac1e45041250adcdecff39a8101cc3b52e5;p=network.git network: Magnificent changes on code. --- diff --git a/functions.bonding b/functions.bonding index 8a04a91a..a6328926 100644 --- a/functions.bonding +++ b/functions.bonding @@ -19,22 +19,35 @@ # # ############################################################################### +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} +} diff --git a/functions.cli b/functions.cli index b6435bcd..56db94c0 100644 --- a/functions.cli +++ b/functions.cli @@ -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} $@ ;; *) diff --git a/functions.constants b/functions.constants index 62c023c4..75ad5779 100644 --- a/functions.constants +++ b/functions.constants @@ -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" diff --git a/functions.device b/functions.device index 67453c74..54e4d6e6 100644 --- a/functions.device +++ b/functions.device @@ -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 index 00000000..f0bfbc07 --- /dev/null +++ b/functions.ethernet @@ -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 $@ +} diff --git a/functions.hook b/functions.hook index 481d3cc5..57b5389e 100644 --- a/functions.hook +++ b/functions.hook @@ -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 index 00000000..25ce046c --- /dev/null +++ b/functions.ports @@ -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} $@ +} diff --git a/functions.ppp b/functions.ppp index 7c8d3414..c1c5dae5 100644 --- a/functions.ppp +++ b/functions.ppp @@ -19,6 +19,10 @@ # # ############################################################################### +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 +} diff --git a/functions.util b/functions.util index 8705726c..83ec302c 100644 --- a/functions.util +++ b/functions.util @@ -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}" +} diff --git a/functions.zone b/functions.zone index 1fc631c0..981c8e27 100644 --- a/functions.zone +++ b/functions.zone @@ -22,12 +22,16 @@ 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 index 00000000..ab2fb18b --- /dev/null +++ b/header-device @@ -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 . # +# # +############################################################################### + +. /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 index 00000000..9e044353 --- /dev/null +++ b/hooks/ports/bonding @@ -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 . # +# # +############################################################################### + +. /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 index 00000000..2d49f49a --- /dev/null +++ b/hooks/ports/ethernet @@ -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 . # +# # +############################################################################### + +. /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 index 00000000..4c35ebce --- /dev/null +++ b/hooks/ports/virtual @@ -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 . # +# # +############################################################################### + +. /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 $@ diff --git a/hooks/zones/bridge b/hooks/zones/bridge index e4bc1f7b..1108bb2a 100755 --- a/hooks/zones/bridge +++ b/hooks/zones/bridge @@ -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 $@ diff --git a/hooks/zones/bridge.ports/bonding b/hooks/zones/bridge.ports/bonding deleted file mode 100755 index 2680d562..00000000 --- a/hooks/zones/bridge.ports/bonding +++ /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 . # -# # -############################################################################### - -. /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 $@ diff --git a/hooks/zones/bridge.ports/bonding b/hooks/zones/bridge.ports/bonding new file mode 120000 index 00000000..3857774a --- /dev/null +++ b/hooks/zones/bridge.ports/bonding @@ -0,0 +1 @@ +ethernet \ No newline at end of file diff --git a/hooks/zones/bridge.ports/ethernet b/hooks/zones/bridge.ports/ethernet index d2544885..0b8fd78e 100755 --- a/hooks/zones/bridge.ports/ethernet +++ b/hooks/zones/bridge.ports/ethernet @@ -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} diff --git a/hooks/zones/bridge.ports/virtual b/hooks/zones/bridge.ports/virtual deleted file mode 100755 index 0e350bbb..00000000 --- a/hooks/zones/bridge.ports/virtual +++ /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 . # -# # -############################################################################### - -. /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 $@ diff --git a/hooks/zones/bridge.ports/virtual b/hooks/zones/bridge.ports/virtual new file mode 120000 index 00000000..3857774a --- /dev/null +++ b/hooks/zones/bridge.ports/virtual @@ -0,0 +1 @@ +ethernet \ No newline at end of file diff --git a/hooks/zones/pppoe b/hooks/zones/pppoe index a3a16880..3cf4877b 100755 --- a/hooks/zones/pppoe +++ b/hooks/zones/pppoe @@ -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 <${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:" "" + 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 c683da69..e315b19a 100755 --- 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} $@ ;; diff --git a/ppp/ip-updown b/ppp/ip-updown index d03e9321..cc746a13 100755 --- a/ppp/ip-updown +++ b/ppp/ip-updown @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # @@ -22,21 +22,33 @@ 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}