#!/bin/sh # Implementation of QoS setup for Econet platform. errmsg() { echo "$@" >&2 return 0 } get_var() { local varname="$1" eval echo \$\{${varname}\} return 0 } # Initialized queues # (Not needed on Econet) hw_queue_init_all() { return 0 } # Initialize all interfaces # (Not needed on Econet) hw_intf_init() { return 0 } # Initialize the hardware setup library hw_init_all() { export TMP_HW_QUEUE_LIST="" return 0 } # Remember selected queue options. They will be committed # during hw_commit_all() hw_queue_set() { local ifname="$1" local q_count="$2" local order="$3" local qsize="$4" local wgt="$5" local sc_alg="$6" local rate="$7" local burstsize="$8" local index="$((order - 1))" local ethwan="$(jsonfilter -i /etc/board.json -e @.network.wan.device)" #if [ "${ifname}" != "${ethwan}" ] ; then # return 2 #fi export TMP_HW_QUEUE_${order}_no="${q_count}" export TMP_HW_QUEUE_${order}_ifname="${ifname}" export TMP_HW_QUEUE_${order}_order="${order}" export TMP_HW_QUEUE_${order}_qsize="${qsize}" export TMP_HW_QUEUE_${order}_wgt="${wgt}" export TMP_HW_QUEUE_${order}_sc_alg="${sc_alg}" export TMP_HW_QUEUE_${order}_rate="${rate}" export TMP_HW_QUEUE_${order}_burstsize="${burstsize}" export TMP_HW_QUEUE_LIST="${TMP_HW_QUEUE_LIST} ${order}" if [ "${rate}" != "" ] && [ $(($rate != 0)) ] ; then errmsg "Per-queue shape rate is not implemented" fi return 0 } # Set policer options. In fact, they are not supported. hw_policer_set() { local action="$1" local dir="$2" local policer_no="$3" shift 3 case "$action" in add) meter="$1" cir="$2" cbs="$3" ebs="$4" pir="$5" pbs="$6" ;; del) ;; esac errmsg "Policer (action $action, direction $dir) is not implemented" return $? } # Set ingress rate. In fact, it is not supported hw_policer_set_ingress_rate() { local ifname="$1" local ingress_rate="$2" local in_burst_size="$3" errmsg "Policer (action set_ingress_rate) is not implemented" } # Configure shaper rate that will be committed during hw_commit_all() hw_shaper_set() { local ifname="$1" local action="$2" local rate="$3" local burstsize="$4" case "${action}" in add) export TMP_HW_SHAPE_RATE="$rate" export TMP_HW_SHAPE_BURSTSIZE="$burstsize" ;; del) export TMP_HW_SHAPE_RATE="" export TMP_HW_SHAPE_BURSTSIZE="" ;; *) return 1 ;; esac return 0 } # Convert shaper in UCI terms to Econet terms hw_sc_alg2str() { local sc_alg="$1" case "${sc_alg}" in SP) echo "PQ" ;; WRR) echo "WRR" ;; *) echo "" return 1 esac return 0 } # Commit all options preserved during hw_commit_all() { local sorted_list="$(echo $TMP_HW_QUEUE_LIST | tr ' ' '\n' | sort | xargs)" local weight_list="" local glob_alg="" local shape_rate="$TMP_HW_SHAPE_RATE" local q_count="0" local mac_qos_flag="" # Reorder queues for q in ${sorted_list} ; do local sc_alg="$(get_var TMP_HW_QUEUE_${q}_sc_alg)" local wgt="$(get_var TMP_HW_QUEUE_${q}_wgt)" if [ "$glob_alg" != "" ] && [ "$sc_alg" != "$glob_alg" ] ; then errmsg "Not matching scheduling algorithm: $sc_alg vs $glob_alg" return 1 fi glob_alg="$sc_alg" case "${sc_alg}" in WRR) if [ $(($q_count >= 8)) != 0 ] ; then errmsg "Too many queues, next queues will be ignored" else weight_list="$weight_list $wgt" fi ;; esac q_count=$((q_count + 1)) done case "${glob_alg}" in WRR) mac_qos_flag="8QWRR" while [ $((q_count < 8)) != 0 ] ; do weight_list="$weight_list 1" q_count=$((q_count + 1)) done ;; SP) mac_qos_flag="8QPQ" q_count="8" ;; esac rm -f "/tmp/qos/wan_link_shape_rate" rm -f "/tmp/qos/wan_link_speed" if [ "${glob_alg}" != "" ] ; then /userfs/bin/qosrule discpline $(hw_sc_alg2str ${glob_alg}) ${weight_list} \ uplink-bandwidth ${shape_rate:-10000000} \ queuemask "$(((1 << q_count) - 1))" echo ${mac_qos_flag} > /proc/qdma_wan/mac_qos_flag if [ -n "${shape_rate}" ]; then echo "${shape_rate}" > "/tmp/qos/wan_link_shape_rate" else /usr/sbin/qos-uplink-bandwidth fi else /userfs/bin/qosrule discpline Enable 0 fi }