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

Протокол распределения меток LDP (Label Distribution Protocol, RFC 5036) устанавливает соответствие между префиксами IGP (FEC) и метками MPLS. Процесс работы LDP состоит из двух фаз: Discovery (обнаружение) и Session (установление сессии). В фазе Discovery маршрутизатор рассылает периодические UDP Hello-сообщения (порт 646) на мультикаст-адрес всех маршрутизаторов подсети 224.0.0.2. В Hello передаётся LDP Identifier (LSR-ID:Label Space, например 10.255.0.1:0) и Transport Address. Обнаружив друг друга, маршрутизаторы переходят ко второй фазе: узел с большим Transport Address открывает надёжное TCP-соединение на порт 646 к Transport Address соседа (по умолчанию это LSR-ID, обычно Loopback0). Поверх TCP происходит согласование параметров (Initialization), обмен Keepalive и рассылка меток (Label Mapping). Типичная ошибка: если между соседями работает UDP Hello, но межсетевой экран блокирует TCP 646 или адрес Loopback недоступен в IGP, сессия LDP никогда не перейдёт в состояние Operational!

Два этапа: UDP discovery и TCP session

LDP (RFC 5036) работает в две независимые фазы. Сначала узлы находят друг друга по UDP 646: Hello-сообщения уходят на 224.0.0.2 (all routers on this subnet) с TTL 1, то есть только по прямым связям (basic/link discovery). Затем один из узлов открывает TCP 646 к transport address соседа, и уже по этому TCP-каналу идут Initialization, KeepAlive, Address, Label Mapping, Label Withdraw/Release и Notification. UDP Hello ничем не защищён и ничего не знает о метках, поэтому видимость соседа в show mpls ldp discovery ещё не означает рабочую сессию.

LDP Identifier и transport address

LDP Identifier - 6 байт: 4 байта LSR-ID (обычно адрес Loopback0, у нас 10.255.0.1) и 2 байта label space ID. Для Ethernet используется platform-wide label space, поэтому идентификатор всегда 10.255.0.1:0. Transport address - адрес, на который соседи шлют TCP. Он передаётся в необязательном IPv4 Transport Address TLV внутри Hello; если TLV нет, используется адрес отправителя Hello (то есть адрес интерфейса). На Cisco по умолчанию transport address равен LSR-ID, на Junos - router-id (transport-address router-id), на Huawei - LSR-ID (mpls lsr-id). Следствие: loopback LSR-ID обязан быть достижим по IGP в обе стороны. Типичный отказ: Hello приходят, discovery видит соседа, но TCP не устанавливается, потому что loopback не анонсирован в OSPF/IS-IS или находится в VRF.

Hello: параметры и таймеры

Hello несёт Common Hello Parameters TLV: hold time (секунды), флаг T (targeted hello) и флаг R (просьба ответить targeted hello). Значение hold 0 означает «по умолчанию» (15 с для link и 45 с для targeted по RFC), 0xFFFF - бесконечность. Интервал отправки обычно равен hold/3. Практические значения: link hello 5 с / hold 15 с на Cisco, Junos и Huawei; targeted hello на Cisco 10 с / hold 90 с (по show mpls ldp parameters), по RFC 15 с / 45 с. Hello-adjacency живёт, пока приходят Hello; сессия закрывается, когда исчезла последняя adjacency с этим соседом либо истёк hold KeepAlive. Поэтому две параллельные линки между одной парой LSR дают две adjacency и одну TCP-сессию.

Кто открывает TCP: active и passive

Сравниваются transport address двух узлов как беззнаковые числа. Узел с большим адресом - active: он открывает TCP-соединение на порт 646 пассивного (локальный порт эфемерный). Пассивный только слушает 646. Поэтому для пары 10.255.0.1 и 10.255.0.11 активной стороной будет P1 (10.255.0.11), а PE1 - passive. Это влияет на диагностику: ACL или CoPP должны пропускать TCP с эфемерного порта на 646, а в обратном направлении - с 646 на эфемерный. Если из-за гонки открылись два соединения, RFC требует оставить одно.

Инициализация сессии: состояния

Состояния сессии по RFC 5036: NON EXISTENT, INITIALIZED, OPENREC, OPENSENT, OPERATIONAL. Active шлёт Initialization (версия протокола 1, KeepAlive time, флаг A - DU или DoD, флаг D - loop detection, Path Vector Limit, Max PDU Length - по умолчанию 4096, Receiver LDP Identifier). Passive проверяет, что принял именно «свой» LDP ID, отвечает Initialization + KeepAlive; после KeepAlive от active обе стороны в OPERATIONAL, и сразу начинается обмен Address и Label Mapping. При несовместимых параметрах отправляется Notification (например, Bad LDP Identifier или Session Rejected) и узел включает backoff: на Cisco интервал растёт от 15 до 120 с (mpls ldp backoff). Согласованное KeepAlive hold по умолчанию 180 с (интервал 60 с) на Cisco и 30 с (интервал 10 с) на Junos.

Типы сообщений

Hello (0x0100) идёт по UDP. По TCP: Initialization (0x0200), KeepAlive (0x0201), Address (0x0300) и Address Withdraw (0x0301), Label Mapping (0x0400), Label Request (0x0401), Label Withdraw (0x0402), Label Release (0x0403), Label Abort Request (0x0404), Notification (0x0001). Сообщение Address важно: оно сообщает все интерфейсные адреса соседа, чтобы LSR мог сопоставить IGP next-hop (адрес линка) с LDP-соседом. Без Address-сообщения привязки приходят, но не используются.

Targeted LDP

Targeted Hello шлётся unicast на конкретный адрес (не TTL 1), поэтому соседом может быть не прямо подключённый узел. Применения: L2VPN pseudowire (VPWS/VPLS через LDP), LDP session protection, LDP поверх RSVP-TE туннеля. Принимающая сторона должна разрешить targeted hello (mpls ldp discovery targeted-hello accept на Cisco, интерфейс lo0 в protocols ldp и при необходимости strict-targeted-hellos на Junos, на Huawei mpls ldp remote-peer настраивается на инициаторе). Флаг R в Hello просит ответить встречным targeted hello.