Теоретические основы и архитектура
Протокол 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 находятся соседи. Различия, которые влияют на дизайн сети оператора:
| Свойство | eBGP | iBGP |
|---|---|---|
| AS соседа | другая | та же (65000) |
| AS_PATH | локальная AS добавляется при отправке | не меняется |
| NEXT_HOP | заменяется на адрес отправителя | не меняется |
| LOCAL_PREF | не передаётся | передаётся, по умолчанию 100 |
| TTL пакетов сессии | 1 (для loopback нужен multihop) | 255 |
| Admin distance Cisco / Junos preference | 20 / 170 | 200 / 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-маршрутов. Требования:
- IGP-достижимость /32 loopback: маршрут именно /32 (без суммаризации), иначе у LDP не появится метка для FEC этого адреса (LDP сопоставляет FEC точно) и LSP до next hop не построится.
- update-source (Cisco), connect-interface (Huawei), local-address (Junos): исходящий SYN уходит с адреса loopback. Без этого маршрутизатор берёт адрес исходящего интерфейса, а соседний PE, ожидая 10.255.0.1, не находит соответствия в конфигурации и сбрасывает соединение: сессия остаётся в Active.
- Адрес должен совпадать на обеих сторонах: на 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, Huaweinext-hop-local, Junos export-политикаthen next-hop self, MikroTiknexthop-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), его отбросит.