return 1
}
+function device_is_bridge() {
+ [ -d "/sys/class/net/${1}/bridge" ]
+}
+
function device_is_up() {
ip link show $(devicify ${1}) 2>/dev/null | grep -qE "<.*UP.*>"
}
grep -q "^${1}" /proc/net/vlan/config
}
+function device_is_ppp() {
+ # XXX need something better
+ [ "${1:0:3}" = "ppp" ]
+}
+
+function device_is_real() {
+ local device=${1}
+
+ [ "${device}" = "lo" ] && \
+ return ${EXIT_ERROR}
+
+ device_is_bonding ${device} && \
+ return ${EXIT_ERROR}
+
+ device_is_bridge ${device} && \
+ return ${EXIT_ERROR}
+
+ device_is_ppp ${device} && \
+ return ${EXIT_ERROR}
+
+ device_is_vlan ${device} && \
+ return ${EXIT_ERROR}
+
+ return ${EXIT_OK}
+}
+
function device_has_vlans() {
if [ ! -e "/proc/net/vlan/config" ]; then
return 1
zone_exists $@ && device_is_up $@
}
+function zone_is_forwarding() {
+ local seconds=45
+ local zone=${1}
+
+ local device
+ while [ ${seconds} -gt 0 ]; do
+ for device in /sys/class/net/${zone}/brif/*; do
+ [ -e "${device}/state" ] || continue
+ if [ "$(<${device}/state)" = "3" ]; then
+ return ${EXIT_OK}
+ fi
+ done
+ sleep 1
+ seconds=$((${seconds} - 1))
+ done
+ return ${EXIT_ERROR}
+}
+
function bridge_devices() {
local bridge=$1
[ -z "${bridge}" ] && return 2
)
}
+function hook_list() {
+ local type=${1}
+ local hook
+ for hook in ${HOOKS_DIR}/*; do
+ hook=${hook##*/}
+
+ [[ ${hook} =~ helper$ ]] && continue
+
+ if [ -n "${type}" ] && [ "$(hook_type ${hook})" != "${type}" ]; then
+ continue
+ fi
+ echo "${hook}"
+ done
+}
+
function config_get_hook() {
local config=${1}
if [ ! -e "${config}" ]; then
# #
###############################################################################
-PPP_RUN=/var/run/ppp
+RED_RUN=/var/run/network/red
PPP_SECRETS=/etc/ppp/secrets
function ppp_pre_up() {
EOF
}
+function ppp_linkname_get() {
+ local config=${1}
+ (
+ . ${config}
+ echo "${LINKNAME}"
+ )
+}
+
+function red_defaultroute_update() {
+ local command="ip route replace default"
+
+ for uplink in ${RED_RUN}/*; do
+ [ -d "${uplink}" ] || continue
+
+ # Skip if no gateway given
+ [ -e "${uplink}/gateway" ] || continue
+
+ command="${command} nexthop via $(<${uplink}/gateway)"
+ if [ -e "${uplink}/weight" ]; then
+ command="${command} weight $(<${uplink}/weight)"
+ fi
+ done
+ $command
+ ip route flush cache
+}
+
+function red_dns_update() {
+ : # XXX todo
+}
rem)
;;
-
+
+ discover)
+ exit ${EXIT_ERROR}
+ ;;
+
*)
echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]"
exit ${EXIT_ERROR}
rem)
;;
+
+ discover)
+ exit ${EXIT_ERROR}
+ ;;
*)
echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]"
#
########################################################################
-. /etc/init/functions
-. /lib/network/functions
+. /lib/network/hook-header
HOOK_NAME=ipv4-static-route
HOOK_TYPE=zone
fi
}
-# First, parse the command line
-
-while [ $# -gt 0 ]; do
- case "${1}" in
- --zone=*)
- zone=${1#--zone=}
- ;;
- --config=*)
- . ${1#--config=}
- check_config
- ;;
- -*)
- log_failure_msg "Unrecognized option: ${1}"
- exit ${EXIT_ERROR}
- ;;
- *)
- action=${1}
- shift
- break
- ;;
- esac
- shift
-done
-
case "${action}" in
- config)
+ add)
while [ $# -gt 0 ]; do
case "${1}" in
--ip=*)
post-down)
;;
+ discover)
+
+ exit ${EXIT_ERROR}
+ ;;
+
*)
echo "Usage: ${0} [interface] {up|down}"
exit 1
EOF
exit $?
;;
+
+ discover)
+ exit ${EXIT_ERROR}
+ ;;
*)
usage
;;
status)
- #check_config
- # XXX Is there a better way?
- if (ip route get ${IP} | grep -q ^local); then
+ echo -e "# ${CLR_BOLD_CYN}PPPoE: ${NAME}${NORMAL}"
+ echo -n "# pppd's PID: "
+ pid=$(head -n1 /var/run/ppp-${NAME}.pid 2>/dev/null)
+ if [ -n "${pid}" ] && [ -d "/proc/${pid}" ]; then
+ echo -e "${CLR_BOLD_GRN}${pid}${NORMAL}"
exit ${EXIT_OK}
else
- exit ${EXIT_ERROR}
+ echo -e "${CLR_BOLD_RED}${pid-off}${NORMAL}"
+ exit ${EXIT_OK}
fi
;;
check_config NAME
# Creating necessary files
- [ -d "${PPP_RUN}/${NAME}" ] || mkdir -p ${PPP_RUN}/${NAME}
+ [ -d "${RED_RUN}/${NAME}" ] || mkdir -p ${RED_RUN}/${NAME}
ppp_secret "${USER}" "${SECRET}"
- cat <<EOF >${PPP_RUN}/${NAME}/options
+ cat <<EOF >${RED_RUN}/${NAME}/options
# Naming options
name ${NAME}
linkname ${NAME}
post-up)
check_config zone NAME
MESSAGE="Starting PPP Daemon on interface ${zone}..."
- pppd file ${PPP_RUN}/${NAME}/options >/dev/null
- evaluate_retval
-
+ if zone_is_forwarding ${zone}; then
+ pppd file ${RED_RUN}/${NAME}/options >/dev/null
+ evaluate_retval
+ else
+ log_failure_msg "Zone ${zone} is not forwaring any traffic..."
+ exit ${EXIT_ERROR}
+ fi
+
ppp_post_up
;;
ppp_pre_down
MESSAGE="Stopping PPP Daemon on interface ${zone}..."
- pid=$(head -n1 /var/run/ppp-${NAME}.pid)
+ pid=$(head -n1 /var/run/ppp-${NAME}.pid 2>/dev/null)
if [ -n "${pid}" ]; then
kill ${pid} &>/dev/null
evaluate_retval
ppp_post_down
;;
- config)
+ add)
# A pregenerated connection name
NAME=$(</proc/sys/kernel/random/uuid)
DEFAULTROUTE=1
shift
done
- check_config zone NAME USER
- cat <<EOF >${CONFIG_ZONES}/${zone}/${HOOK_NAME}_${NAME}
+ UUID=$(uuid)
+ cat <<EOF >${CONFIG_UUIDS}/${UUID}
HOOK="${HOOK_NAME}"
USER="${USER}"
SECRET="${SECRET}"
AUTH="${AUTH}"
EOF
- ln -sf ${CONFIG_ZONES}/${zone}/${HOOK_NAME}_${NAME} \
- ${CONFIG_PPP}/${NAME}
+ ln -sf ${CONFIG_UUIDS}/${UUID} \
+ ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID}
exit ${EXIT_OK}
;;
output=$(pppoe-discovery -I ${zone} \
-U $(</proc/sys/kernel/random/uuid) 2>&1)
if grep -q "Timeout" <<<${output}; then
+ echo "${HOOK_NAME}: FAILED"
exit ${EXIT_ERROR}
else
- echo "${output}"
+ echo "${HOOK_NAME}: OK"
+ echo "${output}" | while read line; do
+ [ "${line:0:1}" = "A" ] || continue
+ echo "${HOOK_NAME}: ${line}"
+ done
exit ${EXIT_OK}
fi
;;
zone=${DEVICE}
+DIR=${RED_RUN}/${LINKNAME}
+
case "${action}" in
ip-up)
+ mkdir -p ${DIR} 2>/dev/null
+
+ echo "${IPREMOTE}" > ${DIR}/remote-ip-address
+ echo "${IPLOCAL}" > ${DIR}/local-ip-address
+
# Update firewall with new IP address(es)
# Prepare main routing table
ip route add table ${zone} default via ${IPREMOTE} dev ${IFNAME}
if [ "${DEFAULTROUTE}" = "1" ]; then
- : # Set default route
- fi
+ ln -sf remote-ip-address ${DIR}/gateway
+ [ -n "${WEIGHT}" ] && \
+ echo "${WEIGHT}" > ${DIR}/weight
- ip route flush cache
+ red_defaultroute_update
+ fi
if [ "${PEERDNS}" = "1" ]; then
- : # $DNS1 --> pdns server
+ echo "${DNS1}" > ${DIR}/dns
+ if [ -n "${DNS2}" ] && [ "${DNS1}" != "${DNS2}" ]; then
+ echo "${DNS2}" > ${DIR}/dns
+ fi
+ red_dns_update
fi
-
- connection --up --zone=${zone} --name=${NAME} \
- --iplocal=${IPLOCAL} --ipremote=${IPREMOTE} --dns="${DNS1} ${DNS2}" \
- --weight=${WEIGHT} --pid=${PPPD_PID}
;;
ip-down)
# Save statistics
ppp_stat "${NAME}" "${CONNECT_TIME}" "${BYTES_RCVD}" "${BYTES_SENT}"
-
- connection --down --zone=${zone}
;;
esac
#
########################################################################
-. /etc/init/functions
-. /lib/network/functions
+. /lib/network/hook-header
HOOK_NAME=stp
HOOK_TYPE=zone
-function check_config() {
- : # XXX TODO
-}
-
-# First, parse the command line
-
-while [ $# -gt 0 ]; do
- case "${1}" in
- --zone=*)
- zone=${1#--zone=}
- ;;
- --config=*)
- . ${1#--config=}
- check_config
- ;;
- -*)
- log_failure_msg "Unrecognized option: ${1}"
- exit ${EXIT_ERROR}
- ;;
- *)
- action=${1}
- shift
- break
- ;;
- esac
- shift
-done
-
-# Second, do the $action
-
case "${action}" in
help)
;;
rem)
;;
+
+ discover)
+ exit ${EXIT_ERROR}
+ ;;
*)
echo "Usage: ${0} {pre-up|post-up|pre-down|post-down|config} [interface]"
vconfig add $(devicify ${MAC}) ${ID} >/dev/null
evaluate_retval
+ device_rename $(get_device_by_mac_and_vid ${MAC} ${ID}) $(port_name)
+ ip link set $(port_name) up
+
ebtables -t broute -A BROUTING -p 802_1Q --vlan-id=${ID} -j DROP
fi
;;
post-up)
if ! zone_has_device_attached ${zone} $(port_name); then
- device_rename $(get_device_by_mac_and_vid ${MAC} ${ID}) $(port_name)
zone_add_port ${zone} $(get_device ${MAC} ${ID})
fi
;;
;;
status)
- device_is_up $(port_name)
- RET=$?
- if [ $RET -eq 0 ]; then
- log_success_msg "Port $(port_name) is up"
+ echo -e "# ${CLR_BOLD_CYN}VLAN port $(port_name)${NORMAL}"
+ echo -n "# State: "
+ if device_is_up $(port_name); then
+ echo -e "${CLR_BOLD_GRN}up${NORMAL}"
+ RET=${EXIT_OK}
else
- log_failure_msg "Port $(port_name) is down"
+ echo -e "${CLR_BOLD_RED}down${NORMAL}"
+ RET=${EXIT_ERROR}
fi
+ echo "# ID : ${ID}"
+ echo "#"
exit ${RET}
;;
fi
}
+function size() {
+ local size=${1}
+
+ local units
+ units[0]="Bytes "
+ units[1]="kBytes"
+ units[2]="MBytes"
+ units[3]="GBytes"
+ units[4]="TBytes"
+
+ local count=${#units}
+ while [ ${count} -gt 0 ]; do
+ if [ ${size} -lt 1024 ]; then
+ break
+ fi
+ size=$((${size} / 1024))
+ count=$((${count} - 1))
+ done
+ printf "%4d %s\n" "${size}" "${units[$((${#units} - ${count}))]}"
+}
+
function port_show() {
- local port
+ local port=$(devicify $1)
+
+ echo "##################################################"
+ echo "#"
+ echo -e "# Port ${CLR_BOLD_BLU}${port}${NORMAL}"
+ echo "# ------------------------------------------------"
- port=$(devicify $1)
+ echo -n "# State: "
+ if device_is_up ${port}; then
+ echo -e "${CLR_BOLD_GRN}up${NORMAL}"
+ else
+ echo -e "${CLR_BOLD_RED}down${NORMAL}"
+ fi
- if ! port_exists ${port}; then
- error "Port ${BOLD}${port}${NORMAL} does not exist."
- return 1
+ echo -n "# Link : "
+ if device_has_carrier ${port}; then
+ echo -e "${CLR_BOLD_GRN}yes${NORMAL}"
+ else
+ echo -e "${CLR_BOLD_RED}no${NORMAL}"
fi
- ip -s link show $port
+ if device_is_up ${port}; then
+ echo "#"
+ echo "# Statistics:"
+ echo -n "# RX: $(size $(</sys/class/net/${port}/statistics/rx_bytes))"
+ echo " ($(</sys/class/net/${port}/statistics/rx_packets) packets)"
+ echo -n "# TX: $(size $(</sys/class/net/${port}/statistics/tx_bytes))"
+ echo " ($(</sys/class/net/${port}/statistics/tx_packets) packets)"
+ fi
+
+ echo "#"
}
function port_add() {
fi
}
+function zone_discover() {
+ local zone=${1}
+
+ for hook in $(hook_list zone); do
+ hook_run ${hook} --zone=${zone} discover
+ done
+}
+
function zone_show() {
local zone
zone=$1
port_del $@
_exit --reload $?
;;
+ discover)
+ zone_discover $@
+ _exit $?
+ ;;
help)
usage zone 0
;;
;;
esac
;;
+ show)
+ case "${1}" in
+ ports)
+ for port in /sys/class/net/*; do
+ port=${port##*/}
+ device_is_real ${port} || continue
+ port_show ${port}
+ done
+ _exit 0
+ ;;
+ esac
+ ;;
-*)
error "Option \"$arg\" is not known."
;;
export PATH=/usr/sbin:/sbin:/usr/bin:/bin
. /lib/network/functions
+. /lib/network/functions.ppp
-if [ -e "${CONFIG_PPP}/${LINKNAME}" ]; then
- . ${CONFIG_PPP}/${LINKNAME}
-fi
+for config in ${CONFIG_ZONES}/${DEVICE}/*; do
+ if [ "$(ppp_linkname_get ${config})" = "${LINKNAME}" ]; then
+ CONFIG=${config}
+ . ${CONFIG}
+ break
+ fi
+done
if [ -n "${HOOK}" ] && [ -x "${HOOKS_DIR}/${HOOK}.helper" ]; then
- exec ${HOOKS_DIR}/${HOOK}.helper --config=${CONFIG_PPP}/${LINKNAME} \
+ exec ${HOOKS_DIR}/${HOOK}.helper --config=${CONFIG} \
$(basename $0) $@
fi