Tc qdisc-Verzögerung bei TCPdump-Aufzeichnung nicht sichtbar

Tc qdisc-Verzögerung bei TCPdump-Aufzeichnung nicht sichtbar

Ich habe zwei Linux-Container, die mit einem Veth-Paar verbunden sind. An der Veth-Schnittstelle eines Containers richte ich eine TC Qdisc Netem-Verzögerung ein und sende den Datenverkehr von dort an den anderen Container. Wenn ich den Datenverkehr auf beiden Seiten mit tcpdump/Wireshark beobachte, kann ich sehen, dass sich die Zeitstempel desselben Pakets beim Absender und beim Empfänger nicht durch die ausgewählte Verzögerung unterscheiden.

Ich wollte genauer verstehen, an welchem ​​Punkt libpcap Zeitstempel für ausgehenden Datenverkehr entsprechend tc qdisc setzt. Ich habe im Internet nach einem Schema/Bild gesucht, aber nichts gefunden. Ich habe dieses Thema gefunden (Wireshark-Paketerfassungspunkt), aber es wird empfohlen, eine Indirektion einzuführen, indem man einen weiteren Container/eine weitere Schnittstelle einführt. Dies ist in meiner Situation keine mögliche Lösung. Gibt es eine Möglichkeit, das Problem zu lösen, indem keine zusätzlichen Zwischenschnittstellen eingeführt werden (d. h. die Topologie nicht geändert wird) und nur durch Aufzeichnen an der bereits vorhandenen veth-Schnittstelle, aber auf eine Weise, bei der die Verzögerung sichtbar ist?

AKTUALISIEREN:

Ich war zu schnell und habe mich deshalb geirrt. Weder meine unten aufgeführte Lösung (dieselbe wie die erste Lösungsvariante der Antwort von @AB) noch die Lösung mit IFB von @AB (die ich bereits überprüft habe) lösen mein Problem. Das Problem liegt im Überlauf der Sendewarteschlange der Schnittstelle a1-eth0des Senders in der Topologie:

[a1-br0 ---3Gbps---a1-eth0]---100Mbps---r1---100Mbps---r2

Ich war zu schnell und habe nur auf eine Verzögerung von 10 ms bei der Verbindung zwischen a1-eth0Router und Netzwerk geprüft r1. Heute habe ich versucht, die Verzögerung zu erhöhen: 100 ms, 200 ms und die Ergebnisse (Verzögerungs- und Ratendiagramme pro Paket, die ich erhalte) beginnen sich für die obige Topologie und für die normale Topologie zu unterscheiden:

[a1-eth0]---100Mbps---r1---100Mbps---r2

Also nein, für genaue Tests kann ich natürlich keine zusätzlichen Links haben: weder von Linux Bridge, noch von diesem IFB, noch von irgendeinem anderen Drittsystem. Ich teste Überlastungskontrollschemata. Und ich möchte das in einer bestimmten Topologie tun. Und ich kann die Topologie nicht nur zum Plotten ändern – ich meine, wenn sich gleichzeitig meine Raten- und Verzögerungsergebnisse/-plots ändern.

UPDATE 2:

Es sieht also so aus, als wäre die Lösung gefunden worden, wie unten zu sehen ist (NFLOG-Lösung).

UPDATE 3:

Hier werden einige Nachteile der NFLOG-Lösung (große Link-Layer-Header und falsche TCP-Prüfsummen für ausgehende TCP-Pakete mit Null-Nutzlast) beschrieben und eine bessere Lösung mit NFQUEUE vorgeschlagen, die keines dieser Probleme aufweist:Falsche TCP-Prüfsumme für ausgehende Pakete mit Nulllänge (erfasst mit iptables). Für meine Aufgaben (Testen von Überlastungskontrollschemata) sind jedoch weder NFLOG noch NFQUEUE geeignet. Wie im selben Link erklärt wird, wird die Sendegeschwindigkeit gedrosselt, wenn Pakete von den iptables des Kernels erfasst werden (so verstehe ich das). Wenn Sie also beim Absender aufzeichnen, indem Sie von der Schnittstelle erfassen (d. h. regelmäßig), erhalten Sie einen Dump von 2 Gigabyte, während Sie beim Absender aufzeichnen, indem Sie von iptables erfassen, einen Dump von 1 Gigabyte erhalten. Grob gesagt.

UPDATE 4:

Schließlich verwende ich in meinem Projekt die Linux-Bridge-Lösung, die in meiner eigenen Antwort unten beschrieben wird.

Antwort1

Entsprechend derPaketfluss in Netfilter und allgemeinem Networkingschematische, tcpdump erfasst (AF_PACKET) nachAusgang (qdisc). Daher ist es normal, dass Sie die Verzögerung im TCPdump nicht sehen: Die Verzögerung war bereits bei der ersten Erfassung vorhanden.

Sie müssten es einen Schritt früher erfassen, also ein drittes System einbeziehen:

S1: system1, führt tcpdump auf der ausgehenden Schnittstelle aus
. R: Router (oder Bridge, je nach Belieben, dies ändert nichts), führt das qdisc-Netem aus.
S2: system2, führt tcpdump auf der eingehenden Schnittstelle aus.

 __________________     ________________     __________________
|                  |   |                |   |                  |
| (S1) -- tcpdump -+---+- (R) -- netem -+---+- tcpdump -- (S2) |
|__________________|   |________________|   |__________________|

Das bedeutet 3 NetzwerkStapelbeteiligt, seien sie real, VM, Netzwerk-Namespace (einschließlichIP-Netze, LXC, ...)


Optional ist es auch möglich, alle speziellen Einstellungen am Router (oder an der Bridge) zu ändern, indem manIFBSchnittstelle mitgespiegeltVerkehr: ermöglicht durch einen Trick (für diesen Fall vorgesehen), Netem quasi nach dem Eingang und nicht beim Ausgang einzufügen:

 _______     ______________________________________________     _______
|       |   |                                              |   |       |         
| (S1) -+---+- tcpdump -- ifb0 -- netem -- (R) -- tcpdump -+---+- (S2) |
|_______|   |______________________________________________|   |_______|

Ein grundlegendes Anwendungsbeispiel für IFB finden Sie intc gespiegeltManpage:

Mithilfe einer ifb-Schnittstelle ist es möglich, eingehenden Datenverkehr durch eine Instanz von sfq zu senden:

# modprobe ifb
# ip link set ifb0 up
# tc qdisc add dev ifb0 root sfq
# tc qdisc add dev eth0 handle ffff: ingress
# tc filter add dev eth0 parent ffff: u32 \
  match u32 0 0 \
  action mirred egress redirect dev ifb0

Benutz einfachnetemauf ifb0 statt sfq (und im nicht-initialen Netzwerk-Namespace, ip link add name ifbX type ifbfunktioniert einwandfrei, ohne Modprobe).

Damit es ordnungsgemäß funktioniert, sind immer noch drei Netzwerkstapel erforderlich.


mitNFLOG

Nach einem Vorschlag von JenyaKh ist es möglich, ein Paket abzufangen mittcpdump,Voregress (also vor qdisc) und dann bei egress (nach qdisc): durch Verwendungiptables(oderNftables), um vollständige Pakete in die Netlink-Log-Infrastruktur zu protokollieren und diese weiterhin mittcpdump, dann wieder mittcpdumpauf der Ausgangsschnittstelle. Dies erfordert nur Einstellungen auf S1 (und benötigt keinen Router/keine Bridge mehr).

Also mitiptablesauf S1 etwa:

iptables -A OUTPUT -o eth0 -j NFLOG --nflog-group 1

Es sollten wahrscheinlich spezifische Filter hinzugefügt werden, um den durchgeführten Test abzugleichen, denntcpdumpFilter ist auf die NFlog-Schnittstelle beschränkt (Wireshark sollte damit besser umgehen können).

Wenn die Antworterfassung erforderlich ist (hier in einer anderen Gruppe, daher ist ein zusätzlichertcpdump):

iptables -A INPUT -i eth0 -j NFLOG --nflog-group 2

Je nach Bedarf ist es auch möglich, sie zu verschieben nachraw/AUSGABEUndRohmaterial/PREROUTINGstattdessen.

Mittcpdump:

# tcpdump -i nflog:1 -n -tt ...

Wenn für die Eingabe eine andere Gruppe (= 2) verwendet wurde:

# tcpdump -i nflog:2 -n -tt ...

Dann gleichzeitig wie immer:

# tcpdump -i eth0 -n -tt ...

Antwort2

AKTUALISIEREN:

Also habe ich schließlich diese Lösung verwendet. Sie ist in meiner Lösung enthalten. Bei mir hat es schließlich gut funktioniert.


Ich (der Themenstarter) habe mein Problem mit Linux Bridge gelöst. Hier [https://www.linuxquestions.org/questions/linux-networking-3/transferring-all-traffic-through-an-extra-interface-4175656515] Ich schrieb, dass ich es geschafft habe, Linux Bridge zu verwenden, schloss die Möglichkeit jedoch aus:"Aber diese Lösung entspricht nicht meinen Anforderungen, da in Wirklichkeit eine zusätzliche Ethernet-Verbindung zwischen den Schnittstellen h1-br0 und h1-eth0 besteht. Ich brauche dieses Zeug für Leistungsmessungen, also kann ich keine zusätzlichen Ethernet-Verbindungen haben. Ich meine, diese Lösung mit Bridge bringt meine Topologie durcheinander, indem sie zusätzliche Verbindungen einführt."

       a1
-----------------
|a1-br0---a1-eth0|---------local network
------------------

Warum habe ich die Lösung zuerst verworfen? Zunächst ist meine Topologie:

a1---3Gbps---r1---100Mbps---r2

Auf der Verbindung r1---r2habe ich die Netem-Rate auf 100 Mbit/s eingestellt, auf der Verbindung a1---r1gibt es keine Ratenbegrenzungen. Da die Übertragungswarteschlange des Routers, r1der sie mit dem Router verbindet, 1000 Pakete umfasst, kam es beim Senden von Datenverkehr von nach zu r2einem Warteschlangenüberlauf (einige Pakete gingen verloren) . Und das war in Ordnung. So passiert es in der realen Welt, wenn Routerwarteschlangen im Falle eines Engpasses überlaufen.a1r2

Jetzt habe ich all diese Recherchen durchgeführt, um auch Verzögerungs- und Ratenbegrenzungen hinzuzufügen a1---r1. So kam ich auf diese Lösung mit Linux Bridge. Aber ich dachte, dass diese Lösung nicht funktionieren würde. Unten sehen Sie die neue Topologie mit Linux Bridge:

[a1-br0 ---3Gbps---a1-eth0]---100Mbps---r1---100Mbps---r2

Mein Problem mit der Lösung war also, dass ich erwartet hatte, dass der Warteschlangenüberlauf jetzt in der Übertragungswarteschlange der Schnittstelle vorhanden sein würde a1-eth0. Das heißt, dies ist der gleiche Weg wie im vorherigen Bild, wo der Überlauf an der Schnittstelle von war, r1mit der er verbunden wurde r2. Analog.

Und diesen Überlauf möchte ich nicht. Denn in der normalen Topologie – ohne Verwendung der Linux-Bridge zur Verzögerungsmessung – haben wir keinen Überlauf der Sendewarteschlange von a1-eth0:

[a1-eth0]---100Mbps---r1---100Mbps---r2

Aber gestern habe ich die Topologie mit Linux Bridge (die dritte Topologie der oben abgebildeten) erneut erstellt und den Datenverkehr in der Topologie von a1nach gestartet r2. Ich habe den Rückstand (aktuelle Anzahl der Pakete in der Warteschlange) der Sendewarteschlange beim a1-eth0Aufrufen des Befehls tc -s qdisc show dev a1-eth0im Zyklus mit 500-ms-Intervall und den Rückstand der Sendewarteschlange von a1-br0mit dem analogen Befehl überprüft.

Das habe ich gesehen a1-eth0und die Nachrichten erhalten:

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 9461862 bytes 6393 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 15280534 bytes 10323 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 21110722 bytes 14257 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 118560b 80p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 26952766 bytes 18199 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 32788882 bytes 22137 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 103740b 70p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 38635372 bytes 26082 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 44477416 bytes 30024 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 50332798 bytes 33975 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 56157058 bytes 37905 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 125970b 85p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 61969532 bytes 41828 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 67784900 bytes 45752 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 73600268 bytes 49676 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 79415636 bytes 53600 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 133380b 90p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 85244342 bytes 57533 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 120042b 81p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 91080458 bytes 61471 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 96923984 bytes 65414 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 102761582 bytes 69353 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 102258b 69p requeues 0 

qdisc netem 8112: root refcnt 2 limit 1000 delay 10.0ms
 Sent 108606590 bytes 73297 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 103740b 70p requeues 0 

Das habe ich gesehen a1-br0und die Nachrichten erhalten:

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

qdisc noqueue 0: root refcnt 2 
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 

Es ist also ersichtlich, dass bei kein Überlauf auftritt a1-eth0und es in Wirklichkeit nicht so „aussieht“, als ob a1-br0etwas gesendet würde, obwohl es in Wirklichkeit sendet. Die Verbindung zwischen a1-bround a1-eth0ist also nicht wie die (die Veth-Paarverbindung) zwischen a1und Router r1. Ich weiß nicht, warum das so ist. Es ist seltsam, weil ich überprüft habe, dass ich beispielsweise die Netem-Verzögerungseinstellung auf einstellen kann a1-br0– es ist also wie eine normale Schnittstelle.

Wie dem auch sei, ich habe überprüft, dass die Lösung mit der Brücke alle meine Anforderungen erfüllt. Ich habe jedoch noch nicht herausgefunden, warum sie funktioniert (ich meine im Sinne dessen, was ich oben erklärt habe – Warteschlangenüberlauf usw.).


Hier sind die Befehle, die ich auf dem Host ausgeführt habe, a1als Referenz. Ich verstehe, dass es schwierig ist, sie ohne den Kontext vollständig zu verstehen. Aber vielleicht hilft es jemandem in der Zukunft:

brctl addbr a1-br0
brctl addif a1-br0 a1-eth0
ip link set dev a1-br0 up
ip addr add dev a1-br0 11.0.0.1/30
ip addr flush dev a1-eth0
route add default gw 11.0.0.2 dev a1-br0
ifconfig a1-eth0 0.0.0.0 up
ethtool -K a1-br0 tx off sg off tso off ufo off

Die Topologie mit IP-Adressen, auf die ich die Befehle angewendet habe, ist auch hier vorhanden:Pingen einer Schnittstelle eines Linux-Routers durch eine andere Schnittstelle dieses Routers. Hier ist die Topologie:

------                           ------                            ------
| a1 |                           | r1 |                            | r2 |
|    | a1-eth0-----------r1-eth0 |    |r1-eth1--------------r2-eth1|    |
-----(11.0.0.1/30)   (11.0.0.2/30)----(11.0.0.9/30)   (11.0.0.10/30)----- 

verwandte Informationen