diff --git a/qosmngr/files/airoha/lib/qos/common/classify.sh b/qosmngr/files/airoha/lib/qos/common/classify.sh index dcc060dee..a709e4a8d 100755 --- a/qosmngr/files/airoha/lib/qos/common/classify.sh +++ b/qosmngr/files/airoha/lib/qos/common/classify.sh @@ -1,9 +1,12 @@ #!/bin/sh # Common classifier library -# Handle classify section -handle_classify() { - cid="$1" #classify section ID +#counter variable to assign classify order value if not added in config +temp_order=1 + +# Function to handle a classify order +handle_classify_order() { + local cid="$1" #classify section ID config_get is_enable "$cid" "enable" 1 # no need to configure disabled classify rules @@ -11,11 +14,53 @@ handle_classify() { return fi - handle_ebtables_rules "$cid" - handle_iptables_rules "$cid" - handle_policer_rules "$cid" + # Create classify file containing classify order + local corder_file="/tmp/qos/classify.order" + + config_get c_order "$cid" "order" + + if [ -z "$c_order" ]; then + c_order=$temp_order; + temp_order=$((temp_order + 1)) + fi + + value=${c_order}_${cid} + echo $value >> $corder_file } +# Sort classify, lower value in uci means higher precedence, so this +# function sorts the classify order in assending order +sort_classify_by_order() { + local corder_file="/tmp/qos/classify.order" + local tmp_corder_file="/tmp/qos/tmp_classify.order" + + sort -n -k1 $corder_file > $tmp_corder_file + cp $tmp_corder_file $corder_file + rm -f $tmp_corder_file +} + +# Handle classify section +handle_classify() { + + local corder_file="/tmp/qos/classify.order" + + while read -r line; do + line_cid=$(echo $line | cut -d '_' -f 2) + + # add ip rule only for classify rules which has non empty + # value forwarding policy option + # if forwarding policy option value empty then add iptables/ + # ip6tables/ebtables/rate_limit rules + config_get fwding_policy "$line_cid" "forwarding_policy" + if [ -n "$fwding_policy" ]; then + handle_ip_rule $line_cid $fwding_policy + else + handle_ebtables_rules $line_cid + handle_iptables_rules $line_cid + handle_policer_rules $line_cid + fi + done < "$corder_file" +} # Configure classifier based on UCI subtree 'qos.classify' configure_classify() { @@ -24,21 +69,34 @@ configure_classify() { rm -f /tmp/qos/classify.ebtables rm -f /tmp/qos/classify.iptables rm -f /tmp/qos/classify.ip6tables + rm -f /tmp/qos/classify.order + rm -f /tmp/qos/tmp_classify.order + rm -f /tmp/qos/classify.iprule # Create files that will contain the rules if not present already mkdir -p /tmp/qos/ touch /tmp/qos/classify.iptables touch /tmp/qos/classify.ip6tables touch /tmp/qos/classify.ebtables + touch /tmp/qos/classify.order + touch /tmp/qos/tmp_classify.order + touch /tmp/qos/classify.iprule # Add flush chain rules flush_chains + #flush added ip rule + flush_ip_rule + # Load UCI file config_load qos - config_foreach handle_classify classify + config_foreach handle_classify_order classify + sort_classify_by_order + handle_classify sh /tmp/qos/classify.ebtables sh /tmp/qos/classify.iptables sh /tmp/qos/classify.ip6tables -} \ No newline at end of file + sh /tmp/qos/classify.iprule + +} diff --git a/qosmngr/files/airoha/lib/qos/qos.sh b/qosmngr/files/airoha/lib/qos/qos.sh index 2a5b0f5dd..e2a0a4734 100755 --- a/qosmngr/files/airoha/lib/qos/qos.sh +++ b/qosmngr/files/airoha/lib/qos/qos.sh @@ -12,6 +12,7 @@ include /lib/ethernet . /lib/qos/common/queue.sh . /lib/qos/common/shaper.sh . /lib/qos/airoha.sh +. /lib/qos/ip_rule.sh configure_qos() { # queue configuration is being done after shaper configuration, diff --git a/qosmngr/files/broadcom/lib/qos/qos.sh b/qosmngr/files/broadcom/lib/qos/qos.sh index 406efc742..7bb950d6c 100755 --- a/qosmngr/files/broadcom/lib/qos/qos.sh +++ b/qosmngr/files/broadcom/lib/qos/qos.sh @@ -2,6 +2,9 @@ . /lib/functions.sh include /lib/ethernet +# include common code +. /lib/qos/ip_rule.sh + IP_RULE="" BR_RULE="" BR6_RULE="" @@ -809,7 +812,7 @@ handle_iptables_rules() { init_iptables_rule config_get proto "$cid" "proto" - config_get traffic_class "$sid" "traffic_class" + config_get traffic_class "$cid" "traffic_class" config_get dscp_mark "$cid" "dscp_mark" config_get dscp_filter "$cid" "dscp_filter" config_get dest_port "$cid" "dest_port" @@ -1060,21 +1063,24 @@ sort_classify_by_order() { #function to handle a classify section handle_classify() { - cid="$1" #classify section ID - config_get is_enable "$cid" "enable" - # no need to configure disabled classify rules - if [ "$is_enable" == '0' ]; then - return - fi local corder_file="/tmp/qos/classify.order" while read -r line; do line_cid=$(echo $line | cut -d '_' -f 2) - handle_ebtables_rules $line_cid - handle_iptables_rules $line_cid - handle_policer_rules $line_cid + # add ip rule only for classify rules which has non empty + # value forwarding policy option + # if forwarding policy option value empty then add iptables/ + # ip6tables/ebtables/rate_limit rules + config_get fwding_policy "$line_cid" "forwarding_policy" + if [ -n "$fwding_policy" ]; then + handle_ip_rule $line_cid $fwding_policy + else + handle_ebtables_rules $line_cid + handle_iptables_rules $line_cid + handle_policer_rules $line_cid + fi done < "$corder_file" } @@ -1097,6 +1103,7 @@ configure_classify() { rm -f /tmp/qos/classify.ip6tables rm -f /tmp/qos/classify.order rm -f /tmp/qos/tmp_classify.order + rm -f /tmp/qos/classify.iprule #create files that will contain the rules if not present already mkdir -p /tmp/qos/ @@ -1105,19 +1112,25 @@ configure_classify() { touch /tmp/qos/classify.ebtables touch /tmp/qos/classify.order touch /tmp/qos/tmp_classify.order + touch /tmp/qos/classify.iprule #add flush chain rules flush_chains + #flush added ip rule + flush_ip_rule + # Load UCI file config_load qos config_foreach handle_classify_order classify sort_classify_by_order - handle_classify classify + handle_classify sh /tmp/qos/classify.ebtables sh /tmp/qos/classify.iptables sh /tmp/qos/classify.ip6tables + sh /tmp/qos/classify.iprule + # broadcom recommends that each time traffic class is set, # the flows should be flushed for the new mapping to take # effect, it then makes sense to make it a part of the diff --git a/qosmngr/files/common/lib/qos/ip_rule.sh b/qosmngr/files/common/lib/qos/ip_rule.sh new file mode 100644 index 000000000..a684368cb --- /dev/null +++ b/qosmngr/files/common/lib/qos/ip_rule.sh @@ -0,0 +1,110 @@ +#!/bin/sh +# add ip rule from qos uci + +IP_RULE="" + +init_ip_rule() { + IP_RULE="" +} + +ip_rule_match_inif() { + IP_RULE="$IP_RULE iif $1" +} + +ip_rule_match_proto() { + IP_RULE="$IP_RULE ipproto $1" +} + +ip_rule_match_dest_port() { + IP_RULE="$IP_RULE dport $1" +} + +ip_rule_match_src_port() { + IP_RULE="$IP_RULE sport $1" +} + +ip_rule_match_dest_ip() { + IP_RULE="$IP_RULE to $1" +} + +ip_rule_match_src_ip() { + IP_RULE="$IP_RULE from $1" +} + +ip_rule_match_dest_port_range() { + IP_RULE="$IP_RULE dport $1-$2" +} + +ip_rule_match_src_port_range() { + IP_RULE="$IP_RULE sport $1-$2" +} + +ip_rule_match_tos() { + IP_RULE="$IP_RULE tos $1" +} + +ip_rule_match_fwmark() { + IP_RULE="$IP_RULE fwmark $1" +} + +handle_ip_rule() { + cid=$1 + fwding_policy=$2 + + init_ip_rule + + # get uci value for selector/match + config_get dest_ip "$cid" "dest_ip" + config_get src_ip "$cid" "src_ip" + config_get ifname "$cid" "ifname" + config_get proto "$cid" "proto" + config_get tos "$cid" "dscp_check" + config_get fwmark "$cid" "traffic_class" + config_get dest_port "$cid" "dest_port" + config_get dest_port_range "$cid" "dest_port_range" + config_get src_port "$cid" "src_port" + config_get src_port_range "$cid" "src_port_range" + + # forming selector/match for rule + [ -n "$ifname" ] && ip_rule_match_inif $ifname + + [ -n "$proto" ] && ip_rule_match_proto $proto + + if [ -n "$src_port" -a -z "$src_port_range" ]; then + ip_rule_match_src_port $src_port + fi + + if [ -n "$dest_port" -a -z "$dest_port_range" ]; then + ip_rule_match_dest_port $dest_port + fi + + [ -n "$src_ip" ] && ip_rule_match_src_ip $src_ip + + [ -n "$dest_ip" ] && ip_rule_match_dest_ip $dest_ip + + if [ -n "$dest_port" -a -n "$dest_port_range" ]; then + ip_rule_match_dest_port_range $dest_port $dest_port_range + fi + + if [ -n "$src_port" -a -n "$src_port_range" ]; then + ip_rule_match_src_port_range $src_port $src_port_range + fi + + [ -n "$tos" ] && ip_rule_match_tos $tos + + [ -n "$fwmark" ] && ip_rule_match_fwmark $fwmark + + # forming full ip rule + if [ -n "$IP_RULE" ]; then + echo "ip rule add $IP_RULE table $fwding_policy" >> /tmp/qos/classify.iprule + echo "ip rule del $IP_RULE table $fwding_policy" >> /tmp/qos/classify.del_iprule + fi +} + +flush_ip_rule() { + if [ -s "/tmp/qos/classify.del_iprule" ]; then + sh /tmp/qos/classify.del_iprule + rm -f /tmp/qos/classify.del_iprule + fi + touch /tmp/qos/classify.del_iprule +} diff --git a/qosmngr/files/linux/lib/qos/qos.sh b/qosmngr/files/linux/lib/qos/qos.sh index 2fad55022..035be3a78 100755 --- a/qosmngr/files/linux/lib/qos/qos.sh +++ b/qosmngr/files/linux/lib/qos/qos.sh @@ -2,6 +2,9 @@ . /lib/functions.sh #set -x +# include common code +. /lib/qos/ip_rule.sh + IP_RULE="" MAJOR="" @@ -510,8 +513,18 @@ handle_classify() { local corder_file="/tmp/qos/classify.order" while read -r line; do line_cid=$(echo $line | cut -d '_' -f 2) - handle_iptables_rules $line_cid - handle_policer_rules $line_cid + # add ip rule only for classify rules which has non empty + # value forwarding policy option + # if forwarding policy option value empty then add iptables/ + # ip6tables/ebtables/rate_limit rules + config_get fwding_policy "$line_cid" "forwarding_policy" + + if [ -n "$fwding_policy" ]; then + handle_ip_rule $line_cid $fwding_policy + else + handle_iptables_rules $line_cid + handle_policer_rules $line_cid + fi done < "$corder_file" } @@ -520,15 +533,20 @@ configure_classify() { rm -f /tmp/qos/classify.iptables rm -f /tmp/qos/classify.ip6tables rm -f /tmp/qos/classify.order + rm -f /tmp/qos/classify.iprule # create files that will contain the rules if not present already mkdir -p /tmp/qos/ touch /tmp/qos/classify.iptables touch /tmp/qos/classify.ip6tables touch /tmp/qos/classify.order + touch /tmp/qos/classify.iprule flush_chains + #flush added ip rule + flush_ip_rule + # Load UCI file config_load qos config_foreach handle_classify_order classify @@ -537,6 +555,7 @@ configure_classify() { sh /tmp/qos/classify.iptables sh /tmp/qos/classify.ip6tables + sh /tmp/qos/classify.iprule }