#server-performance

Linux Traffic Control (tc): en praktisk guide

12 min läsning - 5 juni 2026

hero section cover

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.

FunktionUtgåendeIngående
RiktningUtgåendeInkommande
FormningInbyggdKräver IFB
ÖvervakningStödsStöds
Typisk användningQoS, bandbreddsdelning, pacingHastighetsbegrä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 show

Kontrollera vad som redan finns på gränssnittet, inklusive realtidsräknare:

tc -s qdisc show dev eth0

Rensa 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 || true

Om 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 off

Ställ in fq_codel som systemomfattande standard-qdisc för nya gränssnitt:

sysctl -w net.core.default_qdisc=fq_codel

Fö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=bbr

En 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 30

Begrä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 900mbit

Definiera 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 3

Anslut 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_codel

Klassificera 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:10

Fö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:20

Forma 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 up

Lä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 ifb0

Hä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 1

Prioritering 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:

TrafiktypDSCPTOS hexExempel
InteraktivEF0xb8SSH, DNS, VoIP
FöretagAF410x88HTTP, HTTPS, API:er
BulkCS10x20Säkerhetskopior, FTP, paketuppdateringar
Bästa möjligaCS00x00Allt 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 46

Matcha 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 eth0

Hå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:

SymptomTrolig orsakÅtgärd
RTNETLINK answers: File existsRoot-qdisc är redan konfigureradtc qdisc del dev eth0 root först
Reglerna gäller men trafiken begränsas inteFel gränssnitt, eller så är TSO/GSO fortfarande aktiveratBekräfta med ip link show, inaktivera avlastningar med ethtool -K
Filtret matchar aldrigFelaktig port-/IP-syntax eller maskjusteringLägg till en motåtgärd och kontrollera antalet träffar i tc -s filter show
Regler försvinner efter omstartKonfigurationen finns endast i minnetLägg in i ett skript och anropa från systemd eller en NetworkManager-dispatcher
Hög latens för prioriterad trafikIngen leaf-qdisc, eller burst-värdet är för lågtKoppla 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 root

tc 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.

Blogg

Utvalda denna vecka

Fler artiklar
iperf3-handledning: Testa nätverkshastigheten på Linux och Windows
#bandwidth#server-performance

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

Fler artiklar
background image

Har du frågor eller behöver du en anpassad lösning?

icon

Flexibla alternativ

icon

Global räckvidd

icon

Omedelbar driftsättning

icon

Flexibla alternativ

icon

Global räckvidd

icon

Omedelbar driftsättning