[PATCH] [qos-scripts] Fix packet/connection marking when using halfduplex option
[openwrt.git] / package / qos-scripts / files / usr / lib / qos / generate.sh
index 7715a45..4ee29ca 100755 (executable)
@@ -1,12 +1,21 @@
 #!/bin/sh
 [ -e /etc/functions.sh ] && . /etc/functions.sh || . ./functions.sh
-[ -x /sbin/modprobe ] && insmod="modprobe" || insmod="insmod"
+[ -x /sbin/modprobe ] && {
+       insmod="modprobe"
+       rmmod="$insmod -r"
+} || {
+       insmod="insmod"
+       rmmod="rmmod"
+}
 
 add_insmod() {
        eval "export isset=\${insmod_$1}"
        case "$isset" in
                1) ;;
-               *) append INSMOD "$insmod $* >&- 2>&-" "$N"; export insmod_$1=1;;
+               *) {
+                       [ "$2" ] && append INSMOD "$rmmod $1 >&- 2>&-" "$N"
+                       append INSMOD "$insmod $* >&- 2>&-" "$N"; export insmod_$1=1
+               };;
        esac
 }
 
@@ -14,6 +23,7 @@ add_insmod() {
        # only try to parse network config on openwrt
 
        find_ifname() {(
+               reset_cb
                include /lib/network
                scan_interfaces
                config_get "$1" ifname
@@ -58,16 +68,9 @@ parse_matching_rule() {
                        *:dsthost)
                                append "$var" "-d $value"
                        ;;
-                       *:ipp2p)
-                               add_insmod ipt_ipp2p
-                               append "$var" "-m ipp2p"
-                               case "$value" in
-                                       all) append "$var" "--edk --dc --kazaa --gnu --bit";;
-                                       *) append "$var" "--$value";;
-                               esac
-                       ;;
                        *:layer7)
                                add_insmod ipt_layer7
+                               add_insmod xt_layer7
                                append "$var" "-m layer7 --l7proto $value${pkt:+ --l7pkt}"
                        ;;
                        *:ports|*:srcports|*:dstports)
@@ -110,6 +113,35 @@ parse_matching_rule() {
                                esac
                                ports=1
                        ;;
+                       *:connbytes)
+                               value="$(echo "$value" | sed -e 's,-,:,g')"
+                               add_insmod ipt_connbytes
+                               append "$var" "-m connbytes --connbytes $value --connbytes-dir both --connbytes-mode bytes"
+                       ;;
+                       *:tos)
+                                add_insmod ipt_tos
+                                case "$value" in
+                                        !*) append "$var" "-m tos ! --tos $value";;
+                                        *) append "$var" "-m tos --tos $value"
+                                esac
+                        ;;
+                       *:dscp)
+                                add_insmod ipt_dscp
+                               dscp_option="--dscp"
+                                [ -z "${value%%[EBCA]*}" ] && dscp_option="--dscp-class"
+                               case "$value" in
+                                               !*) append "$var" "-m dscp ! $dscp_option $value";;
+                                               *) append "$var" "-m dscp $dscp_option $value"
+                                esac
+                        ;;
+                       *:direction)
+                               value="$(echo "$value" | sed -e 's,-,:,g')"
+                               if [ "$value" = "out" ]; then
+                                       append "$var" "-o $device"
+                               elif [ "$value" = "in" ]; then
+                                       append "$var" "-i $device"
+                               fi
+                       ;;
                        1:pktsize)
                                value="$(echo "$value" | sed -e 's,-,:,g')"
                                add_insmod ipt_length
@@ -132,6 +164,19 @@ parse_matching_rule() {
                                        !*) append "$var" "-m mark ! --mark $class";;
                                        *) append "$var" "-m mark --mark $class";;
                                esac
+                       ;;
+                       1:TOS)
+                               add_insmod ipt_TOS
+                               config_get TOS "$rule" 'TOS'
+                               suffix="-j TOS --set-tos "${TOS:-"Normal-Service"}
+                       ;;
+                       1:DSCP)
+                               add_insmod ipt_DSCP
+                               config_get DSCP "$rule" 'DSCP'
+                               [ -z "${DSCP%%[EBCA]*}" ] && set_value="--set-dscp-class $DSCP" \
+                               || set_value="--set-dscp $DSCP"
+                               suffix="-j DSCP $set_value"
+                       ;;
                esac
        done
        append "$var" "$suffix"
@@ -148,8 +193,8 @@ config_cb() {
        # Section start
        case "$1" in
                interface)
-                       config_set "$1" "classgroup" "Default"
-                       config_set "$1" "upload" "128"
+                       config_set "$2" "classgroup" "Default"
+                       config_set "$2" "upload" "128"
                ;;
                classify|default|reclassify)
                        option_cb() {
@@ -162,18 +207,18 @@ config_cb() {
        config_get TYPE "$CONFIG_SECTION" TYPE
        case "$TYPE" in
                interface)
-                       config_get enabled "$CONFIG_SECTION" enabled
-                       config_get download "$CONFIG_SECTION" download
+                       config_get_bool enabled "$CONFIG_SECTION" enabled 1
+                       [ 1 -eq "$enabled" ] || return 0
                        config_get classgroup "$CONFIG_SECTION" classgroup
                        config_set "$CONFIG_SECTION" imqdev "$C"
-                       [ -z "$enabled" -o "$(($enabled))" -eq 0 ] || {
-                               C=$(($C+1))
-                               INTERFACES="$INTERFACES $CONFIG_SECTION"
-                               config_set "$classgroup" enabled 1
-                       }
+                       C=$(($C+1))
+                       append INTERFACES "$CONFIG_SECTION"
+                       config_set "$classgroup" enabled 1
                        config_get device "$CONFIG_SECTION" device
-                       [ -z "$device" ] && device="$(find_ifname ${CONFIG_SECTION})"
-                       config_set "$CONFIG_SECTION" device "${device:-eth0}"
+                       [ -z "$device" ] && {
+                               device="$(find_ifname ${CONFIG_SECTION})"
+                               config_set "$CONFIG_SECTION" device "${device:-eth0}"
+                       }
                ;;
                classgroup) append CG "$CONFIG_SECTION";;
                classify|default|reclassify)
@@ -231,19 +276,22 @@ start_interface() {
        local iface="$1"
        local num_imq="$2"
        config_get device "$iface" device
-       config_get enabled "$iface" enabled
-       [ -z "$device" -o -z "$enabled" ] && exit
+       config_get_bool enabled "$iface" enabled 1
+       [ -z "$device" -o 1 -ne "$enabled" ] && {
+               return 1 
+       }
        config_get upload "$iface" upload
        config_get halfduplex "$iface" halfduplex
        config_get download "$iface" download
        config_get classgroup "$iface" classgroup
+       config_get_bool overhead "$iface" overhead 0
        
        download="${download:-${halfduplex:+$upload}}"
        enum_classes "$classgroup"
        for dir in up${halfduplex} ${download:+down}; do
                case "$dir" in
                        up)
-                               upload=$(($upload * 98 / 100 - (32 * 128 / $upload)))
+                               [ "$overhead" = 1 ] && upload=$(($upload * 98 / 100 - (15 * 128 / $upload)))
                                dev="$device"
                                rate="$upload"
                                dl_mode=""
@@ -252,7 +300,7 @@ start_interface() {
                        down)
                                add_insmod imq numdevs="$num_imq"
                                config_get imqdev "$iface" imqdev
-                               download=$(($download * 98 / 100 - (100 * 1024 / $download)))
+                               [ "$overhead" = 1 ] && download=$(($download * 98 / 100 - (80 * 1024 / $download)))
                                dev="imq$imqdev"
                                rate="$download"
                                dl_mode=1
@@ -310,6 +358,16 @@ add_rules() {
                config_get target "$rule" target
                config_get target "$target" classnr
                config_get options "$rule" options
+
+               ## If we want to override the TOS field, let's clear the DSCP field first.
+               [ ! -z "$(echo $options | grep 'TOS')" ] && {
+                       s_options=${options%%TOS}
+                       add_insmod ipt_DSCP
+                       parse_matching_rule iptrule "$rule" "$s_options" "$prefix" "-j DSCP --set-dscp 0"
+                       append "$var" "$iptrule" "$N"
+                       unset iptrule
+               }
+
                parse_matching_rule iptrule "$rule" "$options" "$prefix" "-j MARK --set-mark $target"
                append "$var" "$iptrule" "$N"
        done
@@ -343,6 +401,7 @@ start_cg() {
                append up "iptables -t mangle -A OUTPUT -o $device -j ${cg}" "$N"
                append up "iptables -t mangle -A FORWARD -o $device -j ${cg}" "$N"
                [ -z "$dl" ] || {
+                       append down "iptables -t mangle -A POSTROUTING -o $device -j ${cg}" "$N"
                        [ -z "$halfduplex" ] || {
                                append down "iptables -t mangle -A POSTROUTING -o $device -j IMQ --todev $imqdev" "$N"
                        }
This page took 0.026064 seconds and 4 git commands to generate.