Теоретические основы и архитектура

Протокол BGP (Border Gateway Protocol, RFC 4271) в ядре оператора связи работает в режиме iBGP (Internal BGP). В отличие от eBGP, соединяющего разные автономные системы, iBGP связывает пограничные маршрутизаторы PE внутри одной AS. Ключевая особенность iBGP — правило расщепления горизонта (Split Horizon Rule): маршрутизатор iBGP, получивший маршрут от одного iBGP-соседа, НИКОГДА не пересылает его другому iBGP-соседу! Это правило защищает плоскость управления от петель маршрутизации (ведь внутри AS атрибут AS_PATH не увеличивается). Следствием правила расщепления горизонта является необходимость построения полносвязной топологии iBGP Full Mesh: каждый PE должен иметь прямую логическую сессию со всеми другими PE. Для N маршрутизаторов требуется N*(N-1)/2 сессий (для 10 PE = 45 сессий, для 100 PE = 4950 сессий!). Сессии iBGP устанавливаются между адресами Loopback0 (update-source), чтобы пережить отказ отдельного линка. next-hop-self нужен на PE для маршрутов, полученных от eBGP-соседей (иначе next hop - адрес CE, неизвестный ядру); в VPNv4/VPNv6 PE подставляет свой адрес как next hop автоматически.

iBGP и eBGP: что на самом деле отличается

Протокол один и тот же (RFC 4271, TCP/179), но поведение определяется тем, в одной ли AS находятся соседи. Различия, которые влияют на дизайн сети оператора:

СвойствоeBGPiBGP
AS соседадругаята же (65000)
AS_PATHлокальная AS добавляется при отправкене меняется
NEXT_HOPзаменяется на адрес отправителяне меняется
LOCAL_PREFне передаётсяпередаётся, по умолчанию 100
TTL пакетов сессии1 (для loopback нужен multihop)255
Admin distance Cisco / Junos preference20 / 170200 / 170
Пересылка маршрута другому соседулюбомутолько если маршрут из eBGP или локальный

Последняя строка - split horizon iBGP: маршрут, полученный от iBGP-соседа, нельзя отправлять другому iBGP-соседу. Внутри AS атрибут AS_PATH не растёт, и обнаружить петлю по нему невозможно, поэтому правило заменяет собой loop prevention.

Математика full mesh

Каждый iBGP-спикер должен иметь сессию с каждым другим, иначе часть маршрутов до него не дойдёт. Для N маршрутизаторов нужно N*(N-1)/2 сессий, на каждом по N-1:

  • 4 PE: 6 сессий, по 3 на узел;
  • 10 PE: 45 сессий, по 9;
  • 20 PE: 190 сессий, по 19;
  • 50 PE: 1225 сессий, по 49;
  • 100 PE: 4950 сессий, по 99.

Растёт не только число TCP-сессий. Каждый PE хранит по пути от каждого соседа: при 900 тыс. префиксов и 99 соседях Adj-RIB-In может содержать десятки миллионов путей, а любое добавление PE требует изменения конфигурации на всех остальных. Именно эта цифра заставляет переходить на Route Reflector (следующий урок). Full mesh остаётся нормальным решением для 3-8 PE и как мини-схема внутри кластера.

Peering на loopback и update-source

iBGP-сессию строят между адресами Loopback0, а не физических интерфейсов, по двум причинам: loopback не падает вместе с одним линком (TCP-сессия переживает перестройку IGP по резервному пути), и именно loopback-адрес PE используется в LDP/LSP и как BGP next hop для VPN-маршрутов. Требования:

  1. IGP-достижимость /32 loopback: маршрут именно /32 (без суммаризации), иначе у LDP не появится метка для FEC этого адреса (LDP сопоставляет FEC точно) и LSP до next hop не построится.
  2. update-source (Cisco), connect-interface (Huawei), local-address (Junos): исходящий SYN уходит с адреса loopback. Без этого маршрутизатор берёт адрес исходящего интерфейса, а соседний PE, ожидая 10.255.0.1, не находит соответствия в конфигурации и сбрасывает соединение: сессия остаётся в Active.
  3. Адрес должен совпадать на обеих сторонах: на PE2 в neighbor указан 10.255.0.1, на PE1 исходящий адрес именно он.

Если оба PE одновременно инициируют TCP, возникает collision: по RFC 4271 п. 6.8 остаётся соединение, инициированное маршрутизатором с большим BGP Identifier, второе закрывается. Поэтому в логах иногда видны единичные сбросы при старте, не являющиеся ошибкой.

Next hop и next-hop-self

При eBGP-приёме PE1 получает маршрут 198.51.100.0/24 с NEXT_HOP 172.16.1.2 (адрес CE на стыке). iBGP передаёт этот атрибут без изменений. PE2 получит маршрут с next hop 172.16.1.2, которого нет в IGP ядра, и пометит путь как недоступный (Cisco: inaccessible, Junos: Unusable/hidden, Huawei: не будет active), поскольку BGP не может рекурсивно разрешить next hop. Два решения:

  • next-hop-self на PE при отправке в iBGP (Cisco next-hop-self, Huawei next-hop-local, Junos export-политика then next-hop self, MikroTik nexthop-choice=force-self): next hop становится loopback PE1 10.255.0.1, который есть в IGP и в LDP. Для VPN-маршрутов PE подставляет себя автоматически, для обычных IPv4 в глобальной таблице нужно задать явно.
  • Включить стыковую сеть 172.16.1.0/30 в IGP как пассивный интерфейс. Это решает задачу, но раздувает IGP и ломается при изменении стыка, поэтому в операторских сетях используют next-hop-self.

Правильное разрешение next hop для транзита: BGP next hop -> /32 в IGP -> метка LDP (транспортная метка). Если для 10.255.0.1 нет метки, пакет уйдёт без LSP и P-маршрутизатор, не знающий внешних префиксов (BGP-free core), его отбросит.