Назад | Перейти на главную страницу

При каких обстоятельствах Linux будет игнорировать таблицу маршрутизации при выборе MAC-адреса для исходящего кадра?

Пока отладка проблема с сетевой конфигурацией для набора виртуальных машин, работающих под KVM, я обнаружил обстоятельство, когда ядро ​​в гостевой виртуальной машине решило пометить исходящий кадр Ethernet с адресом назначения, который находится в конфликте с адресом, который он выбрал бы, если он соблюдает таблицу IP-маршрутов ядра.

Итак, в этом примере я ожидал, что исходящий кадр будет доставлен на de: ad: be: 3b: 24: 48, что соответствует хосту, которому принадлежит IP-адрес 10.11.11.2 и которому принадлежит маршрут к 10.8.0.0/24. .

На самом деле произошло то, что ядро ​​решило пометить фрейм адресом 00: 10: db: ff: 70: 01, которое отправило фрейм в направлении 10.11.11.1, который не знает, как маршрутизировать к 10.8.0.0. / 24, и в результате пакет был отброшен.

Это решение противоречило локальной таблице маршрутизации, в которой четко указывалось, что маршрут к 10.8.0.0/24 проходит через 10.11.11.2. См. Подробности в исходном отчете о проблеме.

[Неверный адрес назначения был виден при запуске tcpdump на гостевой виртуальной машине, которая отправляла фрейм в неправильном направлении.].

Фактически, путем объединения локальной таблицы arp для того, чтобы кажущийся MAC-адрес 10.11.11.1 был идентичен фактическому MAC-адресу 10.11.11.2, я смог добиться того, чтобы фрейм шел в правильном направлении.

Итак, мой вопрос: какой механизм, в гостевой виртуальной машине или на хосте KVM, может заставить гостевое ядро ​​игнорировать локальную таблицу маршрутов и отправлять пакет в кадре на (неправильный) хост в 10.11.11.1, хотя 10.11 .11.1 не указан в качестве шлюза для сети назначения (10.8.0.0/24)?

Примечание: iptables в то время был отключен в гостевой системе. Я не знаю, включен ли ebtables на хосте KVM, но даже если бы это было так, как это могло бы заставить ядро ​​в гостевой виртуальной машине отправить пакет в направлении 10.11.11.1?

Одно поведение, которое я заметил, заключается в том, что если я очищаю таблицы ARP затронутого хоста и отправляю запрос ping на затронутый хост из сети 10.8.0.0/24, он получает запрос, а затем немедленно отправляет широковещательное сообщение arp для 10.11.11.1 перед отправкой ответа ping в направлении 10.11.11.1 вместо 10.11.11.2 и, следовательно, 10.8.0.0/24. Что заставляет его попробовать 10.11.11.1, который не указан в качестве шлюза?

Может быть, маршрутизация на основе источника или политики? Linux может иметь несколько таблиц маршрутизации и выбирать, какую из них использовать, исходя из нескольких условий. Проверьте Документация OpenVZ по маршрутизации на основе исходного кода