OpenWrt Forum Archive

Topic: By using Iptables how to limit bandwidth usage of one MAC address

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

Hello All,

Can anyone put some light on how to limit bandwidth of one specific MAC address by using IP tables. My router is TPLINK 3220 V2 running OpenWRT 15.05

Thanks,

You have to use TC and IPTABLES for that.

serverfault.com/questions/174010/limit-network-bandwith-for-an-ip

In order to limit bandwidth of individual IP addresses, I have been TC with HTB. Here are some useful links:

    Homepage: http://luxik.cdi.cz/~devik/qos/htb/
    User Guide: http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm
    tcng is a relatively easy way to describe traffic control structures: http://www.faqs.org/docs/Linux-HOWTO/Tr … HOWTO.html

As a simple example, in order to limit bandwidth of individual IP addresses stored in CLIENT_IP shell variable, with limitations like the following:

    device name = eth0
    total bandwidth available/allowed for the device = 1000kbps up to 1500kbps
    default bandwidth (for clients that do not fall into our filters) = 1kbps up to 2kbps
    bandwidth of CLIENT_IP = 100kbps
    Maximum bandwidth of CLIENT_IP (if there is more bandwidth available) = 200kbps

Commands below would suffice:

tc qdisc add dev eth0 root handle 1: htb default 10

tc class add dev eth0 parent 1: classid 1:1 htb rate 1000kbps ceil 1500kbps

tc class add dev eth0 parent 1:1 classid 1:10 htb rate 1kbps ceil 2kbps

tc class add dev eth0 parent 1:1 classid 1:11 htb rate 100kbps ceil 200kbps

tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src ${CLIENT_IP} flowid 1:11

You didn't specify if you want to limit ingress or egress bandwidth or both. In Linux, you cannot really shape incoming traffic, only police it - this means dropping packets rather than queuing and prioritizing them.

Conceptually, you can't limit the speed at which a remote host delivers packets to your device, so you can only really drop them. They're still going to get delivered to your WAN interface, so they'll still most likely count against your bandwidth allocation from your ISP.

If you really want to limit incoming bandwidth, it's best to use a IFB device (intermediate functional block). This effectively allows you to turn an ingress device into an egress device and thereby benefit from the full range of the tc commands available in Linux.

A nice elegant example of bandwidth limiting outgoing connections with Openwrt and SQM scripts can be found here. You could extend this to incoming bandwidth as SQM scripts defines and uses an IFB device. However, be aware that IFB has a limitation in the sense that you cannot use fwmark targets since the packets get passed to the IFB device without going through the requisite netfilter chain. You'd have to use explicit TC filters and IP addresses.

Another difficulty would be if you're in an IPv4 NAT environment - incoming packets would be directed to the firewall IP, so matching on your internal IP would be impossible. A way around this would be to put an IFB, tc qdsics and filters onto your br-lan interface, but by this point the packets have come in your WAN interface already and so there's very little point in doing any bandwidth limiting.

Oh, and as a final word: limiting incoming bandwidth based on MAC address would be pretty tricky since MAC addresses are link layer 2 - they won't be included in the incoming packet. You'd have to do an arp lookup for each incoming packet (and that wouldn't work for ipv6 since ipv6 doesn't use arp)...

(Last edited by dl12345 on 20 Oct 2016, 18:59)

The discussion might have continued from here.