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

Алгоритм CSPF (Constrained Shortest Path First) — это модифицированный алгоритм Дейкстры (SPF), выполняемый на базе данных TED. В отличие от стандартного SPF, который учитывает только стоимость линков, алгоритм CSPF перед вычислением кратчайшего пути отсекает (прунит) из графа топологии все каналы, которые не удовлетворяют заданным ограничениям: 1. Полоса пропускания (Bandwidth Constraint): каналы, где свободная нераспределённая полоса меньше запрошенной туннелем, сразу исключаются. 2. Цвета каналов (Link Affinity / Admin Groups): каждому физическому каналу ядра присваивается 32-битная битовая маска цвета (например, bit 0 = Золотой/Надёжный линк, bit 1 = Транзитный линк через спутник). При создании туннеля инженер указывает Affinity и Mask: например, требовать прохождения ТОЛЬКО по золотым линкам (Include-any) или строго избегать спутниковых каналов (Exclude-any). 3. Явные пути (Explicit Path): возможность жестко зафиксировать прохождение туннеля через конкретные IP-адреса транзитных маршрутизаторов (Strict Hop) или задать свободный транзит (Loose Hop).

Что делает CSPF

CSPF (Constrained SPF) выполняется на голове LSP по TED и возвращает ERO для сигнализации. Алгоритм: взять граф TED, выкинуть всё, что нарушает ограничения, и запустить Дейкстру на остатке. Порядок отсечения:

  1. Линки без TE-атрибутов и линки, у которых нет свободной полосы на нужном приоритете (unreserved bandwidth[setup priority] меньше требуемой).
  2. Линки, не прошедшие проверку административных групп (affinity).
  3. Узлы и линки, указанные в exclude-address / exclude-списке явного пути.
  4. Линки в SRLG, которые запрещено использовать (для защитных путей).
  5. Дейкстра по TE metric (или IGP metric, если выбрано) на оставшемся графе.

Если после отсечения до хвоста нет пути, туннель остаётся в состоянии Path: not valid, а RSVP вообще не запускается: Path не уходит. CSPF не знает ни о чём, что не отражено в TED, поэтому гонка с устаревшей информацией возможна: путь вычислен, но транзит отвечает PathErr.

Если по стоимости получилось несколько равных путей, выбор зависит от платформы. Cisco берёт путь с наибольшей минимальной свободной полосой, затем с меньшим числом хопов, затем случайный. Junos по умолчанию выбирает случайный (random), либо по настройке least-fill (меньше заполненный) или most-fill. Разные правила - частая причина того, что одинаковая конфигурация на разных платформах даёт разный путь.

Метрика: TE metric или IGP metric

TE metric - отдельное число в sub-TLV 5 (OSPF) / sub-TLV 18 (IS-IS), которое по умолчанию равно IGP-метрике. Её независимость даёт возможность считать TE-путь по другим весам, например по задержке: IGP metric оставляют под пропускную способность, а TE metric задают пропорционально задержке линка. На Cisco выбор метрики для туннеля задаётся tunnel mpls traffic-eng path-selection metric te|igp, и по умолчанию используется TE metric. Junos использует TE metric, если включён ospf traffic-engineering и задан te-metric, иначе IGP metric. В конфигурации лабораторной TE metric линка через P2 (5) меньше метрики через P1 (10): без ограничений CSPF выбрал бы P2, а ограничение affinity заставляет выбрать более дорогой путь.

Administrative groups (affinity)

Административная группа линка - 32-битная маска (OSPF sub-TLV 9, IS-IS sub-TLV 3). Каждый бит - произвольный "цвет": бит 0 - GOLD, бит 1 - SAT. Cisco задаёт её числом mpls traffic-eng attribute-flags 0x1, Junos - именами admin-groups GOLD 0 (имя связано с номером бита) и привязкой к интерфейсу. Администратор определяет смысл бита сам, он не стандартизован.

На стороне туннеля SESSION_ATTRIBUTE (C-Type 1, RFC 3209) несёт три 32-битные маски: exclude-any, include-any, include-all. Линк разрешён, если:

  • (link & exclude-any) == 0: нет ни одного запрещённого цвета;
  • include-any == 0 или (link & include-any) != 0: есть хотя бы один из требуемых;
  • (link & include-all) == include-all: есть все обязательные цвета.

Cisco конфигурирует это парой affinity VALUE mask MASK: для каждого бита из mask бит линка должен совпасть с битом affinity. То есть affinity 0x1 mask 0x3 значит "бит 0 обязан быть 1, бит 1 обязан быть 0, остальные не важны" - совмещение include-all (0x1) и exclude-any (0x2). Junos выражает то же ключевыми словами admin-group include-any, include-all и exclude.

Ловушка, которую знают все, кто работал с Cisco: значение по умолчанию - affinity 0x0 mask 0xFFFF. Это значит, что туннель без явных настроек обходит любой линк, у которого в младших 16 битах выставлен хоть один бит. Достаточно поставить attribute-flags 0x4 на линк "для мониторинга", и все туннели с настройками по умолчанию перестают использовать этот линк. Другая ловушка: смена ограничений не перестраивает работающий LSP мгновенно. Новый путь вычисляется при re-optimization: по таймеру (на Cisco по умолчанию 3600 с), по событию или вручную.

Явные и динамические пути

Path-option описывает, как получить ERO.

ВариантЧто делает CSPFКогда использовать
dynamicвычисляет весь путь по ограничениямосновной режим, адаптируется к отказам
explicit, strict hopsпроверяет путь по TED, но не выбирает егожёсткая привязка, например по требованию лицензии на канал
explicit, loose hopsвычисляет сегменты между указанными узлами"пройти через P1, остальное найди"
explicit, excludeудаляет адреса из графа и считает остальноеобход проблемного узла или линка

Подобъект ERO бывает strict (следующий узел обязан быть соседом) или loose (путь до него вычисляет предыдущий узел из ERO по своему TED, поэтому loose-путь может измениться без участия головы). Cisco поддерживает приоритет вариантов (path-option 10, path-option 20 dynamic): при невозможности первого голова пробует следующий. Параметр verbatim (Cisco) и no-cspf (Junos) отключают проверку по TED и разрешают сигнализировать путь, которого головная точка не видит, например в другой area: ответственность за корректность целиком на операторе.

Явный путь указывает адреса интерфейсов или router-id. Если адрес сменился, а путь остался в конфигурации, туннель получает PathErr 24/2 (Bad strict node) или не проходит проверку по TED. Именованные пути удобно хранить отдельно от туннелей и менять в одном месте.