qosmngr: improvements

- ubus call for reloading each individual service as well as all of
  qos added.
- init script modified to call ubus call and also to have a boot and
  restart section.
- to have separate uci parameters for detination mask and source mask
  make no sense, both destination/source ip and mask in tr181 should
  map to destination/source ip uci parameter, updated.
- firewall rules added by qos are moved to a separate chain, flushing
  is hence restricted to this chain only.
- the hotplug is not really required, hence removed.
This commit is contained in:
Rahul 2020-06-08 18:17:45 +05:30
parent fbc5226978
commit c2b993b494
4 changed files with 117 additions and 96 deletions

View file

@ -1,18 +0,0 @@
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
. /lib/functions/network.sh
network_get_device l3device $INTERFACE
[ -n "$l3device" ] || exit 0
wan_if="$(uci -q get network.wan.ifname)"
for intf in $wan_if; do
if [ "$intf" == "$l3device" ]; then
ubus call uci commit '{"config":"qos"}'
exit
fi
done

View file

@ -3,7 +3,7 @@
# Uncomment this if functions need to called inside /lib/qos # Uncomment this if functions need to called inside /lib/qos
# include /lib/qos # include /lib/qos
START=18 START=21
USE_PROCD=1 USE_PROCD=1
NAME=qosmngr NAME=qosmngr
@ -12,16 +12,10 @@ NAME=qosmngr
include /lib/qos include /lib/qos
start_service() { start_service() {
# Call functions to configure QoS
if [ -f "/etc/config/qos" ]; then if [ -f "/etc/config/qos" ]; then
configure_qos ubus -S call qos reload
fi fi
# procd_open_instance
# start the daemon responsible for reading qos stats
# procd_set_param command "/sbin/qosmngr"
# procd_set_param respawn
# procd_close_instance
} }
stop() { stop() {
@ -30,19 +24,20 @@ stop() {
} }
boot() { boot() {
setup_qos
start start
} }
service_triggers() { service_triggers() {
procd_add_reload_trigger firewall qos procd_add_reload_trigger qos
} }
reload_service() { reload_service() {
# Call functions to configure QoS # Call functions to configure QoS
start start
# reload the daemon responsible for reading qos stats
# ubus -t 5 call qos reload
} }
restart() {
setup_qos
start
}

View file

@ -44,7 +44,7 @@ handle_queue() {
esac esac
# Call tmctl which is a broadcomm command to configure queues on a port. # Call tmctl which is a broadcomm command to configure queues on a port.
tmctl setqcfg --devtype 0 --if $ifname --qid $order --priority $order --weight $wgt --schedmode $salg --shapingrate $rate --burstsize $bs --qsize $qsize tmctl setqcfg --devtype 0 --if $ifname --qid $order --priority $order --qsize 1024 --weight $wgt --schedmode $salg --shapingrate $rate --burstsize $bs
} }
#function to handle a shaper section #function to handle a shaper section
@ -69,14 +69,46 @@ handle_shaper() {
tmctl setportshaper --devtype 0 --if $ifname --shapingrate $rate --burstsize $bs tmctl setportshaper --devtype 0 --if $ifname --shapingrate $rate --burstsize $bs
} }
setup_qos() {
ebtables -t broute -N qos
ret=$?
[ $ret -eq 0 ] && ebtables -t broute -I BROUTING -j qos
iptables -t mangle -N qos_forward
ret=$?
[ $ret -eq 0 ] && iptables -t mangle -I FORWARD -j qos_forward
iptables -t mangle -N qos_prerouting
ret=$?
[ $ret -eq 0 ] && iptables -t mangle -I PREROUTING -j qos_prerouting
iptables -t mangle -N qos_output
ret=$?
[ $ret -eq 0 ] && iptables -t mangle -I OUTPUT -j qos_output
ip6tables -t mangle -N qos_forward
ret=$?
[ $ret -eq 0 ] && ip6tables -t mangle -I FORWARD -j qos_forward
ip6tables -t mangle -N qos_prerouting
ret=$?
[ $ret -eq 0 ] && ip6tables -t mangle -I PREROUTING -j qos_prerouting
ip6tables -t mangle -N qos_output
ret=$?
[ $ret -eq 0 ] && ip6tables -t mangle -I OUTPUT -j qos_output
}
flush_chains() { flush_chains() {
echo "ebtables -t broute -F" > /tmp/qos/classify.ebtables echo "ebtables -t broute -F qos" > /tmp/qos/classify.ebtables
echo "iptables -t mangle -F FORWARD" > /tmp/qos/classify.iptables
echo "iptables -t mangle -F PREROUTING" >> /tmp/qos/classify.iptables echo "iptables -t mangle -F qos_forward" > /tmp/qos/classify.iptables
echo "iptables -t mangle -F OUTPUT" >> /tmp/qos/classify.iptables echo "iptables -t mangle -F qos_prerouting" >> /tmp/qos/classify.iptables
echo "ip6tables -t mangle -F FORWARD" > /tmp/qos/classify.ip6tables echo "iptables -t mangle -F qos_output" >> /tmp/qos/classify.iptables
echo "ip6tables -t mangle -F PREROUTING" >> /tmp/qos/classify.ip6tables
echo "ip6tables -t mangle -F OUTPUT" >> /tmp/qos/classify.ip6tables echo "ip6tables -t mangle -F qos_forward" > /tmp/qos/classify.ip6tables
echo "ip6tables -t mangle -F qos_prerouting" >> /tmp/qos/classify.ip6tables
echo "ip6tables -t mangle -F qos_output" >> /tmp/qos/classify.ip6tables
} }
init_broute_rule() { init_broute_rule() {
@ -112,7 +144,7 @@ broute_rule_set_traffic_class() {
} }
broute_append_rule() { broute_append_rule() {
echo "ebtables -t broute -A BROUTING $BR_RULE" >> /tmp/qos/classify.ebtables echo "ebtables -t broute -A qos $BR_RULE" >> /tmp/qos/classify.ebtables
} }
handle_ebtables_rules() { handle_ebtables_rules() {
@ -193,10 +225,6 @@ iptables_filter_ip_dest() {
IP_RULE="$IP_RULE -d $1" IP_RULE="$IP_RULE -d $1"
} }
iptables_filter_ip_mask() {
IP_RULE="$IP_RULE$1"
}
iptables_filter_port_dest() { iptables_filter_port_dest() {
IP_RULE="$IP_RULE --dport $1" IP_RULE="$IP_RULE --dport $1"
} }
@ -218,11 +246,11 @@ iptables_filter_dscp_filter() {
} }
iptables_filter_ip_len_min() { iptables_filter_ip_len_min() {
IP_RULE="$IP_RULE -m length --length $1" IP_RULE="$IP_RULE -m length --length $1"
} }
iptables_filter_ip_len_max() { iptables_filter_ip_len_max() {
IP_RULE="$IP_RULE:$1" IP_RULE="$IP_RULE:$1"
} }
iptables_set_dscp_mark() { iptables_set_dscp_mark() {
@ -230,18 +258,18 @@ iptables_set_dscp_mark() {
} }
iptables_set_traffic_class() { iptables_set_traffic_class() {
IP_RULE="$IP_RULE -j MARK --set-xmark 0x$1/0x$1" IP_RULE="$IP_RULE -j MARK --set-xmark 0x$1/0x$1"
} }
append_rule_to_mangle_table() { append_rule_to_mangle_table() {
if [ $2 == 4 ]; then if [ $2 == 4 ]; then
echo "iptables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.iptables echo "iptables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.iptables
elif [ $2 == 6 ]; then elif [ $2 == 6 ]; then
echo "ip6tables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.ip6tables echo "ip6tables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.ip6tables
elif [ $2 == 1 ]; then elif [ $2 == 1 ]; then
echo "iptables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.iptables echo "iptables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.iptables
echo "ip6tables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.ip6tables echo "ip6tables -t mangle -A $1 $IP_RULE" >> /tmp/qos/classify.ip6tables
fi fi
} }
handle_iptables_rules() { handle_iptables_rules() {
@ -251,7 +279,7 @@ handle_iptables_rules() {
init_iptables_rule init_iptables_rule
config_get proto "$cid" "proto" config_get proto "$cid" "proto"
config_get traffic_class "$sid" "traffic_class" config_get traffic_class "$sid" "traffic_class"
config_get dscp_mark "$cid" "dscp_mark" config_get dscp_mark "$cid" "dscp_mark"
config_get dscp_filter "$cid" "dscp_filter" config_get dscp_filter "$cid" "dscp_filter"
config_get dest_port "$cid" "dest_port" config_get dest_port "$cid" "dest_port"
@ -259,11 +287,9 @@ handle_iptables_rules() {
config_get src_port "$cid" "src_port" config_get src_port "$cid" "src_port"
config_get src_port_range "$cid" "src_port_range" config_get src_port_range "$cid" "src_port_range"
config_get dest_ip "$cid" "dest_ip" config_get dest_ip "$cid" "dest_ip"
config_get dest_mask "$cid" "dest_mask"
config_get src_ip "$cid" "src_ip" config_get src_ip "$cid" "src_ip"
config_get src_mask "$cid" "src_mask" config_get ip_len_min "$cid" "ip_len_min"
config_get ip_len_min "$cid" "ip_len_min" config_get ip_len_max "$cid" "ip_len_max"
config_get ip_len_max "$cid" "ip_len_max"
config_get ifname "$cid" "ifname" config_get ifname "$cid" "ifname"
#check version of ip #check version of ip
@ -297,23 +323,12 @@ handle_iptables_rules() {
is_l3_rule=1 is_l3_rule=1
fi fi
if [ -n "$src_mask" ]; then
iptables_filter_ip_mask $src_mask
is_l3_rule=1
fi
#filter dest. ip #filter dest. ip
if [ -n "$dest_ip" ]; then if [ -n "$dest_ip" ]; then
iptables_filter_ip_dest $dest_ip iptables_filter_ip_dest $dest_ip
is_l3_rule=1 is_l3_rule=1
fi fi
#filter dest. ip mask
if [ -n "$dest_mask" ]; then
iptables_filter_ip_mask $dest_mask
is_l3_rule=1
fi
#filter dest. port #filter dest. port
if [ -n "$dest_port" -a -z "$dest_port_range" ]; then if [ -n "$dest_port" -a -z "$dest_port_range" ]; then
iptables_filter_port_dest $dest_port iptables_filter_port_dest $dest_port
@ -345,13 +360,13 @@ handle_iptables_rules() {
fi fi
#filter min. IP packet len. #filter min. IP packet len.
if [ -n "$ip_len_min" ]; then if [ -n "$ip_len_min" ]; then
iptables_filter_ip_len_min $ip_len_min iptables_filter_ip_len_min $ip_len_min
is_l3_rule=1 is_l3_rule=1
fi fi
#filter max. IP packet len. #filter max. IP packet len.
if [ -n "$ip_len_max" ]; then if [ -n "$ip_len_max" ]; then
iptables_filter_ip_len_max $ip_len_max iptables_filter_ip_len_max $ip_len_max
is_l3_rule=1 is_l3_rule=1
fi fi
@ -364,18 +379,18 @@ handle_iptables_rules() {
[ -n "$dscp_mark" ] && iptables_set_dscp_mark $dscp_mark [ -n "$dscp_mark" ] && iptables_set_dscp_mark $dscp_mark
#set packet queue mark #set packet queue mark
[ -n "$traffic_class" ] && iptables_set_traffic_class $traffic_class [ -n "$traffic_class" ] && iptables_set_traffic_class $traffic_class
#write iptables rule for dscp marking #write iptables rule for dscp marking
[ -n "$IP_RULE" -a -n "$dscp_mark" ] && append_rule_to_mangle_table "FORWARD" $ip_version [ -n "$IP_RULE" -a -n "$dscp_mark" ] && append_rule_to_mangle_table "qos_forward" $ip_version
if [ -n "$IP_RULE" -a -n "$traffic_class" ]; then if [ -n "$IP_RULE" -a -n "$traffic_class" ]; then
if [ "$ifname" == "lo" ]; then if [ "$ifname" == "lo" ]; then
#write iptables rule for putting WAN directed internal packets in different queue #write iptables rule for putting WAN directed internal packets in different queue
append_rule_to_mangle_table "OUTPUT" $ip_version append_rule_to_mangle_table "qos_output" $ip_version
else else
#write iptables rule for putting WAN directed LAN packets in different queue #write iptables rule for putting WAN directed LAN packets in different queue
append_rule_to_mangle_table "PREROUTING" $ip_version append_rule_to_mangle_table "qos_prerouting" $ip_version
fi fi
fi fi
} }
@ -394,22 +409,14 @@ handle_classify() {
handle_iptables_rules $cid handle_iptables_rules $cid
} }
configure_qos() { configure_shaper() {
# Delete queues
for intf in $(db get hw.board.ethernetPortOrder); do
i=0
for i in 0 1 2 3 4 5 6 7; do
tmctl delqcfg --devtype 0 --if $intf --qid $i
done
done
# Load UCI file # Load UCI file
config_load qos config_load qos
# Processing shaper section(s) # Processing shaper section(s)
config_foreach handle_shaper shaper config_foreach handle_shaper shaper
}
config_foreach handle_queue queue configure_classify() {
#processing classify section #processing classify section
# First remove old files # First remove old files
rm -f /tmp/qos/classify.ebtables rm -f /tmp/qos/classify.ebtables
@ -425,16 +432,48 @@ configure_qos() {
#add flush chain rules #add flush chain rules
flush_chains flush_chains
# Load UCI file
config_load qos
config_foreach handle_classify classify config_foreach handle_classify classify
# For now qosmngr will execute the ebtables and iptables scripts
# that it generates, this can later be integrated with the include
# section of firewall uci bu execute for now
sh /tmp/qos/classify.ebtables sh /tmp/qos/classify.ebtables
sh /tmp/qos/classify.iptables sh /tmp/qos/classify.iptables
sh /tmp/qos/classify.ip6tables sh /tmp/qos/classify.ip6tables
} }
configure_queue() {
# Delete queues
for intf in $(db get hw.board.ethernetPortOrder); do
i=0
for i in 0 1 2 3 4 5 6 7; do
tmctl delqcfg --devtype 0 --if $intf --qid $i &>/dev/null
done
done
# Load UCI file
config_load qos
config_foreach handle_queue queue
}
configure_qos() {
configure_queue
configure_shaper
configure_classify
}
reload_qos() {
local service_name="$1"
if [ -z "$service_name" ]; then
configure_qos
elif [ "$service_name" == "shaper" ]; then
configure_shaper
elif [ "$service_name" == "queue" ]; then
configure_queue
elif [ "$service_name" == "classify" ]; then
configure_classify
fi
}
get_queue_stats() { get_queue_stats() {
local ifname local ifname
json_init json_init

View file

@ -6,9 +6,8 @@ include /lib/qos
case "$1" in case "$1" in
list) list)
echo '{ "queue_stats": { "ifname":"String", "qid":"Integer" } }' echo '{ "queue_stats": { "ifname":"String", "qid":"Integer" }, "reload": { "section":"String" } }'
;;
;;
call) call)
case "$2" in case "$2" in
queue_stats) queue_stats)
@ -18,8 +17,14 @@ case "$1" in
json_get_var qid qid json_get_var qid qid
read_queue_stats $iface $qid read_queue_stats $iface $qid
;; ;;
reload)
read input;
json_load "$input"
json_get_var service section
reload_qos $service
;;
esac esac
;; ;;
esac esac