From 5b61cfba076c61cf09783a7f6ef4150e55b74a3f Mon Sep 17 00:00:00 2001 From: Sebastian Moeller Date: Tue, 3 Mar 2015 13:23:53 +0100 Subject: [PATCH] Teach SQM hotplug tricks Some interfaces like wan-pppoe go away, when the ppp connection is lost and get recreated once the link is established again. SQM now has its own hotplug script to re-enable itself on the interfae just hotplugged. SQM will not touch other instances of itself running on other interfaces if called by hotplug.d. The implementation now allows this functionality by calling run.sh like: /usr/lib/sqm/run.sh interface YOUR_INTERFACE_NAME_HERE e.g.: /usr/lib/sqm/run.sh interface ge00-pppoe If called with a specific interface SQM will only try to disable itself on that interface to clean up all left over state and the re-enable itself on just that interface. Hopefully that allows for better service with instable interfaces like pppoe. The current code passes a simple manual stop start test of the ge00-pppoe interface from the GUI and does seem to do the right thing, at least on cerowrt 3.10.50-1... --- net/sqm-scripts/Makefile | 6 ++-- .../files/etc/hotplug.d/iface/11-sqm | 7 +++++ net/sqm-scripts/files/usr/lib/sqm/run.sh | 30 +++++++++++++++++-- net/sqm-scripts/files/usr/lib/sqm/simple.qos | 3 ++ 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100755 net/sqm-scripts/files/etc/hotplug.d/iface/11-sqm diff --git a/net/sqm-scripts/Makefile b/net/sqm-scripts/Makefile index 298220dfa9..25c964bad9 100644 --- a/net/sqm-scripts/Makefile +++ b/net/sqm-scripts/Makefile @@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=sqm-scripts -PKG_VERSION:=7 -PKG_RELEASE:=3 +PKG_VERSION:=8 +PKG_RELEASE:=1 PKG_LICENSE:=GPLv2 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) @@ -46,6 +46,8 @@ endef define Package/sqm-scripts/install $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/etc/init.d/sqm $(1)/etc/init.d/sqm + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_BIN) ./files/etc/hotplug.d/iface/11-sqm $(1)/etc/hotplug.d/iface/11-sqm $(INSTALL_DIR) $(1)/etc/config $(INSTALL_DATA) ./files/etc/config/sqm $(1)/etc/config/sqm $(INSTALL_DIR) $(1)/usr/lib/sqm diff --git a/net/sqm-scripts/files/etc/hotplug.d/iface/11-sqm b/net/sqm-scripts/files/etc/hotplug.d/iface/11-sqm new file mode 100755 index 0000000000..9543acd763 --- /dev/null +++ b/net/sqm-scripts/files/etc/hotplug.d/iface/11-sqm @@ -0,0 +1,7 @@ +#!/bin/sh + +# teach SQM to re-enable itself when an interface re-appears +logger -t SQM -s "hotplug on interface: ${DEVICE} action: ${ACTION}" + +[ "$ACTION" = ifup ] && /usr/lib/sqm/run.sh interface ${DEVICE} + diff --git a/net/sqm-scripts/files/usr/lib/sqm/run.sh b/net/sqm-scripts/files/usr/lib/sqm/run.sh index d7b86a220f..8995213d76 100755 --- a/net/sqm-scripts/files/usr/lib/sqm/run.sh +++ b/net/sqm-scripts/files/usr/lib/sqm/run.sh @@ -9,16 +9,37 @@ . /lib/functions.sh -STOP=$1 +STOP= ACTIVE_STATE_PREFIX="SQM_active_on_" ACTIVE_STATE_FILE_DIR="/var/run/SQM" mkdir -p ${ACTIVE_STATE_FILE_DIR} +PROTO_STATE_FILE_LIST=$( ls ${ACTIVE_STATE_FILE_DIR}/${ACTIVE_STATE_PREFIX}* 2> /dev/null ) + + +case ${1} in + stop) + logger -t SQM -s "run.sh stop" + STOP=$1 + ;; + interface) + START_ON_IF=$2 # only process this interface + logger -t SQM -s "Re/starting sqm on interface ${START_ON_IF}" + # TODO if $2 is empty just bail... + if [ -z ${START_ON_IF} ] ; + then + logger -t SQM -s "Interface name missing, nothing to do, bailing out" + return 0 + fi + # only try to restart the just hotplugged interface, so reduce the list of interfaces to stop to the specified one + PROTO_STATE_FILE_LIST=${ACTIVE_STATE_FILE_DIR}/${ACTIVE_STATE_PREFIX}${START_ON_IF} + ;; +esac + # the current uci config file does not necessarily contain sections for all interfaces with active # SQM instances, so use the ACTIVE_STATE_FILES to detect the interfaces on which to stop SQM. # Currently the .qos scripts start with stopping any existing traffic shaping so this should not # effectively change anything... -PROTO_STATE_FILE_LIST=$( ls ${ACTIVE_STATE_FILE_DIR}/${ACTIVE_STATE_PREFIX}* 2> /dev/null ) for STATE_FILE in ${PROTO_STATE_FILE_LIST} ; do if [ -f ${STATE_FILE} ] ; then @@ -35,6 +56,11 @@ config_load sqm run_simple_qos() { local section="$1" export IFACE=$(config_get "$section" interface) + + # If called explicitly for one interface only , so ignore anything else + [ -n "${START_ON_IF}" -a "$START_ON_IF" != "$IFACE" ] && return + #logger -t SQM -s "marching on..." + ACTIVE_STATE_FILE_FQN="${ACTIVE_STATE_FILE_DIR}/${ACTIVE_STATE_PREFIX}${IFACE}" # this marks interfaces as active with SQM [ -f "${ACTIVE_STATE_FILE_FQN}" ] && logger -t SQM -s "Uh, oh, ${ACTIVE_STATE_FILE_FQN} should already be stopped." # Not supposed to happen diff --git a/net/sqm-scripts/files/usr/lib/sqm/simple.qos b/net/sqm-scripts/files/usr/lib/sqm/simple.qos index 5df6aa7e25..6e5af4a941 100755 --- a/net/sqm-scripts/files/usr/lib/sqm/simple.qos +++ b/net/sqm-scripts/files/usr/lib/sqm/simple.qos @@ -37,6 +37,9 @@ ipt -t mangle -A QOS_MARK_${IFACE} -m tos --tos Minimize-Delay -j MARK --set-ma # Turn it on. Preserve classification if already performed +#sm: is it correct to do this in $IFACE? Should ingress not be on $DEV? since HTB acts on $DEV? +# SQUASH also does not work on $DEV (that is the IFB will still see the incoming ToS bits whether we squash or not) +# SQUASH is still useful to protect internal machines... if [ "$SQUASH_DSCP" = "1" ] then sqm_logger "Squashing differentiated services code points (DSCP) from ingress." -- 2.30.2