Почему ndisc6 не может обновить таблицу соседей ядра?

Я поработал с ARP/NDP и обнаружил, что таблица соседей не обновляется (в отличие от ).

пример:192.168.0.14 настроен на устройстве, подключенном к участнику VLAN, поэтому мы можем определить его адрес.

      root@ubuntu:/# ip neigh show 192.168.0.14
root@ubuntu:/# arping 192.168.0.14 -i Vlan1000
ARPING 192.168.0.14
60 bytes from ca:6c:4c:92:85:1c (192.168.0.14): index=0 time=38.088 msec
60 bytes from ca:6c:4c:92:85:1c (192.168.0.14): index=1 time=84.431 msec
60 bytes from ca:6c:4c:92:85:1c (192.168.0.14): index=2 time=119.154 msec
60 bytes from ca:6c:4c:92:85:1c (192.168.0.14): index=3 time=53.739 msec
^C
--- 192.168.0.14 statistics ---
4 packets transmitted, 4 packets received,   0% unanswered (0 extra)
rtt min/avg/max/std-dev = 38.088/73.853/119.154/31.015 ms
root@ubuntu:/# ip neigh show 192.168.0.14
192.168.0.14 dev Vlan1000 lladdr ca:6c:4c:92:85:1c REACHABLE

Как вы видете,arpingможет добавить новую запись в таблицу соседей ядра, как показано

Для аналогичного примера IPv6:ndisc6не могу этого сделать:

      root@ubuntu:/# ip neigh show fc02:1000::3
root@ubuntu:/# ndisc6 fc02:1000::3 Vlan1000
Soliciting fc02:1000::3 (fc02:1000::3) on Vlan1000...
Target link-layer address: CA:58:C2:5F:7C:02
 from fc02:1000::3
root@ubuntu:/# ip neigh show fc02:1000::3
root@ubuntu:/#

fc02:1000::3 — это аналогичный действительный IP-адрес, настроенный на устройстве, подключенном к участнику VLAN. Несмотря на получение действительного рекламного сообщения соседа, таблица соседей ядра не обновляется, как показывает пустой выводip neigh

Я также нашел ссылку на кого-то еще, кто видел ту же проблему в комментариях к этому ответу , но без каких-либо объяснений, почему.

1 ответ

Ядро — это место, где ведется учет соседей. Таким образом, если инструмент пользовательского пространства генерирует запрос ARP (для IPv4) или запрос NDP (для IPv6) с использованием необработанных сокетов (AF_PACKET для ARP и AF_INET6, SOCK_RAW для NDP), ответ не имеет значения для ядра...

... за исключением того, что в ядре Linux есть переключатель IPv4 ARP , позволяющий доверять полученному трафику ARP, даже если он не запрошен. Таким образом, ответ ARP на команду arping заставит ядро ​​добавить запись ARP, но для IPv6 такого переключателя нет.

Я признаю, что существует также разница в поведении в Linux при использовании универсального инструмента arping для нескольких ОС вместо iputils-arping: в первом случае запись ARP все равно создается «по какой-то причине».


В любом случае, этого не происходит с IPv6, но это довольно легко обойти: сначала создайте запись, обновите ее позже с помощьюndisc6поскольку ядро ​​получит запись и обработает ответ. Лучше всего использовать устаревший тип состояния : он считается допустимым, но ненадежным.

Чтобы избежать ненужных сбоев,ip neigh changeсначала пробуется без указания MAC-адреса, поэтому сохраняется предыдущая, вероятно, действительная запись, и если попытка не удалась из-за отсутствия записи или, возможно, она находилась в состоянии сбоя (в этих случаях MAC-адрес является обязательным), используйтеip neigh replace(скорее, чемip neigh addчтобы избежать состояния гонки между двумя командами) и предоставить поддельный локальный MAC-адрес.

Для случая ОП:

      ip -6 neigh change fc02:1000::3 nud stale dev Vlan1000 ||
    ip -6 neigh replace fc02:1000::3 lladdr 02:00:00:00:00:00 nud stale dev Vlan1000
ndisc6 fc02:1000::3 Vlan1000

Теперь это должно дать правильную запись:

      ip -6 neigh show fc02:1000::3
Другие вопросы по тегам