5. Настройка передачи IP-префиксов в EVPN-сети (RT-5)

Что же делать, если мы хотим передать в нашу overlay-сеть некие внешние маршруты, не привязанные к какому-то конкретному узлу? Маршруты RT-2 здесь не подойдут. Как помним, маршруты RT-2 жестко привязаны к наличию MAC-адреса и к хост-маске /32 или /128. То есть мы не можем передать в маршруте RT-2 подсеть с произвольной маской. Вроде бы, проблема неразрешима? Именно поэтому был написан еще один RFC - 9136, в котором был описан новый вид EVPN-маршрута - IP Prefix Advertisment, тип маршрута 5.

В чем его "фишка"? Он отвязывается от MAC-адреса, а также снимает ограничение на длину маски, передаваемую в NLRI. Таким образом в RT-5 мы можем передавать, например, маршрут по умолчанию, или маршруты до каких-нибудь внешних подсетей, или даже внутренних подсетей, которые обслуживают наши клиентские домены.

Можно задаться вопросом, а зачем нам передавать маршруты внутренних подсетей, если всё равно MAC/IP-информацию о конечных узлах мы получаем из маршрутов RT-2? А вот зачем.

Посмотрите на иллюстрацию:

Тихий узел

Представим, что "тихий узел" потихоньку сидит себе в сети, и не отправляет никаких данных. Допустим, это какой-то сервер, типа syslog, который ждет обращений к нему со стороны клиентов. Если сервер не отправляет ничего в сеть, то и VTEP2 не знает о его присутствии в сети, следовательно не генерирует маршрут RT-2, а следовательн VTEP1 не имеет никакой информации о сети 192.168.200.0/24 в своей таблице маршрутизации, и не знает ничего о хосте 192.168.200.20.

Если при этом пользователь хочет обратиться к серверу, то он отправит пакет на VTEP1 (на свой шлюз по умолчанию). VTEP1 видит, что пакет адресован не ему, заглянет в свою таблицу маршрутизации, чтобы понять, куда отправить пакет дальше, и подходящего маршрута не найдет! Следовательно VTEP1 ответит пользователю: "у меня нет маршрута к узлу назначению, извини". Таким образом, связности не будет, пока сервер за VTEP2 каким-то образом не даст о себе знать.

И вот тут-то нам и поможет маршрут RT-5! Если VTEP2 начнет анонсировать маршрут до подсети 192.168.200.0/24, то VTEP1 будет иметь маршрут в сеть назнчения, даже если сервер никак о себе не заявляет. В таком случае, ситуация развернется следующим образом:

Анонсируемая подсеть VNI 1200

Пользователь отправляет ICMP-пинг на VTEP1 (свой шлюз), VTEP1 смотрит в таблицу маршрутизации и видит маршрут до сети назначения (192.168.200.0/24), под которую подпадает IP-адрес 192.168.200.20. Таким образом, пакет будет отправлен на VTEP2. VTEP2 увидит, что IP назначения принадлежит сети, которая напрямую к нему подключена посредством интерфейса vlan 200, и со спокойной совестью сгенерирует и отправит в порты, принадлежащие VLAN 200, ARP-запрос, чтобы узнать MAC-адрес "тихого узла", на который последний с радостью ответит. А вот когда он ответит, тут-то VTEP2 и анонсирует RT2 маршрут для "тихого" сервера :). Хотя, технически, он и не нужен - нам для маршрутизации вполне достаточно маршрута RT-5. Тем не менее, теперь мы без проблем сможем связаться с "застенчивым" узлом в удаленной подсети :).

Еще один момент. В структуре NLRI RT-5 (если посмотреть ее Wireshark'ом) можно увидеть такое поле, как Gateway IP. Также в некоторой вендорской документации (например, Juniper), можно встретить разделение маршрутов RT-5 на два типа: "Pure RT-5 route" и "Standard RT-5 route". Отличаются они тем, что в первом случае поле Gateway IP не заполнено (значение равно 0), а во втором случае заполнено неким IP-адресом. Зачем же оно нужно, если в EVPN вместо в качестве next-hop используется VTEP IP (и Router's MAC в качестве вспомогательного средства)? За деталями (весьма зубодробительными) добро пожаловать в RFC 9136, но, вкратце, можно сказать, что в поле Gateway IP едет IP-адрес некст-хопа некоего хоста внутри overlay-сети, который обеспечивает доступ в сеть, префикс которой и переносится данным RT-5 маршрутом.

В-общем, проще продемонстрировать на примере:

PE1 и PE2 - это VTEP'ы. Host1 подключен к PE1 и поднимает с ним BGP-сессию внутри overlay-сети. Host1 по этой BGP-сессии анонсирует в сторону PE-1 некую подсеть SN1, которая расположена за ним. PE-1 в свою очередь, данную подсеть, полученную по BGP от Host1, анонсирует уже в EVPN как маршрут RT-5. И поле Gateway IP в NLRI заполняется IP-адресом Host1.

PE2 устанавливает данный маршрут для SN1 в свою таблицу маршрутизации. При этом next-hop у данного маршрута SN1 будет IP-адрес Host1. В свою очередь IP-адрес Host1 будет разрешаться через соответствующий маршрут RT-2. IP-адрес Host в данном случае будет называться Overlay Index.

Overlay Index необязательно должен быть IP-адресом. Это может быть и MAC-адрес (в таком случае он едет в комьюнити Router's MAC, а не в поле Gateway IP), также это может быть номер ESI. Но в рамках данного материала мы их рассматривать не будем. Если интересно: https://datatracker.ietf.org/doc/html/rfc9136#section-3.2 описывает Overlay Index'ы и приводит некоторые примеры их использования.

Теперь давайте вернемся к настройкам. :) Как последнюю нашу задачу, нам нужно реализовать "внешнюю связность" для нашего PoD'а. Означает это следующее: мы должны импортировать в нашу overlay-сеть некие внешние маршруты через некоторое внешнее устройство (например, это выделенный маршрутизатор/фаерволл, подключенный к одному из наших Leaf'ов). Маршруты будут импортированы в EVPN в качестве маршрутов 5-го типа (IP Prefix Route), а точнее это будет один маршрут - default. Благодаря ему клиенты в разных VRF получат связность друг с другом, а также доступ во внешние сети.

Мы поделим наших клиентов на две независимых VRF: VRF1 и VRF2. Client-1 и Client-2 будут принадлежать VRF1, а Client-3 и Client-4 будут жить в VRF2. Каждого клиента поместим в свой VNI (так будет нагляднее для целей данной главы).

К Leaf-3, который теперь будет играть специальную роль пограничного лифа, будет подключен маршрутизатор GW-1 (на базе Linux/FRR), который будет инжектировать внешние маршруты в нашу топологию. Какова будет его (GW-1) роль? Роль его будет чем-то вроде внешнего файрволла. То есть Leaf-3 будет отдавать на него два физических линка, каждый из которых будет принадлежать своей VRF. Через инжектируемый маршрут по умолчанию, клиенты в одном VRF смогут иметь связность с клиентами в другом VRF. Трафик будет проходить через GW-1 (удобное место, на котором можно реализовать различные политики безопасности).

Leaf-3 по обоим линкам будет отдавать на GW-1 суммарные маршруты подсетей, находящихся за IRB-интерфейсами всех VLAN'ов нашей фабрики.

Задача GW-1 будет состоять в том, чтобы принять маршруты с каждого линка, а обратно отдавать маршрут 0.0.0.0/0.

Приступим.

Топология, клиенты, адреса

Измененная топология - добавлен GW-1. Клиенты снова подключены к своим лифам одним линком (не то, что мультихоминг как-то мешает текущей настройке, просто так будет нагляднее в выводе show-команд).

Топология с внешним маршрутизатором

L2VXLAN/L3VXLAN

Коммутатор
IRB-интерфейс
VLAN
VNI
RT

Leaf-1

192.168.10.254/24

10

1010

1:1010

Leaf-2

192.168.20.254/24

20

1020

1:1020

Leaf-3

192.168.30.254/24

30

1030

1:1030

Leaf-3

192.168.40.254/24

40

1040

1:1040

Клиенты

Клиент
MAC
IP/Mask
VLAN
VRF

Client-1

02:00:00:00:01:bb

192.168.10.1/24

10

VRF1

Client-2

02:00:00:00:02:bb

192.168.20.2/24

20

VRF1

Client-3

02:00:00:00:03:bb

192.168.30.3/24

30

VRF2

Client-4

02:00:00:00:04:bb

192.168.40.4/24

40

VRF2

IP-VRF

VRF
VNI
RT

VRF1

10001

1:10001

VRF2

10002

1:10002

Настройка

По сути сначала мы повторим настройку из части 3 с небольшими изменениями (единственное значимое изменение - разделение клиентов на 2 VRF). После этого на каждом лифе мы включим анонсирование адресов подсетей, в которых у нас есть клиенты, как маршруты RT-5. Затем на Leaf-3 мы выполним настройку BGP-соседства с GW-1 и анонсируем в его сторону наши подсети. Обратно от GW-1 примем дефолтный маршрут. Поехали!

Настройка Leaf-1

Снова приведем здесь начальную конфигурацию, с которой мы начинаем работу (с настроенным underlay):

Теперь переходим к настройке overlay.

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

Создадим клиентский VLAN:

Теперь настроим физический порт, в который подключен наш клиент Client-1:

Создадим IRB-интерфейс:

Теперь настроим интерфейс VXLAN:

Anycast MAC:

Настроим MAC-VRF для VLAN 10:

Теперь настроим IP-VRF и L3VNI для VRF1, который мы будем использовать для передачи маршрутизируемого трафика (inter-VNI):

Здесь есть новая команда - redistribute connected, выполненная в секции address-family ipv4. Эта команда включает анонсирование префиксов подсетей в EVPN как маршруты 5-го типа.

Теперь включим AF EVPN в настройках процесса BGP:

Общий вид выполненных настроек:

C Leaf-1 закончили. Leaf-2 настроим по примерно такому же принципу.

Настройка Leaf-2

Начальная конфигурация:

Конфигурация overlay:

Настройка Leaf-3

Начальная конфигурация:

Настройка overlay:

Обратите внимание, что на Leaf-3 мы создали оба VRF, хотя клиенты Client-3 и Client-4 находятся в VRF2. "Поддержка" VRF1 нам нужна для отправки и принятия маршрутов в данном VRF от GW-1, а также анонсирование этих маршрутов в EVPN. Естественно, необходимо выделить и L3VNI для VRF1. Для VRF1 мы отдаем команду redistribute connected, просто для того, чтобы анонсировать стыковочную сеть до GW-1 (для консистентности). Строго говоря, это не обязательно, но пусть будет.

Теперь переходим к настройке пиринга с GW-1.

Настроим линки в сторону GW-1:

Создадим префикс-лист, отфильтровывающий host-маршруты (/32-маршруты). Мы не хотим отправлять в сторону GW-1 маршруты /32 наших клиентских хостов:

Создадим маршрутную карту, чтобы отфильтровать /32-маршруты EVPN от анонсирования в сторону GW-1.

Теперь настроим BGP-пиринг с GW-1. Определим пир-группу GW-1, укажем группу CLOS в качестве родителя, чтобы наследовать большинство нужных нам настроек BGP, а затем пропишем AS GW-1 (65099) и повесим на направление в сторону GW-1 нашу route-карту.

Общий вид выполненной конфигурации пиринга с GW-1:

Настройка GW-1

Для GW-1 мы возьмем Ubuntu Server 22.04, а в качестве маршрутизационного ПО - FRR 10. Настройки на GW-1 будут совершенно простейшие: по сути, что получили в один линк, то и отправили во второй. И всё. Получается такой своеобразный "отражатель маршрутов", который еще и пропускает через себя трафик. Настраиваем!

В самом начале включим функциональность маршрутизатора:

Сначала настроим интерфейсы через Netplan (стандартная утилита настройки сетевой части в Ubuntu):

Строго говоря, lo0 здесь не нужен, но пусть будет для красоты, все же "с него" будем брать router-id.

Создадим процесс BGP в AS 65099:

Укажем Router ID:

Отключим обязательное требование о наличии фильтрационной политики для eBGP:

Создадим агрегированный маршрут "по умолчанию", который мы будем отдавать на Leaf-3 по обоим линкам. Параметр "summary-only" означает, что более специфические маршруты, подпадающие под агреггированный маршрут, будут отфильтровываться и не анонсироваться:

Создадим пир-группу для обоих наших подключений:

Укажем удаленную AS как "external", то есть любую, отличающуюся от нашей (чтобы не вводить явно номер):

Включим BFD:

Аутентификацию:

Подкрутим таймеры:

И пропишем IP-адреса соседей (линки в сторону Leaf-3):

Общий вид выполненной конфигурации:

На этом настройка нашей сети закончена.

Проверки

Что мы хотим сейчас, в итоге, получить?

На Leaf-1 и Leaf-2 настроены VNI в VRF1, а на Leaf-3 - VNI в VRF2. Наша цель - обеспечить возможность хостам в VRF1 общаться с хостами в VRF2. Весь трафик при этом будет проходить через внешний маршрутизатор GW-1, на котором, при желании, можно повесить какие-нибудь политики безопасности или организовать фаервол. GW-1 должен отдавать маршрут по умолчанию в каждый из VRF.

Проверять будем с помощью пингов от клиентов в VRF1 до клиентов в VRF2 (и наоборот). Также с помощью tcpdump убедимся, что inter-VRF трафик действительно идет через GW-1, а также посмотрим show-команды (нас особенно интересуют маршруты RT-5).

Проверка Leaf-1

Посмотрим, какие маршруты RT-5 имеет Leaf-1 в своей RIB:

Мы видим четыре дефолтных маршрута. Два из них в VRF1, два в VRF2 (два - потому что доступны через 2 спайна). Взглянем на них подробнее:

Мы видим, что некст-хопом является Leaf-3, AS-PATH состоит из Spine (65100) -> Leaf-3 (65003) -> GW-1 (65099). AS-PATH оканчивается на GW-1, который и является родителем этих маршрутов. Route-Target-AS у маршрутов разные - 1:10001 и 1:10002 - соответственно, принадлежат в VRF1 и VRF2 соответственно. Комьюнити Router's MAC содержит в себе MAC-адрес VTEP'а назначения: Leaf-3. VNI - L3VNI соответствующих VRF.

Теперь взглянем подробно на маршрут, который порождает сам Leaf-1:

Это маршрут для подсети, расположенной в VLAN 10. VNI - L3VNI 10001, Router's MAC - MAC-адрес Leaf-1. Route-Target-AS:1:10001 - маршрут принадлежит VRF1 и должен быть установлен в него на тех VTEP'ах, на которых настроен VNI, импортирующий данное комьюнити.

Посмотрим в таблицу маршрутизации Leaf-1 для VRF1:

Мы видим маршрут "по умолчанию" с next-hop'ом - Leaf-3. Трафик по этому маршруту будет отправлен на Leaf-3, инкапсулирован в VNI 10001, а DST_MAC в инкапсулированном пакете будет равен router-mac, что позволит Leaf-3 поднять принятый пакет на третий уровень. Так же мы в таблице видим стыковочную сеть 10.99.1.0/24 между Leaf-3 и GW-1.

Проверка Leaf-2

Видим тот же набор маршрутов. 192.168.20.0/24 мы порождаем сами, поэтому AS-PATH у него пустой (помним, что собственная AS к маршруту приставляется на выходе из автономной системы). Так же мы видим четыре дефолтных маршрута, ведущих к GW-1, как мы видели и на Leaf-1.

Таблица маршрутизации:

В таблицу маршрутизации дефолтный маршрут установился.

Проверка Leaf-3

Маршруты типа RT-5 на Leaf-3:

Видим два дефолтных маршрута, которые мы принимаем от GW-1 и анонсируем в EVPN в соответствующих VRF. Так же порождаем маршруты стыковочных сетей между нами и GW-1, а также сети 192.168.30.0/24 и 192.168.40.0/24.

Взглянем на таблицу маршрутизации в VRF1:

Мы видим два дефолтных маршрута, ведущих в сторону GW-1 (интерфейс Ethernet5). Также мы видим напрямую присоединенную стыковочную сеть с GW-1. А также видим четыре маршрута для клиентских сетей, полученные от Leaf-1 и Leaf-2 через два Spine'а. Строго говоря, получили мы эти маршруты от Spine'ов, но сети анонсируются именно Leaf'ами. Spine'ы их просто ретранслируют нам, а мы эти сети передаем на GW-1, который потом их ретранслирует нам же, но в VRF2.

Посмотрим, что у нас в VRF2:

Опять же видим дефолтный маршрут от GW-1 (интерфейс Ethernet6). Видим стыковочную сеть с GW-1, а также две присоединенных сети, в которых у нас живут Client-3 и Client-4. Сетей 192.168.10.0/24 и 192.168.20.0/24 мы не видим, так как GW-1 их саггрегировал в дефолтный маршрут.

Давайте подробнее посмотрим на дефолтные маршруты в обоих VRF:

Обратите внимание - эти маршруты передаются не как RT-5, а как обычные IPv4-маршруты, так как GW-1 ничего не знает ни о каких EVPN и VXLAN. Эти маршруты наш Leaf-3 уже ретранслирует в EVPN, при этом конвертируя их в RT-5.

Проверка GW-1

Посмотрим, какие маршруты мы получаем от Leaf-3 по линку для VRF1:

Мы получаем стыковочную сеть, а также маршруты из VRF1. А отдаем?

Отдаем в сторону Leaf-3 VRF1 только дефолт.

Из VRF2 мы получаем следующее:

Стыковочная сеть с Leaf-3 и две сети, в которых живут Client-3 и Client-4.

А отдаем?

Дефолт :).

Посмотрим в таблицу маршрутизации:

Мы здесь видим агрегированный дефолт-маршрут, который ведет "в никуда", который мы анонсируем в сторону Leaf-3. Видим Видим стыковочные сети с Leaf-3, а также все четыре клиентских сети, которые мы получаем от Leaf-3 для VRF1 и VRF2.

Больше GW-1 ничего не делает, поэтому и смотреть здесь особо не на что.

Перейдем к проверкам клиентов.

Проверка связности клиентов

Запустим пинг от Client-1 до Client-4:

Посмотрим, как идет трафик, проследим его путь.

  1. Мы видим его на линке между Leaf-1 и Spine-1, инкапсулированный в L3VNI 10001:

Обратите внимание на DST_MAC в инкапсулированном пакете - он равен маку Leaf-3 и присутствовал в комьюнити Router's MAC в соответствующем маршруте EVPN.

  1. Видим трафик на линке между Spine-1 и Leaf-3:

  1. Видим трафик на линке между Leaf-3 и GW-1, в который терминируется VRF1:

  1. Видим трафик на линке между Leaf-3 и GW-1, в который терминируется VRF2:

  1. И теперь видим трафик на линке, напрямую присоединенном к Client-4:

Обратите внимание, что SRC_MAC в кадре, в котором едет ICMP Request - это Anycast MAC IRB-интерфейса Leaf-3.

Визуализировать путь трафика можно таким образом:

Прохождение трафика между VRF с использованием внешнего маршрутизатора

Наши маршруты RT-5 работают, давайте под конец проверим связность всех клиентов друг с другом:

Client-1

Ping Client-2

Ping Client-3

Ping Client-4

Client-2

Ping Client-1

Ping Client-3

Ping Client-4

Client-3

Ping Client-1

Ping Client-2

Ping Client-4

Client-4

Ping Client-1

Ping Client-2

Ping Client-3

Итого: связность между клиентами в двух разных VRF через внешний маршрутизатор - есть.

На этом настройку нашей EVPN-сети можно считать завершенной. Мы настроили основной функционал оверлей-сети, основанной на EVPN/VXLAN: L2-связность между клиентами в пределах одного широковещательного домена, L3-связность между VNI, резервируемое подключение (Multihoming) и инжектирование внешних префиксов в EVPN.

Надеюсь, данный материал был вам полезен.

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

Удачи и всего хорошего!

Виталий Швецов ([email protected])

Last updated