Linux Traffic Control (tc): en praktisk guide
12 min läsning - 5 juni 2026

Styr bandbredd, prioritera trafik och forma inkommande och utgående trafik på Linux med tc. Fungerande konfigurationer för HTB, IFB, DSCP och fq_codel för riktiga servrar.
Linux Traffic Control (tc): en praktisk guide
Linux-kommandot tc ger dig direkt kontroll över hur din server hanterar nätverkstrafiken. Du kan begränsa bandbredden per tjänst, se till att interaktiva sessioner som SSH förblir responsiva när stora dataöverföringar ökar kraftigt, samt styra både utgående och inkommande trafikflöden från ett enda verktyg. Denna guide täcker de grundläggande begreppen, en fungerande HTB-konfiguration, ingående trafikstyrning med IFB, DSCP-baserad prioritering samt hur man felsöker när något går fel.
Så här fungerar tc
Varje tc konfiguration består av fyra rörliga delar:
- qdisc (köhantering). Schemaläggaren som är kopplad till ett nätverksgränssnitt. Den avgör hur paket ska läggas i kö och tas ur kö.
- Klass. En underindelning inom en klassbaserad qdisc. Tänk på den som ett körfält med sin egen hastighetsbegränsning.
- Filter. Granskar paketrubriker (IP-adresser, portar, markeringar) och tilldelar varje paket till en klass.
- Åtgärd. Vad som händer med ett paket när det matchar: vidarebefordra, släppa bort, omdirigera.
Dessa bildar ett träd. Paket kommer in vid rot-qdisc, passerar filter, sorteras in i klasser av en major:minor hanterare och hamnar slutligen i kö vid en blad-qdisc för överföring.
För allt som är mer komplext än portbaserad matchning, markera paket med iptables eller nftables i mangle-tabellen och använd sedan fw filtret i tc för att klassificera efter markering. Det skalar betydligt bättre än att kedja ihop råa u32 regler för varje trafiktyp.
Utgående kontra inkommande
Riktningen spelar roll. Kärnan kan buffra och fördröja utgående paket, vilket är det som möjliggör verklig trafikformning. Inkommande paket har redan passerat nätverket när du ser dem, så du kan bara kontrollera dem (avvisa om de överskrider ett tröskelvärde) om du inte först omdirigerar dem till en IFB-enhet.
| Funktion | Utgående | Ingående |
|---|---|---|
| Riktning | Utgående | Inkommande |
| Formning | Inbyggd | Kräver IFB |
| Övervakning | Stöds | Stöds |
| Typisk användning | QoS, bandbreddsdelning, pacing | Hastighetsbegränsning, grundläggande DDoS-skydd |
De qdiscs du faktiskt kommer att använda
- HTB (Hierarchical Token Bucket). Klassbaserad. Använd den när du vill ha garanterad minimibandbredd per tjänst med möjlighet att låna outnyttjad kapacitet från andra klasser.
- TBF (Token Bucket Filter). Klasslös. Använd den när du bara behöver begränsa ett helt gränssnitt till en enda hastighet.
- fq_codel (Fair Queuing Controlled Delay). Kombinerar rättvisa per flöde med aktiv köhantering för att eliminera bufferbloat. Det har varit standard-qdisc i de flesta Linux-distributioner sedan systemd 217 och levereras som standard i RHEL 9. Anslut den alltid som en leaf-qdisc under HTB-klasser, annars kan ett enda girigt flöde ta upp hela klassen.
Konfigurera tc på en Linux-server
tc levereras med paketet iproute2. På Debian och Ubuntu installerar du det med apt-get install iproute2. På RHEL och derivat yum install iproute. Du behöver root-behörighet eller sudo.
Ta reda på rätt gränssnittsnamn först. Att ange fel gränssnittsnamn är den vanligaste orsaken till att en konfiguration inte ger något resultat:
ip link showKontrollera vad som redan finns på gränssnittet, inklusive realtidsräknare:
tc -s qdisc show dev eth0Rensa bort eventuella befintliga root-qdisc innan du tillämpar en ny konfiguration, för att undvika RTNETLINK answers: File exists fel:
tc qdisc del dev eth0 root 2>/dev/null || trueOm du uppdaterar en befintlig regel istället för att börja från grunden, använd replace istället för add för en atomär byte.
Hårdvaruavlastning som TSO och GSO buntar ihop paket på ett sätt som stör trafikformningen. Stäng av dem på det formade gränssnittet:
sudo ethtool -K eth0 tso off gso offStäll in fq_codel som systemomfattande standard-qdisc för nya gränssnitt:
sysctl -w net.core.default_qdisc=fq_codelFör belastade servrar, kombinera det med BBR-algoritmen för överbelastningskontroll (kärna 4.9+). BBR håller genomströmningen hög utan att köerna växer:
sysctl -w net.ipv4.tcp_congestion_control=bbrEn säkerhetsrutin om du konfigurerar en fjärrmaskin via SSH: öppna en andra session och ha tc qdisc del dev eth0 root klistra in. En felaktig filterregel kan omedelbart låsa ute dig.
Forma utgående trafik med HTB
Med HTB kan du ge varje tjänst ett garanterat minimum (rate) och ett tak (ceil). Oanvänd bandbredd tilldelas den som behöver den, i prioritetsordning. Här är en fungerande konfiguration i tre nivåer för en 1 Gbps-upplänk.
Skapa den överordnade HTB-qdiscen. Den default 30 skickar alla oklassificerade paket till klass 1:30 istället för att låta det kringgå dina regler:
tc qdisc add dev eth0 root handle 1: htb default 30Begränsa den totala genomströmningen till 900 Mbps. Forma alltid något under den faktiska länkkapaciteten, annars bildas en kö på en uppströmsrouter eller ett modem som du inte kontrollerar:
tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbitDefiniera tjänstenivåerna. Lägre prio värden får tillgång till outnyttjad bandbredd först:
# High priority: web and API traffic
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1
# Medium priority: database replication
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 300mbit ceil 900mbit prio 2
# Low priority: bulk and backup traffic
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 100mbit ceil 900mbit prio 3Anslut fq_codel som leaf-qdisc på varje klass så att ett enskilt flöde inte kan dominera sin nivå:
tc qdisc add dev eth0 parent 1:10 handle 10: fq_codel
tc qdisc add dev eth0 parent 1:20 handle 20: fq_codel
tc qdisc add dev eth0 parent 1:30 handle 30: fq_codelKlassificera nu trafiken. För enkel portmatchning u32 är det snabbast:
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 443 0xffff flowid 1:10För allt som är tillståndsberoende, markera i iptables och matcha markeringen med fw:
iptables -t mangle -A OUTPUT -p tcp --dport 5432 -j MARK --set-mark 2
tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 2 fw flowid 1:20Forma inkommande trafik med IFB
Det går inte att styra inkommande trafik på ett inbyggt sätt eftersom paketet redan har använt din bandbredd när det anländer. Lösningen är att omdirigera den inkommande trafiken till ett virtuellt gränssnitt i ett Intermediate Functional Block (IFB), där kärnan behandlar den som utgående trafik och låter dig använda klassbaserade qdiscs.
Ladda modulen och starta gränssnittet:
modprobe ifb numifbs=1
ip link set dev ifb0 upLägg till en ingående qdisc till det fysiska gränssnittet och omdirigera allt till ifb0:
tc qdisc add dev eth0 ingress handle ffff:
tc filter add dev eth0 parent ffff: protocol all u32 \
match u32 0 0 action mirred egress redirect dev ifb0Härifrån ifb0 fungerar det precis som vilket annat gränssnitt som helst. Tillämpa ditt HTB-träd på det på exakt samma sätt som du skulle göra för utgående trafik:
tc qdisc add dev ifb0 root handle 1: htb default 30
tc class add dev ifb0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1Prioritering av trafik med DSCP
DSCP (Differentiated Services Code Point) märker paket med ett 6-bitarsvärde i TOS-byten, så att dina tc filtren kan klassificera efter tagg istället för att söka igenom portar i regeluppsättningen. När du matchar DSCP i tcska du förskjuta värdet 2 bitar åt vänster. DSCP EF (46) blir 0xb8. Masken 0xfc isolerar de 6 DSCP-bitarna från de 2 ECN-bitarna.
En lämplig standardmappning för serverarbetsbelastningar:
| Trafiktyp | DSCP | TOS hex | Exempel |
|---|---|---|---|
| Interaktiv | EF | 0xb8 | SSH, DNS, VoIP |
| Företag | AF41 | 0x88 | HTTP, HTTPS, API:er |
| Bulk | CS1 | 0x20 | Säkerhetskopior, FTP, paketuppdateringar |
| Bästa möjliga | CS0 | 0x00 | Allt annat |
Märk utgående paket i iptables innan de når dina tc filter:
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46Matcha sedan taggen i tc och dirigera det till rätt HTB-klass:
# EF (SSH, VoIP) goes to the high-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip tos 0xb8 0xfc flowid 1:10
# AF41 (web traffic) goes to the medium class
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 \
match ip tos 0x88 0xfc flowid 1:20
# CS1 (bulk) goes to the low-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 \
match ip tos 0x20 0xfc flowid 1:30Övervakning och felsökning
De tre kommandon du kommer att använda hela tiden:
tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0Håll koll på dropped och overlimits räknarna. Förlorade paket innebär att kön är mättad; överskridna gränser innebär att du har nått ett klassgränsvärde och att kärnan har tvingats fördröja eller avvisa trafik. För en realtidsvy:
watch -n 1 'tc -s class show dev eth0'Lägg till -d för interna parametrar (target, interval, quantum) och -j för JSON-utdata om du skickar data via en pipelin till en mätvärdesstack. Kombinera det med ss -tin för att se RTT-uppskattningar och återöverföringar på TCP-lagret.
De flesta fel kan sammanfattas i en kort lista:
| Symptom | Trolig orsak | Åtgärd |
|---|---|---|
RTNETLINK answers: File exists | Root-qdisc är redan konfigurerad | tc qdisc del dev eth0 root först |
| Reglerna gäller men trafiken begränsas inte | Fel gränssnitt, eller så är TSO/GSO fortfarande aktiverat | Bekräfta med ip link show, inaktivera avlastningar med ethtool -K |
| Filtret matchar aldrig | Felaktig port-/IP-syntax eller maskjustering | Lägg till en motåtgärd och kontrollera antalet träffar i tc -s filter show |
| Regler försvinner efter omstart | Konfigurationen finns endast i minnet | Lägg in i ett skript och anropa från systemd eller en NetworkManager-dispatcher |
| Hög latens för prioriterad trafik | Ingen leaf-qdisc, eller burst-värdet är för lågt | Koppla fq_codel till leaf-klasser, höj burst |
Om du någonsin låser dig ute på grund av en felkonfiguration är återställningen enkel:
tc qdisc del dev eth0 roottc Du kan inte skapa bandbredd som du inte har, men på en välutrustad upplänk är det skillnaden mellan förutsägbar prestanda och en server som kollapsar så fort en kund påbörjar en stor överföring. Om du behöver den råa bandbredden och friheten att forma den precis som du vill, ta en titt på FDC:s dedikerade servrar.

iperf3-handledning: Testa nätverkshastigheten på Linux och Windows
Installera iperf3, kör bandbreddstester och justera TCP-buffertarna för exakta resultat på Linux och Windows. Omfattar UDP-, dubbelriktade och 10GbE+-tester
10 min läsning - 7 maj 2026
Anpassade profiler för optimering av arbetsbelastningen på Linux-servrar
16 min läsning - 9 juni 2026

Har du frågor eller behöver du en anpassad lösning?
Flexibla alternativ
Global räckvidd
Omedelbar driftsättning
Flexibla alternativ
Global räckvidd
Omedelbar driftsättning