###############################################################################
# Setup CBQ Traffic Shaping                                                   #
###############################################################################
setup_cbq()
{
    local baseclsid=
    local interface=
    local weight=
    local rate=
    local if_bandwitch

    fix_bandwidth() {
        local num
	local units

	if [ "$bandwidth" = "${bandwidth%:*}" ]; then
	    rate=$bandwidth
	    num=${bandwidth%[KkMm]bit}
	    units=${bandwidth##*[0-9]}
	    weight=${num%[0-9]}${units}
	else
	    weight=${bandwidth##*:}
	    bandwidth=${bandwidth%:*}
	    rate=${bandwidth#*:}
	    bandwidth=${bandwidth%:*}
	fi
    }

    setup_one_tc() {
        class="`echo $clsid $parent $qdisc $bandwidth $avpkt $marks $options`"
	case "$parent" in
	[0-9]*)
	    fix_bandwidth

	    run_tc class add dev $interface parent $parent classid $clsid \
		cbq bandwidth ${bandwidth%:*} rate $rate allot 1514 \
		weight $weight prio 8 maxburst 20 avpkt $avpkt $options

	    case $qdisc in
	    sfq)
	    	run_tc qdisc add dev $interface parent $clsid sfq \
		    quantum $SFQ_quantum perturb $SFQ_perturb
		;;
	    tbf)
	    	run_tc qdisc add dev $interface parent $clsid tbf \
		    limit $TBF_limit burst $TBF_burst rate $TBF_rate \
		    mtu $TBF_mtu peakrage $TBF_peakrate latency $TBF_latency
		;;
	    red)
		run_tc qdisc add dev $interface parent $clsid red \
		    limit $RED_limit min $RED_min max $RED_max avpkt \
		    $RED_avpkt burst $RED_burst bandwidth $if_bandwidth
		;;
	    *)
	        echo "Unknown discipline in qdisc \"$class\" -- qdisc ignored" >&2
		return
		;;
	    esac

	    for mark in `separate_list $marks` ; do
	 	run_tc filter add dev $interface protocol ip \
	 	    parent $baseclsid:0 prio 1 handle $mark fw classid $clsid
	    done

	    echo "   Class \"$class\" defined"
	    ;;
	*)
	    interface=$parent
	    baseclsid=${clsid%:*}

	    case "$qdisc" in
	    cbq)
	    	fix_bandwidth
	        if_bandwidth=$bandwidth

		run_tc qdisc add dev $interface root handle $baseclsid: cbq \
		    bandwidth $if_bandwidth avpkt $avpkt
		run_tc class add dev $interface parent $baseclsid:0 \
		    classid $clsid cbq bandwidth $if_bandwidth rate $rate \
		    allot 1514 weight $weight prio 5 maxburst 20 \
		    avpkt $avpkt $options
		;;

	    ingress)
	        run_tc qdisc add dev $interface handle ffff: ingress
		;;

	    *)
		echo "Unknown discipline in qdisc \"$class\" -- qdisc ignored" >&2
		;;
	    esac
	    echo "   Class \"$class\" defined"
	esac
    }

    while read clsid parent qdisc bandwidth avpkt marks options; do
	case "$clsid" in
	\#*)
	    ;;
	*)
	    [ -n "$clsid" ] && setup_one_tc
	    ;;
	esac
    done < `find_file cbq`

}

run_user_exit qdisc
setup_cbq
