Ядро Linux не проходит через многоадресные UDP-пакеты

35

Недавно я установил новый Ubuntu Server 10.04 и заметил, что мой UDP-сервер больше не может видеть какие-либо многоадресные данные, отправленные на интерфейс, даже после присоединения к многоадресной группе. У меня точно такая же настройка на двух других машинах Ubuntu 8.04.4 LTS, и нет проблем с получением данных после присоединения к той же группе многоадресной рассылки.

Карта Ethernet представляет собой Broadcom netXtreme II BCM5709, а драйвер используется:

b $ ethtool -i eth1
driver: bnx2
version: 2.0.2
firmware-version: 5.0.11 NCSI 2.0.5
bus-info: 0000:01:00.1

Я использую smcroute для управления многоадресными регистрациями.

b$ smcroute -d
b$ smcroute -j eth1 233.37.54.71

После вступления в группу ip maddr показывает вновь добавленную регистрацию.

b$ ip maddr

    1:  lo
        inet  224.0.0.1
        inet6 ff02::1
    2:  eth0
        link  33:33:ff:40:c6:ad
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        inet  224.0.0.1
        inet6 ff02::1:ff40:c6ad
        inet6 ff02::1
    3:  eth1
        link  01:00:5e:25:36:47
        link  01:00:5e:25:36:3e
        link  01:00:5e:25:36:3d
        link  33:33:ff:40:c6:af
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        inet  233.37.54.71 <------- McastGroup.
        inet  224.0.0.1
        inet6 ff02::1:ff40:c6af
        inet6 ff02::1

Пока все хорошо, я вижу, что я получаю данные для этой многоадресной группы.

b$ sudo tcpdump -i eth1 -s 65534 host 233.37.54.71
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65534 bytes
09:30:09.924337 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:09.947547 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
09:30:10.108378 IP 192.164.1.120.58866 > 233.37.54.71.15574: UDP, length 268
09:30:10.196841 IP 192.164.1.120.58848 > 233.37.54.71.15572: UDP, length 212
...

Я также могу подтвердить, что интерфейс получает пакеты mcast.

b $ ethtool -S eth1 | grep mcast_pack
rx_mcast_packets: 103998
tx_mcast_packets: 33

Теперь вот проблема. Когда я пытаюсь захватить трафик с помощью простого сервера ruby ​​UDP, я получаю ноль данных! Вот простой сервер, который считывает данные, отправленные через порт 15572, и печатает первые два символа. Это работает на двух серверах Ubuntu 8.04.4, но не на сервере 10.04.

require 'socket'
s = UDPSocket.new
s.bind("", 15572)
5.times do
  text, sender = s.recvfrom(2)
  puts text
end

Если я отправлю UDP-пакет, созданный в ruby, на localhost, сервер получит его и напечатает первые два символа. Так что я знаю, что сервер выше работает правильно.

irb(main):001:0> require 'socket'
=> true
irb(main):002:0> s = UDPSocket.new
=> #<UDPSocket:0x7f3ccd6615f0>
irb(main):003:0> s.send("I2 XXX", 0, 'localhost', 15572)

Когда я проверяю статистику протокола, я вижу, что InMcastPkts не увеличивается. В то время как на других серверах 8.04, находящихся в той же сети, было получено несколько тысяч пакетов за 10 секунд.

b $ netstat -sgu ; sleep 10 ; netstat -sgu
IcmpMsg:
    InType3: 11
    OutType3: 11
Udp:
    446 packets received
    4 packets to unknown port received.
    0 packet receive errors
    461 packets sent
UdpLite:
IpExt:
    InMcastPkts: 4654 <--------- Same as below
    OutMcastPkts: 3426
    InBcastPkts: 9854
    InOctets: -1691733021
    OutOctets: 51187936
    InMcastOctets: 145207
    OutMcastOctets: 109680
    InBcastOctets: 1246341
IcmpMsg:
    InType3: 11
    OutType3: 11
Udp:
    446 packets received
    4 packets to unknown port received.
    0 packet receive errors
    461 packets sent
UdpLite:
IpExt:
    InMcastPkts: 4656  <-------------- Same as above
    OutMcastPkts: 3427
    InBcastPkts: 9854
    InOctets: -1690886265
    OutOctets: 51188788
    InMcastOctets: 145267
    OutMcastOctets: 109712
    InBcastOctets: 1246341

Если я попытаюсь перевести интерфейс в режим Promisc, ничего не изменится.

На данный момент я застрял. Я подтвердил, что в конфигурации ядра включена многоадресная рассылка. Возможно, есть другие параметры конфигурации, которые я должен проверить?

b $ grep CONFIG_IP_MULTICAST /boot/config-2.6.32-23-server
CONFIG_IP_MULTICAST=y

Есть мысли о том, куда идти отсюда?

buecking
источник
Пойди разберись. Я иду, чтобы ввести новый вопрос, связанный алгоритм счастливо показывает мне, что этот вопрос существует, но на него нет значимых ответов. Бу :(.
VxJasonxV
Я не уверен, как именно я собираюсь присуждать награду. Сотрудник обнаружил проблему, и я выяснил, ПОЧЕМУ это случилось, как это случилось. Я более чем готов принять предложения о том, как присуждать награду.
VxJasonxV
ты все еще рядом? У меня есть к вам несколько вопросов.
VxJasonxV
У меня тоже есть эта проблема. Уважаемый buecking, вы решаете это?
Для тех, у кого была эта проблема - прочитайте все ответы на этот вопрос, потому что есть 2-3 настройки O / S, которые необходимо исправить. Мы решили эту проблему путем изменения rp_filterи /proc/sys/net/ipv4/icmp_echo_ignore_broadcastsзатем он начал работать.
Сэм Голдберг,

Ответы:

35

В нашем случае наша проблема была решена с помощью параметров sysctl, отличных от Maciej.

Обратите внимание, что я не говорю за OP (buecking), я пришел на этот пост из-за проблемы, связанной с основной деталью (нет многоадресного трафика в пользовательском пространстве).

У нас есть приложение, которое считывает данные, отправленные по четырем адресам многоадресной рассылки, и уникальный порт для каждого адреса многоадресной рассылки с устройства, которое (обычно) подключается напрямую к интерфейсу на принимающем сервере.

Мы пытались развернуть это программное обеспечение на сайте клиента, когда оно таинственным образом вышло из строя без какой-либо известной причины. Попытки отладки этого программного обеспечения привели к проверке каждого системного вызова, в конечном итоге все они сказали нам одно и то же:

Наше программное обеспечение запрашивает данные, а ОС никогда их не предоставляет.

Счетчик многоадресных пакетов увеличился, tcpdump показал трафик, достигающий интерфейса box / specific, но мы ничего не могли с этим поделать. SELinux был отключен, iptables работал, но не имел правил ни в одной из таблиц.

Мы были в тупике.

При случайном поиске мы начали думать о параметрах ядра, которые обрабатывает sysctl, но ни одна из документированных функций не была особенно актуальна, или, если они имели отношение к многоадресному трафику, они были включены. Да, и если ifconfig сделал список "MULTICAST" в строке функций (вверх, широковещание, запуск, многоадресная передача). Из любопытства мы посмотрели /etc/sysctl.conf. и вот, у базового изображения этого клиента было добавлено несколько дополнительных строк внизу.

В нашем случае заказчик установил net.ipv4.all.rp_filter = 1. rp_filter - это фильтр Route Path, который (насколько я понимаю) отклоняет весь трафик, который, возможно, не достиг этого поля. Прыжок в подсети, мысль о том, что IP-адрес источника был подделан.

Итак, этот сервер находился в подсети 192.168.1 / 24, а IP-адрес источника устройства для многоадресного трафика находился где-то в сети 10 *. Таким образом, фильтр препятствовал тому, чтобы сервер делал что-либо значимое с трафиком.

Пара твиков, утвержденных заказчиком; net.ipv4.eth0.rp_filter = 1и net.ipv4.eth1.rp_filter = 0мы бежали счастливо.

VxJasonxV
источник
2
Это сработало! rp_filterДля нашего 10 сетевого интерфейса Gb был демпинг всех наших широковещательных пакетов UDP. Отключение фильтра позволяет всему течь.
chrisaycock
У нас были проблемы при настройке потоковой передачи через многоадресную рассылку AMT через устройство tun на приемнике Ubuntu, и мы могли видеть, как пакеты доставляются на устройство через tcpdump, но приложение просто не хочет выполнять потоковую передачу. Этот пост спас нас!
инженер-программист
2
Работая на Ubuntu 14.04, это сработало только после того, как я установил net.ipv4.all.rp_filter = 0. В частности, когда многоадресные данные поступают на eth2, мне пришлось установить и то, net.ipv4.eth2.rp_filter = 0и другое net.ipv4.all.rp_filter = 0.
T-Hawk
4

TL / DR Также убедитесь, что ваша многоадресная рассылка не происходит от vlan. tcpdump -eпоможет определить, если они делают.

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

Мало того, что я мог видеть пакеты в tcpdump, я мог фактически получать другие многоадресные пакеты, для других производителей, только на другом интерфейсе. Команда, которую я использовал для проверки, могу ли я получить многоадресную рассылку, была:

$ GRP=224.x.x.x # set me to the group
$ PORT=yyyy # set me to the receiving port
$ IFACE=mmmm # set me to the name or IP address of the interface
$ strace -f socat -  UDP4-DATAGRAM:$GRP:$PORT,ip-add-membership=$GRP:$IFACE,bind=0.0.0.0:$PORT,multicast-loop=0

Причина в straceтом, что я на самом деле не смог socatраспечатать пакеты на стандартный вывод, но в straceвыводе вы можете ясно увидеть, socatполучает ли реальные данные из связанного сокета (в противном случае он будет отключен после нескольких начальных selectвызовов)

  • rp_filtersysctl - не применяется, системы находятся в одной IP-сети (я установил их 0одинаково, кажется, что 1это настройка по умолчанию, по крайней мере, для Ubuntu).
  • брандмауэры / и т. д. - принимающая система свободна от брандмауэра (я не думаю, что пакеты будут отображаться в tcpdump, если они были защищены брандмауэром, но я думаю, что это возможно, если брандмауэр смешной)
  • IP / Multicast маршрутизация и несколько интерфейсов - я явно присоединился к группе на правильном интерфейсе
  • Дурацкое сетевое оборудование - это было мое последнее средство, но замена ноутбука на Intel NUC не помогла. Это о том, где я начал жевать свои локти и отправлять это в SE.
  • Проблема в моем случае заключалась в использовании VLAN специализированным оборудованием, которое создавало эти многоадресные пакеты. Чтобы увидеть, является ли это вашей проблемой, обязательно включите -eфлаг tcpdumpи проверьте наличие тегов vlan. Прежде чем пользователь сможет получить эти пакеты, пользователь должен будет настроить интерфейс на правильный vlan. На самом деле, для меня это было то, что производители многоадресной рассылки не будут пинговать, но даже не попадут в кэш ARP, хотя я ясно видел ответы ARP.

Чтобы запустить его с VLAN, эта ссылка может быть полезна для настройки многоадресной маршрутизации. (К сожалению, я новичок в этом, поэтому Репутация не позволяет мне добавлять ответ. Отсюда и это редактирование.)

Вот что я сделал (при необходимости используйте sudo):

ip link add link eth0 name eth0_100 type vlan id 100
ip addr add 192.168.100.2/24 brd 192.168.100.255 dev eth0_100
ip link set dev eth0_100 up
ip maddr add 01:00:5e:01:01:01 dev eth0_100
route -n add -net 224.0.0.0 netmask 240.0.0.0 dev eth0_100

Таким образом, создается дополнительный интерфейс для трафика vlan с идентификатором vlan 100. IP-адрес vlan может быть ненужным. Затем многоадресный адрес настраивается для нового интерфейса (01: 00: 5e: 01: 01: 01 - адрес канального уровня для 239.1.1.1), и весь входящий многоадресный трафик привязывается к eth0_100. Я также сделал все возможные шаги в ответах выше (проверьте iptables, rp_filter и т. Д.).

Павел Веселов
источник
@Gero: Добавление многоадресного маршрута настраивает исходящую многоадресную рассылку, а не входящую многоадресную рассылку. Вы не должны связывать многоадресные IP-адреса с интерфейсами напрямую, если вы не делаете что-то напуганное, обычно это работа приложения.
Павел Веселов
2

Возможно, вы захотите попробовать эти параметры:

процедура

echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

sysctl.conf

sed -i -e 's|^net.ipv4.icmp_echo_ignore_broadcasts =.*|net.ipv4.icmp_echo_ignore_broadcasts = 0|g' /etc/sysctl.conf

Они были использованы для включения многоадресной рассылки в RHEL.

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

# allow anything in on multicast addresses
-A INPUT -s 224.0.0.0/4 -j ACCEPT
-A INPUT -p igmp -d 224.0.0.0/4 -j ACCEPT
# needed for multicast ping responses
-A INPUT -p icmp --icmp-type 0 -j ACCEPT
user64259
источник
Параметры «широковещания» применяются и к «многоадресной передаче»
Raedwald
0

Вы используете управляемый коммутатор? У некоторых есть опции для предотвращения «широковещательных штормов» или других проблем многоадресной рассылки, которые могут заставить их предотвращать определенные типы пакетов. Я бы посоветовал взглянуть на документацию по вашему коммутатору.

devicenull
источник
0
s.bind("", 15572)

Уверен в ""? Почему бы не использовать многоадресный IP-адрес для привязки?

poige
источник
Пустые адреса хоста обычно означают «все интерфейсы».
VxJasonxV