${0} start
;;
+ reload)
+ if [ -e /var/lock/subsys/network ]; then
+ : # TODO
+ fi
+ ;;
+
*)
- echo "Usage: ${0} {start|stop|restart}"
+ echo "Usage: ${0} {start|stop|restart|reload}"
exit 1
;;
esac
CONFIG_ZONES=${CONFIG_DIR}/zones
CONFIG_PORTS=${CONFIG_DIR}/ports
+COMMON_DEVICE=black+
+
function is_mac() {
egrep -q "^[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]\:[0-9a-f][0-9a-f]$" <<<$1
}
ip link show $(devicify ${1}) &>/dev/null
}
+function device_is_up() {
+ ip link show $(devicify ${1}) 2>/dev/null | grep -qE "<.*UP.*>"
+}
+
function rename_device() {
local source
local destination
[ -e "$CONFIG_ZONES/$1" ] #|| device_exists $@
}
+function port_is_up() {
+ device_is_up $@
+}
+
+function zone_is_up() {
+ zone_exists $@ && device_is_up $@
+}
+
function bridge_devices() {
local bridge
bridge=$1
port=$(macify ${1})
+function port_name() {
+ echo ${ZONE}s+
+}
+
+function do_up() {
+ : # Do nothing
+}
+
+function do_down() {
+ : # Do nothing
+}
+
+function do_attach() {
+ rename_device $(get_device ${port}) $(port_name)
+ zone_add_port ${ZONE} $(get_device_by_mac ${port})
+}
+
+function do_detach() {
+ zone_del_port ${ZONE} $(get_device_by_mac ${port})
+ rename_device $(get_device_by_mac ${port}) ${COMMON_DEVICE}
+}
+
+function do_status() {
+ device_is_up ${port}
+ RET=$?
+ if [ $RET -eq 0 ]; then
+ log_success_msg "Port $(port_name) is up"
+ else
+ log_failure_msg "Port $(port_name) is down"
+ fi
+ return $RET
+ # TODO: Check if device is attached to a bridge.
+}
+
case "${2}" in
up)
- : # Do nothing
+ do_up
;;
down)
- : # Do nothing
+ do_down
;;
add)
;;
remove)
+ do_detach
+ #do_down
rm -f \
${CONFIG_ZONES}/${ZONE}/port-${port}-ethernet \
${CONFIG_PORTS}/${port}/ethernet
;;
attach)
- rename_device $(get_device ${port}) ${ZONE}s+
- zone_add_port ${ZONE} $(get_device_by_mac ${port})
+ do_up
+ do_attach
;;
detach)
- zone_del_port ${ZONE} $(get_device_by_mac ${port})
+ do_detach
+ ;;
+
+ status)
+ do_status
+ exit ${?}
;;
*)
- echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach}"
+ echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}"
exit 1
;;
esac
port=$(macify ${1})
device=$(devicify ${port})
+function port_name() {
+ echo "${ZONE}v${ID}"
+}
+
+function do_up() {
+ if ! port_is_up $(port_name); then
+ grep -q ^8021q /proc/modules || modprobe 8021q
+ MESSAGE="Adding VLAN ${ID} to port ${port}..."
+ vconfig add ${device} ${ID} >/dev/null
+ evaluate_retval
+ fi
+}
+
+function do_down() {
+ if port_is_up $(port_name); then
+ MESSAGE="Removing VLAN ${ID} from port ${port}..."
+ vconfig rem ${device} ${ID} >/dev/null
+ evaluate_retval
+ fi
+}
+
+function do_attach() {
+ rename_device $(get_device_by_mac_and_vid ${port} ${ID}) $(port_name)
+ zone_add_port ${ZONE} $(get_device ${port} ${ID})
+}
+
+function do_detach() {
+ zone_del_port ${ZONE} $(get_device_by_mac_and_vid ${port} ${ID})
+}
+
+function do_status() {
+ device_is_up $(port_name)
+ RET=$?
+ if [ $RET -eq 0 ]; then
+ log_success_msg "Port $(port_name) is up"
+ else
+ log_failure_msg "Port $(port_name) is down"
+ fi
+ return $RET
+}
+
case "${2}" in
up)
- if ! get_device_by_mac_and_vid ${port} ${ID} >/dev/null; then
- modprobe 8021q
- MESSAGE="Adding VLAN ${ID} to port ${port}..."
- vconfig add ${device} ${ID} >/dev/null
- evaluate_retval
- fi
+ do_up
;;
down)
- if get_device_by_mac_and_vid ${port} ${ID} >/dev/null; then
- MESSAGE="Removing VLAN ${ID} from port ${port}..."
- vconfig rem ${device} ${ID} >/dev/null
- evaluate_retval
- fi
+ do_down
;;
add)
;;
remove)
- # Should we do this here? What about detaching?
- CONFIG=${CONFIG_ZONES}/${ZONE}/port-${port}-vlan-${ID} ${0} ${port} down
+ do_detach
+ do_down
rm -f \
${CONFIG_PORTS}/${port}/vlan-${ID} \
${CONFIG_ZONES}/${ZONE}/port-${port}-vlan-${ID}
;;
attach)
- rename_device $(get_device_by_mac_and_vid ${port} ${ID}) ${ZONE}v${ID}
- zone_add_port ${ZONE} $(get_device ${port} ${ID})
+ do_attach
;;
detach)
- zone_del_port ${ZONE} $(get_device_by_mac_and_vid ${port} ${ID})
+ do_detach
+ ;;
+
+ status)
+ do_status
+ exit ${?}
;;
*)
- echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach}"
+ echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}"
exit 1
;;
esac
shift 2
if [ -z "${port}" ] || [ -z "${action}" ]; then
- echo "Usage: $0 <port> <up|down|attach|detach> [hooks]"
+ echo "Usage: $0 <port> <up|down|attach|detach|status> [hooks]"
echo
exit 1
fi
down)
;;
- attach|detach)
+ attach)
+ ip link set $(devicify ${port}) up # is this required here?
if [ -z "${ZONE}" ]; then
log_failure_msg "ZONE is not set."
exit 1
fi
;;
+ detach)
+ if [ -z "${ZONE}" ]; then
+ log_failure_msg "ZONE is not set."
+ exit 1
+ fi
+ ;;
+
+ status)
+ ;;
+
*)
log_failure_msg "\"${action}\" is not a valid command."
exit 1
. ${hook}
if [ -n "${HOOK}" -a -x "/etc/init.d/networking/hooks/${HOOK}" ]; then
CONFIG=${hook} /etc/init.d/networking/hooks/${HOOK} ${port} ${action}
+ RET=$?
else
echo -e "${FAILURE}Unable to process ${hook}. Either"
echo -e "${FAILURE}the HOOK variable was not set,"
message=""
log_failure_msg
fi
- )
+ exit ${RET}
+ ) || failed=1
done
case "${action}" in
down)
- message="Pushing down port ${port}..."
- ip link set $(devicify ${port}) down
- evaluate_retval
+ # If no ports are running yet, push device down.
+ if ! $0 ${port} status &>/dev/null; then
+ message="Pushing down port ${port}..."
+ ip link set $(devicify ${port}) down
+ evaluate_retval
+ fi
+ ;;
+ status)
+ exit ${failed}
;;
esac
(exit ${failed})
evaluate_retval standard
- # We should bring up every port
- for config in ${CONFIG_ZONES}/${zone}/port-*; do
- port=${config##*/}; port=${port#port-}; port=${port%%-*}
- ZONE=${zone} /etc/init.d/networking/port ${port} up
- done
-
# Attach ports
for config in ${CONFIG_ZONES}/${zone}/port-*; do
port=${config##*/}; port=${port#port-}; port=${port%%-*}
# Detach ports
for config in ${CONFIG_ZONES}/${zone}/port-*; do
- port=${file#port-}; port=${port%%-*}
- ZONE=${zone} CONFIG=${config} \
- /etc/init.d/networking/port ${port} detach
+ port=${config##*/}; port=${port#port-}; port=${port%%-*}
+ ZONE=${zone} /etc/init.d/networking/port ${port} detach ${config}
done
# Bring down the zone and delete it
}
function _exit() {
+ if [ $1 -eq 0 ] && [ "$DO_RELOAD" = "1" ]; then
+ # Reloading network to apply changes immediately
+ vecho "Reloading network settings..."
+ cmd $0 $(verbose && echo "-v") $(debug && echo "-d") reload
+ fi
+
decho "Exiting with code $1."
exit $1
}
+function cmd() {
+ decho "Running command: $@"
+ if verbose; then
+ $@
+ else
+ $@ >/dev/null
+ fi
+}
+
function port_show() {
local port
RET=$?
if [ "$RET" -eq "0" ]; then
vecho "Successfully added port ${BOLD}${port}${NORMAL} (${hook} $@) to ${BOLD}${zone}${NORMAL}."
- /etc/init.d/networking/port ${port} up
+ cmd /etc/init.d/networking/port ${port} up
else
error "Hook ${BOLD}${hook}${NORMAL} exited with $RET."
return $RET
decho " Zone: ${zone} Port: ${port} Hook: ${hook}"
if [ -x "/etc/init.d/networking/hooks/${hook}" ]; then
- /etc/init.d/networking/port ${port} down ## XXX How do we identify only that one hook?
- ZONE=${zone} /etc/init.d/networking/hooks/${hook} ${port} remove $@
+ cmd /etc/init.d/networking/port ${port} down ## XXX How do we identify only that one hook?
+ ZONE=${zone} cmd /etc/init.d/networking/hooks/${hook} ${port} remove $@
RET=$?
if [ "$RET" -eq "0" ]; then
vecho "Successfully removed port ${BOLD}${port}${NORMAL} (${hook} $@) from ${BOLD}${zone}${NORMAL}."
echo "##################################################"
# Up or down?
- if device_exists ${zone}; then
+ if device_is_up ${zone}; then
echo -e "# Device is ${ERROR}up${NORMAL}."
else
echo -e "# Device is ${ERROR}down${NORMAL}."
# Ports
echo -e "# ${ERROR}Ports:${NORMAL}"
+ local config
local port
- for port in ${CONFIG_ZONES}/${zone}/port-*; do
- port=${port##*/}
- echo "# ${port#port-}"
- debug && echo "# TODO: Is port up or down?"
+ for config in ${CONFIG_ZONES}/${zone}/port-*; do
+ port=${config##*/}; port=${port#port-}; port=${port%%-*}
+ if ZONE=${zone} cmd /etc/init.d/networking/port ${port} attach ${config} &>/dev/null; then
+ echo "# ${config#port-} is up"
+ else
+ echo "# ${config#port-} is down"
+ fi
done
echo "#"
vecho "Successfully removed zone ${zone}."
}
+DO_RELOAD=1
+
+# See what to do
while [ "$#" -gt 0 ]; do
arg=$1
shift
case "$arg" in
show)
port_show $@
- _exit $?
+ DO_RELOAD=0 _exit $?
;;
help)
usage port 0
;;
show)
zone_show $@
- _exit $?
+ DO_RELOAD=0 _exit $?
;;
addport)
port_add $@
_exit $?
;;
help)
- usage zone 0
+ DO_RELOAD=0 usage zone 0
;;
esac
;;
+ -*)
+ DO_RELOAD=0 error "Option \"$arg\" is not known."
+ ;;
esac
done