В Arch Linux ARM (Raspberry Pi) Kernel 4.4.37 я создал macvlan, например.
ip link add link eth0 mac0 type macvlan
Виртуальная сетевая карта macvlan появляется в списке, поэтому я назначаю ей IP-адрес и устанавливаю состояние соединения на up. (Кстати, с модами пробовал bridge
, vepa
и private
.)
Затем я могу пропинговать IP-адрес своих клиентов Windows, но когда я проверяю кеш ARP (arp -a
) в Windows они показывают тот же MAC-адрес, что и основной (физический) сетевой адаптер, а не вновь созданный MAC-адрес macvlan.
Я обязательно очистил кеш ARP, попробуйте IP-адрес, который клиенты раньше не видели, и т. Д., Но он всегда показывает неправильный MAC.
Когда я создал статическую запись ARP для клиента Windows для MAC-адреса macvlan и пингую соответствующий IP-адрес, tcpdump показывает эхо-запрос, поступающий на интерфейс macvlan, и ничего не показывает в основном (физическом) интерфейсе. , и я получаю ответ ping на моем клиенте Windows (как только я вспомнил, что нужно настроить правило iptables, чтобы разрешить трафик!)
Как только я очищаю кеш ARP на клиенте и снова проверяю связь, я все еще получаю ответ на запрос проверки связи, но на этот раз запись ARP вернулась к записи основного физического сетевого адаптера в системе Linux.
Просто интересно, что я делаю не так?
В принципе, здесь нет ничего плохого. Вот как ядро Linux работает в отношении разрешения ARP - по умолчанию оно будет отвечать на запросы ARP для любого из своих локальных адресов, независимо от интерфейса, на который они поступают, даже если запрошенный адрес находится на другом интерфейсе.
Чтобы обойти это, вам нужно настроить две переменные sysctl:
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
Вам может потребоваться изменить значение arp_ignore на 2, а также установить arp_filter на 1 в зависимости от ваших IP-адресов / сценария разделения на подсети.
Для полного описания доступных опций для этих переменных, пожалуйста, взгляните на документация kernel.org.
Чтобы это сработало для меня, мне пришлось добавить один шаг к принятому ответу и установить следующую дополнительную переменную:
net.ipv4.conf.all.rp_filter=2
Мне не нужно было устанавливать arp_ignore
до 2, 1 вроде работало. Мне также не нужно было устанавливать arp_filter
до 1 для моей сети.
Итак, полное решение для меня было:
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.all.rp_filter=2
Нашел решение моей проблемы Вот