Общеизвестно, что существуют несколько версий протокола OSPF. Однако не только лишь все знают о том, что для OSPFv2 есть несколько вариантов RFC; подавляющая часть реализаций OSPF соответствуют RFC 1583 или RFC 2328. Пикантность ситуации в том, что эти RFC несовместимы между собой, о чём говорит и показывает вендор-которого-нельзя-называть. Ну и зачем же тогда IETF заморочилось созданием второго стандарта? Ответ прост: RFC 1583 содержит архитектурные недостатки, которые могут привести к образованию в сети петель маршрутизации.

Одно из наиболее ярких отличий между стандартами – вычисление метрики суммарного маршрута на ABR.

When the range's status indicates Advertise, a Type 3 advertisement is generated with Link State ID equal to the range's address (if necessary, the Link State ID can also have one or more of the range's "host" bits set; see Appendix F for details) and cost equal to the smallest cost of any of the component networks.

Вольный перевод:

Если агрегированный префикс подлежит анонсу, необходимо создать LSA3, Link State ID которого равен анонсируемому маршруту (…), а вес – наименьшему весу из входящих в него префиксов.

RFC 1583, раздел 12.4.3

When the range's status indicates Advertise, a Type 3 summary-LSA is generated with Link State ID equal to the range's address (if necessary, the Link State ID can also have one or more of the range's "host" bits set; see Appendix E for details) and cost equal to the largest cost of any of the component networks.

Вольный перевод:

Если агрегированный префикс подлежит анонсу, необходимо создать LSA3, Link State ID которого равен анонсируемому маршруту (…), а вес – наибольшему весу из входящих в него префиксов.

RFC 2338, раздел 12.4.3

Долгое время это изменение казалось мне бессмысленным, что сделали именно так, потому что гладиолус. Однако раздел RFC 2178 весьма доходчиво описывает, где именно собака зарыта:

There are two manifestations of this problem. The first, discovered by DennisFerguson, occurs when an aggregated forwarding address is in use. In this case, the desirability of the forwarding address can change for the worse as a packet crosses an area aggregation boundary on the way to the forwarding address, which in turn can cause the preference of AS-external-LSAs to change, resulting in a routing loop.

Вольный перевод:

Есть два проявления описанной проблемы. Первое, обнаруженное Дэннисом Фергюсоном, возникает при агрегировании forwarding address, когда предпочтительность маршрута до forwarding address ухудшается при пересечении границы зоны, что в свою очередь может изменить приоритет LSA5, в конечном счёте приводя к петле маршрутизации.

Если буйная фантазия после прочтения этого объяснения выдала BSOD – добро пожаловать в клуб. Впрочем, показательный сценарий придумать действительно несложно.

Зоны 1 и 2 включают в себя в том числе и внешние интерфейсы ASBR, чтобы заполнить поле Forwarding Address в LSA5. ABR суммаризуют внешние префиксы, соответствующие этим интерфейсам, при передаче в зону 0. Освежим в памяти алгоритм выбора лучшего внешнего маршрута по версии RFC 1583:

  1. внутренние маршруты лучше внешних;

  2. Тип-1 (E1) лучше Типа-2 (E2);

  3. меньшая метрика имеет больший приоритет;

  4. только для E2: наименьшая метрика до Forwarding Address побеждает.

Относящиеся к делу настройки маршрутизаторов:

R1#show run | section interface|router
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.12.1 255.255.255.0
interface FastEthernet0/1
 ip address 192.168.13.1 255.255.255.0
router ospf 1
 network 0.0.0.0 255.255.255.255 area 0
ABR1#sho run | section interface|router
interface Loopback0
 ip address 2.2.2.2 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.12.2 255.255.255.0
interface FastEthernet0/1
 ip address 192.168.24.2 255.255.255.0
 ip ospf 1 area 1
router ospf 1
 area 1 range 10.1.0.0 255.255.0.0
 network 0.0.0.0 255.255.255.255 area 0
ABR2#sho run | section interface|router
interface Loopback0
 ip address 3.3.3.3 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.35.3 255.255.255.0
 ip ospf 1 area 2
interface FastEthernet0/1
 ip address 192.168.13.3 255.255.255.0
router ospf 1
 area 2 range 10.2.0.0 255.255.0.0
 network 0.0.0.0 255.255.255.255 area 0
ASBR1#sho run | section interface|router
interface Loopback0
 ip address 4.4.4.4 255.255.255.255
interface FastEthernet0/0
 ip address 10.1.46.4 255.255.255.0
 ip ospf cost 1000
interface FastEthernet0/1
 ip address 192.168.24.4 255.255.255.0
router ospf 1
 router-id 4.4.4.4
 redistribute bgp 1 subnets
 network 0.0.0.0 255.255.255.255 area 1
router bgp 1
 bgp router-id 4.4.4.4
 no bgp default ipv4-unicast
 neighbor 10.1.46.6 remote-as 6
 !
 address-family ipv4
  redistribute ospf 1
  neighbor 10.1.46.6 activate
ASBR2#sho run | section interface|router
interface Loopback0
 ip address 5.5.5.5 255.255.255.255
interface FastEthernet0/0
 ip address 192.168.35.5 255.255.255.0
interface FastEthernet0/1
 ip address 10.2.56.5 255.255.255.0
 ip ospf cost 10
router ospf 1
 router-id 5.5.5.5
 redistribute bgp 1 subnets
 network 0.0.0.0 255.255.255.255 area 2
router bgp 1
 bgp router-id 5.5.5.5
 no bgp default ipv4-unicast
 neighbor 10.2.56.6 remote-as 6
 !
 address-family ipv4
  redistribute ospf 1
  neighbor 10.2.56.6 activate
BGP#sho run | s interface|router
interface Loopback0
 ip address 6.6.6.6 255.255.255.255
interface FastEthernet0/0
 ip address 10.1.46.6 255.255.255.0
interface FastEthernet0/1
 ip address 10.2.56.6 255.255.255.0
router bgp 6
 no bgp default ipv4-unicast
 neighbor 10.1.46.4 remote-as 1
 neighbor 10.2.56.5 remote-as 1
 !
 address-family ipv4
  network 6.6.6.6 mask 255.255.255.255
  neighbor 10.1.46.4 activate
  neighbor 10.2.56.5 activate

Проверим, что у R1 есть связность до R6:

R1#sho ip route 6.6.6.6
Routing entry for 6.6.6.6/32
  Known via "ospf 1", distance 110, metric 1
  Tag 6, type extern 2, forward metric 12
  Last update from 192.168.12.2 on FastEthernet0/0, 00:04:10 ago
  Routing Descriptor Blocks:
  * 192.168.12.2, from 4.4.4.4, 00:04:13 ago, via FastEthernet0/0
      Route metric is 1, traffic share count is 1
      Route tag 6
R1#ping 6.6.6.6 source loopback 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 6.6.6.6, 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 = 12/35/56 ms

Оба внешних маршрута имеют тип E2, так что R1 выбирает лучший из них на основе веса маршрута до Forwarding Address:

R1#sho ip ospf database external | include Link State ID|Network Mask|Forward Address|LS Type
  LS Type: AS External Link
  Link State ID: 6.6.6.6 (External Network Number )
  Network Mask: /32
	Forward Address: 10.1.46.6
  LS Type: AS External Link
  Link State ID: 6.6.6.6 (External Network Number )
  Network Mask: /32
	Forward Address: 10.2.56.6
R1#
R1#show ip route 10.2.56.6
Routing entry for 10.2.0.0/16
  Known via "ospf 1", distance 110, metric 1002, type inter area
  Last update from 192.168.13.3 on FastEthernet0/1, 00:01:10 ago
  Routing Descriptor Blocks:
  * 192.168.13.3, from 3.3.3.3, 00:01:10 ago, via FastEthernet0/1
      Route metric is 1002, traffic share count is 1
R1#show ip route 10.1.46.6
Routing entry for 10.1.0.0/16
  Known via "ospf 1", distance 110, metric 12, type inter area
  Last update from 192.168.12.2 on FastEthernet0/0, 00:10:25 ago
  Routing Descriptor Blocks:
  * 192.168.12.2, from 2.2.2.2, 00:10:25 ago, via FastEthernet0/0
      Route metric is 12, traffic share count is 1

Добавим на ASBR2 сущий пустяк – интерфейс loopback с адресом из диапазона 10.2.0.0/16:

ASBR2#sho run interface loopback 1
interface Loopback1
 ip address 10.2.2.2 255.255.255.255

И уезжаем пить пиво на дачу вечером пятницы:

R1#ping 6.6.6.6 source loopback 0                                                            
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 6.6.6.6, timeout is 2 seconds:
Packet sent with a source address of 1.1.1.1 
.....
Success rate is 0 percent (0/5)

Упс, SLA для связности в сети начал неумолимо тикать. А виной всему…

R1#traceroute 6.6.6.6 source loopback 0
Type escape sequence to abort.
Tracing the route to 6.6.6.6
VRF info: (vrf in name/id, vrf out name/id)
  1 192.168.13.3 28 msec 16 msec 20 msec
  2 192.168.13.1 24 msec 20 msec 20 msec
  3 192.168.13.3 36 msec 40 msec 40 msec
  4 192.168.13.1 40 msec 40 msec 40 msec
<ну вы поняли>

Заглянем в мозги R1:

R1#show ip route 6.6.6.6
Routing entry for 6.6.6.6/32
  Known via "ospf 1", distance 110, metric 1
  Tag 6, type extern 2, forward metric 3
  Last update from 192.168.13.3 on FastEthernet0/1, 00:04:17 ago
  Routing Descriptor Blocks:
  * 192.168.13.3, from 5.5.5.5, 00:04:17 ago, via FastEthernet0/1
      Route metric is 1, traffic share count is 1
      Route tag 6
R1#
R1#show ip ospf database external | include Link State ID|Network Mask|Metric|Forward
  Link State ID: 6.6.6.6 (External Network Number )
  Network Mask: /32
	Metric Type: 2 (Larger than any link state path)
	Metric: 1 
	Forward Address: 10.1.46.6
  Link State ID: 6.6.6.6 (External Network Number )
  Network Mask: /32
	Metric Type: 2 (Larger than any link state path)
	Metric: 1 
	Forward Address: 10.2.56.6
R1#
R1#show ip route 10.1.46.6
Routing entry for 10.1.0.0/16
  Known via "ospf 1", distance 110, metric 12, type inter area
  Last update from 192.168.12.2 on FastEthernet0/0, 00:22:00 ago
  Routing Descriptor Blocks:
  * 192.168.12.2, from 2.2.2.2, 00:22:00 ago, via FastEthernet0/0
      Route metric is 12, traffic share count is 1
R1#
R1#show ip route 10.2.56.6
Routing entry for 10.2.0.0/16
  Known via "ospf 1", distance 110, metric 3, type inter area
  Last update from 192.168.13.3 on FastEthernet0/1, 00:05:51 ago
  Routing Descriptor Blocks:
  * 192.168.13.3, from 3.3.3.3, 00:05:51 ago, via FastEthernet0/1
      Route metric is 3, traffic share count is 1

Очевидно, что R1 поменял своё мнение касательно лучшего маршрута до 6.6.6.6/32, переключившись с ASBR1 на ASBR2. А что происходит в палате №6 голове ABR2?

ABR2#show ip route 6.6.6.6
Routing entry for 6.6.6.6/32
  Known via "ospf 1", distance 110, metric 1
  Tag 6, type extern 2, forward metric 13
  Last update from 192.168.13.1 on FastEthernet0/1, 00:17:24 ago
  Routing Descriptor Blocks:
  * 192.168.13.1, from 4.4.4.4, 00:17:24 ago, via FastEthernet0/1
      Route metric is 1, traffic share count is 1
      Route tag 6
ABR2#
ABR2#show ip os database external | include Link State ID|Netowrk Mask|Metric|Forward
  Link State ID: 6.6.6.6 (External Network Number )
	Metric Type: 2 (Larger than any link state path)
	Metric: 1 
	Forward Address: 10.1.46.6
  Link State ID: 6.6.6.6 (External Network Number )
	Metric Type: 2 (Larger than any link state path)
	Metric: 1 
	Forward Address: 10.2.56.6
ABR2#
ABR2#show ip route 10.1.46.6
Routing entry for 10.1.0.0/16
  Known via "ospf 1", distance 110, metric 13, type inter area
  Last update from 192.168.13.1 on FastEthernet0/1, 00:27:01 ago
  Routing Descriptor Blocks:
  * 192.168.13.1, from 2.2.2.2, 00:27:01 ago, via FastEthernet0/1
      Route metric is 13, traffic share count is 1
ABR2#                       
ABR2#show ip route 10.2.56.6                                                         
Routing entry for 10.2.56.0/24
  Known via "ospf 1", distance 110, metric 1001, type intra area
  Last update from 192.168.35.5 on FastEthernet0/0, 00:18:04 ago
  Routing Descriptor Blocks:
  * 192.168.35.5, from 5.5.5.5, 00:18:04 ago, via FastEthernet0/0
      Route metric is 1001, traffic share count is 1

ABR2 добросовестно сравнивает вес маршрутов до обоих ASBR и решает, что ASBR1 ему нравится больше, отсюда и петля. Самое время включить на ABR2 режим совместимости с RFC 2328 – это позволит назначить суммарному маршруту худшую из входящих префиксов метрику. Таким образом, маршрут до Forwarding Address может только улучшиться по пути пакета, но никогда наоборот.

ABR2(config)#router ospf 1
ABR2(config-router)#no compatible rfc1583

Вуаля – R1 снова использует первый маршрут через ABR1:

R1#ping 6.6.6.6 source loopback 0                                                    
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 6.6.6.6, 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 = 12/28/40 ms
R1#
R1#show ip route 6.6.6.6         
Routing entry for 6.6.6.6/32
  Known via "ospf 1", distance 110, metric 1
  Tag 6, type extern 2, forward metric 12
  Last update from 192.168.12.2 on FastEthernet0/0, 00:01:10 ago
  Routing Descriptor Blocks:
  * 192.168.12.2, from 4.4.4.4, 00:01:10 ago, via FastEthernet0/0
      Route metric is 1, traffic share count is 1
      Route tag 6

Лепота ситуации в том, что огромный парк сетевых устройств работает по правилам RFC 1583, включая Cisco IOS, Juniper JunOS, Huawei VRR. Ежу понятно, что это сделано в целях обратной совместимости (более свежие устройства используют RFC 2328 по умолчанию, например, Arista EOS, Cisco NX-OS), однако легкость реализации радикального джихада на своей собственной сети лично меня впечатляет. Впрочем, решение тоже весьма простое: или использовать RFC 2328, или использовать OSPF в максимально простом виде aka KISS: никаких virtual link, NSSA, FA и других CCIE-примочек.

Спасибо за обратную связь: Куралёвой Анастасии

Комментарии (2)


  1. turbidit
    22.11.2022 16:48

    Просто для информации:

    MikroTik RouterOS implements OSPF version 2 (RFC 2328)


  1. Harliff
    23.11.2022 13:22

    Проверил VyOS (1.3.2): RFC 2328 - по умолчанию. Поднял документацию по Vyatta 7.7 - уже там RFC 2328 был по умолчанию.