| Title: Fair Internet bandwidth management on a network using Linux | |
| Author: Solène | |
| Date: 05 August 2022 | |
| Tags: linux bandwidth qos | |
| Description: This article introduce you to network quality of service | |
| to make a router fairly assigning bandwidth to network consumers on | |
| your LAN. | |
| # Introduction | |
| A while ago I wrote an OpenBSD guide to fairly share the Internet | |
| bandwidth to the LAN network, it was more or less working. Now I | |
| switched my router to Linux, I wanted to achieve the same. | |
| Unfortunately, it's not really documented as well as on OpenBSD. | |
| The command needed for this job is "tc", acronym for Traffic Control, | |
| the Jack of all trades when it comes to manipulate your network | |
| traffic. It can add delays or packets lost (this is fun when you want | |
| to simulate poor conditions), but also traffic shaping and Quality of | |
| Service (QoS). | |
| Wikipedia page about tc | |
| Fortunately, tc is not that complicated for what we will achieve in | |
| this how-to (fair share) and will give results way better than what I | |
| achieved with OpenBSD! | |
| # How it works | |
| I don't want to explain how the whole stack involved works, but with tc | |
| we will define a queue on the interface we want to apply the QoS, it | |
| will create a number of flows assigned to each active network streams, | |
| each active flow will receive 1/total_active_flows shares of bandwidth. | |
| It mean if you have three connections downloading data (from the same | |
| computer or three different computers), they should in theory receive | |
| 1/3 of bandwidth each. In practice, you don't get exactly that, but | |
| it's quite close. | |
| # Setup | |
| I made a script with variables to make it easy to reuse, it deletes any | |
| traffic control set on the interfaces and then creates the | |
| configuration. You are supposed to run it at boot. | |
| It contains two variables, DOWNLOAD_LIMIT and UPLOAD_LIMIT that should | |
| be approximately 95% of each maximum speed, it can be defined in bits | |
| with kbits/mbits or in bytes with kbps/mbps, the reason to use 95% is | |
| to let the router some room for organizing the packets. It's like a | |
| "15 puzzle", you need one empty square to use it. | |
| ```sh | |
| #!/bin/sh | |
| TC=$(which tc) | |
| # LAN interface on which you have NAT | |
| LAN_IF=br0 | |
| # WAN interface which connects to the Internet | |
| WAN_IF=eth0 | |
| # 95% of maximum download | |
| DOWNLOAD_LIMIT=13110kbit | |
| # 95% of maximum upload | |
| UPLOAD_LIMIT=840kbit | |
| $TC qdisc del dev $LAN_IF root | |
| $TC qdisc del dev $WAN_IF root | |
| $TC qdisc add dev $WAN_IF root handle 1: htb default 1 | |
| $TC class add dev $WAN_IF parent 1: classid 1:1 htb rate $UPLOAD_LIMIT | |
| $TC qdisc add dev $WAN_IF parent 1:1 fq_codel noecn | |
| $TC qdisc add dev $LAN_IF root handle 1: htb default 1 | |
| $TC class add dev $LAN_IF parent 1: classid 1:1 htb rate $DOWNLOAD_LIMIT | |
| $TC qdisc add dev $LAN_IF parent 1:1 fq_codel | |
| ``` | |
| # Conclusion | |
| tc is very effective but not really straightfoward to understand. | |
| What's cool is you can apply it on the fly without incidence. | |
| It has been really effective for me, now if some device is downloading | |
| on the network, it doesn't affect much the other devices when they need | |
| to reach the Internet. | |
| # Credits | |
| After lurking on the Internet looking for documentation about tc, I | |
| finally found someone who made a clear explanation about this tool. tc | |
| is documented, but it's too abstract for me. | |
| linux home router traffic shaping with fq_codel |