В предыдущей заметке я описал, как можно заткнуть дыру в кривом дизайне OSPF – костылём, который усложняет и так запутанный OSPF.
NSSA-зона ещё больше усугубляет ситуацию: OSPF использует Forwarding Address в Type-5 LSA, которые транслированы из Type-7 LSA, чтобы обеспечить оптимальную маршрутизацию.
Начнём с небольшой и сломанной топологии:
Маршрутизатор ядра (C1) в зоне 0.
Пограничный маршрутизатор (E1) в NSSA-зоне 1.
ABR'ы A1 и A2 соединяют два сегмента сети.
В ситуациях, когда несколько ABR подключены к одинаковому набору зон, стоит обеспечить соединение между ними в каждой зоне, включая опорную. Обоснование остаётся на совести читателя. Соединение в опорной сети может быть выполнено в виде виртуального соединения, если зона, по которой он проходит, не является stub или NSSA.
Происходящее следует из того, как должен работать NSSA:
Пограничный маршрутизатор (E1) проводит redistribute внешнего маршрута (192.168.1.0/24) в NSSA-зону как Type-7 LSA.
ABR генерирует Type-7 LSA на основе Type-5 LSA.
Только один ABR анонсирует Type-5 LSA в опорную сеть (потому что гладиолус – подробнее в RFC 3101).
A1#show ip ospf data external
OSPF Router with ID (192.168.0.1) (Process ID 1)
Type-5 AS External Link States
LS age: 113
Options: (No TOS-capability, DC, Upward)
LS Type: AS External Link
Link State ID: 192.168.1.0 (External Network Number )
Advertising Router: 192.168.0.4
LS Seq Number: 80000001
Checksum: 0x530A
Length: 36
Network Mask: /24
Metric Type: 2 (Larger than any link state path)
MTID: 0
Metric: 20
Forward Address: 192.168.0.2
External Route Tag: 0
Без Forwarding Address в Type-5 LSA, анонсированном A2 (в качестве примера в нашей сети), C1 не смог бы использовать оба равноценных пути до Е1 (C1-A1-E1 и C1-A2-E1); весь трафик пошёл бы через ABR, который распространяет Type-5 LSA.
Как именно ABR понимает, что за значение использовать в Forwarding Address в Type-5 LSA, который создан по Type-7 LSA? Да никак, он просто делегирует проблему другому (пристально смотрим на пункт 6 RFC 1925) – и копирует содержимое из Forwarding Address, которое найдёт в Type-7 LSA.
Вывод: Type-7 LSA обязан иметь Forwarding Address.
A1#show ip ospf data nssa-external
OSPF Router with ID (192.168.0.1) (Process ID 1)
Type-7 AS External Link States (Area 1)
LS age: 90
Options: (No TOS-capability, Type 7/5 translation, DC, Upward)
LS Type: AS External Link
Link State ID: 192.168.1.0 (External Network Number )
Advertising Router: 192.168.0.2
LS Seq Number: 80000001
Checksum: 0xCA8A
Length: 36
Network Mask: /24
Metric Type: 2 (Larger than any link state path)
MTID: 0
Metric: 20
Forward Address: 192.168.0.2
External Route Tag: 0
Если NSSA ASBR не может использовать настоящий внешний next-hop в качестве Forwarding Address, он обычно подставляет адрес loopback (именно поэтому Forwarding Address в прошлом выводе равен 192.168.0.2), что приводит к идеальному ECMP-сценарию на C1:
C1#show ip route 192.168.1.0
Routing entry for 192.168.1.0/24
Known via "ospf 1", distance 110, metric 20, type extern 2, forward metric 3
Last update from 10.0.0.13 on GigabitEthernet0/2, 00:23:35 ago
Routing Descriptor Blocks:
10.0.0.13, from 192.168.0.4, 00:23:35 ago, via GigabitEthernet0/2
Route metric is 20, traffic share count is 1
* 10.0.0.9, from 192.168.0.4, 00:23:35 ago, via GigabitEthernet0/1
Route metric is 20, traffic share count is 1
Если есть желание воспроизвести полученные результаты самостоятельно, начните с OSPF-NSSA-Forwarding-Address топологии для VIRL из репозитория на Github.
Посмотрим, что произойдёт, если выключить интерфейс loopback на E1 (или убрать его из OSPF), вызывая у последнего легкую панику:
Он всё ещё не может использовать настоящий внешний next-hop (потому что никто не анонсирует эту подсеть в OSPF).
У него нет подходящего loopback, который можно анонсировать как внутренний маршрут OSPF.
Как следствие, E1 выбирает какой-то из своих адресов (я уверен, что RFC 3101 детально описывает, какой именно, но я не осилил такие детали) и использует его в качестве Forwarding Address. В нашем случае E1 выбрал IP-адрес на соединении E1-A2.
A1#show ip ospf data external
OSPF Router with ID (192.168.0.1) (Process ID 1)
Type-5 AS External Link States
LS age: 25
Options: (No TOS-capability, DC, Upward)
LS Type: AS External Link
Link State ID: 192.168.1.0 (External Network Number )
Advertising Router: 192.168.0.4
LS Seq Number: 80000002
Checksum: 0x703B
Length: 36
Network Mask: /24
Metric Type: 2 (Larger than any link state path)
MTID: 0
Metric: 20
Forward Address: 10.0.0.18
External Route Tag: 0
Смена Forwarding Address ломает ECMP на C1, так как префикс, соответствующий Forwarding Address, не ведёт теперь по двум равнозначным маршрутам. C1 шлёт весь трафик для E1 через A2.
C1#show ip route 192.168.1.0
Routing entry for 192.168.1.0/24
Known via "ospf 1", distance 110, metric 20, type extern 2, forward metric 2
Last update from 10.0.0.13 on GigabitEthernet0/2, 00:29:09 ago
Routing Descriptor Blocks:
* 10.0.0.13, from 192.168.0.4, 00:29:09 ago, via GigabitEthernet0/2
Route metric is 20, traffic share count is 1
Ура, мы сломали OSPF (снова).
Всё ещё хуже, чем кажется...
Igor Osadchuk поделился со мной следующей пикантной подробностью:
Занятный момент с FA: поскольку он задействован в рекурсивном поиске next-hop, плюс OSPF в этот момент ведёт себя, как distance vector протокол, то получается, что FA должен присутствовать в таблице маршрутизации (в конечном итоге и в FIB), иначе внешний префикс не попадёт в RIB. Увлекательной отладки!
Ещё пара слов для ботанов
Angelos Vassiliou прислал мне письмо, в котором заметил, что мы могли бы использовать команду area 1 nssa translate type7 always, чтобы заставить оба ABR генерировать Type-5 LSA. Это могло бы сработать в ряде пограничных случаев, связанных с разбитой на несколько частей NSSA-зоной, но это не решает нашу проблему.
Есть ещё одна команда (в моем понимании, нарушающая NSSA RFC): area nssa translate type7 supress-fa использует строго нулевое значение в Type-5 LSA, анонсируемых в опорную зону. Это потенциально может привести к ECMP в зоне 0, но не к корректной end-to-end ECMP маршрутизации в случае соединений с разным весом.
Действительно ли жизнь должна быть столь сложна?
Пожалуй, нет. В конце концов, мой календарь утверждает, что на дворе 2017 год, так что большинство маршрутизаторов сегодня достаточно производительны. Вот что можно сделать, чтобы упростить себе жизнь:
Если в сети есть пара сотен маршрутизаторов и скорость сходимости сети не так уж важна, используйте одну зону OSPF.
Если есть сомнения, что OSPF потянет несколько сотен маршрутизаторов в одной зоне – используйте в следующий раз IS-IS.
Если Ваша сеть больше (или неохота проверять масштабируемость OSPF на себе), используйте BGP на границе сети, а OSPF – в её ядре.
Если вендор просит дополнительное вознаграждение за право использовать BGP, объясните ему, что на дворе 2017-ый, и проголосуйте кошельком (aka смените вендора).
Можете также организовать небольшую встречу для консультации, чтобы обсудить такие детали или другой дизайн.
iddqda
????
braonle Автор
Так перевод же, оригинальная заметка от 2017