Если я добавлю следующие настройки на гостевом kvm:
net.ipv4.conf.all.arp_ignore=1
Сеть гостя останавливается (очень прерывисто).
Хост kvm использует мостовую сеть:
auto lo
iface lo inet loopback
iface lo inet6 loopback
auto {{ vbox_interface }}
iface {{ vbox_interface }} inet static
address {{ vbox_main_ipv4 }}
netmask {{ vbox_ipv4_netmask }}
gateway {{ vbox_ipv4_gw }}
pointopoint {{ vbox_ipv4_gw }}
iface {{ vbox_interface }} inet6 static
address {{ vbox_main_ipv6 }}
netmask 128
gateway {{ vbox_ipv6_gw }}
auto br0
iface br0 inet static
address {{ vbox_main_ipv4 }}
netmask 255.255.255.255
bridge_ports none
bridge_stp off
bridge_fd 0
bridge_maxwait 0
{% for ip in vbox_addtl_ipv4 %}
up route add -host {{ ip }} dev br0
{% endfor %}
iface br0 inet6 static
address {{ vbox_main_ipv6 }}
netmask 64
Почему это ?
Как Майкл указывает в комментариях, некоторый контекст:
arp_ignore
( http://kb.linuxvirtualserver.org/wiki/Using_arp_announce / arp_ignore_to_disable_ARP ) -В основном я хочу сохранить эту настройку, поскольку я нахожусь в ненадежной сети arp_ignore = 0
на гостевой виртуальной машине решит проблема. Однако я хотел бы знать, почему (потому что мне не нужно делать это на самом хосте), и я не могу принять это как ответ, потому что я не верю, что его настройка должна привести к отключению сети (например, я хочу решить проблему проблема без установления зависимости) Итак, мой вопрос, я полагаю, следующий: :
Почему arp_ignore = 1
нарушает работу сети kvm-guest <> kvm-host, когда kvm-guest использует pointopoint / 255.255.255.255?
Редактировать 23/10/2018: гостевые интерфейсы config
# The loopback network interface
auto lo
iface lo inet loopback
auto ens7
iface ens7 inet static
address IP from the pool {{ vbox_addtl_ipv4 }}
netmask 255.255.255.255
gateway {{ vbox_main_ipv4 }}
pointopoint {{ vbox_main_ipv4 }}
iface ens7 inet6 static
address xxx::xxx
netmask 64
gateway {{ vbox_main_ipv6 }}
Я проверил это поведение на Ubuntu 18.04 без каких-либо мостов, KVM или Hetzner вообще, и я думаю, что это на самом деле ошибка ядра в отношении обработки arp_ignore
на Ethernet-интерфейсах типа "точка-точка". Шаги для проверки:
netplan
не будет вмешиваться, отключив его вообще.Установите две системы с Ethernet-интерфейсами, подключенными друг к другу, и IP-адресами, назначенными следующим образом:
Sever A:
ip addr addr добавить 192. 168.100.1/32 пэр 192.168.100.2 dev ens33
ip link set ens33 up
Server B:
ip addr addr add 192.168.100.2/32 peer 192.168.100. 1 dev ens33
ip link set ens33 up
Следите за обычным пингом с сервера A на сервер B и ip addr show
выводом, который содержит эту строку:
inet 192.168.100.1 peer 192.168. 100.2/32 scope global ens33
Включите arp_ignore=1
с sysctl net.ipv4.conf.all.arp_ignore=1
на сервере A и увидите, что пинг останавливается, как только истечет таймаут записи ARP. После некоторого времени пинги на некоторое время возобновятся , а затем закончатся снова. Этот процесс будет продолжаться бесконечно.
Запустите tcpdump tcpdump
на сервере B и наблюдайте входящие пинги и исходящие бесконечные , который имеет
запросы к IP-адресу сервера A, приходящие с сервера B без ответа. Иногда, сервер A будет выдавать who-has
запрос на IP-адрес сервера B, будет получать ответ, а сервер B будет временно кэшировать MAC-адрес источника, полученный из этого ARP-запроса, и именно тогда пинг возобновится.
Теперь вот что происходит. Внутри ядра существует разница между широковещательными интерфейсами точка-точка и стандартными широковещательными интерфейсами в том, как iproute2
(и подобные инструменты) заполняют в структуре_ifaddr
, определенной в include/linux/inetdevice.h
. Для обычных интерфейсов поле ifa_address
заполняется адресом локального интерфейса , для интерфейсов точка-точка ifa_address
заполняется адресом удаленного партнера, а поле ifa_local
заполняется адресом локального интерфейса.
Это нормальное и ожидаемое поведение, так как в старые добрые времена любой интерфейс "точка-точка" считался подключенным удаленным устройством; соответствующий ему локальный адрес конечной точки может даже не существовать. Значит, здесь ничего не сломано.
На самом деле сломано то, что обработчик arp_ignore()
, определенный в net/ipv4/arp.c
косвенно использует функцию confirm_addr_indev()
, определенную в net/ipv4/devinet. c
, которая итерационно пытается сопоставить целевой IP-адрес ARP-запроса (т.е. адрес локального интерфейса) с полем ifa_address
всех сконфигурированных записей IP-адресов на интерфейсе.
Это хорошо работает на стандартных интерфейсах, так как их локальный IP-адрес записан в поле ifa_address
, однако на интерфейсах типа точка-точка это не работает, так как в этом поле вместо них записан одноранговый IP-адрес.
Теперь реальный вопрос в том, действительно ли эта проблема нуждается в исправлении, так как уже отмечалось, что нет смысла использовать arp_ignore
на p2p-линках. Я думаю, что это так, так как может существовать ситуация, когда хост, о котором идет речь, имеет более одного интерфейса (и эти интерфейсы не p2p), и кто-то может включить эту штуку с префиксом conf.all
только для того, чтобы видеть, что его p2p-ссылки падают без видимой причины.
Ответ в определении:
arp_ignore -
0 - (по умолчанию): ответ для любого локального целевого IP-адреса, сконфигурированного
на любом интерфейсе
1 - отвечать только в том случае, если целевой IP-адрес является локальным адресом.
настроенный на входящем интерфейсе
2 - отвечать только в том случае, если целевой IP-адрес является локальным адресом.
сконфигурированный на входящем интерфейсе и оба с
IP-адрес отправителя является частью одной подсети на этом интерфейсе.
3 - не отвечать на локальные адреса, настроенные с помощью хоста-области,
ответы даются только для глобальных адресов и адресов ссылок.
4-7 - зарезервированный
8 - не отвечайте по всем локальным адресам
По сути, поскольку сами по себе интерфейсы "точка-точка" не имеют назначенных IP-адресов, "целевой ip на входящем интерфейсе" не существует. IP-адрес присваивается интерфейсу моста... а не реальному интерфейсу связи. Таким образом, ARP не обрабатывается.
.