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 |