Протокол PIM — это набор протоколов для передачи мультикаста в сети между маршрутизаторами. Отношения соседства строится аналогично как и в случае динамических протоколов маршрутизации. PIMv2 отправляет каждые 30 секунд Hello сообщения на зарезервированный мультикаст адрес 224.0.0.13 ( All-PIM-Routers ).
Сообщение содержит в себе Hold Timers — обычно равен 3.5*Hello Timer, то есть 105 секунд по умолчанию.
PIM использует два основных режима работы — Dense и Sparse mode. Начнем c Dense mode.
Source-Based Distribution Trees.
Dense-mode режим целесообразно использовать в случае большого количества клиентов различных мультикаст групп. Когда маршрутизатор получает мулькаст трафик, то первым делом он проверяет его на правило RPF. RPF — данное правило используется для проверки источника мультикаста с юникастовой таблицей маршрутизации. Необходимо, чтоб трафик приходил на тот интерфейс, за которым скрывается данный хост по версии юникастовой таблицы маршрутизации. Этот механизм решает проблему возникновения петли при передаче мультикаста.
R3 из мультикаст сообщения узнает источник мультикаста ( Source IP ) и проверит два потока от R1 и R2 по своей юникастовой таблице. Поток с того интерфейса, на который указывает таблица ( R1 к R3 ), будет передан дальше, а поток от R2 будет дропнут, так как, чтоб добраться до источника мультикаста, надо отправлять пакеты по S0/1.
Вопрос, что будет если у вас два эквивалентных маршрута с одинаковой метрикой? В этом случае маршрутизатор будет выбирать по next-hop у данных маршрутов. У кого выше ip адрес, тот и победил. Если необходимо изменить данное поведение, то можно использовать ECMP. Подробнее тут.
После проверки правила RPF, маршрутизатор отправляет мультикаст пакет всем своим PIM соседям, за исключением того, от кого был получен данный пакет. Остальные PIM маршрутизаторы повторяют данный процесс. Путь, который прошел мультикаст пакет от источника до конечных получателей, образует дерево, которое называется — source-based distribution tree, shortest-path tree (SPT), source tree. Три разных названия, выбирайте любое.
Как решить вопрос с тем, что некоторым маршрутизаторам не сдался какой-то мультикастовый поток и отправлять его некому, а ему вышестоящий маршрутизатор шлет. Для это придуман Prune механизм.
Prune Message.
Например, R2 будет продолжать слать R3 мультикаст, хотя R3 по правилу RPF дропает его. Зачем нагружать канал? R3 шлет PIM Prune Message и R2, при получении данного сообщения, удалит интерфейс S0/1 из списка ( outgoing interface list ) для данного потока, список интерфейсов, с которых надо посылать данный трафик.
The following is a more formal definition of a PIM Prune message:
The PIM Prune message is sent by one router to a second router to cause the second router to remove the link on which the Prune is received from a particular (S,G) SPT.
После получения Prune сообщения, R2 выставляет Prune таймер в 3 минуты. Через три минуты он начнет отправлять трафик опять, пока не получит очередное Prune сообщение. Это в PIMv1.
А в pimv2 добавлен State Refresh таймер ( по умолчанию 60 секунд ). Как только было отправлено Prune сообщение с R3, запускается данный таймер на R3. По истечении данного таймера, R3 будет отправлять State Refresh сообщение, которое будет сбрасывать 3-ех минутный Prune Timer на R2 для данной группы.
Причины отправки сообщения Prune:
- Когда мультикаст пакет не прошел проверку RPF.
- Когда нет локально подключенных клиентов, который запросил мультикастовую группу ( IGMP Join) и нет PIM соседей, которым можно отправлять мультикастовый трафик ( Non-prune Interface).
Graft Message.
Представим, что R3 не захотел трафик от R2, отправил Prune и получал мультикаст от R1. Но вдруг, упал канал между R1-R3 и R3 остался без мультикаста. Можно ждать 3 минуты, пока на R2 не истечет Prune Timer. 3 минуты ждать долго, чтоб не ждать, необходимо послать сообщение, которое моментально выведет данный интерфейс S0/1 на R2 из pruned состояния. Таким сообщением будет Graft сообщение. После получения Graft сообщения, R2 отправит в ответ Graft-ACK.
Prune Override.
Посмотрим на данную схему. R1 вещает мультикаст в сегмент с двумя маршрутизаторами. R3 получает и вещает трафик, R2 получает, но вещать трафик ему некому. Он отправляет Prune сообщение к R1 в данный сегмент. R1 должен удалить Fa0/0 из списка и перестать вещать в данный сегмент, но что будет c R3? А R3 находится в том же сегменте, тоже получил данное Prune сообщение и понял всю трагичность ситуации. Перед тем как R1 перестанет вещать, он устанавливает таймер в 3 секунды и перестанет вещать через 3 секунды. 3 секунды — именно столько времени у R3, чтоб не потерять свой мультикаст. Поэтому R3, как можно скорее, отправляет Pim Join сообщение для данной группы и R1 уже не думает переставать вещать. О Join сообщениях ниже.
Assert Message.
Представим такую ситуацию: в одну сеть вещают сразу два маршрутизатора. Получают один и тот же поток от источника, и оба вещают его в одну сеть за интерфейсом e0. Поэтому им надо определить кто же будет одним единственным вещателем для данной сети. Для этого используются сообщения Assert. Когда R2 и R3 детектируют дупликацию мультикаст трафика, то есть на R2 и R3 приходит мультикаст, который они сами вещают, маршрутизаторы понимают, что тут что-то не так. Маршрутизаторы отправляют в этом случае Assert сообщения, в которые включены Administrative Distance и метрика маршрута при помощи которого достигается источник мультикаста — 10.1.1.10. Победитель определяется так:
- Тот у кого ниже AD.
- Если AD равны, то у кого ниже метрика.
- Если и тут равенство, то тот у кого выше IP в сети, в которую они вещают этот мультикаст.
Победивший в этом голосовании, маршрутизатор становится Designated Router-ом. Для выбора DR также используются Pim Hello. В начале статьи было показано PIM Hello сообщение, там можно заметить DR поле. Побеждает тот, у кого выше IP адреса на этом линке.
Полезная табличка:
MROUTE Table.
После первоначального рассмотрения работы протокола PIM, нам необходимо разобраться с тем, как работать с мультикастовой таблицей маршрутизации. В таблице mroute храниться информация о том, какие потоки были запрошены со стороны клиентов и какие потоки льются с мультикаст серверов.
Например, при получения IGMP Membership Report или PIM Join на каком-то интерфейсе, в таблицу маршрутизации добавляется запись типа ( *, G ):
Данная запись означает, что был получен запрос на трафик с адресом 238.38.38.38. Флаг DC означает, что мультикаст будет работать в режиме Dense mode и С означает, что получатель непосредственно подключен к маршрутизатору, то есть маршрутизатор получил IGMP Membership Report, а PIM Join.
Если есть запись типа (S,G) означает, что у нас есть мультикаст поток:
В поле S — 192.168.1.11, у нас прописан IP адрес источника мультикаста, именно он будет проверяться правилом RPF. При проблемах, первым делом необходимо проверить юникастовую таблицу на маршрут к источнику. В поле Incoming Interface указывает интерфейс, на который поступает мультикаст. В юникастовой таблице маршрутизации, маршрут до источника должен ссылаться на интерфейс, указанный здесь. В Outgoing Interface указывается куда будет мультикаст перенаправлен. Если он пуст, значит к маршрутизатору не поступало запросов на данный трафик. Более подробную информацию о всех флагах можно найти здесь.
PIM Sparse-mode.
Стратегия Sparse-mode противоположна Dense-mode. Когда Sparse-mode получает мультикаст трафик, он будет отправлять трафик только через те интерфейсы, где были запросы на данный поток, например Pim Join или IGMP Report сообщения с запросом на данный трафик.
Cхожие элементы у SM и DM:
- Отношения соседства строятся также, как и в PIM DM.
- Работает правило RPF.
- Выбор DR аналогичен.
- Механизм Prune Overrides и сообщения Assert аналогичены.
Для контроля того, кому, где и какой мультикаст трафик нужен в сети, необходимо общий информационный центр. Таким центром у нас будет Rendezvous Point ( RP ). Все, кто хочет какой-то мультикаст трафик или кто-то начал получать мультикаст трафик от источника, то он отправляет его на RP.
Когда RP получит мультикаст трафик, то отправит его тем маршрутизаторам, которые запросили до этого этот трафик.
Представим такую топологию, где RP это R3. Как только R1 получит трафик от S1, то он инкапсулирует данный мультикаст пакет в юникастовое PIM Register сообщение и отправит его на RP. Откуда он знает кто RP? В данном случае, он настроен статически, а о динамической настройке RP поговорим позже.
ip pim rp-address 3.3.3.3
RP посмотрит — а была ли информация от кого-то, кто хотел бы получать этот трафик? Предположим, что не было. Тогда RP отправит R1 сообщение PIM Register-Stop, что означает — никому не нужен этот мультикаст, в регистрации отказано. R1 не будет посылать мультикаст. Но хост-источник мультикаста будет слать его, так что R1 после получения Register-Stop, запустит таймер Register-Suppression timer, равный 60 секундам. За 5 секунд до истечения данного таймера, R1 будет посылать пустое Register сообщение с Null-Register bit ( то есть без инкапсулированного мультикаст пакета) в сторону RP. RP в свою очередь будет действовать так:
- Если получателей как не было, так и нет, то он будет отвечать Register-Stop сообщением.
- Если получатели появились, то он никак не ответит на него. R1 не получив на свою регистрацию отказа в течении 5 секунд, обрадуется и отправит Register сообщение с инкапсулированным мультикаст на RP.
Как мультикаст доходит до RP вроде бы разобрались, теперь попытаемся ответить на вопрос как RP доводит трафик до получателей. Здесь необходимо ввести новое понятие — root-path tree (RPT). RPT — это дерево с корнем в RP, растущее в сторону получателей, разветвляющиеся на каждом PIM-SM маршрутизаторе. RP создает его, получая PIM Join сообщения и добавляет в дерево новую ветвь. И так, делает каждый нижестоящий маршрутизатор. Общее правило выглядит так:
- Когда PIM-SM маршрутизатор получает PIM Join сообщение на каком-либо интерфейсе, за исключением интерфейса за котором скрывается RP, он добавляет в дерево новую ветвь.
- Также ветвь добавляется, когда PIM-SM маршрутизатор получает IGMP Membership Report с непосредственно подключенного хоста.
Представим, что у нас появился клиент мультикаста на маршрутизаторе R5 на группу 228.8.8.8. Как только R5 получит IGMP Membership Report от хоста, R5 отправляет PIM Join в направлении RP, а сам добавляет в дерево интерфейс, смотрящий на хост. Далее, R4 получает PIM Join от R5, добавляет в дерево интерфейс Gi0/1 и отправляет PIM Join в направлении RP. Наконец то, RP ( R3 ) получает PIM Join и добавляет Gi0/0 в дерево. Таким образом, получается регистрация получателя мультикаста. У нас строится дерево с корнем R3-Gi0/0 → R4-Gi0/1 → R5-Gi0/0.
После этого, будет отправлен PIM Join к R1 и R1 начнет слать мультикаст трафик. Важно заметить, что если хост запросил трафик до того, как началось вещание мультикаста, то RP не будет отправлять PIM Join и вообще не будет ничего отправлять в строну R1.
Если вдруг пока отправляется мультикаст, хост перестанет хотеть его получать, как только RP получит PIM Prune на интерфейс Gi0/0, то сразу отправит PIM Register-Stop непосредственно на R1, а затем и PIM Prune сообщение через интерфейс Gi0/1. PIM Register-stop отправляется юникастом на тот адрес, с которого поступило PIM Register.