Кросспостинг, оригинальная публикация
OSFP, будучи link-state протоколом, исключает петли в топологии за счёт построения дерева кратчайшего пути в рамках одной зоны с помощью алгоритма Дейкстры. Однако поведение OSPF между зонами напоминает скорее поведение distance-vector протоколов, которые обмениваются всего лишь префиксами и соответствующими метриками без каких-либо данных о фактической топологии; по этой причине некоторые авторы могут называть OSPF гибридным протоколом маршрутизации. Механизм защиты от петель маршрутизации между зонами, однако, довольно прост: все зоны должны обмениваться маршрутной информацией через backbone зону, зону 0, прямой обмен маршрутами между зонами невозможен.
Впрочем, тёмный гений изобрёл инструмент разрушения стройной идеи OSPF – речь о функции OSPF Virtual Link (VL). Даже маленькие инженеры знают, что использовать VL – плохая затея; все согласны с тем, что VL оправдан только в крайних случаях для временного и быстрого исправления критичной ситуации. Однако обнаружить подробное объяснение, чем же именно VL так плох помимо дополнительного уровня сложности, оказалось не так-то просто. Сложность инженерам не помеха, поэтому давайте поищем более весомые аргументы против VL.
Нет ничего лучше чашки кофе с утра, рабочей лабы и широкополосного доступа к google.com. Для эмуляции топологии в GNS3 были использованы образы Cisco 7200:
На каждом маршрутизаторе в соответствующей зоне настроен виртуальный интерфейс (loopback0) для назначения OSPF RID и других инфраструктурных задач; loopback на ABR находятся в зоне 0. Схема адресации: 192.168.xy.x|y/24 для соединения Rx и Ry (например, 192.168.12.1 на интерфейсе f0/1 R1). Помимо штатной настройки OSPF, между R1 и R3 создан VL.
Если у читателя много свободного времени, можно убедиться в доступности всех префиксов из любой точки сети; я же сконцентрируюсь на связности R1 и R5:
R1#ping 5.5.5.5 so lo 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 5.5.5.5, timeout is 2 seconds:
Packet sent with a source address of 1.1.1.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 20/30/40 ms
R1#traceroute 5.5.5.5 so lo 0 numeric
Type escape sequence to abort.
Tracing the route to 5.5.5.5
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.14.4 16 msec 24 msec 20 msec
2 192.168.45.5 48 msec 16 msec 24 msec
Трафик следует по кратчайшему маршруту, как и задумывалось. Перейдем к гвоздю сегодняшней программы:
R1(config)#router os 1
R1(config-router)#no capability transit
Transit area capability – это способность OSPFv2 выбрать более оптимальный маршрут для трафика, следующего по VL. Идея довольно проста: необходимо взять префикс, доступный через VL, и сравнить его с имеющимися LSA3; если найдено полное совпадение и маршрут через LSA3 оптимальнее, то следует использовать оптимальный маршрут. OSPFv1 не обладал такой функцией, и весь трафик следовал по тому же пути, что и VL. Если читатель хочет глубже погрузиться в данную тему, могу порекомендовать статью Петра Лапухова. А мы продолжаем:
R1#traceroute 5.5.5.5 so lo 0 n
Type escape sequence to abort.
Tracing the route to 5.5.5.5
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.12.2 44 msec 16 msec 20 msec
2 192.168.23.3 20 msec 40 msec 40 msec
3 192.168.35.5 76 msec 44 msec 44 msec
Изменения есть, но они некритичны: теперь R1 выбирает путь вдоль VL в полном соответствии с поведением OSPFv1 без transit capability. Где же обещанная петля? Добавим нашей топологии некоторой пикантности:
R2(config)#int f1/0
R2(config-if)#ip os cost 100
R3(config)#int f1/0
R3(config-if)#ip os cost 100
Ухудшили плохой маршрут, и что с того?
R1#traceroute 5.5.5.5 so lo 0 n
Type escape sequence to abort.
Tracing the route to 5.5.5.5
VRF info: (vrf in name/id, vrf out name/id)
1 192.168.12.2 20 msec 16 msec 16 msec
2 192.168.12.1 24 msec 16 msec 16 msec
3 192.168.12.2 36 msec 32 msec 44 msec
4 192.168.12.1 28 msec 36 msec 40 msec
5 192.168.12.2 44 msec 48 msec 64 msec
6 192.168.12.1 60 msec 60 msec 60 msec
7 192.168.12.2 80 msec 80 msec 80 msec
8 192.168.12.1 84 msec 76 msec 76 msec
Дамы и господа, это – петля. Теперь взглянем на проделанную работу:
VL между R1-R3;
Transit capability отключена;
Метрика R2-R3 увеличена.
Последний пункт стоит отметить особо: в результате изменения метрики R1 является next-hop для 5.5.5.5/32 с точки зрения R2:
R2#sho ip ro 5.5.5.5 255.255.255.255 longer-prefixes
5.0.0.0/32 is subnetted, 1 subnets
O IA 5.5.5.5 [110/4] via 192.168.12.1, 00:06:21, FastEthernet0/1
Выбор маршрута R2 выглядит довольно естественно; выбор R1 же может показаться странным на первый взгляд:
R1#sho ip ro 5.5.5.5 255.255.255.255 longer-prefixes
5.0.0.0/32 is subnetted, 1 subnets
O 5.5.5.5 [110/103] via 192.168.12.2, 00:08:07, FastEthernet0/1
Однако такое поведение вполне соответствует правилам выбора маршрута в OSPFv1:
5.5.5.5/32 доступен через VL в зоне 0;
трафик следует по тому же пути, что и VL.
R2 ничего не знает ни про VL, ни про transit area; он всего ли маршрутизирует пакеты согласно таблице маршрутизации, построенной на основе LSA3.
На данном этапе может показаться, что причина всех бед – transit capability, а не VL. Впрочем, разрешается этот вопрос довольно просто: подобная проблема была обнаружена в OSPFv1 и решена в OSPFv2 посредством transit area. Читатель может заметить, что описанное поведение родственно по природе микропетлям, возникающим в ходе перестроения дерева, и с ним трудно не согласиться. Впрочем, разница есть и существенная: микропетли представляют собой переходное состояние, тогда как петли из-за VL в OSPFv1 носили постоянный характер.
Немного английского оригинала из OSPFv2 RFC про отличия от OSPFv1:
“When summarizing information into a virtual link's transit area, version 2 of the OSPF specification prohibits the collapsing of multiple backbone IP networks/subnets into a single summary link.”
Section F.2.3, RFC 1247
Проблема, завуалированная авторами RFC в этой фразе, очень похожа по характеру на рассматриваемую в статье. Если бы маршруты зоны 0 можно было бы суммаризовать на ABR, то полученный префикс в LSA3 не смог бы быть использован маршрутизатором с VL. Передача трафика была бы нарушена вследствие разного представления о топологии маршрутизаторами зоны:
Маршрутизатор с VL выбрал бы маршрут из зоны 0; из-за отсутствия точно совпадающего LSA3 был бы выбран путь вдоль VL;
Остальные же маршрутизаторы использовали бы суммарный маршрут из LSA3.
В нашем случае, если бы R3 суммаризовал маршрут до 5.5.5.0/24, то R2 выбрал бы более точный маршрут 5.5.5.0/25 через R4, что привело бы к петле маршрутизации. Решение? Нужно обеспечить всем маршрутизаторам зоны равный доступ к маршрутной информации из зоны 0, запретив изменение последней, т.е. суммаризацию. Стоит отметить, что это не относится к маршрутам из других зон, поскольку эти суммарные маршруты будут одинаковы как в зоне 0, так и других зонах; только ABR зоны-источника могут суммаризовать информацию о топологии из LSA1/2 в простой LSA3. Более того, запрещена только суммаризация префиксов из зоны 0, фильтрация же не ограничена. Последняя не изменяет сам префикс; в результате у маршрутизаторов зоны будет меньше пар LSA1-LSA3 для выбора более оптимального маршрута, что не может привести к описанной в статье проблеме.
Вывод: некоторые малоизвестные настройки по умолчанию лучше не трогать.
P.S. Существует не менее интересный способ выстрелить себе в ногу.
Помогали редактировать статью: Анастасия Куралёва, Максим Климанов.
bukoka
Интересная статья, спасибо автору(ам), что не поленились написать:)
Соглашусь с выводом статьи — заниматься трафик-инжинирингом, отключая включенные по умолчанию фичи на отдельно стоящем роутере (не просто так-то они и включены по дефолту) — не совсем хорошая идея.
Как минимум capability transit надо было бы тогда выключать на всех internal-роутерах данной зоны, чтобы обеспечить консистентный Control-Plane OSPF для них — и петли бы тогда не было ;)
Лучшая идея на мой неискушенный взгляд для задачи TE — использовать для этого предназначенные инструменты — MPLS-TE и\или всяческие другие overlay-техники — благо решений много.
На худой конец играть стоимостью OSPF :)
А по поводу петли — её также можно устроить просто не дав появиться маршруту в RT (ospf distribute-list in) — LSDB засинкалась по всей area, но роутер использует то, что видит в «отфильтрованном» RIB.
Но это не вина протокола, как и не вина протокола в том, что capability transit фича выключена на одном роутере и из-за этого не вышло консистентности Control-Plane по всей Area:)
VL сам по себе безвреден, и используется для того, чтобы закрыть просчеты по дизайну OSPF-домена — а это, имхо, благое дело. Да, можно использовать GRE до ABR — и помещать их в бэкбон зону, но ценой оверхедов на инкапсуляцию; можно сделать «разрывный» OSPF с default-originate по одной части бэкбона — да и вообще много чего сделать с дизайном OSPF, а потом страдать от side-effects:)
В общем Link-state OSPF не панацея от кривизны рук, хоть и очень хорош собой. А при использовании инструмента\фичи, надо либо досконально понимать как он работает, либо делать рабочее PoC-решение (но если на PoC вы используете другое ПО — старое\новое — не факт что сеть в продакшене поведет себя также — всегда есть возможность не предусмотреть баги\доп.фичи)