Verwenden von tc zum Verzögern von Paketen auf nur eine einzelne IP-Adresse

20

Ich bin neu zur Verwendung von tc und netem . Ich möchte Pakete verzögern, die an eine bestimmte IP-Adresse gesendet werden. Die folgenden Befehle bewirken jedoch, dass alle Pakete auf dem System verzögert werden und nicht nur an die IP-Adresse 1.2.3.4 gesendet werden:

tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: prio
tc qdisc add dev eth0 parent 1:1 handle 2: netem delay 500ms
tc filter add dev eth0 parent 1:0 protocol ip pref 55 handle ::55 u32 match ip dst 1.2.3.4 flowid 2:1

Ich vermute, dass ich am Ende eine Art Catch-All-Filter benötige, um anzugeben, dass der gesamte verbleibende Datenverkehr nicht über netem geleitet werden soll. Aber ich kann nichts zum Arbeiten bringen. Wie würde ich das zum Laufen bringen?

Matt White
quelle

Antworten:

14

Ok, ich habe mein eigenes Problem gelöst. Es stellt sich heraus, dass, wenn Sie die ersten 3 Zeilen oben ausführen (die "tc qdisc"), alle Pakete verzögert werden, da es noch keine Filter gibt. In der vierten Zeile wird geändert, dass nur Pakete von dieser einzelnen IP-Adresse verzögert werden. Zusätzliche Filterzeilen können hinzugefügt werden, um der Liste "verzögert" zusätzliche IP-Adressen hinzuzufügen. Also: erstelle keine "netem delay" -Linie, ohne dass ein Filter darauf zeigt.

Matt White
quelle
Vielen Dank, dass Sie zurückgekommen sind und die Antwort gepostet haben. Seltsamerweise fand ich, dass es in beide Richtungen gut funktionierte, aber trotzdem. Ich schrieb ein Wrapper-Skript um diese drei Befehle, um beim Testen zu helfen, dachte nur, ich würde ein wenig zurückgeben :)
Arran Cudbard-Bell
13

Die gewählte Antwort ist falsch / unvollständig. Ich hatte ein ähnliches Problem, die gewählte Antwort hat mir geholfen, aber nicht genug.

Erstens wird der folgende Befehl nicht wirklich benötigt.

tc qdisc del dev eth0 root

Die Root-Qdisc wird "gelöscht", aber sofort durch eine pfifo_fast ersetzt (damit die Konnektivität nicht verloren geht).

Der zweite Befehl:

tc qdisc add dev eth0 root handle 1: prio

Ersetzt die pfifo_fast qdisc durch die prio one. Standardmäßig verfügt die Prio-Warteschlange über 3 Bänder (0, 1, 2), die jeweils von einer Klasse verwaltet werden (1: 1, 1: 2 und 1: 3).

Die Pakete werden über das TOS-Feld des IP-Pakets an eines dieser Bänder gesendet. Diese Konfiguration wird angezeigt, wenn Sie Folgendes ausführen:

tc qdisc ls

Blick auf die "priomap" -Werte.

Dann fügen Sie eine netem qdisc hinzu:

tc qdisc add dev eth0 parent 1: 1 handle 2: netem delay 500ms

Mit diesem Befehl verschieben Sie den gesamten Datenverkehr in das 1: 1-Band (bis der Filter aktiviert ist).

Es gibt jedoch zwei Einschränkungen:

  • Ihr Datenverkehr kann einen anderen TOS-Wert haben und dann an ein anderes Band gesendet werden.
  • Die prio qdisc kann so konfiguriert werden, dass der Datenverkehr zu einem anderen Band geleitet wird.

Das Folgende löste mein Problem, um nicht von dem netem betroffen zu sein, während der Filter nicht angewendet wird. Anstelle der oben genannten Schritte habe ich Folgendes getan:

tc qdisc add dev eth0 root handle 1: prio priomap 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

Dadurch wird der gesamte Datenverkehr standardmäßig 1: 3 an das Band gesendet.

Dann habe ich die Regel hinzugefügt, um den Datenverkehr zu verzögern:

tc qdisc add dev eth0 parent 1: 1 handle 10: netem delay 100ms 10ms

Dadurch wird die qdisc in Band 0 erstellt, aber da der gesamte Datenverkehr in Band 3 übertragen wird, hat mich dies nicht betroffen.

Danach habe ich den Filter hinzugefügt:

tc filter add dev eth0 Protokoll ip parent 1: 0 prio 1 u32 match ip dst 10.0.0.1/32 match ip dport 80 0xffff flowid 1: 1

Jetzt wird mit dem Filter nur die ausgewählte IP / der ausgewählte Port beeinflusst, da wir den ausgewählten Datenverkehr auf das Band 0 umleiten.

Der gesamte andere Datenverkehr bleibt unberührt, da er weiterhin zu Band 3 fließt.

Telegrafist
quelle
was ist die "ip dst 10.0.0.1/32"? Ist das die Ziel-IP? Bedeutet das, dass es eine "ip src xxx.yyy.zz.www / aa" gibt?
Zach Folwick
Ja, es ist die Ziel-IP in meinem Beispiel. Und ja, es gibt eine 'ip src'-Option.
Telegrapher
Der Grund für den ersten Befehl (tc qdisc del) besteht darin, alle vorherigen Zustände zu löschen - wie Sie es möglicherweise haben, wenn Sie experimentieren, um diese Arbeit zu machen. FWIW die akzeptierte Antwort für mich gearbeitet.
Dan Pritts
Danke, diese Antwort war WIRKLICH hilfreich.
PepeHands
1

Einfaches Beispiel von https://wiki.linuxfoundation.org/networking/netem , mit dem Sie Pakete auf eine bestimmte IP-Adresse verschieben können, ohne anderen Datenverkehr zu beeinträchtigen, auch während der Konfiguration:

tc qdisc del dev eth0 root # Ensure you start from a clean slate
tc qdisc add dev eth0 root handle 1: prio
tc qdisc add dev eth0 parent 1:3 handle 30: netem delay 500ms
tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 \
   match ip dst 192.168.1.2 flowid 1:3
NeilenMarais
quelle
Ich muss eine Einschränkung hinzufügen, später schien es, als würde die Verzögerung breiter angelegt, als ich erwartet hatte, und ich konnte ihr nicht auf den Grund gehen. Allerdings schien nicht der gesamte Verkehr verspätet zu sein.
NeilenMarais
0

Ich habe es nicht geschafft, den Datenverkehr auf eine IP zu verschieben, während der Datenverkehr auf einer anderen IP normal bleibt. Dies ist die in diesem Thread beschriebene Methode.

Ich schaffe es jedoch mit den folgenden Befehlen.

tc qdisc add dev eth0 root handle 1: prio priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
tc qdisc add dev eth0 parent 1:2 handle 20: netem delay 0ms
tc filter add dev eth0 parent 1:0 protocol ip u32 match ip src `hostname -I` flowid 1:2
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 15001ms
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip dst 1.2.3.4 flowid 1:1

So verzögern Sie den 15001msDatenverkehr an IP 1.2.3.4vom Host, auf dem der Befehl ausgeführt wird. Der Befehl hostname -Iwird verwendet, um die Haupt-IP des Hosts abzurufen. Der Wert kann jedoch direkt im Befehl ersetzt werden.

Ich musste einen weiteren Filter mit 0msVerzögerung hinzufügen , um dem vom Host kommenden Datenverkehr zu entsprechen. Sicher ist es nicht elegant, aber ich habe es nicht geschafft, dass etwas Schöneres funktioniert.

Der letzte Befehl kann ersetzt werden, um mit einem einzelnen Port übereinzustimmen.

tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip dport 18583 0xffff flowid 1:1

So verzögern Sie den Datenverkehr zum Port 18583anstelle von IP 1.2.3.4.


Ich habe auch eine zweite Methode für diese Antwort gefunden , um den Datenverkehr zu verzögern, 1.2.3.4:18583ohne den anderen Datenverkehr zu beeinträchtigen.

tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol ip  parent 1: prio 1 u32 match ip dst 1.2.3.4 match ip dport 18583 0xffff flowid 1:1
tc filter add dev eth0 protocol all parent 1: prio 2 u32 match ip dst 0.0.0.0/0 flowid 1:2
tc filter add dev eth0 protocol all parent 1: prio 2 u32 match ip protocol 1 0xff flowid 1:2
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 10ms
tc qdisc add dev eth0 parent 1:2 handle 20: sfq
Nicolas Henneaux
quelle