OpenWrt Forum Archive

Topic: Limiting single IP on the LAN. A simple and working script.

The content of this topic has been archived on 24 Mar 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I wanted to limit 1 IP on the LAN. I've read and searched for quite some time and the question seemed to asked quite a lot, but the answers are usually quite complex. Complex scripts and the likes. I needed a very simple script for a seemingly simple thing. With big help of xMff on IRC I made the following script, all credit goes to xMff though, he supplied the code, I just made the script around it. This post is just for the archives as the wiki doesn't let me edit/add anything and I'm not a wiki guru.

It should be easy for anyone with some shell scripting experience to make this work and add/remove things as you like. There just one caveat here, I used a fairly non-elegant way to flush the mangle tables from iptables, if you use mangle for anything else please make sure you remove/edit the "iptables- F -t mangle line" from the script. Rates are in kbit.

#!/bin/sh
#

insmod cls_fw >/dev/null 2>&1
insmod cls_u32 >/dev/null 2>&1
insmod sch_htb >/dev/null 2>&1
insmod sch_sfq >/dev/null 2>&1
insmod sch_ingress >/dev/null 2>&1

DEV="br-lan"
CLIENT_MAC=00:11:22:33:44:55
CLIENT_IP=172.16.0.128
LIMIT_DOWN=200
LIMIT_DOWN_BURST=400
LIMIT_UP=400

start() {

tc qdisc del dev "$DEV" root handle 77:
tc qdisc add dev "$DEV" root handle 77: htb
tc class add dev "$DEV" parent 77: classid 77:1 htb rate 20000kbit
tc class add dev "$DEV" parent 77:1 classid 77:10 htb rate ${LIMIT_DOWN}kbit ceil ${LIMIT_DOWN_BURST}kbit prio 2
tc qdisc add dev "$DEV" parent 77:10 handle 78: sfq perturb 10
tc qdisc add dev "$DEV" ingress
tc filter add dev "$DEV" parent 77: protocol ip prio 2 handle 80 fw flowid 77:10
tc filter add dev "$DEV" parent ffff: protocol ip prio 1 handle 79 fw police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop
iptables -t mangle -I PREROUTING -m mac --mac-source $CLIENT_MAC -j MARK --set-mark 79
iptables -t mangle -I POSTROUTING -d $CLIENT_IP -j MARK --set-mark 80

}

stop() {

tc qdisc del dev $DEV root
iptables -F -t mangle

}

restart() {

    stop
    sleep 1
    start

}

show() {

    tc -s qdisc ls dev $DEV

}

case "$1" in

  start)

    echo -n "Starting bandwidth shaping: "
    start
    echo "done"
    ;;

  stop)

    echo -n "Stopping bandwidth shaping: "
    stop
    echo "done"
    ;;

  restart)

    echo -n "Restarting bandwidth shaping: "
    restart
    echo "done"
    ;;

  show)

    echo "Bandwidth shaping status for $IF:"
    show
    echo ""
    ;;

  *)

    pwd=$(pwd)
    echo "Usage: tc.bash {start|stop|restart|show}"
    ;;

esac

exit 0

I hope this helps those looking to do the same thing as me; limit a single IP on the LAN when QoS or other measures don't seem to work this may do the job.

Feel free to post your own scripts in this thread, or make the above one even better.

I've tested this script on my Asus WL-500g v2, running Kamikaze v8.09.1. Forum mods, if I posted this in the wrong section please move it to the right place, cheers.

(Last edited by blerk on 22 Jan 2010, 00:04)

The version below is adapted for multiple clients and works with IPs alone, no mac required. I have not tested it but it should work.

#!/bin/sh

insmod cls_fw >/dev/null 2>&1
insmod cls_u32 >/dev/null 2>&1
insmod sch_htb >/dev/null 2>&1
insmod sch_sfq >/dev/null 2>&1
insmod sch_ingress >/dev/null 2>&1

DEV="br-lan"
LIMIT_IPS="192.168.1.10 192.168.1.11 192.168.1.12"
LIMIT_DOWN=200
LIMIT_DOWN_BURST=400
LIMIT_UP=400

start() {
    tc qdisc del dev "$DEV" root handle 77:
    tc qdisc add dev "$DEV" root handle 77: htb
    tc class add dev "$DEV" parent 77: classid 77:1 htb rate 20000kbit
    tc class add dev "$DEV" parent 77:1 classid 77:10 htb rate ${LIMIT_DOWN}kbit ceil ${LIMIT_DOWN_BURST}kbit prio 2
    tc qdisc add dev "$DEV" parent 77:10 handle 78: sfq perturb 10
    tc qdisc add dev "$DEV" ingress
    tc filter add dev "$DEV" parent 77: protocol ip prio 2 handle 80 fw flowid 77:10
    tc filter add dev "$DEV" parent ffff: protocol ip prio 1 handle 79 fw police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop

    for ip in $LIMIT_IPS; do
        iptables -t mangle -I PREROUTING -s $ip -j MARK --set-mark 79
        iptables -t mangle -I POSTROUTING -d $ip -j MARK --set-mark 80
    done
}

stop() {
    tc qdisc del dev $DEV root
    iptables -F -t mangle
}

restart() {
    stop
    sleep 1
    start
}

show() {
    tc -s qdisc ls dev $DEV
}

case "$1" in
    start)
        echo -n "Starting bandwidth shaping: "
        start
        echo "done"
    ;;

    stop)
        echo -n "Stopping bandwidth shaping: "
        stop
        echo "done"
    ;;

    restart)
        echo -n "Restarting bandwidth shaping: "
        restart
        echo "done"
    ;;

    show)
        echo "Bandwidth shaping status for $DEV:"
        show
        echo ""
    ;;

    *)
        echo "Usage: $0 {start|stop|restart|show}"
    ;;
esac

exit 0

this works very fine for me

except for this line:

tc filter add dev "$DEV" parent ffff: protocol ip prio 1 handle 79 fw police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop

errors out:

RTNETLINK answers: No such file or directory
We have an error talking to the kernel

as a result only the download limitation works.

any ideas?

update:

got it fixed by installing the act_police module

but the police does not seem to work for me.. so still no limiting on upload speeds

any ideas?
im am using 10.3.1-rc3

(Last edited by tsod on 14 Dec 2010, 23:04)

subscribing

Appears to be very useful bandwidth limiting scripts. Where would I put either one of the above posted scripts? How are they suppose to be used?

tsod wrote:

this works very fine for me

except for this line:

tc filter add dev "$DEV" parent ffff: protocol ip prio 1 handle 79 fw police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop

errors out:

RTNETLINK answers: No such file or directory
We have an error talking to the kernel

here's my error
/etc/init.d/shaper restart
Restarting bandwidth shaping: RTNETLINK answers: Invalid argument
RTNETLINK answers: File exists
RTNETLINK answers: No such file or directory
We have an error talking to the kernel
done

we have the same error but how  can i load act_police module??thanks

(Last edited by jefbuan on 1 Nov 2011, 14:24)

Simply add "insmod act_police" below the other insmod lines.

jow wrote:

Simply add "insmod act_police" below the other insmod lines.

thanks but still have errors,i have multiwan,qos running..

Oct 13 08:55:48 Arkin user.warn kernel: HTB: quantum of class 770001 is big. Consider r2q change.

Had that too, worked nonetheless.

Oct 13 08:55:48 Arkin user.warn kernel: HTB: quantum of class 770001 is big. Consider r2q change.

It appears Tomato firmware had the same issue back in 2008 that was solved. The below link to linksysinfo.org describes the issue and shows how it was solved:

http://www.linksysinfo.org/index.php?th … 21/page-11

Also can someone let me know how to use this script? Is this a startup script?

When I start the script (the second version for multiple IPs) I get the message "Starting bandwidth shaping: RTNETLINK answers: Invalid argument done", but it works (for download only). After stopping the script I can' t open any site.  Torrents are working, but for serfing I have to reboot the router.

(Last edited by mertsalov on 28 Mar 2015, 17:38)

The discussion might have continued from here.