Весьма вероятно, что читатель уже знаком с работой EIGRP stuck-in-active (SIA). Если же нет, то вот выжимка из методички: если маршрутизатор не получает сообщение Reply в ответ на ранее посланный Query в течение Active таймера (3 минуты по умолчанию), то этот маршрутизатор разрывает связность с “зависшим” соседом; параллельно с ожиданием ответа маршрутизатор тыкает палочкой соседа с помощью сообщений SIA-Query, сбрасывая Active timer в случае обратной связи в виде SIA-Reply от соседа. Довольно просто, правда ведь? Выглядит, как защита от потенциально сумасшедшего маршрутизатора в сети. Позволю себе задать занудный длинный и громоздкий вопрос:
Почему SIA обязателен – ведь это поведение невозможно отключить? Почему нельзя просто позволить соседу протухнуть по Holddown timer, в результате сбрасывая Reply от него со счетов?
Ответ несколько зависит от точки зрения (ага, известное “it depends”). Рассмотрим пример:
При таком раскладе SIA никогда и не был бы нужен. Представим, что R3 впал в ступор, перестав отвечать на EIGRP сообщения, а в это же время отвалился 1.1.1.1/32 на R1:
R1 пошлёт Query про 1.1.1.1/32 в сторону R2.
R2 пошлёт Query про 1.1.1.1/32 в сторону R3, однако безрезультатно.
В процессе ожидания произойдёт пара-тройка EIGRP retransmits между R2 и R3.
Либо истечёт Holddown таймер (15с по умолчанию), либо число retransmits превысит 16 (только Cisco знает точно, сколько времени это займёт).
R2 разрывает соседство с R3 и отправляет Reply обратно R1.
Active таймер на R1 за это время не успевает истечь (3 минуты), поэтому 1.1.1.1/32 в состоянии Active можно спокойно убрать из памяти без вреда соседству.
Стоит отметить, что EIGRP был разработан довольно-таки давно – когда serial links были всё ещё в почёте. Важная для нашего обсуждения характеристика этих соединений – относительно большие расстояния и, как следствие, большие задержки. Сегодня serial links являются устаревшими и подлежат замене, однако, есть похожее по характеристикам соединение – радиоканал. Рассмотрим такую схему:
Единственный момент, отличающийся от настроек по умолчанию – использование Frame-Relay на serial link.
R1#sho run | s 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.14.1 255.255.255.0
router eigrp 1
network 0.0.0.0
R2#show 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 Serial4/0
ip address 192.168.23.2 255.255.255.0
encapsulation frame-relay
no keepalive
frame-relay interface-dlci 100
router eigrp 1
network 0.0.0.0
R3#show run | section interface|router
interface Loopback0
ip address 3.3.3.3 255.255.255.255
interface Serial4/0
ip address 192.168.23.3 255.255.255.0
encapsulation frame-relay
no keepalive
frame-relay interface-dlci 100
router eigrp 1
network 0.0.0.0
Попробуем завести стенд без SIA. Эта функциональность появилась в версии 12.1(5), поэтому подойдёт любая прошивка версии 12.0. Отбросить непосредственно сообщения Query с помощью ACL невозможно, однако, мы можем запретить unicast пакеты; таким образом, мы отбросим Query и разрешим Hello. В результате R2 будет считать, что R3 отказал, по истечению Active таймера (180 секунд по умолчанию) вместо Holddown таймера (также 180 секунд по умолчанию). Признаюсь, выглядит, как создание искусственных условий для проявления проблемы, однако чуть ниже мы обсудим этот момент более подробно.
R3#show ip access-lists
Extended IP access list NOUNICAST
10 permit ip any 224.0.0.0 15.255.255.255
20 deny ip any any
Отключим теперь 1.1.1.1/32 и применим ACL на R3:
R3(config)#interface s4/0
R3(config-if)#ip access-group NOUNICAST in
R1(config)#iinterface lo0
R1(config-if)#sh
R1 теперь считает, что маршрут находится в состоянии Active.
R1# show ip eigrp topology active
IP-EIGRP Topology Table for AS(1)/ID(1.1.1.1)
Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply,
r - Reply status
A 1.1.1.1/32, 1 successors, FD is Infinity
1 replies, active 00:00:07, query-origin: Local origin
Remaining replies:
via 192.168.12.2, r, FastEthernet0/0
Спустя 3 минуты R1 должен был бы удалить маршрут, поскольку Reply про него от R2 не приходил, так как не было ответа от R3. Однако, наблюдать можно другое:
R1#show ip eigrp topology active
IP-EIGRP Topology Table for AS(1)/ID(1.1.1.1)
Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply,
r - Reply status
A 1.1.1.1/32, 1 successors, FD is Inaccessible
1 replies, active 00:03:05, query-origin: Local origin
via Connected (Infinity/Infinity), Loopback0
Remaining replies:
via 192.168.12.2, r, FastEthernet0/0
R1#show ip eigrp topology active
IP-EIGRP Topology Table for AS(1)/ID(1.1.1.1)
Что-то пошло не так с настройками? “Я так не думаю” ⓒ. Впрочем, вернёмся к использованию Active таймера вместо Holddown для обнаружения отказа. Представим, что между R1 и R2 есть некоторое количество маршрутизаторов, соединённых с помощью serial links, которые вносят вклад в задержку между R1 и R2. Может ли так случиться, что разница во времени между отказом 1.1.1.1/32 (старт Active таймера) и получением последнего Hello от R3 (сброс Holddown) окажется меньше задержки между R1 и R2? Сценарий маловероятен, но возможен при неудачном стечении обстоятельств:
Хотя R2 разорвёт соседство с R3 спустя 180 секунд, R1 сможет получить информацию об этом лишь через некоторое время.
Если “повезёт”, последний Hello и отказ 1.1.1.1/32 произойдут почти в одно время.
Как только R2 подготовит Reply для R1, на R1 истечёт Active таймер, что приведёт к разрыву соседства между R1 и R2 согласно описанию DUAL. Легко представить, что такое поведение может привести к нестабильности EIGRP на участке сети, весьма удалённом от действительной проблемы.
Почему мы фильтровали только unicast пакеты, а не все EIGRP сообщения разом? Это позволило отказаться от синхронизации отказа 1.1.1.1/32 и получения последнего Hello от R2 на R3, хотя это и можно было бы сделать с некоторой долей автоматизации. Использование Active таймера исключило задержку, вносимую моими руками, не внося при этом изменений в конечный результат.
Теоретические упражнения – это, конечно, замечательно, однако описание выше не согласуется с опытом. Тут я могу предположить следующее:
В целом, проблему можно решить, увеличив разницу между значениями Active и Holddown таймеров. Однако эффективность такого подхода зависит от суммарной задержки между крайними узлами в сети, поэтому это скорее костыль, нежели полноценое решение задачи. Возможно, что IOS 12.0 именно так себя и ведёт; можно было бы проверить это предположение на более древней версии IOS, например, 11-ой, но я не смог такую найти.
Полноценное решение проблемы – SIA. Идея проста: отвязать проверку доступности сети (Query) от проверки доступности соседа (SIA-Query). Такой подход не зависит от задержки в сети по сравнению с решением на таймерах. Кроме того, разделение функций вместо их чрезмерной перегрузки обычно является более жизнеспособной архитектурой.
Какой же практический смысл статьи, особенно с учётом того, что SIA нельзя отключить? Честно говоря, околонулевой, если у вас нет маршрутизатора с весьма древней прошивкой (хотя в этом случае SIA – наименьшая из забот). Мне нравится разбираться, почему появилась та или иная фукнция – возможно, такое знание принесёт чувство удовлетворения кому-то ещё.
Спасибо за рецензию: Анастасии Куралёвой