Почему пакеты ARP или ICMPv6 не обрабатываются устройством Linux TAP

#c #linux #icmp #arp

#c #linux #icmp #arp

Вопрос:

Я открываю TAP-устройство с помощью

 p->fd = open("/dev/net/tun", O_RDWR);

// skipping error handling code

ifr.ifr_flags = IFF_TAP | IFF_ONE_QUEUE | IFF_NO_PI;
strncpy(ifr.ifr_name, p->name, IFNAMSIZ-1);
result = ioctl(p->fd, TUNSETIFF, amp;ifr);

// skipping error handling and setting ipv4 address amp; netmask code

ifr.ifr_flags = (IFF_UP | IFF_RUNNING);
result = ioctl(dummySock, SIOCSIFFLAGS, amp;ifr);
  

Проблема, с которой я сталкиваюсь, заключается в том, что когда приложение (скажем, Mozilla) хочет отправить пакет через tap-устройство, ему необходимо получить mac-адрес dst. Итак, ядро отправляет запрос ARP. Приложение, которое я пишу, пересылает запрос arp (через необработанный сокет на физическом eth-устройстве) и получает ответ arp. Этот ответ arp пересылается обратно на tap-устройство, но ядро отказывается его принимать. Если я добавляю запись arp вручную, запрос arp не генерируется и происходит двусторонний обмен ip-пакетами (mozilla довольна).

Wireshark может получить пакет и не находит ошибок. То же самое происходит с пакетами ICMPv6 (запрос соседей и реклама). Любое приложение, прослушивающее устройство, получает пакет неповрежденным. Но ядро не обрабатывает их для ARP / ICMP.

Мой вопрос в том, почему ядро не принимает сообщения arp reply / ICMPv6? Есть ли какой-нибудь вызов ioctl, который нам нужно вызвать?

Редактировать:

Вот подробная информация о захваченных пакетах (вывод tshark) на tap-устройстве «ethgress»

   9  16.548328    fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
 10  17.243247  fc00:1::100 -> fc00:1::2    ICMPv6 86 Neighbor Advertisement
 11  17.548652    fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
 12  17.668736  fc00:1::100 -> fc00:1::2    ICMPv6 86 Neighbor Advertisement
  

Это вывод ifconfig для «ethgress»

 ethgress  Link encap:Ethernet  HWaddr 00:01:02:03:04:05
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10000
          RX bytes:0 (0.0 b)  TX bytes:7062 (6.8 KiB)
  

Как можно видеть, ядро отказывается принимать пакеты ICMPv6 как полученные. Но пакеты tx увеличиваются.

Отводное устройство «ethgress» настроено с IPv6-адресом fc00: 1::2, и приложение хочет связаться с fc00: 1:: 1. fc00: 1:: 1 находится на том же интерфейсе, что и fc00: 1:100, который отвечает рекламой соседа (целевой IP-fc00: 1::1 в этом пакете) с соответствующим mac-адресом. Tcpdump способен перехватывать его, а wireshark / tshark способен декодировать его без него и говорит, что это правильно сформированный пакет. Но счетчики Rx не увеличиваются ядром, и оно не обновляет свой кэш arp. То же самое происходит с пакетами ARP.

Редактировать 2:

Сеть выглядит следующим образом. Есть два внешних блока, которые настроены как избыточные. Только один из них будет активен. Каждый из них подключен к ПК через физическую сетевую карту. Приложение, которое я пишу, запускается на этом компьютере и открывает необработанный сокет на каждой из сетевых карт. Это также открывает TAP-устройство. Сетевые адаптеры не настроены на IP-адрес. Для устройства TAP настроен как IPv4, так и IPv6-адрес. Стандартное приложение, скажем Mozilla, открывает сокет через tap-устройство и хочет подключиться к активному блоку. Для этого ядро генерирует сообщение ARP-запроса / запроса соседа на tap-устройстве. Приложение считывает это сообщение и пересылает его на обе сетевые карты. Активное окно отвечает на запрос ARP ответом ARP, который приложение считывает и записывает на устройство TAP. Этот ответный пакет arp перехватывается tcpdump, но ядро не обновляет свой кэш arp. Mac-адреса как сетевых адаптеров, так и устройства TAP одинаковы.

Запрашиваются другие параметры.

 cat /proc/sys/net/ipv4/conf/all/log_martians
0
cat /proc/sys/net/ipv4/conf/all/rp_filter
1
cat /proc/sys/net/ipv4/conf/all/arp_filter
0
  

Комментарии:

1. Было бы полезно, если бы вы опубликовали соответствующий снимок Wireshark.

2. Если ARP-запрос отправляется через физическое устройство, то как ответ должен попасть на TAP-устройство? Для меня это больше похоже на проблему конфигурации сети высокого уровня…

3. Я обновил вопрос выводом tshark на tap-устройстве. Приложение, которое я пишу, выполняет мультиплексирование между двумя eth-интерфейсами к tap-устройству. Приложение на tap-устройстве автоматически генерирует arp-запрос, и я пересылаю его на оба eth-интерфейса, но ответит только один (не знаю, какой именно). Приложение поддерживает, какой из интерфейсов eth активен, на основе ответа arp. Он не изменяет ни один из пакетов и прозрачно пересылает пакеты между tap-устройством и активным eth-интерфейсом (на основе ответа arp).

4. Каковы ваши настройки для log_martians , rp_filter и arp_filter ? Как выглядит ваша сеть?

5. @ninjalj Я не знаю, что это за параметры. AFAIK, я не возился с этими параметрами. Немного погуглив, получил значения для этих параметров. Извините за 2-дневную задержку, у меня не было доступа в Интернет в выходные.

Ответ №1:

Этот вопрос уже очень устарел.

(У вас также есть разница между устройствами TUN и TAP https://security.stackexchange.com/questions/46442/openvpn-tap-vs-tun-mode )

Если ваше устройство действительно является TAP-устройством, которое включает ARP, аппаратную адресацию и т.д.: Ваш дамп трафика не включает фрейм ethernet. Две важные детали для этих пакетов ARP и ICMPv6 — это адреса HW dst и src. Фильтр RP является частью этого, но, вероятно, не пропускает ВСЕ возможные комбинации.

Для устройства TUN: не должно быть необходимости в ARP и т.д., Это устройство является «слепым» IP-устройством