tc - simple bandwidth limiting script

  • Thread starter Thread starter dotpointer
  • Start date Start date
D

dotpointer

We have a 42 mbit 4G connection (17 mbit in real), but if we exceed 40 GB per month we are kicked down to 384kbps for the rest of the month. Last month we exceeded the rate after five days.

To work around this I want to put a limit on the bandwidth, limit this huge 17 mbit wire down to something smaller.

I've found various examples, but the closest I've found is wondershaper, which applies many things I'm not interested in. I don't want smart shaping.

I just want to be able to limit download and upload speeds to fixed values, for example 2mbit down and 25kbps up.

Below is what I've come up with so far, based on wondershaper. It seems to work for downlink but not sure about uplink, and it seems it sometimes exceeds the limit - makes spikes.

I have read about tc and qdiscs and filters but I'm quite new to this, never used tc in a project before. System is Slackware 12 if that matters.

Initial questions:

A) As it works I'm looking for suggestions from you out there that master tc (which I don't) - what can be made better here, specifically the upload limiting?

B) At the bottom of the script is the download limiting filter, which drops anything coming in too fast. Will this dropping waste our data amount, like it downloads 17mbit but tc drops until it reaches 2mbit and therefore wasting 15mbit?



(Usage, to limit ppp0 to 125kb/s down and 25kb/s up I run: scriptname start ppp0 125 25)

Code:
#!/bin/bash

# changelog
# 2014-04-22 - initial version
# 2014-05-03 - cleanup

DEV=$2

if [ "$1" = "status" ]
then
# display status then exit
tc -s qdisc ls dev $DEV
tc -s class ls dev $DEV
exit
fi

if [ "$1" = "stop" ]
then
# cleanup
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null
exit
fi

if [ "$1" = "start" ]
then
# convert up- and downlink from kb to kbit
DOWNLINK=$[$3*8]
UPLINK=$[$4*8]

# clean existing down- and uplink qdiscs, hide errors
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null

# uplink

# install root CBQ
tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 10mbit

# main class
tc class add dev $DEV parent 1: classid 1:1 cbq rate ${UPLINK}kbit allot 1500 prio 5 bounded isolated

# filter
tc filter add dev $DEV parent 1: protocol ip prio 18 u32 match ip dst 0.0.0.0/0 flowid 1:1

# downlink

# add downlink qdisc
tc qdisc add dev $DEV handle ffff: ingress

# filter *everything* to it (0.0.0.0/0), drop everything that's coming in too fast
tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate ${DOWNLINK}kbit burst 10k drop flowid :1
fi

Continue reading...
 
Back
Top