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

Ping не работает на интерфейсах TAP с мостом

Я пытаюсь понять правила моста Linux и локального IP,

У меня следующая топология на моем ноутбуке с Linux.

               br0 
     ___________|__________
     |                    |    
  |tap0                  tap1|
  |________Application_______| 

Приведенное выше приложение создает 2 интерфейса tap0 и tap1.

Я создаю мост и подключаю интерфейсы ответвлений к нему:

brctl addif br0 tap0
brctl addif br0 tap1

Чтобы ping работал, мне нужно добавить IP-адрес в интерфейсы, поэтому я добавляю 192.168.13.1 to tap0 и 192.168.13.2 to tap1

Приложение читает из одного интерфейса и записывает в другой интерфейс для обоих интерфейсов.

Теперь, если я запускаю "ping 192.168.13.2 -I tap0"

PING 192.168.13.2 (192.168.13.2) from 192.168.13.1 tap0: 56(84) bytes of data.
From 192.168.13.1 icmp_seq=1 Destination Host Unreachable

tcpdump показывал, что arp не может быть разрешен, поэтому я добавил статические записи ARP:

arp -i tap0 -s 192.168.13.1 62:34:58:e7:8a:3a
arp -i tap1 -s 192.168.13.2 4a:6d:fa:51:7d:2d

brctl showmacs br0
port no mac addr        is local?   ageing timer
  2 4a:6d:fa:51:7d:2d   yes        0.00
  2 4a:6d:fa:51:7d:2d   yes        0.00
  1 62:34:58:e7:8a:3a   yes        0.00
  1 62:34:58:e7:8a:3a   yes        0.00

Мост тоже, похоже, узнал MAC-адреса.

Однако приложение и tcpdump по-прежнему получают 42-байтовые пакеты, показывающие, что пакеты ARP еще не разрешены, а ping дает сообщение о недоступности хоста.

Моя текущая таблица маршрутизации:

ip route ls table main
169.254.0.0/16 dev virbr0  scope link  metric 1000 linkdown 
192.168.13.0/24 dev tap1  proto kernel  scope link  src 192.168.13.2 
192.168.13.0/24 dev tap0  proto kernel  scope link  src 192.168.13.1 
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 linkdown 

Моя текущая локальная таблица маршрутизации:

broadcast 192.168.13.0 dev tap1  proto kernel  scope link  src 192.168.13.2 
broadcast 192.168.13.0 dev tap0  proto kernel  scope link  src 192.168.13.1 
local 192.168.13.1 dev tap0  proto kernel  scope host  src 192.168.13.1 
local 192.168.13.2 dev tap1  proto kernel  scope host  src 192.168.13.2 
broadcast 192.168.13.255 dev tap1  proto kernel  scope link  src 192.168.13.2 
broadcast 192.168.13.255 dev tap0  proto kernel  scope link  src 192.168.13.1 

У меня такое чувство, что здесь маршрутизация может не входить в картину: поскольку это широковещательный домен уровня 2. Но поскольку я не очень разбираюсь в мостах Linux, мне нужен совет, чтобы продолжить.

Как сделать так, чтобы ping работал между tap0 и tap1.

Спасибо Наян

Я думаю, вы не поняли, в чем роль и использование интерфейсы tun / tap, и в этом причина ваших проблем. Позволь мне объяснить.

Рассмотрим tap0 интерфейс как конец виртуального провода с двумя сторонами: видимая сторона: tap0, а невидимая сторона провода в приложение: эта невидимая сторона должна полностью обрабатываться приложением. Приложение будет получать кадры Ethernet как полезные данные, считываемые в файловом дескрипторе, при необходимости декодировать эти данные как Ethernet (потому что он находится в режиме ответвления), затем как ARP или IP и затем будет реагировать на любое необходимое событие. Короче говоря, вашему приложению требуется сетевой стек TCP / IP, чтобы иметь возможность отвечать на пинг.

Примеры таких приложений, использующих устройства tun / tap: openvpn или комбинация QEMU + VM + OS (QEMU здесь, чтобы представить эти полезные данные для драйвера сетевого устройства операционной системы виртуальной машины так же, как этот драйвер будет видеть от реального сетевого устройства).

Когда вы порабощаете tap0 и tap1 к мосту они становятся портами моста: это намек они не должны получать IP (имеет ли смысл назначать IP-адрес каждому порту вашего 24-портового коммутатора?): эти IP-адреса в основном игнорируются, за исключением IP-адреса, принадлежащего хосту: маршрут с сфера местного таким образом добавляется к местный таблица маршрутизации. Вы могли бы добавить эти IP-адреса в вот loopback-интерфейс с тем же результатом. Кроме этого, нет маршрута, который работал бы с этими интерфейсы порты моста, теперь важно их хозяин br0.

Что вам нужно сделать, так это добавить IP-адрес на самом мосту (в этом случае маршрут будет использовать br0 интерфейс) или вместо этого вы можете создать veth пара, поработите одну сторону моста и добавьте IP-адрес на другой стороне: маршрут будет использовать veth интерфейс с IP на нем (и оставьте мост без IP, который чище imho).

Теперь что касается оставшейся части, все зависит от вашего приложения: оно должно обрабатывать эти IP-адреса 192.168.13.1 и 192.168.13.2 самостоятельно, в том числе сначала отвечать на запросы ARP для них, прежде чем отвечать на эхо-запросы ICMP.


Если вы теперь обнаруживаете, что роль приложения заключается не только в создании интерфейсов tun / tap, то вам следует забыть об использовании приложений и интерфейсов tun / tap: используйте сетевые пространства имен которые дублируют столько сетевых стеков, сколько необходимо, создают мосты там, где это необходимо, и veth интерфейсы в этих пространствах имен. Все это можно проверить с помощью ip netns и ip link add ... type veth ....

Вот несколько ссылок на первые 3 части руководства, в которых используется мост и veth интерфейсы с сетевыми пространствами имен (увы, они не используют ip netns что легче выполнить работу):

Развлечение с veth-устройствами, мостами Linux и VLAN в безымянных пространствах имен сети Linux - я II III