Pull to refresh

Сети для самых матёрых. Часть двенадцатая. MPLS L2VPN

Reading time 48 min
Views 157K
Долго ли коротко ли, но шестерни в очередной раз провернулись и linkmeup встал на ступень Tier 2. И несколько достаточной платёжоспособности энтерпрайзов проявили заинтересованность в организации связи между своими филиалами через сети linkmeup.

L3VPN, который мы рассмотрели в прошлом выпуске, покрывает собой огромное количество сценариев, необходимых большинству заказчиков. Огромное, но не все. Он позволяет осуществлять связь только на сетевом уровне и только для одного протокола — IP. Как быть с данными телеметрии, например, или трафиком от базовых станций, работающих через интерфейс E1? Существуют также сервисы, которые используют Ethernet, но тоже требуют связи на канальном уровне. Опять же ЦОДы между собой любят на языке L2 общаться.

Вот и нашим клиентам вынь да положь L2.

Традиционно раньше всё было просто: L2TP, PPTP да и всё по большому счёту. Ну в GRE ещё можно было спрятать Ethernet. Для всего прочего строили отдельные сети, вели выделенные линии ценою в танк (ежемесячно).

Однако в наш век конвергентных сетей, распределённых ЦОДов и международных компаний это не выход, и на рынок выплеснулось некоторое количество масштабируемых технологий випиэнирования на канальном уровне.

Мы же в этот раз сосредоточимся на MPLS L2VPN.



Итак, сегодня в программе:
  • О технологиях L2VPN
  • VPWS
    • Data Plane
    • Control Plane
    • Практика
    • Виды VPWS

  • VPLS
    • Data Plane
    • Control Plane
    • VPLS Martini Mode (targeted LDP)
      • Практика

    • VPLS Kompella Mode (BGP)
      • Обнаружение соседей или Auto-Discovery
      • Передача префиксов
      • Распределение меток и механизм Label Block
      • Практика


  • Иерархический VPLS (H-VPLS)
    • Практика H-VPLS

  • Проблемы VPLS
  • Полезные ссылки



Технологии L2VPN


Прежде чем погрузиться в тёплый MPLS, взглянем на то, какие вообще виды L2VPN существуют.

  • VLAN/QinQ — их можно сюда отнести, поскольку основные требования VPN выполняются — организуется виртуальная L2 сеть между несколькими точками, данные в которой изолированы от других. По сути VLAN per-user организует Hub-n-Spoke VPN.
  • L2TPv2/PPTP — устаревшие и скучные вещи.
  • L2TPv3 вместе с GRE имеют проблемы с масштабированием.
  • VXLAN, EVPN — варианты для ЦОД'ов. Очень интересно, но DCI не входит в планы этого выпуска. Зато о них был отдельный подкаст (слушайте запись 25-го ноября)
  • MPLS L2VPN — это набор различных технологий, транспортом для которых выступает MPLS LSP. Именно он сейчас получил наиболее широкое распространение в сетях провайдеров.

Почему он победитель? Главная причина, безусловно, в способности маршрутизаторов, передающих MPLS-пакеты абстрагироваться от их содержимого, но при этом различать трафик разных сервисов.

Например, Е1-кадр приходит на PE, сразу же инкапсулируется в MPLS и уже никто по пути даже не заподозрит, что там внутри — важно только вовремя поменять метку.

А на другой порт приходит Ethernet-кадр и по тому же самому LSP он может пройти по сети, только с другой меткой VPN.
А кроме того MPLS TE позволяет строить каналы с учётом требований трафика к параметрам сети.

В связке же с LDP и BGP становится более просто настраивать VPN и автоматически находить соседей.

Возможность инкапсулировать трафик любого канального уровня в MPLS называется AToMAny Transport over MPLS.

Вот список поддерживаемых AToM протоколов:

  • ATM Adaptation Layer Type-5 (AAL5) over MPLS
  • ATM Cell Relay over MPLS
  • Ethernet over MPLS
  • Frame Relay over MPLS
  • PPP over MPLS
  • High-Level Data Link Control (HDLC) over MPLS



Два мира L2VPN

Для построения любого L2VPN существуют два концептуально разных подхода.

  • Point-to-Point. Применим к любым типам протоколов канального уровня и в принципе, в полной мере исчерпывает все сценарии применения L2VPN. Поддерживает все мыслимые и немыслимые протоколы. Причём некоторые из них ещё и по-разному может реализовывать.
    В основе лежит концепция PW — PseudoWire — псевдопровод.

    Вы хотите соединить два узла друг с другом. Тогда сеть провайдера для вас будет как один виртуальный кабель — то, что вошло в него на одном конце обязательно выйдет на другом без изменений.

    Общее название услуги: VPWSVirtual Private Wire Service.


  • Point-to-Multipoint. Этот режим только для Ethernet, поскольку только в нём фактически такая необходимость есть. В этом случае у клиента может быть три-пять-десять-сто точек подключения/филиалов, и все они должны передавать данные друг другу, причём, как одному конкретному филиалу, так и всем сразу. Это до боли напоминает обычный Ethernet-коммутатор, но было бы страшной банальностью об этом говорить.

    Название технологии: VPLSVirtual Private LAN Service.




Терминология

Традиционно термины будут вводиться по мере необходимости. Но о некоторых сразу.

PEProvider Edge — граничные маршрутизаторы MPLS-сети провайдера, к которым подключаются клиентские устройства (CE).
CECustomer Edge — оборудование клиента, непосредственно подключающееся к маршрутизаторам провайдера (PE).
ACAttached Circuit — интерфейс на PE для подключения клиента.
VCVirtual Circuit — виртуальное однонаправленное соединение через общую сеть, имитирующее оригинальную среду для клиента. Соединяет между собой AC-интерфейсы разных PE. Вместе они составляют цельный канал: AC→VC→AC.
PWPseudoWire — виртуальный двунаправленный канал передачи данных между двумя PE — состоит из пары однонаправленных VC. В этом и есть отличие PW от VC.





VPWS. Точка-точка


VPWSVirtual Private Wire Service.

В основе любого решения MPLS L2VPN лежит идея PW — PseudoWire — виртуальный кабель, прокинутый из одного конца сети в другой. Но для VPWS сам этот PW и является уже сервисом.

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

Ну, например, у клиента в Котельниках находится 2G-базовая станция, а контроллер — в Митино. И эта БС может подключаться только по Е1. В стародавние времена пришлось бы протянуть этот Е1 с помощью кабеля, радиорелеек и всяких конвертеров.

Сегодня же одна общая MPLS-сеть может использоваться, как для этого Е1, так и для L3VPN, Интернета, телефонии, телевидения итд.

(Кто-то скажет, что вместо MPLS для PW можно использовать L2TPv3, но кому он нужен с его масштабируемостью и отсутствием Traffic Engineering'а?)

VPWS сравнительно прост, как в части передачи трафика, так и работы служебных протоколов.

VPWS Data Plane или передача пользовательского трафика




Туннельная метка — то же, что и транспортная, просто длинное слово «транспортное» не помещалось в заголовок.

0. Между R1 и R6 уже построен транспортный LSP с помощью протокола LDP или RSVP TE. То есть R1 известна транспортная метка и выходной интерфейс к R6.

1. R1 получает от клиента CE1 некий L2 кадр на AC интерфейс (то может оказаться Ethernet, TDM, ATM итд. — не имеет значения).

2. Этот интерфейс привязан к определённому идентификатору клиента — VC ID — в некотором смысле аналогу VRF в L3VPN. R1 даёт кадру сервисную метку, которая сохранится до конца пути неизменной. VPN-метка является внутренней в стеке.

3. R1 знает точку назначения — IP-адрес удалённого PE-маршрутизатора — R6, выясняет транспортную метку и вставляет её в стек меток MPLS. Это будет внешняя — транспортная метка.

4. Пакет MPLS путешествует по сети оператора через P-маршрутизаторы. Транспортная метка меняется на новую на каждом узле, сервисная остаётся без изменений.

5. На предпоследнем маршрутизаторе снимается транспортная метка — происходит PHP. На R6 пакет приходит с одной сервисной VPN-меткой.

6. PE2, получив пакет, анализирует сервисную метку и определяет, в какой интерфейс нужно передать распакованный кадр.



Если вы читали предыдущий выпуск про L3VPN, то в вопросе передачи пользовательского трафика не увидите ничего нового — пара MPLS-меток и передача по транспортному LSP. Ingress PE проверяет какие метки поставить и в какой интерфейс отправить, P меняет транспортную метку, а Egress PE по метке VPN принимает решение, в какой AC-интерфейс передать полученный кадр.


VPWS Control Plane или работа служебных протоколов





Транспортная метка может назначаться как LDP (см. выпуск про MPLS), так и RSVP-TE (ещё ждёт своего часа).

Для примера, возьмём LDP — по всей сети запускается этот протокол, который для каждого Loopback-адреса каждого MPLS-маршрутизатора распространит по сети метки.

В нашем случае R1 после работы LDP будет, грубо говоря, знать 5 меток: как добраться до каждого из оставшихся маршрутизаторов.

Нас интересует LSP R1→R6 и обратно. Заметьте, что для того, чтобы VC перешёл в состояние UP, должны быть оба LSP — прямой и обратный.

Существует несколько разных способов реализации услуги VPWS. Об этом мы поговорим чуть ниже, а для примера разберём ту, которая наиболее часто сейчас используется.

За распространение сервисных меток отвечает тот же LDP, только генно-модифицированный — Targeted LDP. Теперь он может устанавливать соединение с удалёнными маршрутизаторами и обмениваться с ними метками.

В нашем примере к R1 и R6 подключены клиенты. R1 через LDP сообщит свою метку для этого клиента R6 и наоборот.

На обоих концах вручную мы настраиваем удалённую LDP-сессию. Она никак не привязана к VPN. То есть одна и та же сессия может использоваться для обмена метками любым количеством VPN.

Обычный LDP — это link-local протокол и ищет соседей среди непосредственно подключенных маршрутизаторов, то есть TTL его пакетов — 1. Однако tLDP достаточна IP-связность.

Как только с обеих сторон появятся AC-интерфейсы с одинаковым VC-ID, LDP поможет им сообщить друг другу метки.

В чём отличия tLDP от LDP?
LDP tTLDP
Соседями могут быть только непосредственно подключенные маршрутизаторы Соседом может быть любой маршрутизатор в сети, с которым есть IP-связность.
Поиск всех возможных соседей Соседи уже определены конфигурацией
Широковещательная рассылка сообщений Discovery Адресная отправка сообщения Discovery конкретным соседям.
В качестве FEC обычно выступает IP-адрес В качестве FEC обычно выступает VC ID

Чтобы сильно далеко не убегать, сразу же практика.

Как собрать лабу для MPLS L2VPN?


В качестве тестового стенда использована связка UnetLab + CSR1000V. И то и другое вы можете получить совершенно бесплатно и законно.
UnetLab OVA.
Cisco CSR1000V IOS-XE.
Инструкции по установке UNL и добавлению образов CSR1000V: Тыц.

Соответственно далее все команды по настройке MPLS L2VPN даны в нотации Cisco IOS-XE.

Внимание: для каждой ноды CSR1000V требуется 2,5 ГБ RAM. В противном случае образ либо не запустится, либо будут различные проблемы, вроде того, что порты не поднимаются или наблюдаются потери.


Практика VPWS


Упростим топологию до четырёх магистральных узлов. По клику можете открыть её в новой вкладке, чтобы смотреть на неё Alt+Tab'ом, а не ворочать страницу вверх-вниз.



Наша задача — прокинуть Ethernet от Linkmeup_R1 (порт Gi3) до Linkmeup_R4 (порт Gi3).

На шаге 0 IP-адресация, IGP-маршрутизация и базовый MPLS уже настроены (см. как).
Файл начальной конфигурации.

  1. Настраиваем xconnect на обоих концах на AC-интерфейсах (PE-CE), обращаем внимание, что VC-ID должен быть одинаковым.

    Linkmeup_R1(config)#interface Gi 3
    Linkmeup_R1(config-if)#xconnect 4.4.4.4 127 encapsulation mpls

    Linkmeup_R4(config)#interface Gi 3
    Linkmeup_R4(config-if)#xconnect 1.1.1.1 127 encapsulation mpls

    Команда xconect 4.4.4.4 127 encapsulation mpls заставляет LDP поднять удалённую сессию с узлом 4.4.4.4 и создаёт MPLS PW с VC ID 127. Важно, чтобы VC ID совпадали на двух противоположных AC-интерфейсах — это указатель того, что их нужно срастить.

  2. Профит.


На этом конфигурация VPWS закончена.
Файл конфигурации VPWS.

Давайте проследим, что там происходило за кулисами протоколов (дамп снят с интерфейса GE1 Linkmeup_R1). Можно выделить основные вехи:

0) IGP сошёлся, LDP определил соседей, поднял сессию и раздал транспортные метки. Как видите, Linkmeup_R4 выделил транспортную метку 19 для FEC 4.4.4.4.



1) А вот tLDP начал свою работу.

--А. Сначала мы настроили его на Linkmeup_R1 и tLDP начал периодически отправлять свой Hello на адрес 4.4.4.4



Как видите, это юникастовый IP пакет, который отправляется с адреса Loopback-интерфейса 1.1.1.1 на адрес такого же Loopback удалённого PE — 4.4.4.4.

Упакован в UDP и передаётся с одной меткой MPLS — транспортной — 19. Обратите внимание на приоритет — поле EXP — 6 — один из наивысших, поскольку это пакет служебного протокола. Подробнее мы об этом поговорим в выпуске о QoS.

Состояние PW пока в DOWN, потому что с обратной стороны ничего нет.



--Б. После того, как настроили xconnect на стороне Linkmeup_R4 — сразу Hello и установление соединения по TCP.



В этот момент установлено LDP-соседство:



--В. Пошёл обмен метками:


В самом низу можно видеть, что FEC в случае VPWS — это VC ID, который мы указали в команде xconnect — это идентификатор нашего VPN — 127.

А чуть ниже выделенная ему Linkmeup_R4 метка — 0х16 или 22 в десятичной системе.

То есть этим сообщением Linkmeup_R4 сообщил Linkmeup_R1, мол, если ты хочешь передать кадр в VPN с VCID 127, то используй сервисную метку 22.

Тут же вы можете видеть ещё кучу других сообщений Label Mapping — это LDP делится всем, что нажил — информацией про все FEC. Нас это мало интересует, ну а Lilnkmeup_R1 и подавно.

То же самое делает и Linkmeup_R1 — сообщает Linkmeup_R4 свою метку:



После этого поднимаются VC и мы можем увидеть метки и текущие статусы:





Команды show mpls l2transport vc detail и show l2vpn atom vc detail в целом идентичны для наших примеров.

2) Далее соседи будут только поддерживать контакт:



3) Теперь всё готово для передачи пользовательских данных. В этот момент мы запускаем ping. Всё предсказуемо просто: две метки, которые мы уже видели выше.



Почему-то Wireshark не разобрал внутренности MPLS, но я вам покажу, как прочитать вложение:



Два блока, выделенных, красным — это MAC-адреса. DMAC и SMAC соответственно. Жёлтый блок 0800 — поле Ethertype заголовка Ethernet — значит внутри IP.

Далее чёрный блок 01 — поле Protocol заголовка IP — это номер протокола ICMP. И два зелёных блока — SIP и DIP соответственно.

Теперь вы можете в Wireshark!

Соответственно ICMP-Reply возвращается только с меткой VPN, потому что на Linkmeup_R2 возымел место PHP и транспортная метка была снята.



Если VPWS — это просто провод, то он должен спокойно передать и кадр с меткой VLAN? Да, и нам для этого не придётся ничего перенастраивать. Вот пример кадра с меткой VLAN:



Здесь вы видите Ethertype 8100 — 802.1q и метку VLAN 0x3F, или 63 в десятичной системе.

Если мы перенесём конфигурацию xconnect на сабинтерфейс с указанием VLAN, то он будет терминировать данный VLAN и отправлять в PW кадр без заголовка 802.1q.




Виды VPWS


Рассмотренный пример — это EoMPLS (Ethernet over MPLS). Он является частью технологии PWE3, которая суть развитие VLL Martini Mode. И всё это вместе и есть VPWS. Тут главное не запутаться в определениях. Позвольте мне быть вашим проводником.

Итак, VPWS — общее название решений для L2VPN вида точка-точка.

PW — это виртуальный L2-канал, который лежит в основе любой технологии L2VPN и служит туннелем для передачи данных.

VLL (Virtual Leased Line) — это уже технология, которая позволяет инкапсулировать кадры различных протоколов канального уровня в MPLS и передавать их через сеть провайдера.
Выделяют следующие виды VLL:

VLL CCCCircuit Cross Connect. В этом случает нет метки VPN, а транспортные назначаются вручную (статический LSP) на каждом узле, включая правила swap. То есть в стеке будет всегда только одна метка, а каждый такой LSP может нести трафик только одного VC. Ни разу не встречал его в жизни. Главное его достоинство — он может обеспечить связность двух узлов, подключенных к одному PE.

VLL TCCTranslational Cross Connect. То же, что CCC, но позволяет с разных концов использовать разные протоколы канального уровня.

Работает это только с IPv4. PE при получении удаляет заголовок канального уровня, а при передаче в AC-интерфейс вставляет новый.

Интересно? Начните отсюда.

VLL SVCStatic Virtual Circuit. Транспортный LSP строится обычными механизмами (LDP или RSVP-TE), а сервисная метка VPN назначается вручную. tLDP в этом случае не нужен. Не может обеспечить локальную связность (если два узла подключены к одному PE).

Martini VLL — это примерно то, с чем мы имели дело выше. Транспортный LSP строится обычным образом, метки VPN распределяются tLDP. Красота! Не поддерживает локальную связность.

Kompella VLL — Транспортный LSP обычным образом, для распределения меток VPN — BGP (как и полагается, с RD/RT). Уау! Поддерживает локальную связность. Ну и ладно.

PWE3Pseudo Wire Emulation Edge to Edge. Строго говоря, область применения этой технология шире, чем только MPLS. Однако в современном мире в 100% случаев они работают в связке. Поэтому PWE3 можно рассматривать как аналог Martini VLL с расширенным функционалом — сигнализацией так же занимаются LDP+tLDP.

Коротко его отличия от Martini VLL можно представить так:

  • Сообщает статус PW, используя сообщение LDP Notification.
  • Поддерживает Multi-Segment PW, когда end-to-end канал состоит из нескольких более мелких кусков. В этом случае один и тот же PW может стать сегментов для нескольких каналов.
  • Поддерживает TDM-интерфейсы.
  • Предоставляет механизм согласования фрагментации.
  • Другие...

Сейчас PWE3 — стандарт де факто и именно он был в примере выше.

Я тут везде говорю об Ethernet для того, чтобы показать наиболее наглядный пример. Всё, что касается других канальных протоколов, это, пожалуйста, на самостоятельное изучение.




VPLS. Point-to-Multipoint


Мне очень нравится термин точка-многоточка. Есть в нём что-то детское, игривое. И это то, о чём мы поговорим сейчас.

VPLS — Virtual Private LAN Service. По своей сути — это коммутатор. Провайдер подключает несколько точек заказчика к своей сети в разных её концах и обеспечивает L2 связность. И теперь это задача транспортной сети провайдера — заботиться о правильной коммутации кадров, то есть изучении MAC-адресов.

Терминология

VPLS-домен — изолированная виртуальная L2-сеть, то есть, грубо говоря, один отдельный L2VPN. Два разных клиента — два разных VPLS-домена.

VSIVirtual Switching Instance. Виртуальный коммутатор в пределах одного узла.

Для каждого клиента (или сервиса) он свой. То есть трафик разных VSI не может кочевать из одного в другой.

Аналог VRF/VPN-instance в L3VPN.

В терминах Cisco это VFIVirtual Forwarding Instance. Я позволю себе вольно обращаться с терминами VPLS-домен, VSI и VFI, иногда используя их как синонимы.
VEVPLS Edge — узел PE, участник VPLS-домена.


VPLS Data Plane


В общих чертах передача пользовательского трафика выглядит, как и для случая VPWS, но добавляется шаг изучения MAC'ов и проверки MAC-таблицы при передаче трафика.

  1. На AC-порт PE-маршрутизатора пришёл пользовательский кадр.
  2. PE-маршрутизатор смотрит в заголовок Ethernet и проверяет MAC-адрес отправителя.
    А) Если он уже есть в таблице MAC-ов данного VSI, PE сразу переходит к шагу 3.
    Б) Если этого адреса ещё нет — он записывает соответствие MAC-порт в таблицу и тоже переходит к шагу 3.
  3. PE-маршрутизатор смотрит в заголовок Ethernet и проверяет MAC-адрес получателя.

    А) если таковой присутствует в таблице MAC-адресов данного VSI:
    1. PE ищет выходной интерфейс для кадра с данным MAC'ом. Это может быть физический интерфейс или PW.
    2. Если порт назначения — физический интерфейс — просто отправляет в этот порт.
      Если это PW, то добавляет соответствующую метку — сервисную. Эта метка будет неизменна до конца пути.
    3. PW — это всегда канал между двумя IP-узлами, поэтому зная IP-адрес удалённого PE, локальный PE из таблицы меток извлекает транспортную и ставит её сверху стека — она будет меняться на каждом P-маршрутизаторе.


    Б) Если же MAC-адрес неизвестен, то как порядочный коммутатор наш PE должен выполнить широковещательную рассылку кадра по всем PE данного VSI. И он делает, подлец.
    1. Локальный PE составляет список всех удалённых PE этого VSI, и, создав копии этого кадра, вставляет в них сервисные метки — каждому своя.
    2. Далее на каждую копию кадра навешивается ещё и транспортная метка (тоже своя для каждого PE).
    3. Весь этот ворох кадров рассылается по сети провайдера.
    4. Также копии широковещательного кадра отправляются в AC-интерфейсы, если такие есть, без заголовков MPLS.

  4. Удалённый PE после получения кадра и снятия меток (то есть когда уже определил VSI) тоже действует как обычный коммутатор:

    А) Если MAC-адрес источника пока не известен, вносит его в таблицу. В качестве входного интерфейса будет указан PW к Ingress PE.
    Б) Если MAC-адрес назначения ему известен, отсылает кадр в тот порт, за которым он изучен. Отсылается уже чистый Ethernet-кадр, без каких-либо заголовков MPLS.
    В) Если этот MAC не удалось найти в таблице? Широковещательная рассылка по всем AC-портам этого VSI. Заметьте, PE не будет рассылать этот кадр в PW данного VSI, потому что все другие PE уже получили копию этого кадра от входного PE. Это всё то же правило расщепления горизонта (Split Horizon), и так достигается отсутствие петель коммутации и широковещательных штормов. (Ах, если бы всё было так просто...)

Есть просто гиф, которая показывает, что происходит. А есть та же гиф, только с голосом.




Как и в обычном коммутаторе записи в MAC-таблице VSI периодически протухают и удаляются.

В вопросе изучения MAC-адресов в VPLS есть один нюанс, который резко отличает его от L3VPN. PE должен не просто знать физический порт, откуда пришёл кадр — важно определить соседа или, точнее PW как виртуальный интерфейс. Дело в том, что клиентский кадр нужно отправить не просто в какой-то физический порт, а именно в правильный PW, иными словами, правильному соседу.

Для этой цели каждому соседу выдаётся личная метка, с которой тот будет отправлять кадр этому PE в данном VPLS-домене. И в дальнейшем по VPN-метке, заглянув в LFIB, PE узнает, от какого соседа пришёл кадр.

Напомню, что L3VPN без разницы, откуда пришёл IP-пакет, поэтому для префикса в VRF всем соседям сообщается одна и та же метка.



Схема доставки пользовательского трафика незамысловата. Но что же с пресловутым Control Plane'ом? Опять придётся поломать мозги или малыми жертвами?

Извините, но дальше начинается трэш и содомия. Не сразу — попозже, но будет. Вы действуете на свой страх и риск.


VPLS Control Plane


Из работы Data Plane уже видно, что для VPLS требуется полносвязная топология PE для каждого VSI. Причём не все PE MPLS-сети провайдера будут соседями, а только те, где есть этот же VSI.

Поэтому один из главных вопросов в VPLS — обнаружение всех PE, куда подключены клиенты данного VSI. Существует здесь два подхода: ручная настройка и автоматическое обнаружение. Первый путь изначально предложила Cisco (драфт Мартини), отцом второго является Juniper (драфт Компелла).

11 выпусков СДСМ пропагандировал упрощение жизни инженера и автоматизацию всего и вся. И вот, настал тот момент, когда нужно забыть всё, чему вас учили. Это первый случай (если не поднимать холивар вокруг VTP), когда решение с ручной настройкой соседей оказывается более популярным.
Стало интересно?

Прежде чем приоткроем кулисы, хочу сделать замечание: независимо от того, что мы вытворяем с VPN-метками, транспортные LSP строятся как обычно LDP или RSVP-TE. Поэтому далее касаться транспорта мы будем только вскользь.

Точно также, независимо от используемого режима, VPLS при более детальном рассмотрении разваливается на point-to-point PW. То есть мы имеем не некое централизованное облако коммутации, а просто набор виртуальных линий между всеми соседями. Решение о передаче кадра принимает Ingress PE или, проще говоря, выбирает нужный PW.

Слово «драфт», прочно закрепившееся за этими двумя подходами, уже давно неправомерно и используется по исторической инерции. Драфтом предложение может быть только шесть месяцев.

На данный момент draft-martini переродился в RFC 4447 — Интернет-стандарт про PWE3, а драфт-Компелла устарел и умер.
Если же говорить именно о VPLS, то тут есть два стандарта:

“Virtual Private LAN Service (VPLS) Using BGP for Auto-discovery and Signaling”. RFC 4761.
“Virtual Private LAN Service (VPLS) Using Label Distribution Protocol (LDP) Signaling” RFC 4762.
Историческая справка по методам.


VPLS Martini Mode (LDP)


В начале двухтысячных индустрия усиленно занялась поисками решений для L2VPN в масштабах оператора. Критерии были следующими:

  • Простота внедрения (очевидное требование)
  • На существующем железе (протоколы не должны требовать аппаратной доработки)
  • Поддержка уже функционирующих протоколов на сетях операторов.
  • Принцип работы нового механизма не должна кардинально отличаться от существующих моделей.

Люка Мартини — бывший сотрудник Cisco — на этот необъявленный конкурс предоставил решение на основе LDP.
Работать оно будет поверх MPLS-сети.

Для сигнализации меток будет использоваться LDP, который уже является частью MPLS. VPLS Martini Mode описан в стандарте RFC4762.

Именно это лаконичное решение и стало стандартом де факто в большинстве сетей по всему миру. С тем, как работает Martini-mode мы уже познакомились в части про VPWS. Ровно то же самое и здесь, только удалённые LDP сессии создаются для каждого VSI не с одним соседом, а с несколькими.

LDP используется для распределения сервисных меток. Удалённые сессии с каждым соседом в VPLS-домене настраиваются вручную. Поскольку заранее известны все участники этого VPLS, каждому из них LDP выделяет индивидуальную метку в сообщении LDP Label Mapping Message.

Если добавляется новый PE в VPLS-домен, необходимо настроить LDP-соседство со всеми существующими PE этого VPLS. После чего с каждым из них новый PE обменятся метками.

В течение всего времени, LDP проверяет доступность своих соседей. Если какой-то из соседей выходит из группы или становится недоступным, сессия разрывается и все изученные MAC'и в PW к этому соседу очищаются.

Если состояние какого-либо из AC-портов VPLS-домена переходит в состояние Down, либо происходит другое событие, заставляющее очистить MAC-адреса с AC-порта, то PE сообщает об этом всем своим соседям, настаивая на удалении MAC-адресов в сообщении LDP MAC Withdraw (К сожалению CSR1000V на тестовом стенде этого не делает).
Известны случаи, когда в случае изменения состояния AC-порта, PE отправляет сообщение LDP MAC withdraw без уточнения, какие именно MAC'и. Это означает, что каждый сосед должен очистить всю таблицу MAC-адресов данного VPLS-домена.

Теперь представьте, что счёт идёт на сотни, возможно, тысячи записей. И по всей сети все PE начинают изучать MAC-адреса. А что они делают с кадром, когда не находят MAC получателя? Рассылают всем. Возникает кратковременный широковещательный шторм без петли коммутации.

Пока без петли. Ирония в том, что такой взрыв броадкаста можно забить каналы передач данных, особенно узкие, например, РРЛ. И тогда начнут теряться пользовательские данные. А если забьются очереди приоритетного трафика CS6-CS7, в котором передаются пакеты протоколов, то и STP может поломаться и ERPS сомкнуть кольцо — и образуется вполне себе реальная петля коммутации с нарастающим эффектом.

Если VPLS-домен не ограничен небольшим участком сети (а обычно это не так) прилечь может всё. Нет повести печальнее на свете, чем шторм в VPLS-сЕти. Пожалуйста, не делайте так.

В конце я расскажу о других неприятных ситуациях, которые могут возникнуть в VPLS сети.


Практика VPLS


Разберём работу VPLS на практике по шагам вот по этой схеме. Это всё та же сеть, но теперь клиент решил, что ему недостаточно двух точек, он хочет четыре и объединить их все в одну сеть.


Кликабельно.
Забыли о том, что у нас до этого был сервис VPWS — этой конфигурации больше нет. Файл начальной конфигурации.

Итак на шаге 0 у нас готовы необходимые транспортные LSP, а соответственно, и маршрутизация итд.

  1. Создаём VFI — Virtual Forwarding Instance

    Linkmeup_R1(config)#l2vpn vfi context Blue 
    Linkmeup_R1(config-vfi)#vpn id 63
    Linkmeup_R1(config-vfi)#member 3.3.3.3 encapsulation mpls
    Linkmeup_R1(config-vfi)#member 4.4.4.4 encapsulation mpls

    Режим по умолчанию — LDP signaling. VPN ID — аналог VCID из предыдущего примера — уникальный идентификатор VPN. Он должен совпадать на всех узлах. Следующими двумя командами мы указываем соседей, что мешают спать которые тоже являются членами этого VPLS-домена. По сути это указание LDP установить удалённую сессию с ними, после которого он начинает отправлять LDP Hello настроенным соседям.

    Аналогичные команды выполняем на Linkmeup_R3 и Linkmeup_R4...



    Linkmeup_R3
    Linkmeup_R3(config)#l2vpn vfi context Blue 
    Linkmeup_R3(config-vfi)#vpn id 63
    Linkmeup_R3(config-vfi)#member 1.1.1.1 encapsulation mpls
    Linkmeup_R3(config-vfi)#member 3.3.3.3 encapsulation mpls



    Linkmeup_R4
    Linkmeup_R4(config)#l2vpn vfi context Blue 
    Linkmeup_R4(config-vfi)#vpn id 63
    Linkmeup_R4(config-vfi)#member 1.1.1.1 encapsulation mpls
    Linkmeup_R4(config-vfi)#member 4.4.4.4 encapsulation mpls




  2. Создаём Service Instance на AC-интерфейсах.

    Linkmeup_R1(config)#interface gigabitEthernet 3
    Linkmeup_R1(config-if)#service instance 10 ethernet
    Linkmeup_R1(config-if-srv)#description Blue-A
    Linkmeup_R1(config-if-srv)#encapsulation default
    

    Linkmeup_R1(config)#interface gigabitEthernet 4
    Linkmeup_R1(config-if)#service instance 12 ethernet
    Linkmeup_R1(config-if-srv)#description Blue-C
    Linkmeup_R1(config-if-srv)#encapsulation default
    

    В режиме конфигурации интерфейса мы создаём Service Instance — это привязка интерфейса к сервисам. Каким именно — настроим позднее. Номер Service Instance произвольный — он локальнозначимый для интерфейса (как и у классического сабинтерфейса).

    encapsulation default означает, что мы хватаем все кадры без разбора (а могли бы выбирать по метке VLAN или по факту наличия двух меток — QinQ, например), то есть весь физический интерфейс привязываем к VFI.

    Хочу знать больше про Service Instance...

    Резонный вопрос от сторонников бритвы Оккамы — зачем какие-то service instance — недостаточно ли просто bridge-domain прописать?
    Мысль верная, но service-instance — это «новый» подход к концепции обработки тегированного трафика и называется он EVC — Ethernet Virtual Circuit.
    Тут мы на минуту переключимся на Ethernet-коммутаторы, чтобы понять истоки появления этой идеи.

    Традиционно метка VLAN использовалась как для разделения трафика в транках, так и для принятия решения о его коммутации в пределах устройства.
    То есть если с двух разных интерфейсов пришли два кадра с тегом 802.1q 10, то они оба попадали в один VLAN 10 на коммутаторе, соответственно оказывались в одном широковещательном домене. При этом физически нельзя было принять на устройстве больше 4094 VLAN (если не считать QinQ).
    Концепция EVC разделяет эти функции — тег 802.1q по-прежнему служит для разделения трафика в транках, однако решение о коммутации теперь на стороне Service instance.
    То есть Service-instance — это удобный способ разделить один физический интерфейс на несколько логических и в зависимости от метки VLAN и других параметров помещать пришедшие кадры в тот или иной сервис.

    Например VLAN 10 может быть назначен разным клиентам на разных портах одного коммутатора и далее прокинут через PW на другой конец сети, однако при этом нет необходимости настраивать VLAN 10 глобально на устройстве и тем самым помещать все порты с VLAN 10 в один широковещательный домен.
    То есть два кадра с тегом 10, придя на разные порты одного коммутатора сразу передадутся по xconnect и нигде не пересекутся. Таким образом понятие VLAN становится локально значимым для порта.

    При этом Service Instance может проверять не только верхний тег VLAN, но и внутренний или оба в случае QinQ или значение приоритета CoS. Можно задать также диапазон VLAN, помещаемых в данный сервис, настроить снятие, добавление или изменение тегов.
    Варианты коммутации: передать в xconnect или в bridge-domain.

    В случае маршрутизатора классический саб-интерфейс (типа GE1/1.1234) заменяется на Service instance с более широкими возможностями по выбору инкапсуляции.

    Учитывая, что до сих пор не всё понятно с этим EVC, отсылаю вас к более пространным объяснениям: на Cisco и на русском.

  3. Теперь нам нужно связать сервисы на AC-интерфейсах (service instance) с VFI. Для этого нам понадобятся bridge-domain.

    Linkmeup_R1(config)#bridge-domain 255
    Linkmeup_R1(config-bdomain)# member vfi Blue
    Linkmeup_R1(config-bdomain)# member gigabitEthernet 3 service-instance 10
    Linkmeup_R1(config-bdomain)# member gigabitEthernet 4 service-instance 12

    Цифра 255 в общем-то произвольная (0-4096). Может выбираться в соответствии с клиентским VLAN, например. Строго локальный для устройства и никуда не передаётся.

    Команда member позволяет к bridge-domain привязать различные сервисы. Первой командой подключаем VFI, двумя другими AC-интерфейсы — теперь все они в одном широковещательном домене.

    Хочу знать больше про Bridge-domain...

    Bridge-domain это что-то вроде виртуального коммутатора в пределах одного устройства. Если вы привяжете к одному brdige-domain пару физических интерфейсов, то они окажутся в одном широковещательном сегменте. Похоже на VLAN, но более гибкое. То есть, дословно переводя, это L2-мостик между двумя сущностями. В нашем случае между физическим интерфейсом и VPLS.

    Конфигурация других PE...



    Linkmeup_R3
    Linkmeup_R3(config)#interface gigabitEthernet 3
    Linkmeup_R3(config-if)#service instance 13 ethernet
    Linkmeup_R3(config-if-srv)#description Blue-D
    Linkmeup_R3(config-if-srv)#encapsulation default

    Linkmeup_R3(config)#bridge-domain 255
    Linkmeup_R3(config-bdomain)# member vfi Blue
    Linkmeup_R3(config-bdomain)# member gigabitEthernet 3 service-instance 13



    Linkmeup_R4
    Linkmeup_R4(config)#interface gigabitEthernet 3
    Linkmeup_R4(config-if)#service instance 11 ethernet
    Linkmeup_R4(config-if-srv)#description Blue-B
    Linkmeup_R4(config-if-srv)#encapsulation default

    Linkmeup_R4(config)#bridge-domain 255
    Linkmeup_R4(config-bdomain)# member vfi Blue
    Linkmeup_R4(config-bdomain)# member gigabitEthernet 3 service-instance 11


На этом настройка VPLS Martini Mode закончена.
Файл конфигурации VPLS Martini Mode.
На некотором оборудовании существует два способа настройки VPLS Martini Mode. Другой сейчас считается устаревшим, но допустимым. Вместо команды l2vpn vfi context Blue используется l2 vfi Blue. Главным образом разница заключается в том, что member меняется на neighbor, а привязка к Bridge-domain делается не в секции bridge-domain, а в собственно секции vfi или на интерфейсе в режиме настройки Service instance.

Подробнее вы можете посмотреть в альтернативном фaйле конфигурации VPLS Martini Mode.

Что произошло?

1. Сразу после этого устанавливаются соединения LDP и происходит обмен метками. Технически LDP достаточно привязки к bridge-domain — не обязательно, чтобы были AC-интерфейсы (это поведение зависит от производителя.).

Вот обмен между Linkmeup_R1 и Linkmeup_R3:



FEC 63 — номер нашего VPN. Метка выделена 0x18 (или 24).



То есть, когда Linkmeup_R3 будет отправлять кадры в этом VFI AC-интерфейсу, подключенному к Linkmeup_R1, он должен добавить VPN-метку 24. А транспортная при этом — 17.



Заметьте, что разным соседям Linkmeup_R1 выдаёт разные метки — это для того, чтобы можно было корректно изучить MAC-адреса потом.

2. Если запустить пинг с Blue-A, то в дампе (на интерфейсе Gi1 Linkmeup_R1) можно увидеть сначала ARP-запрос:




Поскольку он широковещательный, то следом за ним можно увидеть его точную копию с одной лишь разницей — метки VPN и транспортная:



Один кадр был отправлен на Linkmeup_R3, другой — на Linkmeup_R4.

3. В таблице MACов видим MAC-адрес узла Blue-A (AABB-CC00-0700) — он находится за портом GE3.EFP10 (Ethernet Flow Point и Service instance 10) — и MAC, соответствующий IP-адресу 192.168.0.2 (AABB-CC00-0300) — за интерфейсом Pseudoport Blue.100401a.



К сожалению, установить зависимость между Pseudoport и pseudowire мне так и не удалось. Как инженеру определить, с какого PW изучается MAC-адрес? Например show l2vpn vfi показывает очевидное соответствие, но эти имена никак не перекликаются.



Если кому-то удастся проследить связь между Pseudoport и pseudowire, эта статья станет чуточку полнее.

Естественно, это всё строго локально. Как и обычные коммутаторы — VPLS не сигнализирует MAC'и другим PE, а занимается их изучением исключительно в рамках Data Plane.

Ещё раз шаги настройки:

  1. Создать VFI, с одинаковым VPN ID на всех PE и настроить связность со всеми соседями.
  2. Привязать AC-интерфейсы к Service Instance.
  3. Связать VFI и Service Instance с помощью Bridge-domain.

Итак подытожим про Martini mode:

  • Для сигнализации меток VPN используется протокол LDP (метод DU).
  • Метки используются рационально — без какого-либо запаса. Это очень важный момент, поскольку ресурс меток ограничен и легко может стать узким местом.
  • Соседи на каждом узле настраиваются вручную. (Но к этому вопросу мы ещё вернёмся — всё совсем не так плохо).
  • Масштабируемость оригинального режима Martini, строго говоря, не велика — это ограничение полносвязной топологии. Но и для этой проблемы уже есть решение.




VPLS Kompella Mode (BGP)


Проблему поиска соседей решил Кирити Компелла — сотрудник Juniper. Он отталкивался от тех же критериев, но решил, что MBGP, опробованный на L3VPN, подойдёт лучше на роль протокола распределения меток.

Схема обмена маршрутной информацией, однажды расширенная до VPNv4 маршрутов, вполне может быть применена и для доставки меток VPLS. Механизм Route Target поможет с автоопределением соседей. А рут-рефлекторы решат задачу реализации полносвязной топологии, которая остро стоит в Martini Mode.

Другое название VPLS Kompella-mode — VPLS Auto-Discovery, потому что именно это является его качественным отличием от Martini. Также вы можете услышать VPLS BGP Signaling.

Control Plane выполняет здесь две основные функции:

— Обнаружение соседей
— Передача маршрутной информации и обмен метками.


Обнаружение соседей или Auto-Discovery


Ничего нового выдумывать тут не пришлось. Схема обнаружения соседей уже применённая в L3VPN прекрасно работает и здесь.

Route Target, который является Extended Community — главный признак принадлежности к определённому VSI. Грубо говоря — если RT совпадают — значит в одном VSI.

Строго говоря: Если RT полученного анонса совпадает с настроенным в VSI, значит этот VSI хочет знать информацию из анонса.

Как и в L3VPN можно гибко организовать взаимодействие между различными VSI. Но так крайне редко кто делает.

Чуть подробнее

Каждый VSI имеет свой RT.

В секции BGP для VPLS есть своя Address Family: L2VPN AFI (25) и VPLS SAFI (65)
В ней настраивается соседство с абсолютно всеми PE, которые могут участвовать в каком-либо VPLS-домене. Заметьте, здесь без привязки к конкретному VSI.

Если используются RR, то соседство поднимается только с ними.

Когда BGP хочет сообщить L2-префикс всем PE данного VSI, он высылает BGP Update всем настроенным здесь соседям, опять же независимо от того, хотят они получать данный префикс или нет. Здесь всё так же, как в L3VPN — там vpnv4-префиксы тоже рассылаются всем PE.

Когда удалённый PE получает этот BGP Update, он проверяет RT в поле NLRI и сравнивает с теми, которые настроены в его VSI.

Если совпадение найдено, PE импортирует этот префикс в нужный VSI. Если нет — отбрасывает.
Вот так и реализован Auto-Discovery.

То есть это не какая-то отдельная фаза, чтобы выявить всех участников VPLS-домена и составить их список, а просто механизм распознавания свой-чужой по отношению к анонсу.


Передача префиксов


В целом префикс L2VPN — вещь довольно искусственная — PE своим BGP Update, скорее, сообщает сам факт своего участия в VPLS-домене и метку этого факта. Но это не играет большой роли.

Какого-то адреса, тем более MAC'а, в поле NLRI сообщения BGP Update VPLS не передаёт. Помните, что изучение MAC-адресов — это полностью функция Data Plane.

Однако различать анонсы разных VSI всё равно нужно, поэтому знакомый нам Route Distinguisher тоже присутствует. Обычно он составляет автоматически из номера AS и VPN ID.

Однако что-же передаётся в NLRI? Только метка и RD? Не совсем:



Формально, префикс — это RD+порядковый номер узла в VPLS-домене+блок меток.


Распределение меток


Помните фразу "Хочешь накормить человека один раз — дай ему рыбу. Хочешь накормить его на всю жизнь — дай ему удочку"? Для выделения меток в VPLS Kompella mode используется механизм блоков меток. Один PE другому не сообщает точное значение — он даёт ему информацию для её вычисления.

Я по себе я знаю, что пытаться понять что-то пока ты не знаешь, зачем оно нужно — путь к несварению и трата лишнего времени. В конце этой главы я расскажу, зачем нужна такая странная схема, а пока вы разбираетесь, просто поверьте мне и Кирити Компелле — нужна.

Есть мнение, что видео перед текстом помогает лучше разобраться.


Если не вдаваться в конфигурацию, то выглядит это так:

  1. В каждом VSI настраивается RD и RT — их функции ровно те же самые, что в L3VPN. На CSR1000V это происходит автоматически, не требуя ручной настройки. RD позволяет разделять информацию разных VSI при передаче. RT позволяет маршрутизатору-получателю определить, в какой VSI нужно эту информацию транслировать. RD и RT позже будут передаваться в сообщении BGP Update.

  2. В секции BGP настраивается новая адрес-фэмили L2VPN VPLS, внутри которой поднимается соседство со всеми PE.
    Вообще-то нужно создать полносвязную топологию соседства. Но мы же помним, что механизм Route-Reflector'ов позволяет обойти это требований, установив соседство только с одним RR (или несколькими в случае кластера RR)?

  3. Под каждый VSI PE-маршрутизатор выделяет блок из пространства меток. И вот тут-то и начинается интересное. В BGP Update от локального PE удалённому передаётся следующая информация:

    • RD
    • RT
    • Порядковый номер узла в VPLS-домене.
    • Блок меток MPLS

      • VE ID
      • VE Block Offset
      • VE Block Size
      • Label Base

Напомню, что VEVPLS Edge — граница сети VPLS — PE-маршрутизатор на котором запущен VPLS.

Прежде чем я ударюсь во все тяжкие про формулы и значения, я считаю себя обязанным объяснить на пальцах в общем как это работает, потому что потратил кучу времени и нервов, чтобы разобраться.
Я искренне верю, что RFC является источником безусловной ясности, но порою в том же виде, в каком им является формула эквивалентности массы и энергии для Ньютона.

Когда на PE приходит L2VPN кадр со стороны MPLS сети, нужно точно знать, от какого он соседа — это нужно, чтобы изучить MAC-адрес, поэтому как и в случае с режимом Martini основная идея заключается в том, что PE каждому соседу в конкретном VSI должен сообщить уникальную метку, чтобы видеть, от кого пришёл кадр.

Вот на такой простой картинке посмотрим поподробнее:



Пусть R1 за главного.

0. В Kompella mode R1 не передаёт метку в явном виде своим соседям R2 и R3.
1. Вместо этого он им сообщает из какого диапазона нужно метки выбирать, чтобы идентифицировать данный VC.
2. У каждого РЕ есть свой порядковый номер n в VPLS-домене. Зная свой номер и диапазон меток, соседи вычисляют исходящую сервисную метку: отсчитывают n-ую по счёту с начала. То есть R2 взял вторую (2), а R3 — третью (3).
3. R2 и R3 сообщают свои номера R1, и он тоже вычисляет, какая входящая сервисная метка будет от R2, какая от R3, отсчитывая от начала диапазона 2 и 3.
4. Аналогично свои собственные диапазоны определяют R2 и R3 и сообщают их друг другу и R1. И цикл вычислений повторяется.
5. В конце концов все будут знать и исходящие метки для данного VPLS и входящие.

Теперь вторая итерация: поглубже копнём, какой матан лежит под этой простой идеей.

VE ID настраивается вручную — это идентификатор PE-маршрутизатора в домене VPLS (его порядковый номер). Должен быть уникален в пределах одного VSI.

LBLabel Base — это начало диапазона, первая метка, которая может быть использована.
VBSVE Block Size — это длина блока меток — или проще, минимальное количество меток в этом VSI. Для Cisco по умолчанию это 10. Для Juniper — 8 (может быть уменьшен до 2 или увеличен).

Вот как будет выглядеть набор меток: {LB, LB+1, .., LB+VBS-1}.

В целом, схема простая:


VE ID 100-109 взяты от балды для примера

На этой анимации показан процесс распределения меток на PE1: Если PEX хочет отправлять трафик на PE1, он должен использовать соответствующую метку X.

Вот ещё пример для PE5:



Метки выделяются по порядку — первая из блока — соседу с наименьшим VE-ID. Вторая — второму по величине итд.
То есть такая ситуация невозможна:



Однако если выделенного количества меток мало, то поможет параметр VBOVE Block Offset — смещение блока. Он позволяет создать несколько блоков. И тем соседям, кому не хватило, метки распределяются по тому же принципу, но из нового блока, с новым LB.

Необходимый VBO вычисляется по формуле: VBO = ЦЕЛОЕ(VE-ID/VBS)*VBS.

Хочется заметить, что VBO — это не про смещение меток, это про диапазон, в который попадает порядковый номер VE. Если попал в первый диапазон — берётся первый блок меток, если во второй — то второй итд.

Таким образом в случае использования нескольких блоков, набор меток будет выглядеть так же, как и прежде {LB, LB+1,… LB+VBS-1}, но LB при этом зависит от VBO. То есть у нас связка <LB, VBO, VBS>



То есть имеем строгое соответствие: узлу с VE ID (VBO+n) соответствует метка (LB+n).

Третья итерация — на реальном примере.

Возьмём клиента с десятью сайтами. VBS у нас стандартный — 10. VE-ID соответствуют номеру маршрутизатора: PE1 — 101, PE2-102,… PE 10 — 110. Рассмотрим как будут взаимодействовать PE1 и PE5.

1. PE1 выбирает в качестве Label Base 1000 — то есть 1000-1009 — это блок меток, из которого его соседи смогут взять себе по одной.

2. PE1 вычисляет VBO. VBO=ЦЕЛОЕ(101/10)*10=100.

3. PE1 передаёт собирает все данные в BGP Update всем своим соседям: LB: 1000, VBS:10, VBO:100, VE-ID:101. Ну и всякие RD, RT, которые нам сейчас не интересны. Сам PE1 пока никаких меток не считает — он ждёт Update от соседей.

4. BGP Update от PE1 достигает PE5. Его VE-ID: 105. И сейчас ему нужно вычислить исходящую метку для данного VSI (чей RT указан так же в BGP Update)в сторону PE1.

5. Первое, что делает PE5 — проверяет, а умещается ли он в блок, анонсированный PE1. Вот здесь и понадобится VBO. Должно выполниться неравенство VBO ≤ PE5 VE-ID ≤ VBO+VBS-1. И оно выполняется 100≤105≤109. Поясню. PE1 вычислил, что его ID в диапазоне 100-109 (со смещением 100 и длиной 10) — соответственно все узлы с VE ID из этого набора будут выбирать метку из первого блока.

6. Итак PE5 в пределах анонсируемого диапазона, поэтому он может идти дальше и вычислить свою исходящую метку по формуле (PE1 LB + PE5 VE-ID — VBO) = (1000 + 105 — 100) = 1005. Ещё раз вся эта арифметика, означает, что от LB нужно отсчитать столько меток, каким по счёту идёт VE-ID от VBO. Значит, PE5, чтобы отправить L2 кадр данного VSI на PE1 вставит в MPLS-заголовок VPN-метку 1005. PE1 пока не знает, про метку 1005 — ему предстоит её вычислить, как это сделал PE5. А для этого нужно узнать его VE ID.

7. Теперь PE5 тоже должен отправить BGP Update всем соседям (технически, не надо дожидаться 7 шага — такую последовательность я взял для примера. PE5 отправляет свой BGP Update как только всё было настроено).

  • а. Выбрал LB, например, 5000.
  • б. Вычислил VBO = RND(105/10)*10=100.
  • в. Скомпоновал BGP Update. LB: 5000, VBS:10, VBO:100, VE-ID: 105.
  • г. Отправил его всем PE.

8. Когда PE1 узнал VE-ID соседа (из BGP Update), он может посчитать входящую метку для данного соседа и VSI. И он делает то же самое:

  • а. Проверяет неравенство по полученным VBO И VBS: VBO ≤ PE1 VE-ID ≤ VBO+VBS. 100≤101≤109. Отлично.
  • б. Вычисляет входящую метку: (PE1 LB + PE5 VE-ID — VBO) = (1000 + 105 — 100) = 1005 — то же самое число, что посчитал и PE5 для исходящей метки. То есть когда PE1 получит кадр с меткой VPN 1005, он будет знать сразу и то, какому VPN он предназначен и от какого соседа пришёл, то есть как изучить его MAC, если необходимо.

9. Но это ещё не всё. PE1 должен теперь вычислить и исходящую метку к PE5. И все данные у него для этого имеются.

(PE5 LB + PE1 VE-ID — VBO) = (5000 + 101 — 100) = 5001. То есть PE1 при отправке кадров в этот VSI к PE5 вставит в них VPN-метку 5001.

10. PE5 вычисляет входящую: (PE5 LB + PE1 VE-ID — VBO) = (5000 + 101 — 100) = 5001.

Вот это я называю взаимовыручкой!

К сожалению, довольно очевидный и в корне своём логичный механизм я могу описать только таким сложным языком.
Если вы ещё не эволюционировали до понимания механизма Label Block, вернитесь к видео четырьмя экранами выше.

Интересна судьба PE10, которая окажет своё влияние на жизни всех других PE. Дело в том, что он не укладывается в блок 100-109 со своим VE ID 110. Его VBO будет 110=ЦЕЛОЕ(110/10)*10. А в качестве LB он выбрал 10000.

Когда PE10 пришлёт результаты своих калькуляций PE5, неравенство не выполнится: 110 ≤ 105 ≤ 119.
В этом случае запускается процесс выделения нового блока.

1. PE5 выбирает новый LB 5030, VBS уже выбран PE10 — 10.
2. Имея уже данные от PE10,

  • А. PE5 вычисляет исходящую метку к PE10: (PE10 LB + PE5 VE-ID — PE5 VBO) = 5 — 100) = 10005. Обратите внимание, что отнимается локальный VBO.
  • Б. Вычисляет входящую метку от PE10: (PE5 New LB + PE10 VE-ID — PE10 VBO) = (5030 + 110 — 110) = 5030. Используется новый LB и VBO PE10.

3. PE5 высылает PE10 новый BGP Update, анонсируя уже два префикса: первый — старый, а второй — LB: 5030, VE ID: 105, VBS:10, VBO:110.
4. VE-ID PE10 в этот раз входит в новый диапазон 110-119,

  • А. поэтому он может вычислить исходящую метку: (PE5 LB + PE10 VE-ID — PE10 VBO) = (5030 + 110 — 110) = 5030. То есть PE10 при отправке кадра этого VSI на PE5 должен вставить VPN-метку 5030.
  • Б. Может он вычислить и входящую от PE5: (PE10 LB + PE5 VE-ID — PE5 VBO) = (10000 + 105 — 100) = 10005. Здесь он использует тот VBO, в который входит PE5, а не PE10.

5. Каждый PE должен будет выделить по второму блоку меток, чтобы общаться с PE10. Вычисления продолжаются.

Скрупулёзное объяснение механизма Label Block от виновников: Juniper.

И в этот момент должно стать жутко. Во-первых мы только что потеряли 10 меток на КАЖДОМ PE (9 не использовано из второго блока и одна метка из первого — которая для самого этого PE). Во-вторых, от того, как мы назначим VE-ID, зависит, насколько рационально будут использованы метки. В-третьих, мы должны своими собственными руками настроить VE-ID и VE-range! Вот этими вот руками, которыми мы MPLS поднимали в пару команд!

Должны быть очень веские доводы, почему протокол реализован именно так, а не по аналогии с LDP или MBGP для L3VPN.

Знаете, что по этому поводу, говорит RFC 4761?
Using a distinct BGP Update message to send a demultiplexor to each
remote PE would require the originating PE to send N such messages
for N remote PEs. The solution described in this document allows a
PE to send a single (common) Update message that contains
demultiplexors for all the remote PEs, instead of N individual
messages. Doing this reduces the control plane load both on the
originating PE as well as on the BGP Route Reflectors that may be
involved in distributing this Update to other PEs.

Не очень понятно, какие там нагрузки на Control Plane.

Как это водится в СДСМ, дальше вы читаете эксклюзив. Причём на этот раз, вероятно, не только рунетовского уровня, но и вообще во всём Интернете я не нашёл адекватного пояснения, зачем эта система блоков была изобретена. Не смейтесь сильно, но я даже писал Компелле, когда ни один из окружающих меня CCIE не ответил на этот вопрос.

Всё это из-за столь желанной функции Auto-discovery (про которую уже было выше) и специфики L2, а именно изучения MAC-адресов. И всё будет понятнее в сравнении с L3VPN, где про назначения блока меток никто даже не думал.

Итак, как работает Auto-Discovery в L3VPN? Некоторый PE страждет рассказать всему миру о двух вещах — во-первых, о том, какие префиксы он знает, во-вторых о том, кому они предназначены. И он хочет рассказать об этом всем сразу без разбора — все, кто являются его MBGP соседями получат его Update, а по RT поймут, интересны ли им эти анонсы. На нет — и суда нет — отбросят. А если интересны, то в свою таблицу маршрутизации VPN занесут полученный префикс и его VPN-метку.

Всё то же самое верно и для L2VPN. За исключением одного: изучения MAC-адресов. BGP в L3VPN сообщает всем одну и ту же метку — ему совершенно без разницы, откуда потом придёт пакет с данными, главная его забота — передать его в правильный клиентский интерфейс.

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

И здесь-то и кроется дьявол. В BGP Auto-Discovery происходит в тот же момент, что и анонс префикса.

И, во-первых, совершенно не в духе BGP будет, если сначала отсылать пустой Update с целью поиска всех участников VPLS-домена, а потом отдельно то же самое, но с конкретными метками каждому из них.

И даже, если вы приемлете «во-первых» (Фуфуфу), появляется, «во-вторых». Во-вторых, анонс конкретных меток найденным соседям. Хорошо, когда нет RR, и один PE может отправить другому Update адресно. Тогда каждый PE получит только своё сообщение и только свою метку. Но реальность такова, что RR стали её (реальности) частью и, имея соседство только с RR, PE шлёт Update ему, а тот рассылает всем своим клиентам. А если PE шлёт несколько Update'ов, то все они разлетятся по всем. Получается, что каждый его сосед получит не только свою метку, но и все остальные, которые ему даром не сдались.

Просто представьте себе дамп в котором вы видите сотню Update'ов для левых устройств.

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

И знаете, пока эта концепция блока меток не сформировалась в непротиворечивый набор синапсов в моём мозге, я с пренебрежением относился к ней. Она казалась мне топорной и устаревшей. Примерно, как DVMRP. Но теперь я проникся идеей и даже несколько удивлён тому, что внятного объяснения нигде нет.

Замечу также, что ситуацию с потерянными метками несколько пересмотрели с выпуском RFC 6624 (в котором, кстати, Компелла тоже принял непосредственное участие):
Label blocks and label values are managed by the PEs. As sites get
added and removed, labels are allocated and released. The easiest
way to manage these is to use fixed-size label blocks rather than
variable-size blocks, although the signaling described here supports
either. If an implementation uses fixed-size blocks, then allocating
a label for a new site may requiring allocating a new block;
similarly, freeing a label may require freeing a block.
If the implementation requires fixed-size blocks, there is probably a
default block size, but the implementation SHOULD allow the
administrator to choose a size. Larger label block sizes mean more
potential «wasted» labels but less signaling overhead, a trade-off
that the administrator might want to control.

И более того, режим LDP-Signalling + BGP Auto-Discovery позволяет совместить достоинства обоих методов. Хотя и появляется вот этот самый двухшаговый механизм — сначала изучаем соседей, потом рассылаем метки.


Практика VPLS Kompella (BGP Signalling)


Остаёмся с той же сетью:

Предыдущая конфигурация снова очищается до начальной.
Файл начальной конфигурации.

  1. Создаём VFI, как это делали в режиме Martini:

    Linkmeup_R1(config)#l2vpn vfi context Blue 
    Linkmeup_R1(config-vfi)#vpn id 63 
    Linkmeup_R1(config-vfi)#autodiscovery bgp signaling bgp 
    Linkmeup_R1(config-vfi-autodiscovery)#ve id 101

    Этот способ позволяет настроить три типа VFI: ручной Martini с настройкой соседей. BGP Autodiscovery + BGP Signalling, либо BGP Autodiscovery + LDP Signalling. В нашем случае мы выбрали оба — BGP.

    Опционально мы можем задать количество членов VPLS-домена. В cisco по умолчанию — 10. Командой ve range Х можно увеличить от 11 до 100 (но не уменьшить). Huawei — по умолчанию 10, можно изменять (1-16000). Juniper — по умолчанию 8, можно изменять (2,4,8, 16...)

    Route Distinguisher и Route Target мы можем не настраивать — они будут назначены автоматически. Разве что вам хочется странного — объединить в один домен разные VFI.

    Далее я даю команду mpls label range 1000 1999. Она глобально задаёт диапазон динамически используемых меток. Вообще говоря этого делать не нужно, поскольку так всем приложениям MPLS (LDP, TE, BGP) мы указываем, какие метки выбирать, а я не люблю кому-то что-то указывать. Но я делаю это для более наглядной иллюстрации вычисления меток.

    Linkmeup_R1(config)#mpls label range 1000 1999
     Label range change will cause 
     5 labels in the old dynamic range [16-1048575] to go out of range

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

  2. Привязываем интерфейсы к Service Instance:

    Linkmeup_R1(config)#interface gigabitEthernet 3
    Linkmeup_R1(config-if)#service instance 10 ethernet 
    Linkmeup_R1(config-if-srv)#description Blue-A
    Linkmeup_R1(config-if-srv)#encapsulation default
    
    Linkmeup_R1(config)#interface gigabitEthernet 4
    Linkmeup_R1(config-if)#service instance 12 ethernet 
    Linkmeup_R1(config-if-srv)#description Blue-C
    Linkmeup_R1(config-if-srv)#encapsulation default 

  3. Связываем VFI и Service Instance.

    Linkmeup_R3(config)#bridge-domain 255
    Linkmeup_R1(config-bdomain)#member vfi Blue
    Linkmeup_R1(config-bdomain)#member gigabitEthernet 3 service-instance 10
    Linkmeup_R1(config-bdomain)#member gigabitEthernet 4 service-instance 12

  4. Ну что же, дело осталось за малым — BGP.

    Сначала поднимаем базовое соседство с Linkmeup_R3 и Linkmeup_R4.

    Linkmeup_R1(config)#router bgp 64500 
    Linkmeup_R1(config-router)#neighbor 3.3.3.3 remote-as 64500
    Linkmeup_R1(config-router)#neighbor 3.3.3.3 update-source Loopback 0
    Linkmeup_R1(config-router)#neighbor 4.4.4.4 remote-as 64500
    Linkmeup_R1(config-router)#neighbor 4.4.4.4 update-source Loopback 0

    Потом создаём Address-Family L2VPN VPLS и указываем соседей, которые будут участвовать в L2VPN. Заметьте, не в конкретном VFI Blue, а вообще.

    Linkmeup_R1(config-router)#address-family l2vpn vpls 
    Linkmeup_R1(config-router-af)#neighbor 3.3.3.3 activate 
    Linkmeup_R1(config-router-af)#neighbor 3.3.3.3 send-community extended 
    Linkmeup_R1(config-router-af)#neighbor 3.3.3.3 suppress-signaling-protocol ldp
    
    Linkmeup_R1(config-router-af)#neighbor 4.4.4.4 activate 
    Linkmeup_R1(config-router-af)#neighbor 4.4.4.4 send-community extended 
    Linkmeup_R1(config-router-af)#neighbor 4.4.4.4 suppress-signaling-protocol ldp

    Здесь вы должны помнить, что обычно мы используем Route Reflector'ы — не нужно настраивать всех соседей вручную, иначе смысл Auto-Discovery теряется. То есть если всего PE-устройств в сети MPLS — 100, в данном VPLS-домене — 20, а L2VPN RR — 2, то на каждом PE нужно поднять соседство только с этими двумя RR. Ну вы же не маленькие, чтобы я вам это рассказывал?

    send-community extended — как и в L3VPN включаем передачу Extended Community (RT).
    suppress-signaling-protocol ldp — и запрещаем сигнализацию LDP.

    Вот что BGP знает о VPLS, ещё даже не имея соседей:



    Верхняя строка — это RD, выбранный автоматически: AS:VPN ID. Нижняя — это префикс, который будет передаваться соседям.

    Аналогичные манипуляции производим на Linkmeup_R3 и Linkmeup_R4.

    Конфигурация всех PE



    Linkmeup_R1
    Linkmeup_R1(config)#l2vpn vfi context Blue 
    Linkmeup_R1(config-vfi)#vpn id 63 
    Linkmeup_R1(config-vfi)#autodiscovery bgp signaling bgp 
    Linkmeup_R1(config-vfi-autodiscovery)#ve id 101
      
    Linkmeup_R1(config)#mpls label range 1000 1999
    
    Linkmeup_R1(config)#bridge-domain 255
    Linkmeup_R1(config-bdomain)#member vfi Blue
    Linkmeup_R1(config-bdomain)#member gigabitEthernet 3 service-instance 10
    Linkmeup_R1(config-bdomain)#member gigabitEthernet 4 service-instance 12
    
    Linkmeup_R1(config)#interface gigabitEthernet 3
    Linkmeup_R1(config-if)# service instance 10 ethernet 
    Linkmeup_R1(config-if-srv)#description Blue-A
    Linkmeup_R1(config-if-srv)#encapsulation default 
    
    Linkmeup_R1(config)#interface gigabitEthernet 4
    Linkmeup_R1(config-if)# service instance 12 ethernet 
    Linkmeup_R1(config-if-srv)#description Blue-C
    Linkmeup_R1(config-if-srv)#encapsulation default 
    
    
    Linkmeup_R1(config)#router bgp 64500 
    Linkmeup_R1(config-router)#neighbor 3.3.3.3 remote-as 64500
    Linkmeup_R1(config-router)#neighbor 3.3.3.3 update-source Loopback 0
    Linkmeup_R1(config-router)#neighbor 4.4.4.4 remote-as 64500
    Linkmeup_R1(config-router)#neighbor 4.4.4.4 update-source Loopback 0
    
    Linkmeup_R1(config-router)#address-family l2vpn vpls 
    Linkmeup_R1(config-router-af)#neighbor 3.3.3.3 activate 
    Linkmeup_R1(config-router-af)#neighbor 3.3.3.3 send-community extended 
    Linkmeup_R1(config-router-af)#neighbor 3.3.3.3 suppress-signaling-protocol ldp       
    Linkmeup_R1(config-router-af)#neighbor 4.4.4.4 activate 
    Linkmeup_R1(config-router-af)#neighbor 4.4.4.4 send-community extended 
    Linkmeup_R1(config-router-af)#neighbor 4.4.4.4 suppress-signaling-protocol



    Linkmeup_R3
    Linkmeup_R3(config)#l2vpn vfi context Blue
    Linkmeup_R3(config-vfi)#vpn id 63
    Linkmeup_R3(config-vfi)#autodiscovery bgp signaling bgp
    Linkmeup_R3(config-vfi-autodiscovery)#ve id 103
    
    Linkmeup_R3(config)#mpls label range 3000 3999
    
    Linkmeup_R3(config)#bridge-domain 255
    Linkmeup_R3(config-bdomain)#member vfi Blue
    Linkmeup_R3(config-bdomain)#member gigabitEthernet 3 service-instance 13
    
    Linkmeup_R3(config)#interface gigabitEthernet 3
    Linkmeup_R3(config-if)#service instance 13 ethernet 
    Linkmeup_R3(config-if-srv)#description Blue-D
    Linkmeup_R3(config-if-srv)#encapsulation default 
    
    Linkmeup_R3(config)#router bgp 64500
    Linkmeup_R3(config-router)#neighbor 1.1.1.1 remote-as 64500
    Linkmeup_R3(config-router)#neighbor 1.1.1.1 update-source Loopback 0
    Linkmeup_R3(config-router)#neighbor 4.4.4.4 remote-as 64500
    Linkmeup_R3(config-router)#neighbor 4.4.4.4 update-source Loopback 0
    
    Linkmeup_R3(config-router)#address-family l2vpn vpls 
    Linkmeup_R3(config-router-af)#neighbor 1.1.1.1 activate 
    Linkmeup_R3(config-router-af)#neighbor 1.1.1.1 send-community extended 
    Linkmeup_R3(config-router-af)#neighbor ppress-signaling-protocol ldp                 
    Linkmeup_R3(config-router-af)#neighbor 4.4.4.4 activate
    Linkmeup_R3(config-router-af)#neighbor 4.4.4.4 send-community extended 
    Linkmeup_R3(config-router-af)#neighbor 4.4.4.4 suppress-signaling-protocol ldp



    Linkmeup_R4
    Linkmeup_R4(config)#l2vpn vfi context Blue
    Linkmeup_R4(config-vfi)#vpn id 63
    Linkmeup_R4(config-vfi)#autodiscovery bgp signaling bgp
    Linkmeup_R4(config-vfi-autodiscovery)#ve id 104
    
    Linkmeup_R4(config)#mpls label range 4000 4999
    
    Linkmeup_R4(config)#bridge-domain 255
    Linkmeup_R4(config-bdomain)#member vfi Blue
    Linkmeup_R4(config-bdomain)#member gigabitEthernet 3 service-instance 131
    
    Linkmeup_R4(config)#interface gigabitEthernet 3
    Linkmeup_R4(config-if)#service instance 11 ethernet 
    Linkmeup_R4(config-if-srv)#description Blue-B
    Linkmeup_R4(config-if-srv)#encapsulation default 
    
    Linkmeup_R4(config)#router bgp 64500
    Linkmeup_R4(config-router)#neighbor 1.1.1.1 remote-as 64500
    Linkmeup_R4(config-router)#neighbor 1.1.1.1 update-source Loopback 0
    Linkmeup_R4(config-router)#neighbor 3.3.3.3 remote-as 64500
    Linkmeup_R4(config-router)#neighbor 3.3.3.3 update-source Loopback 0
    
    Linkmeup_R4(config-router)#address-family l2vpn vpls 
    Linkmeup_R4(config-router-af)#neighbor 1.1.1.1 activate 
    Linkmeup_R4(config-router-af)#neighbor 1.1.1.1 send-community extended 
    Linkmeup_R4(config-router-af)#neighbor 1.1.1 suppress-signaling-protocol ldp         
    Linkmeup_R4(config-router-af)#neighbor 3.3.3.3 activate
    Linkmeup_R4(config-router-af)#neighbor 3.3.3.3 send-community extended 
    Linkmeup_R4(config-router-af)#neighbor 3.3.3 suppress-signaling-protocol ldp



    Для разных устройств я указал разные mpls label range, чтобы более наглядной была разница между локальными и удалённым метками.

На этом конфигурация MPLS Kompella Mode закончена.
Файл конфигурации VPLS Kompella Mode. Альтернативного метода, как в случае с Martini здесь нет.

Что произошло?

0. Связность между CE уже появилась



1. BGP установил сессии и разослал свои Update'ы.



А в Update нас интересует NLRI



Это Linkmeup_R1 сообщает Linkmeup_R3, как вычислить VPN-метку для трафика, предназначенного ему для VPLS с RT 65400:63. CE-ID (он же VE ID)=101, VBO=100, VBS=10, LB=1000.



Это уже Linkmeup_R3 сообщает Linkmeup_R1: CE-ID=103, VBO=100,VBS=10, LB=3000



И вот Linkmeup_R4 сообщает Linkmeup_R1: CE-ID=104, VBO=100,VBS=10, LB=4000

Linkmeup_R1 на Linkmeup_R4 передал то же, что и на Linkmeup_R3.

Давайте, не заглядывая в таблицы меток на PE, посчитаем, какие метки будут назначены?

Linkmeup_R3→Linkmeup_R1
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤103≤109.
Метка: LB + Local VE ID — VBO = 1000+103-100=1003.
Метку 1003 вставит Linkmeup_R3 в кадр, который хочет отправить на Linkmeup_R1 в этом VFI.

Linkmeup_R1→Linkmeup_R3
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤101≤109.
Метка: LB + Local VE ID — VBO = 3000+101-100=3001.
Метку 3001 вставит Linkmeup_R1 в кадр, который хочет отправить на Linkmeup_R3 в этом VFI.

Linkmeup_R1→Linkmeup_R4
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤101≤109.
Метка: LB + Local VE ID — VBO = 4000+101-100=4001.

Linkmeup_R4→Linkmeup_R1
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤104≤109.
Метка: LB + Local VE ID — VBO = 1000+104-100=1004.

Осталось вычислить пару Linkmeup_R4→Linkmeup_R3 и Linkmeup_R3→Linkmeup_R4.
Linkmeup_R4→Linkmeup_R3
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤104≤109.
Метка: LB + Local VE ID — VBO = 3000+104-100=3004.

Linkmeup_R3→Linkmeup_R4
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤103≤109.
Метка: LB + Local VE ID — VBO = 4000+103-100=4003.

2. Сверимся с ситуацией на PE.





Ну, вроде, как всё правильно. К сожалению, в реальной жизни таких красивых цифр не увидишь, там будут нагромождения тарабарщины. Но с другой стороны, и вчитываться в них вам особо не придётся — обычно, если метка выделена, то уже не принципиально, какая.

3. Соответственно, если сейчас мы отправим ping с Blue-A на Blue-D, то должны увидеть VPN-метку 3001 в ICMP-Request и 1003 в ICMP-Reply:



А в этот раз Wireshark почему-то распознал ICMP в MPLS



Вы по-прежнему можете использовать команды show mpls l2transport vc detail и show l2vpan atom vc detail для просмотра деталей:





Командой show bgp l2vpn vpls rd X ve-id Y block-offset Z вы можете вывести всю информацию о блоке меток от данного соседа.



А так посмотреть утилизацию блока меток:





Сложность и количество команд настройки выглядит больше, чем для режима Martini, но нужно помнить, что:

1) Это однократная настройка. При добавлении нового PE в VPLS-домен, настраивать нужно только его (в случае использования RR). Для Martini придётся пройтись по всем существующим PE этого VPLS-домена.
2) Конфигурация по большей части одинаковая — меняется только VE ID. Секция BGP вообще берётся копипастом (в случае использования RR).

Ещё раз повторим шаги конфигурации:

  1. Настраиваем VFI, указывая VPN ID, протоколы, VE ID.
  2. Создаём Service Instance на AC-интерфейсах.
  3. Связываем VFI и Service Instance через bridge-domain.
  4. В секции BGP поднимаем соседство с RR в Address-family L2VPN VPLS.

Теория и практика VPLS Kompella mode на примере Juniper: русским для русских. Конфигурация и примеры вычисления меток: Сама cisco.




Matini vs Kompella


В результате, какие преимущества даёт использование BGP Kompella mode перед Martini Mode?

  • Auto-Discovery. Нет необходимости на каждом PE настраивать удалённые LDP-сессии со всем участниками этого VPLS-домена. При использовании RR вопрос полной связности совсем отпадает.

  • Вместе с Auto-Discovery BGP поддерживает и обмен префиксами/метками. Это обычно ставится в плюс методу, хотя это необходимая функция. Здесь, вероятно, лучше заметить, что если у оператора уже есть инфраструктура BGP, то L2VPN сигнализацией через BGP впишется в неё органично. А вот если этот протокол до сих пор не использовался, то выглядеть он может, как пятая нога.

  • У BGP всё схвачено на предмет Inter-AS VPN. Option C позволит организовать бесшовный (seamless) MPLS между различными AS и протянуть через него тысячи PW.

Однако всё ли так очевидно? Копнём поглубже.

Междоменные (Inter-AS) VPN не такая уж большая сложность для Martini при организации иерархического VPLS — тогда нет нужды создавать полносвязную топологию PE-устройств в VPLS-домене. Про H-VPLS мы ещё поговорим позже. Можем вычеркнуть это из его слабых сторон.

Что же касается столь активно эксплуатируемого Auto-Discovery в Kompella, то тут есть два замечания:

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

Во-вторых, RFC 4762 вводит механизм Auto-Discovery в режим Martini. Реализован он может быть через RADIUS или через тот же BGP.

Например, оборудование cisco позволяет настроить режим LDP + BGP Autodiscovery командой autodiscovery LDP signaling BGP в секции l2vpn vfi. С одной стороны имеем простой и неизбыточный метод распределения меток, с другой механизм автоматического поиска соседей (правда секцию BGP придётся оставить).

Как бы то ни было у Martini теперь есть решения для задачи обнаружения соседей и ещё одно очко присуждается Гриффиндору.

Вместе с бережным отношением к меткам, простотой конфигурации и отладки, Martini Mode не только не выглядит аутсайдером, но и, вообще-то давно сыскал любовь операторов. И сегодня он занимает подавляющую долю рынка.



Ну и под занавес ещё одна оптимизация VPLS, которая делает жизнь чуточку легче.


Иерархический VPLS (H-VPLS)


Изначально VPLS — это плоская технология — все соседи одного ранга. И если в Kompella mode RR в очередной раз эффективно решают проблему полносвязной топологии, то Martini Mode в операторских сетях может вызвать кризис рабочей силы — все инженеры будут только настраивать удалённые LDP-сессии. Напомню сложность задачи O(n^2): n*(n-1)/2 — где n — число узлов.



Такая топология скрывает и ещё одну проблему — широковещательные кадры Ethernet — каждый пакет будет повторён столько раз, сколько соседей у данного PE.

А не можем ли мы здесь применить что-то вроде BGP-шных Route Reflector'ов?

Можем. Наш путь к спасению — H-VPLS (Hierarchical VPLS), который описан в RFC 4762.

H-VPLS разделяет маршрутизаторы VPLS-домена на два ранга: PE-rs и MTU-s.

PE-rsPE — routing and switching. Это ядро сети VPLS. Это большие производительные железки, которые функционируют как обычные PE. Другие названия PE-rs: PE-POP, n-PE.

MTU-sMulti-Tenant Unit — switching. Это могут быть более слабые устройства, которые подключаются к PE-rs с одной стороны. А с другой к ним подключаются CE. Другие названия MTU-s: u-PE, PE-CLE.



MTU-s обычно имеют восходящие интерфейсы к двум PE-rs — для отказоустойчивости. Но может быть и один. Механизмы подключения MTU-s к PE-rs: MPLS PW или QinQ. Поскольку мы тут про MPLS, то будем рассматривать только первый способ.

PE-rs между собой взаимодействуют как обычные PE, образуя полносвязную топологию и используют правило расщепления горизонта.

При взаимодействии PE-rs и MTU-s, PE-rs воспринимает PW от MTU-s как AC-интерфейс, то есть, как рядового клиента. А значит:

— Всё, что PE-rs получил от MTU-s он рассылает всем соседним PE-rs и всем подключенным MTU-s,
— То, что PE-rs получил от соседнего PE-rs он рассылает всем подключенным к нему MTU-s, но не отправляет другим PE-rs.

Таким образом, каждому MTU-s нужно поддерживать связь только с двумя (или одним) соседом, а количество PE-rs достаточно невелико, чтобы организовать между ними полносвязную топологию. При добавлении нового узла нужно настроить только его и вышестоящий PE-rs.

Для организации Inter-AS VPN H-VPLS тоже может сослужить службу. Например, два подключенных друг к другу ASBR могут быть PE-rs более высокого уровня иерархии.

Итак H-VPLS — это решение трёх задач:

  • Улучшение масштабируемости сети в плане Contol Plane.
  • Оптимизация Data Plane за счёт уменьшения числа копий широковещательных кадров.
  • Возможность делить VPLS-домен на сегменты и ставить на доступ более дешёвое оборудование.

Так! Стоп, а что насчёт MAC-таблицы на PE-rs? То, что в обычном VPLS было P, в H-VPLS стало PE, а соответственно, должно заниматься клиентскими данными — изучать MAC-адреса. Причём от всех MTU-s, которые к нему подключены. А вместе с тем заниматься рассылкой и репликацией клиентских кадров.

Получается, что, введя иерархию на Control Plane мы форсировали создание иерархии и на Data Plane. Справившись с одной проблемой масштабируемости, H-VPLS создал новую. Счёт MAC-адресов в этом случае может идти на тысячи и сотни тысяч, вопрос флудинга встаёт на новом уровне, нагрузка на CPU может значительно возрасти. Но решения для этой ситуации H-VPLS не предлагает.

Впрочем, удешевление устройств уровня доступа, видимо, вполне окупает этот лёгкий дискомфорт.

Ну что, попробуем настроить?


Практика H-VPLS


Мы не будем усложнять себе жизнь резервированиями и Dual-Homing'ом. Вместо этого останемся в рамках нашей же топологии, но Linkmeup_R1 станет MTU-s, а Linkmeup_R2 — PE-rs.



Снова уничтожаем всю конфигурацию.
Файл начальной конфигурации.

Технически H-VPLS может быть реализован и на базе режима Kompella, но вот такой необходимости там нет, поэтому мы отталкиваемся от режима Martini.

  1. Начнём с понятного — PE-rs. Сейчас Linkmeup_R2, Linkmeup_R3 и Linkmeup_R4 выступают в качестве PE-rs — между ними настраивается полносвязная топология в VFI.

    Linkmeup_R2(config)#l2vpn vfi context Blue
    Linkmeup_R2(config-vfi)# vpn id 63
    Linkmeup_R2(config-vfi)# member 3.3.3.3 encapsulation mpls
    Linkmeup_R2(config-vfi)# member 4.4.4.4 encapsulation mpls

    Интерфейсов на Linkmeup_R2 нет, поэтому bridge-domain не нужен.

    Конфигурация Linkmeup_R3 и Linkmeup_R4



    Linkmeup_R3
    Linkmeup_R3(config)#l2vpn vfi context Blue
    Linkmeup_R3(config-vfi)# vpn id 63
    Linkmeup_R3(config-vfi)# member 2.2.2.2 encapsulation mpls
    Linkmeup_R3(config-vfi)# member 4.4.4.4 encapsulation mpls
    
    Linkmeup_R3(config-vfi)#bridge-domain 255
    Linkmeup_R3(config-bdomain)# member vfi Blue
    Linkmeup_R3(config-bdomain)# member gigabitEthernet 3 service-instance 13
    
    Linkmeup_R3(config-bdomain)#interface GigabitEthernet3
    Linkmeup_R3(config-if)# service instance 13 ethernet
    Linkmeup_R3(config-if-srv)#  description Blue-D
    Linkmeup_R3(config-if-srv)#  encapsulation default



    Linkmeup_R4
    Linkmeup_R4(config)#l2vpn vfi context Blue
    Linkmeup_R4(config-vfi)# vpn id 63
    Linkmeup_R4(config-vfi)# member 2.2.2.2 encapsulation mpls
    Linkmeup_R4(config-vfi)# member 3.3.3.3 encapsulation mpls
    
    Linkmeup_R4(config-vfi)#bridge-domain 255
    Linkmeup_R4(config-bdomain)# member vfi Blue
    Linkmeup_R4(config-bdomain)# member gigabitEthernet 3 service-instance 11
    
    Linkmeup_R4(config-bdomain)#interface GigabitEthernet3
    Linkmeup_R4(config-if)# service instance 13 ethernet
    Linkmeup_R4(config-if-srv)#  description Blue-D
    Linkmeup_R4(config-if-srv)#  encapsulation default




  2. На Linkmeup_R1 создаём PW до Linkmeup_R2.

    Linkmeup_R1(config)#l2vpn xconnect context Blue_10
    Linkmeup_R1(config-xconnect)# member GigabitEthernet3 service-instance 10
    Linkmeup_R1(config-xconnect)# member 2.2.2.2 6310 encapsulation mpls

    Первой командой входим в режим настройки xconnect, следующими двумя связываем AC-интерфейс и VC-канал.

    ID 6310 произвольный, но должен совпадать с тем, который мы настроим на PE-rs. Здесь я выбрал 63 — как индикатор VPN ID, а 11 — порядковый номер VC на данном MTU-s.

    Настройка интерфейса остаётся прежней:

    Linkmeup_R1(config-xconnect)#interface GigabitEthernet3
    Linkmeup_R1(config-if)# service instance 10 ethernet
    Linkmeup_R1(config-if-srv)#encapsulation default

    Для интерфейса Gi4 делаем то же самое

    Linkmeup_R1(config)#l2vpn xconnect context Blue_10
    Linkmeup_R1(config-xconnect)# member GigabitEthernet4 service-instance 12
    Linkmeup_R1(config-xconnect)# member 2.2.2.2 6320 encapsulation mpls
    
    Linkmeup_R1(config-xconnect)#interface GigabitEthernet4
    Linkmeup_R1(config-if)# service instance 12 ethernet
    Linkmeup_R1(config-if-srv)#encapsulation default


  3. Осталось терминировать эти PW на стороне Linkmeup_R2:

    Linkmeup_R2(config)#bridge-domain 255
    Linkmeup_R2(config-bdomain)# member vfi Blue
    Linkmeup_R2(config-bdomain)# member 1.1.1.1 6310 encapsulation mpls
    Linkmeup_R2(config-bdomain)# member 1.1.1.1 6320 encapsulation mpls

На этом базовая настройка H-VPLS Martini Mode закончена.
Файл конфигурации H-VPLS



Что произошло? PW поднялись:



VFI на Linkmeup_R2 про них знает:



MAC'и отлично изучает:



С H-VPLS появляется ряд вопросов, которые уже за рамками этой статьи:

  1. Резервирование. Dual-Homing MTU-s к двум PE-rs. Очень распространённый дизайн.
  2. H-VPLS с QinQ на доступе, вместо MPLS PW.
  3. Технологии защиты от петель и проброс STP BPDU через сеть VPLS.

Немного приоткроют завесу над этими вопросами следующие два документа: H-VPLS PE-rs Redundancy for QinQ Access и Настройка VPLS Multihoming на маршрутизаторах Juniper tutorial.



А теперь пара историй о коварстве L2 c механизмом широковещательных рассылок.

Случай А


В общем-то даже не случай — а то, как обычно это всё работает.

Большой клиент, много трафика. И вот случается что-то страшное, и таблица MAC-адресов очищается. И сотни дурнопахнущих мегабит устремляются во все концы VPLS-домена. И на линиях, где раньше проходил только трафик данного филиала этого клиента, теперь летит всё-всё-всё.

Коварство этой ситуации заключается в том, что это кратковременные всплески, которые мгновенно забивают очереди QoS, вызывая потери, невзирая на ширину канала. И вы даже не увидите эти всплески в статистике интерфейса, потому что оборудование просто не успело их зафиксировать.

Случай Б


Вообще-то он уже был описан раньше, да и похож немного на Случай А. В этот раз просто дам больше деталей. Вот такая сеть:



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

Но, случается что-то страшное и таблица MAC-адресов очищается. И весь трафик этого VSI, для которого не изучен в данный момент MAC-адрес назначения, будет широковещаться. И если, например, общий трафик этого клиента составлял 400 Мб/с, то это 400 Мб/с флуда по всей сети, которая упрётся в 100 Мб/с арендованного канала. После чего последуют кратковременные потери трафика на время переизучения MAC-ов. А для больших сетей это может занять несколько минут.

Случай В


Расширим случай Б. Теперь у нас на доступе не один клиент, а кольцо коммутаторов. И одна линия между ними выполнена в виде РРЛ-пролёта. Ситуация не такая редкая, учитывая масштабы расстояний в нашей необъятной, а, скорее, даже типичная.


В целом, происходит всё то же, что и в случае Б, но при этом у нас здесь есть ещё какое-то решение по защите от петель: STP или какой-то проприетарный протокол. Суть их одна — заблокировать лишний порт. А если что-то не так со связностью, о которой они судят по наличию и отсутствию сообщений, разблокировать.

Теперь следующий шаг наших размышлений — флуд, который заваливает узкие линии и ведёт к потерям пакетов. Если в этом трафике большое количество высокоприоритетных пакетов CS6/CS7, то теряться будут и кадры протоколов. И тогда начинается цирк — протокол восстанавливает линк, потому что думает, что топологии хана, и что происходит? В открытый порт устремляется 100 Мб/с трафика, который усугубляет ситуацию.

Это всё может дальше и по нарастающей пойти, цепляя за собой всё большие и большие участки сети.

Случай Г


Буква эта даже немного говорящая. Потому что такой случай не может произойти просто так. Вот такая сеть.



Дизайн в данном случае предполагает, что между двумя PE прокинут дополнительный PW для сигнализации протокола защиты от петель (как и в случае В). Точнее их два — один через прямой линк, другой окольный через MPLS-сеть.

То есть мы получаем физическое кольцо коммутаторов, разделённое одним заблокированным портом.
Да, автор знает, что так сети не строят. Да, автор знает о последствиях. Нет, автор, не принимал участия в разработке дизайна.

И ещё одна деталь — в разных кольцах есть точки подключения одного и того же клиента, соответственно, в них направлен один и тот же VSI.

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

Итак, когда обрывают сразу два конца одного кольца, PE оказывается изолированным, соответственно все его PW переходят в состояние Down, в том числе и служебный для протокола защиты от петель. Протокол думает, что кольца сейчас разомкнуты (а они действительно разомкнуты) и восстанавливает заблокированный интерфейс в обоих кольцах. Чувствуете уже засаду? у нас есть две цепочки коммутаторов, которые кончаются на двух PE и подключены к интерфейсам, привязанным к одному и тому же VSI. Два разомкнутых физических кольца срастаются в одно замкнутое логическое кольцо. И если один PE изолирован и не может навредить остальной части сети, то второй вполне себе в бою и начинает злостно рассылать широковещательный трафик.



Случай Д


Имеется сеть VPLS с двумя центральными PE. Например, это сеть DCI. ДЦ1 подключен к двум PE — так называемый Dual-Homing — режиме Active/Active — то есть оба плеча могут принимать и передавать трафик. При этом коммутация внутри не происходит — поэтому петля исключена.


Всё прекрасно, пока трафик в обоих направлениях ходит через одно и то же плечо. Интересное начинается в случае ассиметричного пути. Например, трафик к ДЦ1 приходит по левому плечу, а уходит по правому.

В целом, нормальная ситуация. Но не для L2. PE1 будет изучать MAC-адреса других ДЦ — весь такой молодец, но трафик от ДЦ1 будет приходить на PE2, который ни сном ни духом про MAC-адреса. Соответственно, он будет полученный трафик широковещать и привет ситуации А-В.



Да, часть этих проблем — это непродуманный дизайн. Да, есть те или иные «решения», которые позволяют уменьшить вероятность и серьёзность проблем, но Ethernet — как вода — просочится везде. И главная проблема — в механизме широковещательных рассылок — это ахилесова пята по всём остальном прекрасного протокола, который завоевал мир.

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

Однако это данность, от которой никуда не деться. И если мы не можем убрать корень проблемы в виде механизма широковещательной рассылки в Ethernet, то можно придумать способ с ней бороться.

О нём мы и поговорим в следующий раз — EVPN. Революционное решение, которое переносит функцию изучения MAC-адресов на Control Plane и привлекает для этого BGP.




Полезные ссылки


Аккумулирую все материалы, использовавшиеся в статье в одном месте. Аккуратно: высокая концентрация знаний.

  • Весело задорно про MPLS вообще: Тыц.
  • Коротко о мирном AToM'е: Тыц.
  • Описание работы Компелла:Тыц.
  • Juniper о том, как работает механизм Label Block: Тыц и Мыц.
  • Конфигурация VPLS BGP на Cisco и примеры вычисления меток: Тыц.
  • Про Мартини от Мартини: Тыц.
  • Скрупулёзное сравнение двух методов: Тыц.
  • Историческая справка по методам: Тыц.
  • Простыми английскими словами про H-VPLS: Тыц.
  • H-VPLS от циски, как всегда сложно: Тыц.
  • H-VPLS Multihoming и STP по-русски: Тыц.
  • Внеклассное чтение — EVPN: Тыц.

Концептуальные вещи

Luc De Ghein. MPLS Fundamentals 1st Edition. Ina Minei, Julian Lucek. MPLS-Enabled Applications: Emerging Developments and New Technologies 3rd Edition.

Также напоминаю, что список лучших книг по сетям сейчас тут.

Все аббревиатуры, использованные в статье, вы можете найти в глоссарии linkmeup.

Благодарности

» Дмитрию Фиголю, Александру Клипперу и Дмитрию JDima за вычитку материала и комментарии.
» Антону Клочкову за организацию лабы.
» Дарье Кормановой за иллюстрации.
» Моей жене и детям, что отпустили меня в командировку, где я и сделал всё это.

Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
+47
Comments 20
Comments Comments 20

Articles