# #
###############################################################################
-function cli_config() {
- if cli_help_requested $@; then
- cli_usage root-config
- exit ${EXIT_OK}
- fi
+IDENT=" "
- if [ -n "${1}" ]; then
- network_config_set $@
- else
- network_config_print
+function cli_help_requested() {
+ local argument="${1}"
+
+ if [ -n "${argument}" ]; then
+ if listmatch ${argument} help -h --help; then
+ return ${EXIT_OK}
+ fi
fi
+
+ return ${EXIT_ERROR}
}
-function cli_device() {
- if device_config_exists ${1}; then
- local device=${1}
- local action=${2}
- shift 2
+function cli_run_help() {
+ local command="$@"
- case "${action}" in
- down|up)
- device_${action} ${device} $@
+ print "Run \"${command} help\" to get more information."
+ return ${EXIT_OK}
+}
+
+function cli_device_headline() {
+ local device=${1}
+ assert isset device
+
+ local long=0
+ shift
+ while [ $# -gt 0 ]; do
+ case "${1}" in
+ --long)
+ long=1
;;
esac
- else
- local action=${1}
shift
+ done
- case "${action}" in
- create)
- device_${action} $@
- ;;
+ local type
+ if zone_exists ${device}; then
+ type="zone"
+ elif port_exists ${device}; then
+ type="port"
+ else
+ type="unknown"
+ fi
- discover)
- echo "# XXX need to implement --raw here"
- local device
- for device in ${devices}; do
- cli_device_discover ${device} $@
- done
- ;;
+ local headline_prefix
+ case "${type}" in
+ zone)
+ headline_prefix="Zone ${device}"
+ ;;
+ port)
+ headline_prefix="Port ${device} ($(device_get_type ${device}))"
+ ;;
+ *)
+ headline_prefix="Device ${device} ($(device_get_type ${device}))"
+ ;;
+ esac
- show|"")
- local device
- for device in $(device_get $@); do
- device_print ${device}
- done
- ;;
- *)
- cli_usage device
- ;;
- esac
+ # Print the hook for all zones.
+ if [ "${type}" = "zone" ]; then
+ headline_prefix="${headline_prefix} ($(zone_get_hook ${device}))"
fi
-}
+ cli_headline 1 "${headline_prefix}"
-function cli_device_discover() {
- local device=${1}
- shift
+ # Print the device status.
+ local status
+ case "$(device_get_status ${device})" in
+ ${STATUS_UP})
+ status=${MSG_DEVICE_STATUS_UP}
+ ;;
+ ${STATUS_DOWN})
+ status=${MSG_DEVICE_STATUS_DOWN}
+ ;;
+ ${STATUS_NOCARRIER})
+ status=${MSG_DEVICE_STATUS_NOCARRIER}
+ ;;
+ *)
+ status=${MSG_DEVICE_STATUS_UNKNOWN}
+ ;;
+ esac
+ cli_print_fmt1 1 "Status" "${status}"
+ if enabled long; then
+ cli_print_fmt1 1 "Address" "$(device_get_address ${device})"
+ fi
+ if device_is_up ${device}; then
+ cli_print_fmt1 1 "MTU" "$(device_get_mtu ${device})"
+ fi
+ if enabled long; then
+ device_is_promisc ${device} &>/dev/null
+ cli_print_fmt1 1 "Promisc" "$(cli_print_bool $?)"
+ fi
+
+ cli_space
+
+ # Print the device stats.
+ device_is_up ${device} && cli_device_stats 2 ${device}
+
+ if enabled long; then
+ # Virtual devices.
+ device_is_vlan ${device} && cli_device_vlan ${device}
- local device_type=$(device_get_type ${device})
- if [ "${device_type}" != "real" ]; then
- return ${EXIT_OK}
+ # Bonded devices.
+ device_is_bonded ${device} && cli_device_bonded ${device}
+
+ # Bonding devices.
+ device_is_bonding ${device} && cli_device_bonding ${device}
fi
+}
- local raw
+function cli_device_stats() {
+ local level=${1}
+ local device=${2}
- while [ $# -gt 0 ]; do
- case "${1}" in
- --raw)
- raw=1
- ;;
- esac
- shift
- done
+ # This section will print statistical data from the device.
+ local packets bytes errors
- local up
- device_is_up ${device} && up=1
- device_set_up ${device}
+ cli_headline ${level} "Statistics"
+ local format="%-10s %9d packets %6s (%d errors)"
- enabled raw || echo "${device}"
+ # RX
+ packets=$(device_get_rx_packets ${device})
+ bytes=$(device_get_rx_bytes ${device})
+ errors=$(device_get_rx_errors ${device})
- local hook
- local out
- local ret
- for hook in $(hook_zone_get_all); do
- out=$(hook_zone_exec ${hook} discover ${device})
- ret=$?
-
- [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue
-
- if enabled raw; then
- case "${ret}" in
- ${DISCOVER_OK})
- echo "${hook}: OK"
- local line
- while read line; do
- echo "${hook}: ${line}"
- done <<<"${out}"
- ;;
-
- ${DISCOVER_ERROR})
- echo "${hook}: FAILED"
- ;;
- esac
- else
- case "${ret}" in
- ${DISCOVER_OK})
- echo " ${hook} was successful."
- local line
- while read line; do
- echo " ${line}"
- done <<<"${out}"
- ;;
-
- ${DISCOVER_ERROR})
- echo " ${hook} failed."
- ;;
- esac
- fi
- done
+ cli_print ${level} "${format}" "Received" "${packets}" "$(beautify_bytes ${bytes})" "${errors}"
- echo # New line
+ # TX
+ packets=$(device_get_tx_packets ${device})
+ bytes=$(device_get_tx_bytes ${device})
+ errors=$(device_get_tx_errors ${device})
- [ "${up}" = "1" ] || device_set_down ${device}
+ cli_print ${level} "${format}" "Sent" "${packets}" "$(beautify_bytes ${bytes})" "${errors}"
+ cli_space
}
-function cli_port() {
- if cli_help_requested $@; then
- cli_usage root-port
- exit ${EXIT_OK}
- fi
+function cli_device_vlan() {
+ local device=${1}
- local action
- local port
+ cli_headline 2 "VLAN"
- if port_exists ${1}; then
- port=${1}
- action=${2}
- shift 2
+ cli_print_fmt1 2 "Parent" "$(vlan_get_parent ${device})"
+ cli_print_fmt1 2 "VID" "$(vlan_get_id ${device})"
+ cli_space
+}
- # Action aliases
- case "${action}" in
- start)
- action="up"
- ;;
- stop)
- action="down"
- ;;
- show)
- action="status"
- ;;
- esac
+function cli_device_bonded() {
+ local device=${1}
- case "${action}" in
- edit|up|down|status)
- port_${action} ${port} $@
- ;;
- *)
- error "Unrecognized argument: ${action}"
- exit ${EXIT_ERROR}
- ;;
- esac
- else
- action=${1}
- shift
+ cli_headline 2 "Bonding information"
- case "${action}" in
- create|destroy)
- port_${action} $@
- ;;
- *)
- error "Unrecognized argument: ${action}"
- exit ${EXIT_ERROR}
- ;;
- esac
+ local master=$(bonding_slave_get_master ${port})
+ cli_print_fmt1 2 "Master" "${master}"
+
+ local mode=$(bonding_get_mode ${master})
+ if [ "${mode}" = "active-backup" ]; then
+ local active_slaves=$(bonding_get_slaves ${master} --active)
+ local active="false"
+ if list_match "${device}" ${active_slaves}; then
+ active="true"
+ fi
+ cli_print_fmt1 2 "Active slave" "$(cli_print_yesno ${active})"
fi
+
+ cli_space
}
-function cli_zone() {
- if cli_help_requested $@; then
- cli_usage root-zone
- exit ${EXIT_OK}
- fi
+function cli_device_bonding() {
+ local device=${1}
+ assert isset device
- local action
- local zone
+ cli_headline 2 "Bonding information"
- if zone_name_is_valid ${1}; then
- zone=${1}
- action=${2}
- shift 2
+ local mode=$(bonding_get_mode ${device})
- # Action aliases
- case "${action}" in
- start)
- action="up"
- ;;
- stop)
- action="down"
+ cli_print_fmt1 2 "Mode" "${mode}"
+ if [ "${mode}" = "802.3ad" ]; then
+ local lacp_rate=$(bonding_get_lacp_rate ${device})
+ cli_print_fmt1 2 "LACP rate" "${lacp_rate}"
+ fi
+ cli_space
+
+ local slave slave_suffix
+ local active_slaves=$(bonding_get_slaves ${device} --active)
+ for slave in $(bonding_get_slaves ${device}); do
+ # Print the device status.
+ local status
+ case "$(device_get_status ${slave})" in
+ ${STATUS_UP})
+ status=${MSG_DEVICE_STATUS_UP}
;;
- show)
- action="status"
+ ${STATUS_DOWN})
+ status=${MSG_DEVICE_STATUS_DOWN}
;;
- esac
-
- case "${action}" in
- config|down|edit|port|status|up)
- zone_${action} ${zone} $@
+ ${STATUS_NOCARRIER})
+ status=${MSG_DEVICE_STATUS_NOCARRIER}
;;
*)
- error "Unrecognized argument: ${action}"
- cli_usage root-zone-subcommands
- exit ${EXIT_ERROR}
+ status=${MSG_DEVICE_STATUS_UNKNOWN}
;;
esac
- else
- action=${1}
- shift
- case "${action}" in
- create|remove)
- zone_${action} $@
- ;;
- ""|*)
- if [ -n "${action}" ]; then
- error "Unrecognized argument: '${action}'"
- echo
- fi
-
- cli_usage root-zone
- exit ${EXIT_ERROR}
- ;;
- esac
- fi
+ if list_match "${slave}" ${active_slaves}; then
+ slave_suffix="(active)"
+ else
+ slave_suffix=""
+ fi
+ cli_print_fmt1 2 "Slave ${slave}" "${status} ${slave_suffix}"
+ done
+ cli_space
}
-function cli_start() {
- if cli_help_requested $@; then
- cli_usage root-start
- exit ${EXIT_OK}
- fi
+function cli_headline() {
+ local level=${1}
+ local format=${2}
+ shift 2
- local zones=$(zones_get $@)
+ local ident=$(cli_ident ${level})
- local zone
- for zone in ${zones}; do
- zone_up ${zone}
- done
+ local out
+ printf -v out "${ident}${CLR_BLACK_B}${format}${CLR_RESET}\n" "$@"
+ printf "${out}"
}
-function cli_stop() {
- if cli_help_requested $@; then
- cli_usage root-stop
- exit ${EXIT_OK}
- fi
+function cli_statusline() {
+ local level=${1}
+ shift
- local zones=$(zones_get $@)
+ local head=${1}
+ shift
- local zone
- for zone in ${zones}; do
- zone_down ${zone}
- done
+ cli_print $(( ${level} - 1 )) "%-12s %s" "${head}" "$@"
}
-function cli_restart() {
- if cli_help_requested $@; then
- cli_usage root-restart
- exit ${EXIT_OK}
- fi
-
- cli_stop $@
+function cli_print() {
+ local level=${1}
+ local format=${2}
+ shift 2
- # Give the system some time to calm down
- sleep ${TIMEOUT_RESTART}
+ local ident=$(cli_ident $(( ${level} + 1 )))
- cli_start $@
+ local out
+ printf -v out "${ident}${format}\n" "$@"
+ printf "${out}"
}
-function cli_status() {
- if cli_help_requested $@; then
- cli_usage root-status
- exit ${EXIT_OK}
- fi
+function cli_print_fmt1() {
+ local level=${1}
+ shift
- local zones=$(zones_get $@)
+ local space=$(( 34 - (${level} * ${#IDENT}) ))
+ local format="%-${space}s %s"
- local zone
- for zone in ${zones}; do
- zone_status ${zone}
- done
+ cli_print ${level} "${format}" "$@"
}
-function cli_reset() {
- if cli_help_requested $@; then
- cli_usage root-reset
- exit ${EXIT_OK}
+function cli_print_bool() {
+ if [ "${1}" = "${EXIT_TRUE}" ]; then
+ echo "true"
+ else
+ echo "false"
fi
+}
- warning_log "Will reset the whole network configuration!!!"
-
- # Force mode is disabled by default
- local force=0
-
- while [ $# -gt 0 ]; do
- case "${1}" in
- --force|-f)
- force=1
- ;;
- esac
- shift
- done
-
- # If we are not running in force mode, we ask the user if he does know
- # what he is doing.
- if ! enabled force; then
- if ! cli_yesno "Do you really want to reset the whole network configuration?"; then
- exit ${EXIT_ERROR}
- fi
+function cli_print_yesno() {
+ if [ "${1}" = "${EXIT_TRUE}" ]; then
+ echo "yes"
+ else
+ echo "false"
fi
+}
- local zone
- for zone in $(zones_get --all); do
- zone_remove ${zone}
- done
+function cli_print_enabled() {
+ enabled ${1}
- local port
- for port in $(ports_get --all); do
- port_remove ${port}
- done
+ cli_print_bool $?
+}
- # Re-run the initialization functions
- init_run
+function cli_print_warning() {
+ local level=${1}
+ shift
- exit ${EXIT_OK}
+ cli_print ${level} "${CLR_YELLOW_B}%s${CLR_RESET}" "$@"
}
-function cli_help_requested() {
- local argument="${1}"
+function cli_space() {
+ printf "\n"
+}
- if [ -n "${argument}" ]; then
- if listmatch ${argument} help -h --help; then
- return ${EXIT_OK}
- fi
- fi
+function cli_ident() {
+ local level=${1}
+ assert isinteger level
- return ${EXIT_ERROR}
+ local ident=""
+ while [ ${level} -gt 1 ]; do
+ ident="${ident}${IDENT}"
+ level=$(( ${level} - 1 ))
+ done
+
+ print "${ident}"
}
-function cli_usage() {
- local what=${1}
-
- case "${what}" in
- root)
- echo "${0}: [command] <options ...>"
- echo
- echo " start - ..."
- echo " stop - ..."
- echo " restart - ..."
- echo " status - ..."
- echo
- echo " config - ..."
- echo
- echo " device - ..."
- echo " zone - ..."
- echo
- ;;
- root-config)
- echo "${0}: ${what#root-} [KEY=VAL, ...]"
- echo
- echo " This command allows setting of global configuration parameters."
- echo
- echo " If no additional arguments are passed it will list the current configuration."
- echo
- echo " You can overwrite the settings like the following:"
- echo
- echo " ${0} ${what#root-} DEBUG=1 ..."
- echo
- ;;
- root-reset)
- echo "${0}: ${what#root-} [--force | -f]"
- echo
- echo " This command resets the network configuration."
- echo
- echo " Will delete all zones and ports."
- echo
- echo -e " ${COLOUR_RED}USE WITH CAUTION!${COLOUR_NORMAL}"
- echo
- ;;
- root-start|root-stop|root-restart)
- echo "${0}: ${what#root-} [--local-only|--remote-only|--all|<zone>...]"
- echo
- echo " This commands ${what#root-}s all zones by default."
- echo " One can pass several parameters to only process a subset of all"
- echo " available zones:"
- echo
- echo -e " ${COLOUR_BOLD}--local-only${COLOUR_NORMAL}"
- echo " Process all local zones which includes every zone without red."
- echo
- echo -e " ${COLOUR_BOLD}--remote-only${COLOUR_NORMAL}"
- echo " Process all remote zones which means only the red ones."
- echo
- echo -e " ${COLOUR_BOLD}--all${COLOUR_NORMAL}"
- echo " Process all zones. This is the default parameter."
- echo
- echo " Additionally, you can pass one or more zone names which will"
- echo " be processed."
- echo
- ;;
- root-status)
- echo "${0}: ${what#root-} [--local-only|--remote-only|--all|<zone>...]"
- echo
- echo " This commands shows status information of all zones by default."
- echo " One can pass several parameters to only process a subset of all"
- echo " available zones:"
- echo
- echo -e " ${COLOUR_BOLD}--local-only${COLOUR_NORMAL}"
- echo " Process all local zones which includes every zone without red."
- echo
- echo -e " ${COLOUR_BOLD}--remote-only${COLOUR_NORMAL}"
- echo " Process all remote zones which means only the red ones."
- echo
- echo -e " ${COLOUR_BOLD}--all${COLOUR_NORMAL}"
- echo " Process all zones. This is the default parameter."
- echo
- echo " Additionally, you can pass one or more zone names which will"
- echo " be processed."
- echo
- ;;
- root-zone)
- echo "${0}: ${what#root-} <create|remove> <zone> [<type> <options...>]"
- echo
- echo " Create or remove a zone."
- echo
- echo -e " ${COLOUR_BOLD}create <zone> <type> <options>${COLOUR_NORMAL}"
- echo " Create a new zone of type <type> where <zone> is an allowed"
- echo " zone name."
- echo
- echo -e " ${COLOUR_BOLD}remove <zone>${COLOUR_NORMAL}"
- echo " Remove the zone <zone>."
- echo
- echo " You may also edit the configuration of the zones."
- echo
- echo -e " ${COLOUR_BOLD}<zone> ...${COLOUR_NORMAL}"
- echo " Edit the zone <zone>."
- echo
- ;;
- usage)
- echo
- echo " Run '${0} help' to get information how to use this tool."
- echo
- ;;
- *)
- error "No help available for this command '${what}'."
- echo
- ;;
- esac
+function cli_yesno() {
+ local message="$@ [y/n] "
+ local yesno
- echo "Network configuration tool. Report all bugs to <http://bugs.ipfire.org>."
-}
+ while true; do
+ printf "\n${message}"
+ read yesno
-function cli_status_headline() {
- local zone=${1}
+ # Check for "yes".
+ if listmatch ${yesno} y Y yes YES Yes; then
+ return ${EXIT_TRUE}
- local state="${COLOUR_DOWN}DOWN${COLOUR_NORMAL}"
- zone_is_up ${zone} && state="${COLOUR_UP}UP${COLOUR_NORMAL}"
+ # Check for "no".
+ elif listmatch ${yesno} n N no NO No; then
+ return ${EXIT_FALSE}
+ fi
+ done
+}
- echo -e "${zone} - ${state} - $(zone_get_hook ${zone})"
+function cli_get_key() {
+ local key="${1%%=*}"
+ echo "${key/--/}"
}
-function cli_headline() {
- echo
- echo -e "${COLOUR_BOLD}$@${COLOUR_NORMAL}"
+function cli_get_val() {
+ echo "${@#*=}"
}
-function cli_yesno() {
- local message="$@ [y/N] "
- local yesno
+function cli_usage() {
+ local command="$@"
+ local basename="$(basename ${0})"
- echo
- echo -ne "${message}"
- read yesno
+ if ! isset command; then
+ command="${basename} help"
+ fi
+
+ echo "The given command was not understood by ${basename}." >&2
+ echo "Please run '${command}' for detailed help." >&2
+}
- if listmatch ${yesno} y Y j J yes YES Yes; then
- return ${EXIT_OK}
+function cli_show_man() {
+ local manpage=${1}
+ assert isset manpage
+
+ if ! binary_exists man; then
+ error "The man package is not installed on this system."
+ error "Please install 'man' in order to view the help."
+ exit ${EXIT_ERROR}
fi
- return ${EXIT_ERROR}
+ man ${manpage}
}