Оптимизация передачи multicast-трафика в локальной сети с помощью IGMP snooping

934867d01d6443baaae44fe60801c881.jpg

Всем привет! Сегодня хотел бы затронуть тему передачи multicast-трафика в локальной корпоративной сети, а именно работу технологии IGMP snooping на коммутаторах. Так получилось, что за последнюю неделю ко мне обратилось несколько человек с вопросами по этой технологии. И я решил подготовить небольшую статью с описанием данной технологии. Но в процессе подготовки, выяснилось, что краткостью здесь не отделаешься, так как есть о чём написать. Кому интересен вопрос работы IGMP snooping, добро пожаловать под кат.

Достаточно часто мы не особенно задумываемся над тем, как передаётся multicast-трафик в пределах нашего L2-домена корпоративной сети. Напомню, multicast-трафик (он же «многоадресный трафик») предназначен для передачи данных определённой группе устройств. По умолчанию коммутатор передаёт multicast-трафик как broadcast (широковещательный), т.е. на все порты без исключения. Это обусловлено тем, что в пакете multicast в качестве MAC-адреса получателя использует специально сформированный адрес, никому не принадлежащий в сети. Если multicast-трафика не много, это не создаёт больших проблем и чаще всего администратор не предпринимает никаких мер по оптимизации его передачи. Если же такого трафика много или хочется просто «причесать» сеть, встаёт задача ограничить его распространение. Тут на помощь приходят различные технологии оптимизации передачи multicast-трафика на канальном уровне (IGMP snooping, CGMP и пр.). Наиболее распространённой и мультивендорной является технология IGMP snooping. IGMP snooping на многих устройствах включён по умолчанию. Например, это справедливо для коммутаторов Cisco. Но как часто бывает, счастье из коробки получить удаётся далеко не во всех случаях. Включённый IGMP snooping не всегда даёт предполагаемый результат и multicast-трафик в ряде случаев почему-то продолжает литься из всех портов. Давайте попробуем со всем этим разобраться.

Начать стоит с аббревиатуры IGMP. Всем нам известно, что когда в сети появляется устройство, которое хочет получать определённый multicast-трафик, это устройство сообщает о своём желании по средствам протокола IGMP (Internet Group Management Protocol). На многих устройствах по умолчанию используется IGMP версии 2. Обмен сообщениями данного протокола в самом простом случае выглядит следующим образом:

  1. Устройство, когда решает получать multicast-трафик, отправляет свой запрос в сообщении IGMP Membership Report (далее IGMP Report). В нём указывается, что именно устройство желает получать. Адрес запрашиваемой multicast-группы указывается в качестве IP-адреса назначения. Данное сообщение в первую очередь предназначается ближайшему маршрутизатору. Ведь именно он отвечает за передачу трафика между локальным сегментом и остальной сетью.
  2. Получив такое сообщение, маршрутизатор начинает транслировать в данный сегмент сети, запрашиваемый multicast-трафик. Конечно, это происходит при условии, что маршрутизатор сам участвует в передаче multicast-трафика и получает нужный трафик.
  3. Чтобы быть уверенным, что в сети всё ещё есть получатели multicast-трафика, маршрутизатор периодически рассылает сообщение IGMP General Membership Query (далее IGMP General Query). Ведь если никого уже нет, зачем попусту «засорять» данный сегмент сети никому не нужным трафиком.
  4. В ответ на IGMP General Query маршрутизатор получает сообщение IGMP Report. Обычно его отправляет один из получателей multicast-трафика. Остальные услышав это сообщение, просто молчат, так как одного подтверждения для каждой группы достаточно. Выбор того, кто будет отвечать маршрутизатору, реализуется через механизм Report Suppression.
    Report Suppression
    Если у нас в сети много получателей multicast-трафика, их ответы на IGMP General Query могут породить достаточно большое количество сообщений IGMP Report. Так как маршрутизатору достаточно получить всего одно такое сообщение, используется следующий механизм оптимизации. В сообщении IGMP General Query указывается максимальное время (Maximum Response Time — MTR), в течении которого маршрутизатор ждёт ответа. Клиент, получив IGMP General Query, выбирает произвольное значение таймера от 0 до MTR. Как только выбранное время таймера истекает, клиент отправляет сообщение IGMP Report. Это происходит только в том случае, если до этого клиент не получил IGMP Report от какого-то другого получателя.
  5. Когда устройство больше не желает получать multicast-трафик для определённой группы, оно шлёт сообщение IGMP Leave.
  6. На это маршрутизатор отвечает сообщением IGMP Membership Group-Specific Query (далее IGMP Group-Specific Query), уточняя, есть ли ещё в сети устройства, желающие получать трафик для данной группы. Обычно этих сообщений маршрутизатор отправляет два. Если такие устройства в сети есть, они откликнутся. Если нет, маршрутизатор прекратит трансляцию трафика в локальный сегмент сети.

Более подробно о работе протокола IGMP, да и в целом о multicast-трафике можно почитать, например, в цикле статей сети для самых маленьких.

Так как все сообщения IGMP проходят через коммутатор, он мог бы их анализировать, чтобы определить за какими портами находятся те или иные получатели multicast-трафика. И далее на основании этой информации передавать трафик только туда, куда это необходимо. Собственно, именно этим и занимается технология IGMP snooping.

Реализация IGMP snooping у разных производителей сетевого оборудования в каких-то нюансах может отличается. Но в целом схема работы похожа. Предлагаю в общих чертах рассмотреть её работу на примере коммутаторов Cisco. Далее мы посмотрим на весь процесс более детально:

  1. Первое, что делает коммутатор, определяет, где находится маршрутизатор (ы). Для этого он слушает наличие в сети сообщений IGMP General Query, PIM, DVMRP и пр.
  2. Устройство отправляет IGMP Report, когда хочет получать тот или иной multicast-трафик. Данное сообщение перехватывает коммутатор. Из такого сообщения коммутатор получает следующую информацию: устройство с таким-то MAC-адресом, находящееся за определённым портом, хочет получать трафик такой-то multicast группы. Причём для коммутатора при идентификации multicast группы важен не IP-адрес этой группы (IP-адреса multicast групп лежат в диапазоне 224.0.0.0 — 239.255.255.255), а её MAC-адрес. У нас всё-таки коммутатор и он работает на канальном уровне. Как мы знаем, MAC-адрес формируется по определённому правилу из IP адреса multicast группы. Вся эта информация заносится в таблицу MAC-адресов коммутатора.
    Далее коммутатор отправляет в сторону маршрутизатора IGMP Report, содержащий такую же информацию, как была получена от устройства.
  3. Маршрутизатор, получив сообщение IGMP Report, начинает передавать multicast-трафик. Но так как теперь коммутатор знает, где находится устройство, которое желает его получать, он передаёт этот трафик только на определённый порт. Ведь теперь в таблице MAC-адресов есть запись с MAC-адресом multicast-группы, которая смотрит на конкретный порт.
  4. Периодически маршрутизатор отправляет в сеть IGMP General Query. Коммутатор перехватив его, рассылает данное сообщение через все порты, несмотря на то, что он знает, где находятся получатели multicast-трафика.
  5. Получив IGMP General Query, устройство отвечает сообщением IGMP Report. Коммутатор перехватывает это сообщение, отправляет его только в сторону маршрутизатора. Остальные получатели multicast-трафика его не получают. А, значит, отвечают своими сообщениями IGMP Report (таким образом механизм Report Suppression нарушается). Коммутатор, получив от всех клиентов такие сообщения, обновляет записи MAC-адресов получателей у себя в таблице. Тем самым поддерживая записи в актуальном состоянии. Безусловно, в сторону маршрутизатора все эти сообщения отсылать смысла нет, поэтому коммутатор дальше с ними ничего не делает.
  6. Если устройство решает прекратить получать трафик для определённой multicast-группы, оно отправляет сообщение IGMP Leave. Коммутатор, как обычно, перехватывает его.
  7. Во-первых, коммутатор проверят, нет ли за этим же портом (откуда пришло сообщение IGMP Leave) других получателей multicast-трафика. Ведь в этот порт может быть подключен другой коммутатор. Для этого он отправляет сообщение IGMP Group-Specific Query. Если ответа на него не последовало, коммутатор просто убирает закрепление MAC-адреса multicast-группы за данным портом. Если ответ пришёл, продолжает передавать трафик через данный порт.
  8. Далее коммутатор проверяет, а есть ли на нём другие получатели multicast-трафика для данной группы, но находящиеся за другими портами. Для этого он просто смотрит в свою таблицу MAC-адресов.
    • Если такие получатели есть, больше коммутатор ничего не делает. Посылать сообщение IGMP Leave в сторону маршрутизатора смысла никакого нет.
    • Если это был последний получатель для данной multicast-группы, коммутатор отправляет сообщение IGMP Leave в сторону маршрутизатора.
  9. Получив сообщение IGMP Leave, маршрутизатор рассылает сообщения IGMP Group-Specific Query, которые коммутатор в свою очередь рассылает через все свои порты. Конечно же, никто не откликается и маршрутизатор перестаёт передавать трафик для данной группы.

Итак, в общих чертах мы разобрали теоретические основы. Попробуем посмотреть, как это выглядит на практике.

Наша топология сети будет выглядеть следующим образом:

fbebc374122e4c0b8abe5bc623bf853b.jpg

Источник и получатель потокового multicast-трафика будет реализован через VLC media player (далее VLC проигрыватель).

IGMP snooping отключён, источник multicast-трафика находится в другой сети

Начнём с того, что рассмотрим передачу multicast-трафика без использования технологии IGMP snooping. Для начала отключим IGMP snooping. Как мы помним, на оборудовании Cisco он включён по умолчанию:

cbs-sw-2960x#conf t
cbs-sw-2960x(config)#no ip igmp snooping 
cbs-sw-2960x(config)#exit
cbs-sw-2960x#
cbs-sw-2960x#sh ip igmp snooping 
Global IGMP Snooping configuration:
-------------------------------------------
IGMP snooping                : Disabled

На роутере включаем маршрутизацию multicast-трафика и запускаем протокол маршрутизации multicast-трафика PIM (Protocol Independent Multicast) в режиме dense-mode. Нам не принципиален режим. Главное, чтобы маршрутизатор запустил IGMP на нужном нам интерфейсе и обеспечил передачу через себя multicast-трафика.

На источнике включаем VLC проигрыватель в режиме передачи потокового трафика. Это и будет наш источник multicast-трафика. В качестве адреса группы будем использовать 230.255.0.1. Передавать по сети будем только аудио. В качестве передаваемой композиции выбираем Adele Rolling in the Deep. Момент важный, так как именно она лучше всего передаётся по сети (факт проверен).

Чуточку тернистый путь уже в самом начале
С проблемой маршрутизации multicast-трафика я столкнулся уже при настройке первого компьютера, который должен был стать источником. В качестве подопытных я взял несколько ноутбуков, которыми пользуются инженеры компании.

Я установил VLC проигрыватель, настроил передачу потокового аудио и… ничего не увидел в дампе Wireshark на внешнем интерфейсе данного компьютера.

Заглянув в таблицу маршрутизации, я увидел два маршрута в сеть 224.0.0.0/4 с абсолютно одинаковой метрикой 276. Причем первым в списке шёл маршрут через некий интерфейс с адресом 169.254.55.11. И только вторым шёл маршрут через нормальный интерфейс данного компьютера (172.17.16.11).

d5b66533dcd94892bdf646dbf3d9c016.png

В связи с этим все multicast-пакеты заворачивались на непонятный интерфейс. Заглянув в сетевые подключения, я обнаружил активированный интерфейс Cisco Systems VPN Adapter. Данный интерфейс появляется в системе, когда на компьютер устанавливается Cisco VPN client. Это достаточно старое решение для подключения по VPN и, видимо, его просто забыли удалить.
294184a92cbe402fbc5f6ade771798fc.jpg

Отключение данного интерфейса решило проблему.

Далее на клиенте включаем VLC проигрыватель в режиме получения потокового аудио для группы 230.255.0.1.
И снова проблемы…
Когда я перешёл к настройке получателя потокового аудио, у меня сходу не заработало. Тут я нисколечко не удивился, а сразу полез в таблицу маршрутизации. На этом компьютере симптомы были идентичные: multicast-пакеты не появлялись на проводном интерфейсе.
b385cdaa8f9f4b7fb407658d6bc4824b.png

И опять я обнаружил два маршрута в сеть 224.0.0.0/4 с абсолютно одинаковой метрикой 306. Но теперь первым был стандартный маршрут loopback интерфейса. Обычно метрика маршрута для этого интерфейса больше, метрики через другие интересы. По какой-то причине в моём случае они были равны.

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

e5ea17257c1f4b239ecabd502ebee86a.png

После того, как я установил галочку «Автоматическое изучение метрики», multicast-пакеты стали нормально уходить с данного компьютера.

В итоге на обоих компьютерах была проблема с маршрутизацией multicast-трафика, но в каждом случае источник проблемы был свой.


Сразу видим, как пошёл multicast-трафик. В нашем случае это пакеты потокового вещания, на транспортном уровне использующее протокол UDP.

b47809d77aa540ba95ded9b71542e539.png

Не забываем о TTL
Стоит заметить, что по умолчанию VLC проигрыватель устанавливает TTL для пакетов потокового вещания равным 1. Это значит, что такие пакеты не могут быть переданы в другую сеть, т.е. маршрутизироваться. Поэтому для нашего случая в настройках VLC значение TTL было выставлено больше единицы.

По дампу видно, что получатель запросил трафик (отправил сообщение IGMP Report) и маршрутизатор сразу же начал транслировать в сеть нужный multicast-трафик. Сообщений IGMP Report целых два. Видимо, второе VLC проигрыватель отправляет для верности. Одного сообщения вполне было бы достаточно.

Проверяем таблицу маршрутизации multicast-трафика на маршрутизаторе. В ней появились записи, свидетельствующие о том, откуда и куда передаётся трафик:

cbs-rtr-4000#sh ip mroute 
IP Multicast Routing Table
Flags: D - Dense, S - Sparse, B - Bidir Group, s - SSM Group, C - Connected,
       L - Local, P - Pruned, R - RP-bit set, F - Register flag,
       T - SPT-bit set, J - Join SPT, M - MSDP created entry, E - Extranet,
       X - Proxy Join Timer Running, A - Candidate for MSDP Advertisement,
       U - URD, I - Received Source Specific Host Report, 
       Z - Multicast Tunnel, z - MDT-data group sender, 
       Y - Joined MDT-data group, y - Sending to MDT-data group, 
       G - Received BGP C-Mroute, g - Sent BGP C-Mroute, 
       N - Received BGP Shared-Tree Prune, n - BGP C-Mroute suppressed, 
       Q - Received BGP S-A Route, q - Sent BGP S-A Route, 
       V - RD & Vector, v - Vector, p - PIM Joins on route, 
       x - VxLAN group
Outgoing interface flags: H - Hardware switched, A - Assert winner, p - PIM Join
 Timers: Uptime/Expires
 Interface state: Interface, Next-Hop or VCD, State/Mode

(*, 230.255.0.1), 00:29:20/stopped, RP 0.0.0.0, flags: DC
  Incoming interface: Null, RPF nbr 0.0.0.0
  Outgoing interface list:
    GigabitEthernet0/0/1.115, Forward/Dense, 00:29:20/stopped

(172.17.16.11, 230.255.0.1), 00:03:27/00:02:32, flags: T
  Incoming interface: GigabitEthernet0/0/1.116, RPF nbr 0.0.0.0
  Outgoing interface list:
    GigabitEthernet0/0/1.115, Forward/Dense, 00:03:27/stopped

Видим, что источником multicast-трафика является хост 172.17.16.11. При этом получатели находятся за интерфейсом GigabitEthernet0/0/1.115. Маршрутизатор запоминает только, куда слать трафик. Базу самих получателей он не ведёт.

Давайте посмотрим на дамп трафика на клиенте, отфильтрованный по сообщениям IGMP:

fd97259aa6934e4d9c11d4be43256854.png

  1. Нажимаем кнопку «Воспроизведение» в проигрывателе VLC и наш компьютер запрашивает получение multicast-трафика для группы 230.255.0.1, отправив сообщение IGMP Report. Как мы уже отметили, отправляет он два таких сообщения.
    Получив данное сообщение, маршрутизатор начинает трансляцию multicast-трафика (потокового аудио) в локальную сеть и на нашем клиенте мы начинаем слышать передаваемую по сети музыку.
  2. Периодически (каждые 60 секунд) маршрутизатор рассылает сообщение IGMP General Query.
  3. Наш компьютер откликается на данное сообщение, отправляя в обратную сторону IGMP Report для группы 230.255.0.1.
  4. Наживаем кнопку «Остановить» в проигрывателе VLC и наш компьютер отправляет сообщение IGMP Leave, о том, что он больше не хочет получать multicast-трафик для группы 230.255.0.1.
  5. Маршрутизатор в ответ на IGMP Leave отправляет сообщение IGMP Group-Specific Query для 230.255.0.1. Он хочет понять, есть ли в данном сегменте сети, другие получатели. Ровно через 1 секунду маршрутизатор отправляет повторное сообщение IGMP Group-Specific Query. И ещё через 1 секунду, не получив в ответ ни одного IGMP Report, прекращает передавать multicast-трафик в данный сегмент сети.
  6. Периодически маршрутизатор продолжает рассылать сообщение IGMP General Query. Но так как наш компьютер больше не заинтересован в получении чего-либо, он ничего на это не отвечает.

Так как на коммутаторе у нас выключен IGMP snooping, весь multicast-трафик рассылается (флудится) по всем портам в нашем VLAN’е, пока там есть хотя бы один получатель. Когда получателей больше не будет, маршрутизатор тут же прекратит передачу трафика в данный сегмент сети.
45e9e80cab9047729cadd67d0b9d4c1e.jpg

Дамп трафика с компьютера в том же сегменте сети, но не участвующего в получении потокового трафика:

84ab7665bb444517ad55a0487ddffbb5.png
Точно также будут обстоять дела со всеми IGMP сообщениями. Они будут рассылаться на все порты без исключения. Что является абсолютно логичным, так как во всех этих сообщениях в качестве адреса получателя используется multicast-адрес.

IGMP snooping включён, источник multicast-трафика находится в другой сети

Теперь перейдём к рассмотрению ситуации, когда на коммутаторе включен IGMP snooping.

Запускаем IGMP snooping на Cisco 2960x:

cbs-sw-2960x(config)#ip igmp snooping 
cbs-sw-2960x(config)#exit
cbs-sw-2960x#
cbs-sw-2960x#sh ip igmp snooping 
Global IGMP Snooping configuration:
-------------------------------------------
IGMP snooping                : Enabled

Для начала проверяем, удалось ли коммутатору обнаружить маршрутизатор. Как мы помним, это первый пункт в списке задач IGMP snooping:
cbs-sw-2960x#sh ip igmp snooping mrouter 
Vlan    ports
----    -----
 115    Gi1/0/19(dynamic)

Видим, что за портом Gi1/0/19 спрятался наш маршрутизатор. Как мы ранее обсуждали, коммутатор подсматривает за наличием в сети пакетов, свидетельствующих о присутствии маршрутизатора. В случае 2960x коммутатор ждёт пакеты IGMP General Query, PIM или DVMRP.
Sep 17:39:39 MSK: IGMPSN: router: PIMV2 Hello packet received in 115
Sep 17:39:39 MSK: IGMPSN: router: Is not a router port on Vlan 115, port Gi1/0/19
Sep 17:39:39 MSK: IGMPSN: router: Is not a router port on Vlan 115, port Gi1/0/19
Sep 17:39:39 MSK: IGMPQR: vlan_id 115: querier/multicast router detected on port Gi1/0/19 in Disabled state
Sep 17:39:39 MSK: IGMPSN: router: Created router port on Vlan 115, port Gi1/0/19
Sep 17:39:39 MSK: IGMPSN: mgt: Reverting flood mode to only multicast router ports for Vlan 115.
Sep 17:39:39 MSK: IGMPSN: Adding router port Gi1/0/19 to all GCEs in Vlan 115
Sep 17:39:39 MSK: IGMPSN: added rport Gi1/0/19 on Vlan 115
Sep 17:39:39 MSK: IGMPSN: router: Learning port: Gi1/0/19 as rport on Vlan 115

Коммутатор увидел сообщение PIMV2 Hello от маршрутизатора на порту Gi1/0/19 и добавил себе об этом информацию.

Снова запускаем нашу трансляцию потокового аудио и смотрим, что мы имеем на маршрутизаторе:

(*, 230.255.0.1), 00:00:12/stopped, RP 0.0.0.0, flags: DP
  Incoming interface: Null, RPF nbr 0.0.0.0
  Outgoing interface list: Null

(172.17.16.11, 230.255.0.1), 00:00:12/00:02:47, flags: PT
  Incoming interface: GigabitEthernet0/0/1.116, RPF nbr 0.0.0.0
  Outgoing interface list: Null

Появился источник трафика — 172.17.16.11. Получателей пока нет, о чём свидетельствует строка: Outgoing interface list: Null.

Запускаем клиент VLC, нажимаем кнопку «Воспроизведение» и наслаждаемся музыкой. Параллельно смотрим Wireshark, где видим, как идут multicast-пакеты потокового вещания:

f3c2f339415246b19c0fb29377a515f6.png
Теперь самое интересное. Анализируем сообщения IGMP на стыке получатель-коммутатор и коммутатор-маршрутизатор.

Пройдём по основным шагам:

1. После нажатия кнопки «Воспроизведение» в проигрывателе VLC, наш компьютер запрашивает получение multicast-трафика для группы 230.255.0.1, отправив сообщение IGMP Report.

3dd8078a91af42b0b0c1bffcf847eab1.png
Прим. Пакеты на получателе

Коммутатор, когда получил сообщение IGMP Report, заносит себе информацию, о том, что за его портом (в нашем случае — это порт GE0/0/15) есть получатель трафика для группы с MAC-адресом 01:00:5e:7f:00:01.

Замечание. Найти запись о данном MAC-адресе на коммутаторе не удастся. Он нигде не фигурирует, в том числе в стандартном выводе «show mac address-table».

2. IGMP Report попадает на маршрутизатор. Если мы заглянем в само сообщение, то увидим, что это оригинальное сообщение от нашего ПК. Коммутатор его просто переслал на порт, куда подключен маршрутизатор:

e3d3578b930245b7ad6ee2303fa8d06f.png
Прим. Пакеты на маршрутизаторе. Подчёркнутый MAC адрес принадлежит ПК

Если бы на коммутаторе уже был клиент, который получал трафик для группы 230.255.0.1, коммутатор бы просто начал трансляцию трафика через наш порт (GE0/0/15) и больше ничего не предпринимал бы. Это логично, так как у коммутатора уже был бы нужный трафик, который следовало просто завернуть на ещё один порт. Но в нашем примере, данный клиент первый.

3. Маршрутизатор начинает трансляцию потокового трафика в локальную сеть.

cd94ff54917e453788c1e0ab1e5b9d5a.png
Прим. Пакеты на маршрутизаторе

4. Коммутатор в свою очередь передаёт трафик на порт GE0/0/15, куда подключен наш ПК.

78758bc2e83347d9b13fb46fb32a233b.png
Прим. Пакеты на получателе

5. Компьютер отправляет повторный запрос на получение multicast-трафика (специфика реализации поддержки IGMP на VLC проигрывателе).

8158f2cd786f47b7bb408a8e4eb51ba6.png
Прим. Пакеты на получателе

Так как оно не очень вписывается в нормальное поведение, коммутатор данное сообщение сбрасывает. В связи с этим на маршрутизаторе мы его уже не видим.

6. Периодически маршрутизатор рассылает сообщения IGMP General Query.

7. Коммутатор транслирует их без изменений на все свои порты.

c88827c71a654676a3c1dc3211d5b8b9.png
Прим. Пакеты на получателе. Подчёркнутый MAC адрес принадлежит маршрутизатору

8. Компьютер откликается на данное сообщение, отправляя в обратную сторону IGMP Report для группы 230.255.0.1.

9. Коммутатор пересылает первое полученное сообщение IGMP Report (а в данном примере сообщение от нашего компьютера и является первым) в сторону маршрутизатора.

180fd14e2574407ba0ad21740aceda7f.png
Прим. Пакеты на маршрутизаторе. Подчёркнутый MAC адрес принадлежит получателю

Коммутатор, получив первое сообщение IGMP Report пересылает его только в сторону маршрутизатора. Другим получателям данное сообщение не передаётся, в отличии от обычной схемы работы без IGMP snooping. Т.е. механизм Report Suppression нарушается. Таким образом каждый получатель вынужден будет отправить своё сообщение IGMP Report в ответ на IGMP General Query. Получив такие сообщения, коммутатор актуализирует свою базу соответствия получателей multicast-трафика и внутренних портов.

10. Наживаем кнопку «Остановить» в проигрывателе VLC. Компьютер отправляет сообщение IGMP Leave, о том, что он больше не хочет получать multicast-трафик для группы 230.255.0.1.

690ce206817f4dcf966aa1378036945d.png
Прим. Пакеты на получателе

11. На компьютер приходит сообщение IGMP Group-Specific Query для группы 230.255.0.1. Если мы его развернём, мы увидим, что данное сообщение отправил коммутатор:

042a27c04388498aa348e354635c1f5e.png
Прим. Пакеты на получателе. Подчёркнутый MAC адрес принадлежит коммутатору. При этом IP-адрес отправителя коммутатор использовал 172.17.15.1 (это адрес маршрутизатора)

Т.е. коммутатор, получив сообщение IGMP Leave, выполняет проверку, нет ли других устройств за данным портом, желающих получать multicast-трафика для группы 230.255.0.1.

В сторону маршрутизатора коммутатор ничего не отправляет. Пока коммутатор никак не тревожит маршрутизатор, так как он ещё не уверен, что нужно что-то делать с multicast-трафиком.

12. Ровно через одну секунду коммутатор отправляет повторное сообщение IGMP Group-Specific Query.

13. И ещё через одну секунду, не получив в ответ ни одного IGMP Report, прекращает передавать multicast-трафик на данный порт.

9ebd85a62384409ebcba786ddbebcbc5.png
Прим. Пакеты на получателе. Трансляция прекратилась в 13:32:58:58

14. После того, как коммутатор понял, что за портом, где было принято сообщение IGMP Leave, больше нет получателей, он проверяет, а есть ли у него получатели за другими портами. Для этого он смотрит у себя в таблице MAC-адресов наличие записей для MAC-адреса 01:00:5e:7f:00:01 (как мы помним, это MAC-адрес группы 230.255.0.1). Если бы к данному коммутатору были подключены другие получатели, коммутатор на этом бы остановился и продолжил передавать multicast-трафик. Но в нашем случае, других получателей нет. Поэтому он отправляет маршрутизатору сообщение IGMP Leave.

d3bfa80f2a2e4c17aa882fd9be18b717.png
Прим. Пакеты на маршрутизаторе. Подчёркнутый MAC адрес принадлежит коммутатору

15. Получив сообщение IGMP Leave, маршрутизатор, начинает проверку наличия других получателей трафика. Он же не знает, что коммутатор уже сам всё проверил. Маршрутизатор отправляет сообщение IGMP Group-Specific Query для группы 230.255.0.1.

16. Это сообщение коммутатор транслирует на все свои порты. В том числе на порт, куда подключён наш компьютер. Как видно из дампа теперь данное сообщение отправлено маршрутизатором:

de5d1b4d93c9474fa5f571a1b02153aa.png
Прим. Пакеты на получателе. Подчёркнутый MAC адрес принадлежит маршрутизатору

17. Через одну секунду после отправки первого сообщения маршрутизатор отправляет повторное сообщение IGMP Group-Specific Query.

18. И ещё через одну секунду, не получив в ответ ни одного IGMP Report (что ожидаемо, так как мы уже знаем, что коммутатору до этого никто не откликнулся), маршрутизатор прекращает передавать потоковый трафик в данный сегмент локальной сети.

d3b153c81b824fd3b5272a75a145bdc4.png
Прим. Пакеты на маршрутизаторе. Трансляция прекратилась в 13:33:00:65

19. Маршрутизатор продолжает раз в минуту рассылать сообщение IGMP General Query.

20. Коммутатор в свою очередь транслирует его на все свои порты.

Итоговый дамп с устройств
Я специально отфильтровал дампы таким образом, чтобы было точно видно, в какой момент начинается трансляция трафика, а в какой завершается. Большую часть UDP пакетов я убрал для большей наглядности.

Дамп на получателе (получатель-коммутатор):

46f67fa7855a4d318bab763b092982b1.png

Дамп на маршрутизаторе (коммутатор-маршрутизатор):

cc41d2af9e7944198cf3b357cbf56896.png


Резюмируя, можно сказать следующее. Коммутатор перехватывает все сообщения IGMP от клиентов. Анализирует их. И в зависимости от ситуации пересылает эти сообщения на маршрутизатор или же удаляет. Так же коммутатор сам участвует в процессе создания IGMP сообщений. Когда последний клиент решает прекратить получать multicast-трафик, мы имеем две проверки наличия получателей. Первую выполняет коммутатор, а вторую — маршрутизатор. Во всей этой схеме маршрутизатор ведёт себя абсолютно также, как в случае, когда у нас на коммутаторе нет IGMP snooping. Т.е. маршрутизатор никак не догадывается о наличии коммутатора с включенной технологией IGMP snooping.

Давайте ещё посмотрим на дамп трафика компьютера, который не участвует в получении потокового трафика, но находится в той же локальной сети.

57061d850d40473cb98647133d9b40f6.png
Прим. Подчёркнутый MAC адрес принадлежит маршрутизатору

Из дампа видно, что данный компьютер за всё время получил только два вида сообщений и ни одного multicast-пакета потокового вещания:

  1. Сообщение IGMP Group-Specific Query, которое отправил маршрутизатор, когда в сети больше не осталось ни одного получателя multicast-трафика.
  2. Сообщение IGMP General Query, которое периодически рассылает маршрутизатор.

Таким образом, при включенном IGMP snooping коммутатор, во-первых, шлёт multicast-трафик для определённых групп только на те порты, где есть реальные получатели. Т.е. оптимизирует передачу данного типа трафика.
1f0418d3b7b441f9a08f95baf5116a23.jpg

Во-вторых, уменьшает количество IGMP сообщений в сторону маршрутизатора. Фактически маршрутизатор узнаёт только о присутствии первого и об отключении последнего получателей multicast-трафика. Подключение и отключение остальных получателей полностью регулируется коммутатором, что является логичным.

В-третьих, существенно уменьшает количество IGMP сообщений, которые попадают на все порты коммутатора, не вовлечённые в передачу multicast-трафика. Как мы помним, в случае отсутствия IGMP snooping все пакеты IGMP без исключения рассылаются на все порты.

Осталось посмотреть, что мы увидим на самом коммутаторе:

cbs-sw-2960x#sh ip igmp snooping groups
Vlan      Group                    Type        Version     Port List
-----------------------------------------------------------------------
115       230.255.0.1              igmp        v2          Gi1/0/14, Gi1/0/15, 
                                                           Gi1/0/19

Мы видим, что получатели multicast-трафика для группы 230.255.0.1 находятся за портами Gi1/0/14, Gi1/0/15 и Gi1/0/19. За портом Gi1/0/19 находится сам маршрутизатор. Коммутатор автоматически добавил порт с маршрутизатором. Для получения более детальной информации на коммутаторе можно запустить отладчик debug ip igmp snooping.

IGMP snooping включён, источник multicast-трафика находится в той же сети

И так, когда источник находится где-то в другом месте нашей сети, всё прекрасно работает. Но давайте теперь перенесём наш источник multicast-трафика в тот же сегмент сети, где находятся получатели. Ситуация вполне себе житейская. Например, мы имеем систему приёма телевизионных каналов со спутника и несколько STB-приставок. Или же используем VLC проигрыватель или, например, камеры-видео наблюдения, передающие данные сразу нескольким потребителям, находящимся в том же сегменте сети. Ещё один кейс — передача multicast-трафика между контроллером беспроводной сети и точками доступа. Как в этой ситуации отработает IGMP snooping?

Для чистоты эксперимента на маршрутизаторе отключаем PIM, так как теперь нам не нужно больше маршрутизировать multicast-трафик.

Рассматривать вариант с отключённым IGMP snooping смысла нет: весь трафик будет просто передаваться как широковещательный. Поэтому проверяем, что IGMP snooping включён, и запускаем потоковую трансляцию на нашем импровизированном сервере. На клиенте пока VLC проигрыватель не запускаем (т.е. клиент никаких IGMP сообщений не отправляет).

Видим, что на наш компьютер, выполняющий роль клиента, стал сразу же сыпаться multicast-трафик:

6db9d9cf89954130a5cad746efec4070.png

Странно, ведь IGMP snooping включен. Посмотрим, как изменится ситуация, если на клиенте запустить VLC проигрыватель и подключиться к группе 230.255.0.1 (именно её мы продолжаем использовать для трансляции нашего потокового аудио). Нажимаем кнопку «Воспроизведение», видим, как наш компьютер отправил сообщение IGMP Report, начинаем слышать музыку. Понятное дело, что multicast-трафик на компьютер приходил всё время. Просто теперь клиент VLC стал его обрабатывать:

48ccfeb9907940b1bc4a69d662beea35.png

Сообщения IGMPv3
Я думаю, Вы уже заметили, что в дампе фигурируют пакеты IGMPv3. При этом ранее мы везде видели только IGMPv2. Обусловлено это тем, что на оборудовании Cisco по умолчанию используется IGMPv2. А в ОС Windows (7, 8, 10) используется IGMPv3. Во всех предыдущих случаях на маршрутизаторе был включён IGMP и клиенты, получая периодически от маршрутизатора сообщения IGMPv2 General Query, автоматически переключились также на вторую версию протокола. В текущем сценарии на маршрутизаторе отключён IGMP, поэтому клиент использует третью версию протокола.

Теперь нужно убедиться, продолжает ли коммутатор рассылать multicast-трафик через все остальные порты. Или наконец заработал IGMP snooping и коммутатор стал слать трафик только туда, где есть клиенты. Но нет. Ничего не поменялось. На другом компьютере, который никак не участвует в нашем эксперименте, мы видим multicast-трафик (сам дамп приводить не буду, multicast-пакеты мы уже хорошо знаем в лицо). Стоит отметить, в дампе мы не обнаружим ни одного сообщения IGMP Report, которые ранее отправил наш клиент, и которые, по идее, должны были также рассылаться на все порты. Значит IGMP snooping на коммутаторе всё-таки частично работает: как минимум коммутатор перехватывает IGMP сообщения.
97e8550285f7460783b239f6a80df890.jpg

Впору заглянуть в консоль коммутатора. Информация о получателях для различных групп пуста:

cbs-sw-2960x#sh ip igmp snooping groups 
cbs-sw-2960x#

Запустив отладчик (debug), видим:
Sep 13:54:01 MSK: IGMPSN: Received IGMPv3 Report for group v3 received on Vlan 115, port Gi1/0/15
Sep 13:54:01 MSK: IGMPSN: Rx IGMPv3 Report on Gi1/0/15 when Querier is not IGMPv3, Vlan 115.

Из этих сообщений единственно, что становится ясным, — коммутатор получил сообщение IGMPv3 Report, при этом версия некого Querier не советует IGMPv3 (о Querier поговорим немного позже). А что мы получим, если переключим IGMPv3 на нашем компьютере на IGMPv2 (данная процедура делается через реестр). Вдруг заведётся.

Проверяем. Поведение коммутатора осталось таким же, но вот сообщения в отладчике поменялись:

Sep 15:07:08 MSK: IGMPSN: Received IGMPv2 Report for group 230.255.0.1 received on Vlan 115, port Gi1/0/15
Sep 15:07:08 MSK: IGMPSN: group: Received IGMPv2 report for group 230.255.0.1 received on Vlan 115, port Gi1/0/15
Sep 15:07:08 MSK: IGMPSN: router: Is not a router port on Vlan 115, port Gi1/0/15
Sep 15:07:08 MSK: IGMPSN: group: Skip client info adding - ip 172.17.15.11, port_id Gi1/0/17, on vlan 115
Sep 15:07:08 MSK: IGMPSN: No mroute detected: Drop IGMPv2 report for group 230.255.0.1 received on Vlan 115, port Gi1/0/15

Из этих сообщений становится понятно, что коммутатор игнорирует информацию в сообщениях IGMP (и более того их удаляет), так как у него нет «mroute». И тут мы начинаем вспоминать, что первым пунктом программы IGMP snooping является определение, где находится маршрутизатор. И не важно собираемся ли мы маршрутизировать multicast-трафик или нет. В предыдущем разделе мы проверяли вывод команды «show ip igmp snooping mrouter». Там был указан номер порта, куда был подключен наш маршрутизатор, рассылающий сообщения IGMP General Query. Так вот, коммутатору с IGMP snooping обязательно нужно знать, где находится маршрутизатор multicast-трафика. Порт на коммутаторе, куда будет подключен так

© Habrahabr.ru