Zeitproblem nach Routen-Hinzufügen/Löschen (Route nicht verwendet)

Zeitproblem nach Routen-Hinzufügen/Löschen (Route nicht verwendet)

Ich habe eine Anwendung, die einen Raw-IP-Socket ausführt. Das Ziel dieses Sockets wird durch Routen bestimmt, die über den Befehl „ip route add“ installiert wurden. Diese Routen können sich während der Lebensdauer eines Sockets ändern (z. B. weil sich der nächste Hop ändert).

Vereinfacht gesagt, nehmen wir an, ich habe zwei Schnittstellen eth0und eth1. Außerdem habe ich eine Standardroute über eth0.

Der Endpunkt des Raw-Sockets ist beispielsweise 10.10.10.10eth1 und hat die Adresse 100.0.0.1. Während der Lebensdauer des Raw-Sockets mache ich Folgendes:

ip -f inet route delete 10.10.10.10
ip -f inet route add 100.0.0.2 dev eth1
ip -f inet route add 10.10.10.10/32 via 100.0.0.2 dev eth1

Was ich jetzt sehe, ist, dass nach dieser Operation der Verkehr für ein paar Sekunden richtig läuft eth1, dann läuft er (über eth0) für eine kurze Zeit (weniger als eine halbe Sekunde) schief und dann läuft er wieder richtig (soweit ich das erkennen kann, dauerhaft).

Meine Hauptfrage lautet also: -Kann jemand erklären, was hier schiefgehen könnte? Ich habe versucht, es ip route flush cachenach der zuvor erwähnten Sequenz hinzuzufügen, aber das hat nichts bewirkt. Ich bin derzeit verwirrt, warum der Verkehr manchmal unterbrochen wird. Ich denke, es liegt entweder an einem Timingproblem bei den Routing-Befehlen oder an einem anderen Auslöser, der die Route für den Bruchteil einer Sekunde deaktiviert, aber mir gehen die Optionen aus.

Ich habe versucht, die Option auf meinem Raw-Socket zu verwenden SO_BINDTODEVICE, aber leider hat das nicht viel geholfen. Der Hauptunterschied besteht darin, dass bei einem Fehler im Datenverkehr dieser nicht gesendet wird.überhaupt, weil es über die falsche Schnittstelle laufen würde. Ich hatte jedoch gehofft, dass dies errno auf etwas wie E_CANNOTROUTE (das existiert nicht) setzen würde, sodass ich dies abfangen und erneut versuchen könnte, das Paket zu senden. Derzeit geschieht dies nicht, aber gibt es eine Möglichkeit, einen solchen Fehler abzufangen? Ich habe (fast) die volle Kontrolle über das System und die Anwendung, die den Socket ausführt.

Eine Lösung, von der ich weiß, dass sie funktionieren würde, wäre, keine L3-Raw-Sockets, sondern AF_PACKETSockets zu verwenden (und ARP/ND auch selbst zu machen), aber darauf möchte ich jetzt lieber noch nicht näher eingehen.

Aktualisieren

Ich habe das Verhalten in meinem System verbessert, indem ich dieses Routenänderungsverhalten geändert habe. Wenn ich den nächsten Hop aktualisieren muss, schaue ich mir jetzt die bereits installierte Route an und ergreife basierend darauf Maßnahmen:

  • Wenn es nicht da ist, installiere ich einfach die neue Route und überspringe das Löschen.
  • Wenn die genaue Route bereits vorhanden ist (gleiche nh, gleiches Gerät), mache ich jetzt nichts.
  • Wenn für diese Route ein anderes NH vorhanden ist, führe ich jetzt ein spezifischeres Löschen nur für dieses NH durch, gefolgt von einem Hinzufügen.

Dadurch wurden die meisten meiner Probleme behoben, aber manchmal passiert dasselbe immer noch (wenn auch viel seltener), wenn tatsächlich ein Löschen+Hinzufügen erfolgt (letzter Fall im neuen Mechanismus). Außerdem erklärt dies immer noch nicht, was schief läuft (es umgeht es lediglich), also lasse ich diese Frage vorerst offen, da ich wirklich neugierig bin, was hier schief läuft.

Zu Ihrer Information: Ich habe das Problem auf CentOS, soweit ich den Wechsel von CentOS4 auf CentOS6, 32-Bit, überblicken kann.

Antwort1

Wenn ich das richtig verstehe, sollten die Pakete immer über eth1 rausgehen, und Ihr Problem ist, dass beim Update auf einen neuen Nexthop auf eth1 Ihre Pakete manchmal über eth0 rausgehen? Das liegt daran, dass Ihr Löschen+Hinzufügen keine atomare Operation ist.

Versuchen Sie zuerst das Hinzufügen und dann das Löschen. Das Löschen muss spezifisch sein (ich glaube, mit dem Gerät und dem nächsten Hop), damit nicht auch die neue Route gelöscht wird, die Sie gerade hinzugefügt haben.

Antwort2

Gibt es eine Standardroute (oder eine andere Route, die 10.10.10.10/32 abdeckt) über eth0? Wenn Sie zuerst löschen und dann hinzufügen, kann es zu einem Race Condition kommen, bei dem das Löschen erfolgt, Pakete in der Zeit zwischen Löschen und Hinzufügen die Standardroute verlassen, dann das Hinzufügen erfolgt und Pakete dorthin gehen, wo Sie es erwarten.

Für mich klingt das definitiv nach einer Art Race Condition, was höchstwahrscheinlich an der nicht-atomaren Natur der beiden von Ihnen erwähnten Routing-Operationen liegt (wie in Law29 angegeben).

verwandte Informationen