Транспортный механизм EIGRP: типы служебных пакетов, надёжная доставка обновлений и проблема зависания маршрутов.
На какой мультикаст-адрес EIGRP отправляет Hello-пакеты?
Что такое SIA (Stuck-in-Active) в EIGRP?
Как подтверждаются надёжные пакеты EIGRP?
Что происходит при потере маршрута, если нет feasible successor?
Для чего предназначен CR-bit (Conditional Receive) в EIGRP?
Протокол EJRP Протокол EJRP
Протокол EJRP в сам протокол. TCP имеет встроенное подтверждение получения сообщений, но TCP использовать нельзя, потому что TCP с Multicast не работает. А RTP, который в EGRP есть как транспортный протокол, умеет работать и с Multicast, и с подтверждением сообщений. И если нужно будет, может отправить Unicast. У него достаточно хитрая организация передачи данных. Ничего кроме EGRP сообщений, впрочем, в него положить не получится. Чем хорош этот RTP? Он будет передавать данные либо быстро, либо надежно. TCP у нас передает данные надежно, но не умеет гарантировать, что какие-то данные точно быстро дойдут до получателя. Потому что все эти механизмы — доставили, надо подтвердить,
надо подтвердить, что получили подтверждение — это занимает некоторое время, и поэтому некоторые сообщения могут доставляться долго. В RTP у нас есть механизм, при котором работа идет быстро. И в то же время гарантированная доставка тоже есть. RTP умеет на лету переключаться между этими двумя режимами. Для того чтобы RTP работал, нужно, чтобы поддерживался мультикаст на канальном уровне. Сразу возникает вопрос, а что делать во фрейм-рилее, что делать в DMVPN, в котором с мультикастом напряженка? Здесь мы можем вспомнить, что EJRP писался Cisco для своих роутеров, и, соответственно, в фрейм-рилее и в DMVPN у Cisco есть такая штука, как эмуляция мультикаста. Если нам что-то нужно будет отправить на канальном уровне мультикастом или бродкастом, то у нас есть ключевое слово бродкаст во фрейм-рилее или у нас есть ручной маппинг мультикаста в DMVPN. Мы можем просто в явном виде сказать, что когда у нас есть желание
отправить какой-то мультикастовый пакет на интерфейсе, на самом деле мы вместо него отправляем пачку юникастовых кадров. Это и есть фактически эмуляция мультикаста. В каждом сообщении RTP у нас будет передаваться сначала заголовок, а потом данные. И данные будут иметь форму TLV — тройку type length value. Сейчас мы говорим про совершенно произвольный абстрактный заголовок, который есть у любого сообщения. Он будет опять же выровнен по границе 4 байт. Начинается всё с header version, просто версия заголовка, она плюс-минус всегда одинаковая. Потом указание на код операции — что мы за сообщение передаем, фактически указание, что внутри лежит. Двухбайтовая чек-сумма. Некоторые флаги, которые будут зависеть от того, что внутри лежит. И поля sequence number и acknowledge number. Здесь мы можем насторожиться — как удивительно интересно. В TCP очень
подозрительно похожие поля sequence number и acknowledge number. И не случайно вы можете насторожиться, потому что технология подтверждения данных в RTP очень похожа на TCP. Мы посылаем какой-то кусок данных, указываем его sequence number, и соответственно в ответ нам идет подтверждение на этот sequence number. Если сосед что-то подтверждает, он нам говорит в acknowledge number: я принял успешно сообщение с номером таким-то. Только в TCP у нас идет нумерация потока байт, и поэтому мы вкладываем в sequence number не просто номер куска сообщений, а номер первого байта, который мы передаем. А acknowledge, соответственно, последний байт, который был принят штатно в порядке общей очереди. А в RTP у нас каждый пакет пронумеровывается отдельно. Сначала мы отправляем пакет номер один, потом пакет номер два, пакет номер три и acknowledge именно пакеты. Такая небольшая
разница с TCP всё-таки есть. Если вдруг вы будете работать в EGRP с режимами нескольких адресных семейств, здесь будет указываться, какое именно адресное семейство вы будете использовать. Смысл в том, что по одному и тому же каналу можно передавать несколько разных сообщений EGRP. И здесь можно будет указывать, соответственно, что за адресное семейство. Вы имеете в виду IPv4, IPv6, IPv4 Unicast, Multicast. Можно будет с этим делом поиграть. В CCNA мы с этим ничего не трогаем, в CCNP тоже не трогаем, но в CCIE, если захотите, можете это поковырять. И вы указываете номер автономной системы. Это уже привычное нам значение. Вы просто отправляете, что сообщение идет в автономке с номером таким-то. И всё. Номер автономки в EGRP двухбайтовый. Никаких ограничений на использование
номеров автономных систем нету. Главное, чтобы у вас на ваших роутерах номер автономной системы был везде одинаковый. Если вдруг у вас есть несколько различных автономных систем, то с помощью этого номера вы можете как раз указать, где EGRP-шная дружба у вас должна происходить, а где не должна. Дальше идут сами данные. Так. Страшная табличка. Запоминать её не надо, но некоторые вещи отсюда надо будет запомнить. Я вам покажу, какие. Здесь показано, что у нас в EGRP есть несколько типов пакетов. И эти пакеты различаются как раз кодом операции. Самый первый пакет, который у нас изучался в EGRP на CCNA, это пакет Hello. С помощью этих пакетов мы обнаруживаем соседей, проверяем согласованность настроек соседей и разные другие вещи тоже делаем. Если вы отправляете такой пакет, вы его всегда отправляете мультикастом. Hello пакеты всегда идут мультикастом, всегда идут на
уровне интерфейса на всех соседей. Вы не отправляете отдельно Hello пакет Васе, отдельно Пете, отдельно Коле. Вы отправляете один пакет. Дальше, если его нужно будет расклонить, эмуляция бродкаста этим займется. Hello пакеты подтверждать нет смысла, потому что если вдруг потеряется Hello, ничего плохого в этом не будет. Вы просто следующий пакет отправите через 5 секунд и всё. Дальше. Код операции у Hello пакетов будет пятерка. Возвращаясь на предыдущий слайд, вот у нас оп-код, 1-байтовое поле, в котором указывается, что внутри лежит. Если вы здесь указываете пятерку, это будет Hello пакет. Если вдруг у вас есть какие-то данные, которые вы хотите отправить, и вы отправляете эти данные, и вам хочется эти данные отправить надежно, на эти надежные данные надо будет что-то отправить в ответ, чтобы подтвердить доставку. Вы можете отправить абсолютно любой Unicast-овый пакет, в котором вы укажете acknowledge number того, что вы приняли,
для того чтобы подтвердить, что вы приняли какие-то данные. Как в TCP: мы отправляем какой-то сегмент с данными, и нам возвращается ответ — любой другой сегмент, в котором указано, что я получил какие-то данные. В этом сегменте могут бежать какие-то полезные данные, или могут не бежать никакие полезные данные, просто приходит пустой сегмент, в котором написано, я получил то, что ты только что отправил. В RTP точно такая же система. Абсолютно любой пакет может подтвердить доставку данных, пришедших немножко раньше. Главное, чтобы он Unicast-овым пакетом был. Но если вдруг вам ничего не хочется отправлять специального, вы можете отправить пустой Hello пакет. И такой пустой Hello пакет вы отправляете, указываете в нем acknowledge number и говорите, всё хорошо, мы получили какие-то данные. Единственное отличие такого пакета от настоящего Hello будет то, что он пойдет Unicast. Точно так же acknowledge нет смысла подтверждать в ответ. Такой пакет не надо подтверждать,
он отправился в сеть и всё. Если вдруг сосед не получил наш acknowledge, он нам переотправит свои данные, которые хотел отправить, но не получил на них подтверждение, и мы ему снова это заacknowledge-им. Поэтому acknowledge нет смысла подтверждать в ответ. Код операции там точно та же самая пятерка. В старых версиях IOS можно встретить следы отдельного типа пакетов, который назывался Ack, и у него был другой код операции, восьмерка. Но его ни в стандарте нету, ни в актуальных версиях он не используется. Если вы попытаетесь acknowledge отправить восьмерку, то актуальные операционные системы просто не поймут. Дальше. Пакет важный, который называется Update. В этом пакете, собственно, всё мясо будет. Когда вы отправляете какие-то полезные данные, вы отправляете их либо Multicast, если вы на интерфейсе видите несколько соседей,
либо если этот интерфейс Point-to-Point, или вы хотите переотправить какие-то данные, то в этом случае можете отправить такой пакет Unicast. Апдейты могут идти и так, и так. RTP на лету выбирает, каким конкретно механизмом отправить каждый конкретный апдейт. Апдейты содержат важную информацию, поэтому их нужно подтверждать. Любой другой Unicast-овый пакет, и даже Unicast-овый апдейт, тоже пойдет для того, чтобы подтвердить получение апдейта. Но если ничего не хочется отправлять в ответ, то можно отправить пустой Hello, и он будет называться Acknowledge. У апдейтов код операции единичка. Это самый важный пакет, который есть в RTP. Иногда будет нужно отправить запрос маршрута соседу, спросить, у тебя есть живой маршрут, и сообщение будет называться Query. Query. Оно, так же как и апдейты, может идти Multicast, может идти Unicast.
И если вы отправляете такой запрос, то, соответственно, надо будет подтвердить, что получатель его получил, на него надо прислать отдельный Acknowledge. Можно прислать Acknowledge reply. Unicast-овый reply подойдет для того, чтобы ответить на запрос, на Query. Или можно отдельно отправить Acknowledge, а потом ответить reply-ем, когда будет вам удобно. И Query, и reply должны доставляться надежно. Это важные сообщения, мы их разберем чуть дальше. Соответственно, оба они доставляются надежно, и для обоих из них нужно подтверждать доставку. Query можно подтвердить reply-ем, если у вас сразу есть готовый ответ. Reply подтверждаются отдельным, как правило, пустым acknowledge. Коды операции тройка-четверка. Вы можете не запоминать коды операции. Здесь важно было, на самом деле, то, что когда-то давно был отдельный тип пакета Ack, а сегодня пустой Hello пакет является замечательным подтверждающим пакетом для получения данных. На какой адрес отправляется Unicast Update?
На адрес соседа. Мы же знаем всех соседей наперечёт. У нас эти соседи все в отдельной табличке сидят, поэтому мы можем отправить ему пакет адресный. Ещё два специальных пакета: SIA Query и SIA Reply. Разберем попозже, что они означают. Они всегда идут Unicast, всегда идут надежно. Коды операции у них немножко другие. Они по типу такие же, как Query и Reply, просто используются они в специальном сценарии. И поэтому у них отдельные названия и отдельный код операции. А логика у них, в принципе, такая же, как у Query и Reply. Формат такой же. Есть некоторые типы пакетов, которые можно проследить, во-первых, в старой литературе, во-вторых, в справке IOS. Если вы, допустим, пробуете включить дебаг, там можно включить дебаги EIGRP packet. И система при отображении справки показывает, какие типы пакетов она, в принципе, знает. Первые пакеты, которые мы с вами разобрали,
они встречаются в современных сетях. Эту штуку вы можете встретить. И такие пакеты действительно будут передаваться. Но есть также и другие типы пакетов, которые Cisco показывает в справке. Они иногда встречаются в старых книгах, но по факту сегодня не используются. Есть сообщение, которое называется Request. Оно использовалось для сценария с так называемым route-сервером, когда у вас был один сервер, который подключен к толстому общему коаксиалу. К этому коаксиалу подключались многие разные другие серверы. И они дружили не между собой напрямую, они дружили все с этим route-сервером. Для сокращения количества соседств. Как в OSPF придумали LSA-ку-двушку. Здесь такая же история. Это был роутер, который по факту принимал все маршруты от соседей в сегменте. Дальше он просто раздавал эти маршруты соседям с указанием next-hop-ов соседей. Поэтому трафик ходил между соседями напрямую.
Хотя они друг с другом не пирились, они друг друга не видели. Но они работали только с этим route-сервером. И для получения маршрутов через route-сервер использовалось сообщение Request. Сегодня нет смысла использовать такую штуку, потому что сегодня EIGRP прекрасно работает в сценарии, когда каждый видит каждого. Дальше. Реквесты отправлялись как Multicast, так и Unicast. Можно было отправлять Multicast request, в принципе, если было очень сильно нужно. Они отправлялись ненадежно. Код операции у них был двойка. Сегодня реквестов вы не увидите. Сообщение типа Probe. Это, опять же, тяжелое наследие старого протокола IGRP. Вы могли отправлять зонды на соседа и могли таким образом соседа пинговать. Ты мне давно ничего не присылал, это потому что ты мне ничего не хочешь присылать, или потому что ты труп. Мы могли Unicast подергать соседа. Это был код операции семерка.
Опять же, сегодня, если посмотреть исходные коды операционной системы Cisco IOS, на эти ответы, на зонды, вообще ответчик даже не висит. Поэтому в 11-м IOS он уже считался устаревшим. Но тем не менее вопросики показываются. И для обмена IPX-овых маршрутов был специальный отдельный тип пакета, который назывался IPX SAP. Опять же, в современных сетях, в современных IOS-ах у вас просто блока, плагина для IPX уже больше не будет. Поэтому Cisco показывает, что она такой тип пакета знает, а по факту с ним работать не будет. В этой табличке показаны все опкоды, которые когда-либо существовали. Звездочкой помечены те типы пакетов, которые не реализованы в современных версиях IOS. Отдельных пакетов, которые имели бы тип восьмерки, acknowledge,
в современных IOS-ах нету. И семерок-шестерок тоже нету. Двойку, в принципе, можно ещё встретить в IOS-ах, в которых она есть. Но даже если говорить про стандарт, там написано, что неплохо было бы его реализовать. По факту не написано, как это делать, но это уже мелочи. Всё остальное — пакеты, которые обведены в верхнюю рамочку, вы должны будете знать, какие они. Это Hello, Acknowledge, Update, Query, Reply, SIA Query, SIA Reply. А кто из них отправляется мультикастом, кто юникастом — надо будет просто понимать. Это надо не запоминать, это надо просто понимать. Hello сообщения всегда идут мультикастом. Они очевидно ненадежны, идут мультикастом, просто отправляются в среду и всё. Апдейты — надо просто запомнить, что они могут быть и такие, и такие. За счет того, что в апдейтах содержится важная информация, они обязательно доставляются надежно. В принципе, все сообщения, которые есть в актуальных версиях IOS,
все доставляются надежно, кроме Hello. Hello и пустой Hello, который используется для acknowledge, они ненадежны. Всё остальное по факту надежно. Мультикаст используется как для Hello, обычных нормальных Hello, так и для Query и Update. Всё остальное идет Unicast. Так, по поводу гарантированной доставки я, в принципе, всё уже рассказал. В EIGRP, если вдруг вы захотите отправить сообщение, которое нужно отправить надежно, вы проставляете Sequence Number. Если вы хотите отправить пакет, которому не требуется надежная доставка, то вы в Sequence Number ставите ноль. В TCP так делать было нельзя. Мы не могли отправить просто сообщение, какое-то внеплановое с непонятным номером, которое не по очереди идет. А здесь можно. Если вы хотите отправить пакет с номером X, вы отправляете пакет и пишете в нем. Если вам требуется надежная доставка, пишете в нем X. Если вы захотите переотправить какие-то данные,
которые, вы знаете, сосед недополучил, или у вас есть подозрение, что сосед их не получил, вы можете их переотправить и тем самым обеспечите ту самую гарантированную доставку. Если вы отправили пакет с номером X, и к вам пришел какой-нибудь Unicast-пакет, в котором прописан acknowledge number X, то вы понимаете, что сосед этот пакет получил и обработал. Соответственно, Sequence Number увеличивается на единичку при отправке любого пакета, которому требуется гарантия доставки. Сначала отправляем первый пакет, потом второй, потом третий, и нумерацию пакетов мы ведем отдельно для каждого соседа. Если у нас есть роутер, и у него два соседа, левый и правый, то нумерация с каждым по отдельности будет согласовываться. Более того, отдельно нумеруются пакеты, которые идут к нам, и отдельно нумеруются пакеты, которые идут от нас. Так же, как в TCP, отдельно нумеруются байты, которые мы отправляем, и отдельно нумеруются байты,
которые мы принимаем. Если вдруг вы получаете Unicast-овый пакет, в котором указано ненулевое поле acknowledge number, то это и есть подтверждение. Все, кроме Hello, доставляется надежно. Так, по поводу мультикаста. Там, где есть смысл отправлять одно сообщение сразу многим, EIGRP использует мультикаст. Во-первых, это Hello. Если мы не прописываем статических соседей. Можно такую штуку сделать: в EIGRP указать, что есть какой-то IP-шник, который всегда на интерфейсе есть. Если у вас тип интерфейса такой, в котором мультикаст может быть затруднен, то вы можете прописать четко конкретных соседей, сказать, что с этими соседями мы ведем обмен Unicast-ом, потому что мультикаста там в принципе нет. В остальных случаях Hello идет мультикастом.
Апдейты в норме идут мультикастом. Но есть нюанс. Первый нюанс заключается в том, что если вы отправили в интерфейс, в котором у вас несколько соседей, апдейт, некоторые из этих соседей подтвердили получение апдейта, а некоторые нет, вы переотправляете данные с помощью Unicast-а. Вы отдельно всем, кто не подтвердил получение мультикастового апдейта, досылаете эту самую разницу с помощью Unicast-а. И плюс дополнительно вы еще делаете Unicast-овые апдейты в ситуации, когда у вас устанавливается соседство. Роутер Hello отправил, сказал, что он в сети существует, и дальше у вас начинается 3-way handshake. С помощью Unicast-овых апдейтов роутеры устанавливают соседство. Они согласуют sequence number-а, они обмениваются стартовыми базами. И вот как раз в этой ситуации апдейты для роутеров, которые устанавливают соседские отношения, будут идти Unicast-ом.
С запросами, когда у нас пропадает какой-то маршрут, та же самая примерная история. Планово мультикаст, Unicast для ретрансмитов. И если у нас есть point-to-point интерфейс, на котором сосед по определению всего один, или у нас есть статические соседи, которые прописаны вручную, мы их не обнаружили автоматически, мы их прописали вручную как администратор, то с ними тоже обмен будет идти Unicast-ом. Запоминать здесь это не нужно. Нужно понимать, что планово для апдейтов и запросов используется мультикаст, но в некоторых случаях может использоваться также и Unicast. Не обязательно все пакеты будут идти мультикастом, но, по крайней мере, некоторые мультикастом точно идут. Если вдруг вы отправляете какой-то пакет в среду, то EIGRP будет использовать следующий алгоритм. Если есть кто-то, кто хочет получить эти данные,
а вы знаете, кто хочет получить эти данные, потому что у вас есть список всех соседей и есть список пакетов, которые они подтверждали, вы для каждого соседа ведете учет, что вы им отправляли, что они получали. Если у вас есть какой-то новый пакет, который вы хотите отправить в среду, то вы отправляете пакет мультикастом. Среди всех получателей этого пакета вы вычисляете время, в течение которого должны прийти все подтверждения. На каждом соседе вы знаете среднее время прохождения пакетов туда-обратно. Retransmission timeout. Вы вычисляете для каждого соседа Smooth Round Trip Time, SRTT. Дальше на основании SRTT вы вычисляете RTO и ждете все подтверждения в течение этого самого времени RTO, Retransmission Timeout. Если все получили подтверждение, вы говорите: все хорошо,
мы отправили мультикастовый апдейт, мы получили на него все acknowledge, все замечательно. Если кто-то недоподтвердил получение апдейта, то вы отправляете Unicast-ом задолженности тем, кто не подтвердил эти сообщения. Вы говорите: у нас есть в среде Вася, Петя, Коля, Сережа за одним и тем же интерфейсом, мы отправили мультикаст, Вася, Петя подтвердили, Коля, Сережа нет. Мы отправляем специальные пакеты отдельно Коле и отдельно Сереже. Есть еще один замечательный момент, который называется Conditional Receive. В CCNP он вам не понадобится, но на CCIE, если вдруг вы замахиваетесь, эта штука вам будет нужна. Это ситуация, при которой вы отправили мультикастовый пакет, вам не подтвердили некоторые участники получение этого пакета, а вам надо еще один мультикастовый пакет отправить в среду. И получится: если вы отправите новый мультикастовый пакет и он до всех дойдет, то тот сосед, который получил пакет внепланово,
он вам должен будет его подтвердить. И если он подтверждает тот пакет, то непонятно, что делать с предыдущим пакетом, который он недоподтвердил. Может получиться ситуация, при которой у него есть более свежая дельта, а более старой дельты нету. И соответственно обрабатывать такой пакет будет невозможно. Поэтому вы отправляете следующие мультикасты только для тех, кто получил все предыдущие пакеты. Вы выставляете флажок Conditional Receive в исходящих мультикастах. И это означает, что если вы знаете, что получили все свои предыдущие апдейты, то вы этот пакет обрабатываете. Если же вы видите, как получатель, что пришел какой-то пакет, в нем стоит флаг Conditional Receive и у него номер не совпадает с тем, что вы ожидаете увидеть, то в этой ситуации вы не обрабатываете такой пакет. Вы ждете, что Unicast-ом именно на вас придут все пакеты в нужном порядке.
Если вы хотите, можно отключить использование мультикаста на интерфейсе вообще. В некоторых очень экзотических средах это может быть интересно. Вы прописываете просто всех соседей вручную в Static Neighbors, и у вас все пакеты будут идти Unicast-ом. Не рекомендуется это делать. Только если вы это делаете, то вы должны будете понимать, что другого способа существовать в этом интерфейсе у вас просто не будет. Например, это какие-нибудь каналы типа спутниковых или что-то еще, там, где мультикаста может действительно не быть. Так, дальше. Если у нас есть два роутера, которые будут устанавливать соседские отношения, они будут сначала работать с помощью Hello-пакетов. Они будут обнаруживать друг друга. Они будут с помощью Hello-пакетов проверять непротиворечивость настройки друг друга. Проверяют номера автономных систем,
проверяют MTU, синхронизируют sequence number-а. Они по факту будут считать, что у них номера будут нулевые, но если посмотреть в Wireshark, что там будет передаваться, там может с sequence number-ами быть некая сложность. Сложность будет заключаться в том, что для того, чтобы запутать потенциальных злоумышленников, может быть такое, что стартовые sequence number-а будут не нулевые. По проводу будут передаваться эти номера с прибавленными какими-то чексуммами. И для того, чтобы обезопасить себя от злоумышленников, можно эти стартовые номера синхронизировать на роутерах. В принципе, в TCP подобная ситуация есть, когда вы флаг SYN отправляете, то как раз там initial sequence number согласуется, с какого байта вы начинаете нумерацию. Как будет происходить установление соседства? Сначала Hello-пакетами роутеры обнаруживают друг друга,
проверяют, что они правильно настроены. Дальше вы запускаете процедуру установления соседства с помощью апдейтов, в которых ничего нет, так называемый null update. И в них есть флажок. Помните, там 4-байтовое поле с флагами было? Для апдейтов вы выставляете флаг init, и в этом init вы проставляете указания, какие стартовые номера у вас будут. Дальше. Пример. Я сейчас анимацию покажу. У нас есть два роутера, они только-только включились. И может быть такое, что в этом проводе есть еще другие роутеры какие-то. И когда роутер 10.0.0.2 отправлял Hello-пакеты, он отправлял Hello-пакеты, и эти два товарища с ним уже установили полноценные взаимоотношения. Более того, в работе у этого роутера были какие-то апдейты,
и он посылал на этом интерфейсе апдейты. И у него получается, что сейчас пакеты, которые он отправляет, будут иметь стартовый номер 5. В ситуации, когда роутер 10.0.0.2 отправлял пакеты до того, как включился 10.0.0.1, он уже этих пакетов отправил 5 штук и в ближайшее время собирается отправлять 6-й. Тут у нас включается 10.0.0.1, у него стартовый номер 0. И они хотят согласовать стартовые номера для того, чтобы понять, кто с каким номером будет передавать данные. Самый первый пакет, который отправляется... Так, где анимация? Это первый Hello-пакет отправляет роутер 10.0.0.1. Как только такой Hello-пакет виден, в ответ идет другой Hello-пакет от 10.0.0.2. В нем прописано, куда отправляется такой пакет — на мультикастовый адрес. В Hello у нас ненадежная доставка, поэтому они не нумеруются. Sequence number 0, acknowledge number 0.
Мы ничего не подтверждаем, мы просто отправляем Hello-сообщение. Дальше. Два роутера увидели друг друга. Они отправляют друг другу эти самые null-апдейты. Сообщение типа апдейт, в котором никакого апдейта по факту нету. В них указывается Unicast-овый адрес того, кто прислал Hello-пакет навстречу. И в них указывается стартовый sequence number, с которого будет идти нумерация. У 10.0.0.2 уже были отправлены сообщения, поэтому он говорит: я хочу отправить сообщение со стартовым номером 6, чтобы показать, что все остальные пакеты, которые я буду штатно отправлять, они будут идти как раз с номера 6. 10.0.0.1 получает такое сообщение и говорит: окей, а я буду отправлять сообщения с номера 1, у меня пока никаких сообщений не отправлялось. Я буду отправлять в этот интерфейс, в эту среду, где другие роутеры тоже есть, сообщения с sequence number 1. Но я подтверждаю, дорогой 10.0.0.2, тебе получение сообщения со стартовым номером 6,
sequence number 6. Апдейт идет Unicast-ом, поэтому он может подтвердить какие-то данные. И в acknowledge number 6 как раз показывается, что сообщение с sequence number 6 было успешно получено. Дальше 10.0.0.2 принимает такой апдейт. И с помощью этой процедуры установления соседства он понимает, что двусторонняя связность есть, все хорошо. Единственное, что это сообщение, апдейт, шло Unicast-ом, но тем не менее его все равно надо подтвердить. В нем sequence number 1 стоит, поэтому мы говорим: да, мы подтверждаем получение сообщения с номером 1. Но у нас больше ничего нет, что мы хотели бы отправить. Поэтому мы отправляем просто пустой Hello-пакет, который будет по сути называться ACK. Мы в нем проставляем sequence number 0, потому что ACK не нужен acknowledge, у них нет своего номера. И мы в acknowledge number проставляем единичку, что это сообщение подтверждает получение пакета с номером 1. Этот пакет имел номер 6, этот пакет имел номер 1.
Дальше. После того как эти три пакета у нас прошли — первый пакет, второй пакет, третий пакет — это в принципе процедура, очень напоминающая TCP-шную процедуру установления сессии. Трехэтапное рукопожатие. В нулевых апдейтах фактически происходит то же самое, что в TCP идет в сегментах, в которых стоит флаг SYN. Это согласование стартовых номеров, это проверка двусторонней связности. И этот ACK очень напоминает последнее сообщение ACK, которое есть в трехэтапном рукопожатии. Смысл у него тот же самый — подтвердить, что трехэтапное рукопожатие закончилось. После того как трехэтапное рукопожатие закончилось, дальше можно начинать передавать боевые данные. Стартовая таблица у 10.0.0.2 определенно какая-то была, поэтому он говорит: я тебе хочу отправить данные, которые у меня есть. И он отправляет апдейт, говорит, что у меня есть такие сети. В этом апдейте он указывает какой-то стартовый номер
и говорит, что хочет отправить данные с какими-то сетями, которые у него за спиной есть, чтобы все про эти сети узнали. Это сообщение acknowledge-ится, потому что апдейты доставляются надежно. Пусть даже оно пришло мультикастом, мы ответ посылаем Unicast-ом, пустое сообщение, говорим: да, все хорошо, мы acknowledge-им пакет номер 7. И если вдруг у 10.0.0.1 за спиной какие-то сетки есть, он про них тоже расскажет с помощью своего апдейт-сообщения, и acknowledge придет в ответ на это. После того как все маршруты обменяны, дальше идет нормальная боевая работа. Все роутеры посылают друг другу Hello-сообщения с пустыми номерами. Sequence number 0, acknowledge number 0. Вот так будет устанавливаться сессия в EIGRP. Что должно проверяться в Hello? В Hello передается номер автономной системы. Проверяются совпадения коэффициентов для вычисления формулы composite distance.
Если коэффициенты этой самой K-values 1, 2, 3, 4, 5, 6 не совпадают, то сессия не установится. Если номер автономки не совпадает, тоже не установится. И понятное дело, если мы будем, допустим, аутентификацию использовать, она тоже должна совпадать. Все остальное, включая таймеры, может быть различным. Таймеры, которые мы будем передавать, например, в Hello-сообщениях, будут указывать лишь на то, через сколько мы требуем, чтобы нас вычеркнули из таблицы соседей, если мы ничего нового не присылаем. Они не обязаны совпадать в соседних Hello. По поводу таймеров. Для контроля соседства мы используем таймер Hello time — как часто отправлять Hello-пакеты. И Hold time — это через сколько признавать соседа мертвым, если он ничего не присылает. Оба таймера контролирует тот, кто отправляет Hello-пакеты. Вы в Hello-пакетах пишете, через сколько вас признают мертвым, если вы ничего не пришлете. Разумно делать так, чтобы эти таймеры были одинаковые на соседних железках.
Это, однако, не требуется. Вы можете проставить таймеры совершенно произвольным образом. Вы можете сказать, что у вас две железки друг на друга смотрят на одном и том же интерфейсе, и одна железка отправляет Hello-сообщение раз в секунду, а другая отправляет Hello-сообщение раз в час. Сделать такое можно. Смысла в этом, наверное, не очень много. Разумно, чтобы сообщения отправлялись более-менее регулярно, синхронно. Также разумно делать, чтобы Hold time был, во-первых, больше, чем Hello time, во-вторых, чтобы он был больше хотя бы раза в три. Дело в том, что если у вас потеряется один Hello-пакет, вы не хотите, чтобы у вас разваливалось соседство. Если у вас потеряется два пакета, это тоже не повод разваливать соседство. Но если уж три пакета Hello потерялось, то здесь уже однозначно — три подряд потерянных Hello-пакета — это потерянный сосед целиком. Если вы используете таймер по умолчанию, то Hello time по умолчанию 5 секунд на быстрых интерфейсах.
Hold time 15 секунд на быстрых интерфейсах. Если вы меняете Hello time, то по умолчанию Hold time будет, если вы его не задаете в явном виде, равен как раз трехкратному Hello-таймеру. Если вы отправляете Hello-сообщение и указываете, что обещаете в течение следующих Hold time секунд прислать следующее Hello, но получатель ничего не получает, то он вас выбрасывает из таблицы. И он вам отправляет сообщение Goodbye, оно же Peer Termination. И оно будет состоять из обычного Hello, просто у него будут указаны все коэффициенты метрики 255. Если вдруг вы работаете со старым IOS, он просто такое Hello-сообщение проигнорирует, потому что у него заведомо коэффициенты метрики не совпадают с вашими. Вы вряд ли будете выставлять в здравом уме в реальности все коэффициенты 255.
Если у вас будет новый IOS, сравнительно новый, свежее чем 2000 года, например, то тот, кто получит такое сообщение, он поймет, что его вычеркнули из таблицы соседей. Это самое Peer Termination, или сообщение Goodbye. Оно очень полезное именно тем, что если вдруг действительно просто случайно потерялись Hello-сообщения, а так, в принципе, трафик нормально ходит, и сосед вычеркнул вас из таблицы соседей и отправил вам сообщение «я тебя прибил». Чтобы в этой ситуации вы не думали, что у вас все хорошо Чтобы вы понимали, что сосед с той стороны вас перестал считать нормальным соседом Это и есть peer termination, это не отдельный тип сообщения Это банальный hello, в котором указано k-values 255 для всех шести значений Для всех шести коэффициентов В некоторых ситуациях peer termination будет отправляться также просто в нормальной работе Если вы, например, выключаете EIGRP, указываете в настройках роутер EIGRP shutdown
То всем соседям тоже отправляется peer termination Соседство искусственно разваливается Для того чтобы соседи не ждали 15 секунд, пока вы перестанете присылать hello-пакеты А чтобы соседи сразу с вами разорвали соседские отношения Если вы штатно выключаете EIGRP, то эта штука позволяет соседям обновить таблицу сразу Дальше Когда у нас идет нормальная работа, маршруты мы анонсируем в сообщениях типа update Мы посылаем пакет update И подтверждаются эти сообщения любым unicast-овым пакетом Если вдруг вы отправляете update и этот update не проходит То вы переотправляете этот update, но уже, как говорилось, с unicast-ом И ждете, пока недостающие апдейты придут от соседей Недостающие acknowledge
Если у вас за время, в течение которого вы собирались отправить какие-то апдейты соседу Накопилось несколько префиксов, которые вы хотите отправить одним скопом То вполне можно в одном апдейте отправить несколько указаний Что вы знаете определенные сетки с определенными векторами метрик В одном апдейте может идти несколько префиксов Здесь у нас как раз ситуация вида Появилась новая сетка У нас отправляется апдейт с номером 10 Сосед говорит, все хорошо, я его получил Acknowledge идет unicast-ом И не sequence number 0, а acknowledge number 10 Потом еще что-то происходит Сетка снова появляется Идет новый апдейт с sequence-номером 11 И ответного acknowledge нету Мы ждем некоторое время Retransmission timeout, который вычисляется на основе SRTT И переотправляем этот апдейт, но уже unicast-ом IP-шник unicast-ового соседа, который нам не прислал подтверждение, мы знаем
Первичные апдейты идут multicast-ом Вы отправляете один апдейт на всех И вы ждете от каждого соседа, который такой multicast-овый пакет должен был на интерфейсе получить Подтверждение Если кто-то не прислал, то вы ему штатно переотправляете Sequence number при этом сохраняется Это та же самая информация И содержимое этого апдейта точно такое же, как было в исходном пакете Именно поэтому, чтобы не напрягать лишний раз других соседей, вы не отправляете этот повторный апдейт multicast-ом Вы говорите, не дошел пакет только до одного Поэтому дергать того, кому не пришло, мы будем адресно, не будем дергать всех подряд И acknowledge приходит с acknowledge number 11 В этой ситуации все хорошо, все замечательно Если не приходят сообщения в течение некоторого времени, мы повторяем, повторяем, повторяем отправку Но рано или поздно, если не приходит acknowledge, то не приходят, наверное, и hello-пакеты
А если не приходят hello-пакеты, то через 15 секунд мы признаем соседа трупом Поэтому мы посчитали retransmission timeout, переотправили апдейт, потом еще раз переотправили апдейт, потом еще раз переотправили А потом уже и hold time вышел, и мы соседа признали трупом, и выкинули его из таблицы, и перестали посылать ему апдейты Если к вам приходят апдейты, то вы их анализируете только если они пришли от правильного соседа, который есть в таблице От кого попало апдейты вы не принимаете, это не RIP RIP принимал апдейты от кого попало У него не было концепции соседей, он отправлял сообщения просто всем и принимал апдейты тоже от всех EIGRP принимает только от тех, с кем проверена связь и заранее установлена сессия Все маршруты, которые приходят в апдейтах, попадают в таблицу топологии И сразу про этот маршрут мы запускаем проверку feasibility condition Если маршрут прошел feasibility condition, мы соседа, который прислал такой маршрут, объявляем feasible successor
Если маршрут не прошел feasibility condition, то мы соседа объявляем non-successor У нас есть сетка, допустим, 10.0.0.0/24 Есть для этой сетки feasible distance, которая посчитана, допустим, 100 И есть список next hop для этой сети Мы говорим, у нас есть IP-шник 192.168.1.1, который прошел feasibility condition, и мы его пометили как feasible successor И есть 192.168.1.2 Он не прошел feasibility condition, мы его объявили non-successor Те маршруты, которые прошли feasibility condition, могут быть отправлены в таблицу маршрутизации Но не обязательно будут отправлены Обычно отправляются маршруты с наименьшей метрикой И тот маршрут, который будет иметь наименьшую метрику, тот next hop, который прислал маршрут с наименьшей метрикой Посчитанный на нас с наименьшей computed distance Будет называться словом successor
Successor обязательно feasible successor Но не наоборот Почему можно отправлять маршруты, которые прошли feasibility condition, в таблицу маршрутизации? Потому что они не содержат петли Даже если этот маршрут не очень выгодный Он не такой выгодный, как тот, который прислал successor Он все равно хороший Вы можете смело, без дополнительных проверок, эти маршруты сразу вставлять в таблицу маршрутизации Что бы ни случилось, до тех пор, пока топология не перестроится Этот маршрут петлю через нас не содержит И если вдруг топология перестроится, мы об этом обязательно узнаем Именно поэтому в feasibility condition FD, feasible distance, должно быть строго больше, чем RD Если бы она была меньше либо равна, я показывал, что там петля могла бы возникнуть в будущем И про это никто бы не узнал За счет того, что FD строго больше, чем RD Если вдруг топология будет перестроена То мы про это обязательно узнаем Так, каждый префикс в таблице топологии будет иметь состояние
И это состояние можно будет посмотреть Там легенды есть, когда вы делаете show IP EIGRP topology Там показываются всякие страшные слова И напротив каждого маршрута показывается буковка Либо P, либо A, либо еще что-то бывает Чаще всего мы увидим P, это значит, что маршрут пассивный С ним все хорошо, у нас есть хотя бы один feasible successor С этим маршрутом все в порядке, им можно пользоваться В таблице маршрутизации он есть, пакеты по нему ходят Все замечательно Если у нас ни одного feasible successor нету Но при этом есть хотя бы один non-successor Есть подозрение, что все-таки надежда на то, что эта сетка еще где-то доступна Она еще у нас теплится Мы такой маршрут объявляем активным Активный маршрут — это значит, что им пользоваться нельзя Мы не можем сидеть на попе ровно У нас просыпается шило в соответствующем месте И мы начинаем оперативно-розыскные мероприятия Мы пытаемся понять, а сосед, который прислал нам плохой маршрут
Он нам его прислал, потому что он на самом деле через нас посчитал Или потому что у него где-то еще способ добраться до этой сети есть И мы ему посылаем сообщение с помощью алгоритма DUAL Мы запускаем diffusing updates, что эта сетка, допустим, пропала У нас нет ни одного feasible successor Мы хотим найти способ добраться до сети Если никто нигде в сети не знает, как добраться до сетки То хотя бы пусть нам об этом сообщит Мы из таблицы топологии эту сетку уберем Активный маршрут — это как раз такое, что все следственные органы подорвались И начинают искать с Шерлоками Холмсами, собаками И всем, чем только можно Хотя бы один роутер, у которого есть хотя бы один живой feasible successor Здесь надо помнить определение feasible distance Что это наименьшая метрика, computed distance наша За все время нахождения маршрута в пассивном состоянии Пока с маршрутом было все хорошо У него была метрика, которую мы ставили в таблицу маршрутизации И которую анонсировали своим соседям
Самая маленькая метрика, которую мы когда-либо видели Она может только уменьшаться, она не может увеличиваться, если с маршрутом все хорошо И мы помним ее И для того чтобы проверить, может ли гипотетический маршрут содержать петлю через нас Мы говорим Это возможно, например, в ситуации, когда это условие не выполняется Если это условие выполняется, маршрут заведомо и точно петлю через нас не содержит Поэтому тот, кто его прислал, он заведомо может быть установлен в таблицу маршрутизации в качестве next hop По поводу этих самых diffusing updates Этот алгоритм называется DUAL, Diffusing Update Algorithm Он будет состоять из двух частей Первая — это диффузия того, что какая-то сетка доступна У нас появилась новая сетка И она начинает распространяться сюда, сюда Этот роутер получил указание, что сетка доступна Он тоже во все стороны начинает ее рассылать То же самое, если сеть перестала быть доступна
Роутер узнал, что сетки нету Начинает рассылать сообщение У меня этой сетки больше нету, а у вас И сообщение о том, что эта сетка пропала Начинает распространяться точно так же по всей сети Мы спрашиваем у этого роутера У тебя есть такая сеть? Если у него мы были next hop, он говорит Нет, у меня такой сети нету Начинает спрашивать А у тебя есть такая сеть? А у тебя есть такая сеть? И дальше все эти запросы типа А у тебя есть такая сеть? А у тебя есть такая сеть? Они начинают разбегаться по всей сети Если выяснится, что у вас есть два next hop Два маршрутизатора, которые присылали вам анонс сетки Просто невкусные Они были у вас non-successor-ами И вы задали им вопрос У тебя есть такая сетка А они вам тоже в ответ спросили У вас тоже такая сетка есть? Вы понимаете, что на самом деле у соседа такой сети нет И вы сетку из таблицы топологии вычеркиваете Что такая сеть точно больше в сети не присутствует Если все задали друг другу Каждый задал каждому вопрос
У тебя такая сетка есть? То сети на самом деле ни у кого нет Если у кого-то сетка такая будет Кто-то скажет А у меня же есть такая сеть на самом деле У меня здесь запасной маршрут есть в эту сетку Он скажет У меня есть живой next hop У меня есть живой feasible successor И тогда, когда его спросят У тебя такая сетка есть? Он скажет, да, все хорошо И запускает алгоритм DUAL с диффузией доступности Когда у нас идет указание Что такая сетка действительно есть Все хорошо Сетка нормальная, живая, рабочая Для алгоритма DUAL у нас будут использоваться Два типа сообщений Апдейты Будут указывать на то, что у нас есть Хороший маршрут, который можно использовать Либо что сетка, которая у нас была Она заведомо перестала работать Для обоих случаев будет использоваться апдейт Если у нас есть маршрут, который использовался У него был feasible successor, но он пропал И у нас есть только подозрение, что надо проверить
Насколько живой маршрут присылали нам соседи non-successor-ы В этом случае мы этим самым non-successor-ам отправляем сообщение query Мы спрашиваем, ребят, а у вас есть живой маршрут? Если мы посылаем сообщение query соседу И мы у него были next hop-ом Он понимает, что через нас до этой сети больше добраться нельзя Если мы посылаем сообщение query соседу А у него есть живой next hop, но это не мы Он нам сразу посылает сообщение У меня все хорошо, у меня есть такой маршрут Пожалуйста, ходи через меня Ты не устроишь петлю Оба этих механизма query и update будут использоваться для того, чтобы разослать обновление маршрутной таблицы по сети Update Когда все хорошо или когда уже все точно плохо Прям совсем точно Совсем нет никакого доступа И query — это про то, что мы не знаем, как добраться до сети, но у нас есть подозрения Так, по поводу query
Если вы отправляете запрос, вы должны на него получить ответ Ответ на query — это всегда reply Query доставляется надежно, поэтому в принципе вы можете отправить query и получить на него acknowledge А потом получить reply и отправить на него acknowledge Но в принципе можно будет и отправить query и получить в ответ reply сразу с указанием acknowledge number И потом уже этот reply подтвердить Будет ли здесь промежуточный acknowledge или не будет, это уже не так важно Если вы отправляете запрос, вы говорите, что у нас есть подозрения, что какие-то сетки на самом деле недоступны У нас есть подозрения, что какие-то сети могут быть доступны, но они доступны не через нас И мы отправляем query, в котором указываем, возможно, несколько префиксов, потому что у нас, возможно, отвал был для нескольких сетей И все эти сети загоняем в один query-запрос
Дальше, мы отправляем запрос в этом самом query и говорим, через нас доступа до этой сети нету И вы указываете так называемую бесконечную метрику А бесконечная метрика — это такая метрика, у которой delay будет максимально возможный Maxint — это 4 миллиарда 200 с чем-то миллионов Если вы отправляете указание, что сетка через вас в этом самом query недоступна И вы указываете бесконечно большую метрику, это как раз будет означать, что через вас до этой сети добраться нельзя Если вы отправляете запрос, через тебя можно добраться до сети, вы ожидаете услышать в ответ сообщение типа reply Может быть, не сразу, может быть, через промежуточный acknowledge-пакет Но тем не менее, если вы query отправили, вы ожидаете, что на него ответ все-таки придет И в этом ответе вы ожидаете либо сообщение «У меня такой сети точно нету, я всех своих спросил, и они ответили, что нету» И это будет означать, что вам тоже придет сообщение с бесконечно большой метрикой
Или к вам придет нормальная хорошая метрика Это, в принципе, аналог апдейта, который просто идет не как апдейт, который можно, например, multicast-ом прислать А это именно ответ на ваш query Оно идет unicast, и оно говорит, ты спрашивал недавно про такие префиксы Пожалуйста, ходи через меня до этих префиксов, у меня метрика вот такая Прибавь к тем метрикам, которые я тебе сказал, те метрики, как ты знаешь меня, и ты получишь нормальный, хороший, живой маршрут Если у нас есть сетка, и в этой сети был какой-то роутер, который знал маршрут во внешний мир, но перестал И он говорит, у меня теперь этой сети больше нету, а у вас Отправляет сообщение query Если у вас есть successor И это не тот, кто прислал вам query У вас successor И вам кто-то сбоку прислал запрос Вы говорите, у меня все хорошо, я сразу отправляю reply без каких-либо acknowledge
Unicast-овый reply подтверждает получение query Говорю, у меня есть метрика маршрута, у successor какая-то хорошая Все замечательно, все нормально Не писать в компот, в нем повар ноги моет, потому что маршрут живой, маршрут точно рабочий Если запрос приходит от successor Но у вас есть другие feasible successor-ы Вы просто перескакиваете с того, кто вам прислал сообщение Через меня до этой сети больше добраться нельзя На другой роутер сразу, немедленно Обновляете метрику и отправляете бывшему successor reply, что через меня до этой сети добраться можно Я раньше через тебя ходил, а сейчас буду ходить через кого-то другого Раньше у нас была метрика через successor, допустим, 100 Он прислал запрос, через тебя можно добраться Мы говорим, 100 была на самом деле через тебя А через другой какой-то роутер, который проходит feasibility condition У нас метрика 150, и вы в ответ посылаете указание Я знаю, как добраться до этой сети, но 100, которое я заявлял раньше, это было через тебя
А сейчас знаю, как добраться за 150 Ходи, пожалуйста, через меня Если вы получаете апдейт от не-successor-а Какой-то другой роутер прислал вам сообщение И маршрут у вас уже находится в активном состоянии На самом деле живого successor-а нету Тот successor, который был, он спросил у вас, где взять эту сетку И вы понимаете, что через него до этой сети добраться уже нельзя Живых feasible successor-ов нету Вы объявляете маршрут в активное состояние И тут вам кто-то другой спрашивает, как добраться до такой сети? Тоже присылает query Вы говорите сразу, reply, понятия не имею У меня маршрут в активном состоянии, у меня все плохо, маршрут недоступен И, соответственно, если вы всех соседей таким образом оповещаете, что через вас достать сетку нельзя То рано или поздно диффузия недоступности, что сетки нету
Распределяется по всем-всем-всем роутерам Если вдруг обычный reply Здесь пока про stuck in active ничего нету Это просто обычный query, обычный reply Если вдруг у вас есть successor И нету других feasible successor'ов И к вам приходит запрос от successor'а С указанием того, что через него добраться до сетки нельзя Соответственно, вы в этом случае объявляете префикс активным И всем non-successor'ам рассылаете query Говорите, что делать? На самом деле, successor'у при этом тоже может отправиться query Это уже другая тема Вы отправляете всем non-successor'ам query Если вдруг они отвечают вам reply'ями, что через них добраться нельзя Вы отправляете итоговый reply тому, кто спрашивал То есть successor'у И если вдруг вы говорите, что я опросил всех своих соседей
Они мне сказали, что до сетки добраться нельзя Вы объявляете, что с префиксом всё хорошо, он не работает Переводите его в пассивное состояние С бесконечно большой метрикой Или если кто-то вам сказал, что через него добраться до сети можно Вы опять же переводите префикс в пассивное состояние Уже с какой-то хорошей метрикой Говорите, что нам кто-то прислал reply Что через него добраться можно Мы будем ходить через него Это механизм, как распространяются запросы Если у нас сетка где-то перестала работать, next hop Мы говорим, оставляем successor'а, оставляем маршрут в таблице топологии Просто мы помечаем его как активный, что пользоваться им по факту нельзя Но лучше, если мы некоторое время до выяснения всех обстоятельств next hop трогать не будем То есть даже если сосед нам прислал сообщение query, а мы держали его как successor У нас таблица маршрутизации была как successor Мы лучше до выяснения всех обстоятельств, до завершения работы алгоритма DUAL
Трогать next hop не будем Лучше трафик заблэкхолить, чем устроить петлю маршрутизации Это такая особенность EIGRP Поэтому, опять же, на CCNP это вам не понадобится На CCIE это довольно тонкий момент, который вам будет нужен EIGRP, в отличие от RIP, очень боится петли маршрутизации Он их очень не хочет делать Поэтому в ситуации, когда сетка переходит в активное состояние У вас next hop в таблице маршрутизации держится, хоть и неправильный Он держится старый, через который заведомо сетка не работает До тех пор, пока все обстоятельства не будут выяснены И у нас не будет указания, что маршрут переходит в пассивное состояние С новым next hop, через который можно добраться до сети В среднем можно говорить, что если у вас более-менее свежие роутеры Если у вас не огромная какая-то топология Не безумное количество маршрутов То на выяснение всех взаимоотношений между роутерами Требуется 1–2 секунды
То есть если это реальная топология из 50 роутеров Как-то между собой соединённых То на то, чтобы они друг другу разослали query, reply Требуется весьма небольшое время Есть один нюанс Не все роутеры могут быть быстрыми Особенно это было актуально в старые годы Когда у нас роутеры были реально медленными Сегодня, когда у вас процессоры в 1000 МГц Не являются никаким исключением из нормы Это не так актуально Но раньше роутеры действительно могли быть очень тормозными И плюс к тому, каналы, которыми они были соединены Они тоже могли быть очень тормозными И hello-таймеры, которые были на медленных каналах Как вы помните, они были 60–180 То есть вы раз в 60 секунд отправляли hello-пакет И через 3 минуты после того, как сосед перестал присылать вам hello-сообщение Вы признавали его мёртвым И это было очень неприятно
Потому что 3 минуты по факту Вы сидели и ждали перед тем, как признать соседа мёртвым Особенно было неприятно Если вас кто-то спросил Знаешь ли ты, как добраться до какой-то сети А вы в этот момент как раз отвалились Сосед-то вам задал вопрос Вы, может быть, даже этот запрос успели подтвердить пустым acknowledge'ем И дальше вы отвалились Вас уже ничего не волнует Сосед сидит и ждёт у моря погоды Когда вы ему наконец пришлёте reply И все остальные, кто задавал вопрос по цепочке Тоже сидят и ждут Потому что они не понимают, что с префиксом делать Эта штука называется stuck in active Маршрут, зависший в активном состоянии Или SIA Если у вас префикс перешёл в активное состояние Префикс может быть переведён обратно в пассивное состояние Только после того, как все, кому вы задали вопрос query, прислали вам reply Если кто-то из соседей не отвечает на query, то это непонятно, почему происходит
Но в любом случае мы не отвечаем тому, кто спросил этот префикс у нас То есть если мы задали вопрос — через тебя можно добраться до сети? И нам никто ничего не отвечает Мы не отвечаем нашему соседу, который задавал вопрос И он думает, что это тормозим мы А тормозим не мы, это тормозит кто-то следующий в цепочке Для того чтобы понять, кто тормозит Есть специальный механизм, который называется SIA-query, SIA-reply Здесь есть анимация Давайте я сейчас перезапущу её Так Вот анимация У нас есть какая-то сетка Она через какое-то время перестаёт работать Так Где анимация? Анимация Так, с анимацией какая-то проблема случилась Сейчас она... Вот, сетка перестаёт работать Роутер отправляет запрос query Своему соседу Тот своим соседям начинает отсылать query
Те своим соседям начинают отсылать query И ждут ответов От некоторых соседей приходят ответы Вот, например, этот получил ответ Отослал ответ соседу Этот ответ получил на одном интерфейсе, но не на всех И молчит в ответную сторону Поэтому соседний роутер говорит Через тебя — я тебе задавал вопрос — можно добраться? Получает сообщение SIA-query Ты что молчишь? Я тебе задавал вопрос, ты не ответил Роутер, в свою очередь От тех, от кого он ждёт ответа Посылает сообщение Я тебе задал вопрос, ты что не отвечаешь? И так все роутеры в цепочке Друг другу задают вопрос Ты что тупишь? Хорош тупить И этот роутер задаёт вопрос Ты что тупишь? И если вдруг этот роутер действительно ещё живой То он отвечает Со мной всё в порядке Я не туплю, я просто задумался У меня потерялось ответное сообщение Всё в порядке Вот тебе reply И соответственно он отправляет reply И этот reply дальше по цепочке идёт
В сторону исходного спрашивающего роутера Фишка в том, что на сообщение «Ты что тупишь?» Ответ SIA-reply идёт немедленно Когда вы отправляете обычный query У вас есть 3 минуты Это active таймер Когда вы отправляете обычный query У вас 3 минуты Таймер на то, чтобы получить ответ Active таймер Это сколько времени маршрут может находиться в активном состоянии Если мы получили запрос от successor'а У нас маршрут перешёл в активное состояние Мы ждём 3 минуты До получения сообщения о том, что маршрут есть или маршрута нет Если у нас сосед за 3 минуты не ответил Значит с ним всё плохо Этот таймер нельзя особо трогать И в этом нет особого смысла Если у вас интерфейсы достаточно быстрые
Если вы задали вопрос И вам сосед на быстрых интерфейсах Перестаёт отправлять какие-то ответы То вы его очень быстро вытащите из таблицы соседей Потому что у вас hello-сообщения перестанут приходить Но в случае, если у вас есть медленный сосед На медленном интерфейсе У него как раз 3 минуты есть на то, чтобы прочухаться Чтобы понять, что происходит Если мы посылаем ему какие-то сообщения А он не отвечает И этот самый active таймер Он как раз тоже 3 минуты То есть сколько маршрут может жить в активном состоянии Предполагается, что таймеры hello time Вы не будете настраивать какие-то совсем гигантские И hold time у вас тоже вряд ли больше 3 минут будет Если вы отправили запрос query И он в течение 3 минут не вернулся То у вас однозначно протухло соседство И вы этого соседа из таблички вычёркиваете И говорите: всех, кого хотели спросить, всех спросили
Никто нам не сказал, что маршрут живой Мы выкинули тех, кто не ответил вовремя, из таблицы В общем, всё понятно с этим маршрутом Но этот самый запрос SIA-query, SIA-reply Он позволяет нам немножко ускорить этот процесс Если мы задаём вопрос Ты живой? Ты тупишь? Ответь мне, пожалуйста То на него немедленно приходит сообщение Это не я туплю Это кто-то тупит дальше за мной За моей спиной Если вы задали вопрос Соответственно, ты что тупишь? И вы получаете ответ Это не я туплю Это кто-то за моей спиной тупит То вы продляете состояние active На половину времени active таймера То есть на половину времени Это на 90 секунд По стандарту нигде не написано Как должна работать эта штука Но по факту Cisco допускает до трёх продлений То есть если вы задаёте вопрос Ты что тупишь? Вам отвечают
Это не я туплю Вы продлили таймер на 90 секунд Через 90 секунд снова спрашиваете Ты что тупишь? Он говорит Это снова не я туплю Вы говорите окей И наконец в третий раз спрашиваете Ты что тупишь? И если сосед говорит Это снова не я туплю То вы уже не поддаётесь на эти уловки Вы говорите Нет, так не бывает Если ты три раза На мои вопросы Тупишь ли это ты Отвечаешь, что это не ты тупишь То ты должен был Соответственно сам спросить У своих соседей Кто тупит И за три попытки Пропинговать того, кто тупит Вы должны были уже определиться Кто тупит Должны были выкинуть его из таблицы соседей Поэтому Этот механизм Он позволяет как раз Определить Что происходит в сети И в принципе В большинстве ситуаций За одно пинание соседа Вы можете выяснить Кто именно тупит Но смысл заключается в том Что иногда Сами эти пакеты Query, reply Могут потеряться SIA-query SIA-reply
Вот Да В современном мире Stuck in active вы не увидите Именно потому, что Hello-таймеры На современных роутерах Сильно меньше, чем Active таймер Вся эта штука была нужна Только на медленных каналах Каналы, которые Медленнее, чем T1 Медленнее, чем полтора мегабита В секунду И да Там как раз Это было актуально Сегодня это уже не актуально Но в экзаменах всё ещё есть Механизм Stuck in active Он будет как раз Нужен в ситуации Когда мы отправили запрос И мы не получаем вовремя Ответа на наш запрос И это один из способов Соответственно бороться с тем Что вот мы Отправляем какие-то запросы И они в итоге Слишком долго идут По нашей сети Один из способов Борьбы с проблемой Долгих этих самых Квайр-запросов Это стак инэкшн Который штатно В EJRP используется
Но повлиять на него Вы особо не можете Самое большее Что вы можете сделать Это подкрутить таймеры А вот То, что вы можете сделать Если у вас есть Много квайр-запросов И некоторые из них Начинают теряться Некоторые из них Начинают тормозить То вы можете В принципе Как сказать Вы можете сократить Области В которых у вас Распространяются Эти самые квайр-запросы Очень полезная штука Что в некоторых ситуациях Вы можете сделать так Чтобы на роутеры Некоторые В принципе Квайри не отправлялись Вообще никакие Штука Это будет называться Стаб роутер Если у вас есть Роутер И вы знаете Что через этот роутер Нельзя добраться До других сетей Этот маршрутизатор Будет нетранзитный Он тупиковый Например Это Маршрутизатор филиала Вот у вас Есть Сетка Какая-то Сеть предприятия У нее есть Пограничный блок Это соответственно Роутер Бордер HQ1
Это роутер Бордер HQ2 И вы говорите Что у вас Есть какие-то Филиальные VPN сетки Которые подключаются Через туннели VPN К двум Вот этим Маршрутизаторам Headquarters 1 Headquarters 2 Если вдруг Между HQ1 И HQ2 Теряется связь Вот И HQ2 Хочет отправить Трафик на HQ1 Он может сказать У меня потерялась Сетка Вот сетка X Я не могу До нее добраться Он может отправить Запрос А есть ли у тебя Сетка X На стаб роутеры Он на все роутеры Это может сделать На все роутеры Отправить к Варе Но получится Что даже если вдруг Этот стаб роутер Скажет Да через меня До этой сети Можно добраться То у вас Связь между HQ1 И HQ2 По факту Будет идти через VPN И через туннели И это совершенно Не то Чего вы Наверное Захотите сделать Если у вас Потеряет роутер HQ связь То он должен сказать Что просто Ребят извините У меня просто Нету доступа К этой сети Не ходите До меня через нее Потому что
Иначе если будет Кто-то Кто подключен К роутеру HQ2 Он будет ходить В эту сетку Вот так вот Это совсем не то Чего вы хотите В то же время Если вдруг HQ2 скажет Что у меня Доступа в эту сеть Нет То соответственно Тот филиальный роутер Который пытается До этой сети добраться Он просто пойдет Через второй маршрут И все Вот если вы знаете Что у вас Что-то примерно Наподобие Такой топологии Используется Вы можете сказать Что через филиальные роутеры Через Роутеры Которые находятся Вот через VPN туннели В принципе Нельзя пропускать Транзитные маршруты Вообще Этот роутер Он всегда Конечный Всегда тупиковый К нему Подключаются Конечные юзеры Вот И соответственно Он принимает Апдейты Он даже отправляет Какие-то апдейты Но Если вдруг Какая-то сетка Дохнет То ему присылать Запросы на эту сетку Не надо Особенно если Эта сетка Какая-то где-то Вообще непонятно где То есть в принципе Стаб роутеру Квари Не присылаются Никогда И ни зачем Ни почему
Вот Это не единственный вариант Как бы Ограничение Распространения Квари запросов Но он очень простой Он настолько простой Что фактически Состоит из буквально Одной команды И когда у вас Маршрутизатор Стаб Помечается Соответственно У вас Зона распространения Квари Будет намного меньше Если у вас Этих самых Филиальных роутеров Много То соответственно Да У вас Вот тут Квари распространяются А в филиальной сетке Они у вас не ходят И вероятность того Что кто-то из этих роутеров Подвиснет Тоже соответственно Будет маленькая Но она будет нулевая Потому что Если даже кто-то И подвиснет Он все равно Квари не получает Вот Есть правда нюанс Если вы Стаб роутер Помечаете То Этот роутер Не будет Действительно Никогда Транзитным роутером Для EGRP Маршрутов То есть Если вдруг Вы пометили роутер Транзитным То уже не получится К нему подключить
Еще один EGRP Роутер Который будет Куда-то там посылать Апдейты Роутер Стаб скажет Баста Карапузики Мы не работаем Как транзитный роутер Поэтому чужие Апдейты Которые к нам Приходят Мы дальше Не обрабатываем Да Маршрут мы в таблицу Себе поставим Мы скажем Что до этой сети Добраться можно Но сами про нее Рассказывать уже Никуда не будем То есть этот роутер Перестает быть транзитным Для обычных нормальных EGRP маршрутов это на самом деле тоже хорошо и вполне логично. Мы говорим, что наш роутер тупиковый, он нетранзитный. Если даже кто-то нам говорит «через меня можно добраться до вот этой сети», то вы говорите «да, окей, через него можно добраться до этой сети, но обратно этот маршрут уже в другие внешние роутеры, в другие VPN каналы вы не посылаете». Очень простая, очень элегантная штука. И она действительно очень сильно экономит ресурсы роутеров. Если у вас есть такие роутеры, которые целиком филиальные, то прям замечательный механизм. Стаб, который упрощает конфигурацию очень-очень сильно.
В принципе, все то же самое можно сделать с помощью других механизмов, но это будет намного более громоздкое решение. А стабы — это просто одну команду дал, и всё, и сразу у вас решена практически 90% проблем. У нас как раз тут очередная мультяшка. Что если у нас есть роутеры, которые помечены как стабы, и где-то у нас в сети случается авария, то зона распространения аварии будет ограничена роутерами, которые последние в цепочке перед стабами. Когда какую-то сетку присылают в запросе «есть ли у тебя такая сеть», на роутер, у которого ни одного живого настоящего соседа нету, он говорит: «У меня ни одного нету соседа, которому я мог бы дальше этот квери форварднуть. Сюда я не посылаю, потому что это стаб. Сюда я не посылаю, потому что это тоже стаб. Отсюда у меня пришёл квери». Соответственно, среди всех соседей, к которым я мог бы это переслать, у меня больше ничего не осталось. Я посылаю ответ: «У меня такой сети нет». То же самое снизу. Ему прислали запрос. Он говорит: «У меня сюда посылать квери нельзя, сюда посылать квери нельзя, отсюда квери только что пришёл. Поэтому я говорю: у меня этой сети точно нет».
И вот этот роутер говорит: «Окей, ко мне пришёл вопрос, есть ли у тебя такая сетка. Я задал вопрос на один интерфейс, на другой интерфейс. На двух интерфейсах два роутера-соседа мне сказали: у меня этой сети нет. Я отвечаю: у меня этой сети тоже нет». Причём всё это дело происходит внутри сети предприятия на быстрых линках. Через VPN всё это дело не ходит. Соответственно, ответы приходят с очень большой вероятностью очень быстро. Со стабами есть один нюанс. Стаб-роутер никогда не может быть транзитным для обычных нативных EIGRP маршрутов. Но это не единственный тип маршрутов, который в EIGRP есть. Есть маршруты, которые изначально нативные в EIGRP взялись, а есть и другие типы маршрутов. Как минимум маршруты, которые изначально пришли в EIGRP откуда-то ещё. Например, если вы включаете редистрибуцию из условного RIP, у вас есть роутер, на котором есть RIP и есть EIGRP. И в этом роутере вы берёте RIP-овские маршруты и перекладываете их в EIGRP.
В этой ситуации такой маршрут в RIP, если бы вы перекладывали эти маршруты в RIP, он бы был абсолютно точно такой же, как и все остальные RIP-овские маршруты. Он ничем не выделялся бы. Разве только вы могли метрику какую-нибудь ему сделать похуже, или тег проставить, или что-то ещё экзотическое сделать. Но в принципе всё равно это был бы нормальный RIP-овский маршрут. А вот если вы в EIGRP маршруты кладёте, то у него будет сразу признак, что этот маршрут изначально взялся не из EIGRP. Он изначально откуда-то ещё прибежал, а потом его туда редистрибутнули. Соответственно, у каждого маршрута есть флаг. Не флаг, там формат пакета даже на самом деле будет разный. По сути это можно воспринимать как свойство: откуда взялся маршрут — изначально из EIGRP или откуда-то ещё? У любого маршрута, что внутреннего, что внешнего, будет IP-шник сети и маска, то есть префикс фактически.
Будет указание, через кого до этой сети можно добраться, на кого ставить маршрут NextHop. В нормальной ситуации NextHop — это тот IP-шник, с которого мы отправляем наши апдейты. Но иногда NextHop можно будет какой-то другой поставить. И, естественно, вектор метрик. Для каждого префикса мы говорим, как мы эту сетку знаем. Мы говорим про bandwidth, delay, reliability, load, jitter, энергия, MTU и hop count. Если маршрут будет внешний, то дополнительно к этому передаётся router-id. Это как раз тот самый случай, когда router-id в EIGRP начинает играть роль. Для каждого роутера у нас должен быть какой-то уникальный идентификатор. И в случае со внешними маршрутами нам нужно будет понимать, кто конкретно вбросил этот маршрут в EIGRP. И здесь как раз используется router-id. Я напоминаю, что это концепция у Cisco просто назначения уникального идентификатора, который действительно должен быть уникальным среди всех роутеров.
Router-id на роутерах, которые не вбрасывают в EIGRP никакие маршруты, не являются ASBR-ами, вы можете, в принципе, назначать не уникальный. Он нигде не сравнивается, нигде не проверяется. А вот если у вас ASBR-ы будут разные, то на них надо всё-таки уникальный router-id поставить. Cisco по умолчанию берёт router-id с интерфейсов, если вы не задаёте в явном виде. Перебираются сначала все лупбэки. Среди них берётся самый большой IP-адрес. Если лупбэков нету, то берётся самый большой IP-шник с физических интерфейсов. На самом деле правило, которое я говорю, что сначала перебираются лупбэки, а потом физические интерфейсы, оно неточное. Сначала перебираются все виртуальные интерфейсы, то есть лупбэки, какие-то интерфейсы, которые не настоящие. А только потом уже перебираются интерфейсы, на которых есть соседи. Лупбэк просто такой образцово-показательный виртуальный интерфейс. Так, дальше.
Если у нас был маршрут, который переложен из другого протокола динамической маршрутизации, мы должны будем понимать, что все роутеры, которые обрабатывают EIGRP-шный маршрут, это так или иначе Cisco. Соответственно, если кто-то вбрасывает в EIGRP маршруты, это какая-то Cisco, на которой есть внешний маршрутный источник, и эта Cisco берёт маршруты откуда-то ещё и перекладывает их в EIGRP. Если мы говорим, что эта Cisco перекладывала маршруты из другого EIGRP, то есть у нас была одна автономка EIGRP, AS, допустим, 1, у нас была другая автономка EIGRP, автономная система 2, и у нас на границе между ними был роутер, у которого один интерфейс в одну автономку смотрел, другой в другую, и было запущено два экземпляра EIGRP. В этой ситуации мы можем маршруты EIGRP-шные перекладывать между автономками, и в этом случае мы можем сказать, из какого именно экземпляра, из какой именно автономки EIGRP пришёл к нам внешний маршрут.
Этот самый external AS-number для EIGRP прямо указывает именно номер автономки. А если у вас был OSPF, то там будет указываться process ID. Помните, я говорил, что когда вы вешаете router OSPF и дальше число — этот уникальный идентификатор инстанса OSPF — по факту по сети никогда не передаётся. Так вот, передаётся. Только передаётся не в OSPF, а в EIGRP или в BGP. Вы можете там указать, что маршрут, который в EIGRP взялся, он на самом деле взялся изначально не из EIGRP, а из OSPF, и указываете номер экземпляра OSPF. Дальше. Есть метка. Точно такая же метка, как в EIGRP. Просто произвольное число. Вы можете маршруты свои раскрасить и дальше на эти метки ориентироваться при фильтрации, при анализе, прописывании политик или чего-то ещё. И наконец, если у вас есть маршрут, переложенный из внешнего источника, в котором есть метрика, то вы указываете, что за тип маршрута был изначально и какая у него была метрика.
Для внешних маршрутов вы видите, откуда они взялись. Если там OSPF, например, был, вы увидите, кто придумал такой маршрут, вы увидите, откуда он взялся, из какого экземпляра OSPF. Вы увидите, что это именно OSPF-овский экземпляр был. Если вы видите здесь число 1, вы понимаете, что это единичка не EIGRP-шная автономка, а именно OSPF-овская автономка — по полю external protocol. И вы видите, какая метрика была на этом ASBR у OSPF, у того маршрута, который он положил в EIGRP. EIGRP для этих внешних маршрутов передаёт такие хитрые дополнительные атрибуты. Не сказать, чтобы они прямо зачем-то были сильно нужны, но тем не менее вы можете на основе этих атрибутов в EIGRP прописывать политики с помощью route-map-ов. И вы можете матчить всё это. Вы можете сказать, что если маршрут пришёл по OSPF на ASBR и дальше от этого ASBR пришёл к нам EIGRP-шный маршрут, то мы можем сказать, что то, что на ASBR стоило, допустим, не больше 40 копеечек, мы обрабатываем одним образом.
А то, что на ASBR стоило больше 40 копеечек в OSPF, обрабатываем другим образом. Гипотетически такое сделать можно. На практике не стоит. Несмотря на то, что это можно получить и увидеть, обрабатывать маршруты в зависимости от этих меток приходится крайне редко. Таймеры. Уже в принципе про них всё рассказал. HelloTimer 5 секунд на быстрых интерфейсах, 60 секунд на медленных. Можно поменять. Менять вы должны будете одновременно оба таймера. И за таймер отвечает отправитель. HoldTime по умолчанию три раза по HelloInterval. Если вы меняете HelloInterval, то HoldTime подстраивается автоматически. Вы можете задать его вручную, и тогда он будет переопределён. По умолчанию он трёхкратный Hello. Вы можете сказать, например, я хочу поменять только HelloTimer, я хочу поставить 10 секунд. И тогда HoldTime у вас автоматически 30 подстраивается.
Но если вы скажете, что не хотите 30, а хотите 15 — окей, не проблема, будет 15. ActiveTimer 90 секунд. И если мне память не изменяет, его поменять, по-моему, нельзя. А может и можно. Но дальше на слайдах увидим, можно или нет. 90 секунд — это половина HoldTime для медленных интерфейсов. И ещё одна штука, которая в EIGRP есть, — это возможность проверить, что апдейты, которые пришли к вам, они пришли действительно от того, от кого надо. Проблема в том, что если у вас есть интерфейс, на этом интерфейсе у вас есть сосед, вы с соседом проверили, что всё хорошо, всё правильно. Автономки правильные. Коэффициенты метрики правильные. IP-шники правильные. Всё замечательно. Но тут появляется злобный враг, который начинает поддельные сообщения от имени соседского роутера вам отправлять. У вас роутеры R1 и R2 подружились, а злобный враг, который в этот провод встроился, он начинает вам от имени R2 посылать какие-то сообщения.
Как определить, что сообщение приходит действительно от того, кто его отправил? В EIGRP есть возможность подписывать сообщение с помощью такой, в кавычках, цифровой подписи. Вы можете не пользоваться этим механизмом, то есть просто отправлять пакеты — hello-пакеты, update-пакеты. Или вы можете использовать, в кавычках, цифровую подпись. Там будет называться Hash Message Authentication Code — HMAC. Соответственно, есть два алгоритма, с помощью которых можно это делать. Можно использовать хеш MD5, можно использовать хеш SHA256. Для того чтобы SHA256 использовать, надо будет хитрый режим включить, который мы с вами пока не проходили. Но MD5 в принципе достаточно неплохой механизм. Несмотря на то, что MD5 хеши сейчас считаются очень небезопасными.
И несмотря на то, что вы можете с помощью специальных таблиц восстановить оригинальное значение какого-то сообщения, если у вас только хеш есть, вы можете попытаться понять, из чего взялся этот хеш, из какой строки он взялся. Но на это требуется достаточно немаленькое время. Если у вас есть два роутера, которые друг другу посылают пакеты, то задача атакующего, который будет пытаться подделать эти пакеты, — на лету подобрать такое значение хеша MD5, которое устроит получателя. На лету это не всегда получится сделать. Если он не знает оригинальный пароль, то подменить сообщение так, чтобы это произошло за какое-то более-менее вменяемое время, у атакующего не получится. Поэтому даже MD5, несмотря на то, что во всяких серьёзных применениях его использовать нельзя, в real-time сценариях типа того же EIGRP, где подделывать сообщение надо за единицы секунд, его использовать вполне ещё можно.
Но если вы серьёзно озабочены безопасностью, то, конечно, имеет смысл рассмотреть вариант с SHA2. Если вы настраиваете проверку подлинности, то те пакеты, которые приходят неподписанными, будут игнорироваться. Вполне логично. Если приходит пакет и он не проходит проверку подлинности, он тоже игнорируется. Вы начинаете обрабатывать только те пакеты, у которых с цифровой подписью всё в порядке. Это всё, что касалось теоретической части про работу протокола EIGRP. Как можно передавать пакеты, кому передаются пакеты, как передаются пакеты. И сейчас нам, конечно, было бы интересно посмотреть, как это самое EIGRP настраивается. Продолжение следует...