Протокол Spanning Tree: механизм предотвращения петель в Ethernet, логика выбора корневого коммутатора и расчёт топологии без петель.
Каково время сходимости RSTP по сравнению с классическим STP?
Какие порты STP находятся в состоянии Forwarding?
Какова стоимость порта 100 Мбит/с по схеме 1998 года?
Что происходит с Edge Port (PortFast) при получении BPDU?
Из каких компонентов состоит вектор приоритета BPDU?
Вчера мы с вами обсуждали вопрос того, как коммутатор коммутирует кадры. Мы говорили, что у нас есть коммутатор, который принимает кадры на каких-то портах, и дальше на всех других портах копии этих кадров отсылает, кроме некоторых портов, куда копии кадров отсылать не надо. Мы говорили про то, что есть правило, которое указывает, куда копии кадров отправлять не надо. Этих правил на самом деле много. Самое первое, самое очевидное правило: если у нас есть какой-то кадр, который пришёл на наш свитч через определённый порт, никогда по определению не надо копию этого кадра отправлять обратно в тот же самый порт. Очевидная причина, почему этого не надо делать — потому что там уже этот кадр видели, и в норме коммутатор, прикидываясь толстым жёлтым коаксиалом, прикидываясь шлангом, не делает вещи, которые в коаксиале были бы невозможны. В коаксиале, если мы отправляем какой-то кадр, он никогда повторно в этом же проводе сам не зарождается, пока кто-то другой не захочет отправить ещё один такой же кадр. Поэтому коммутатор, когда начинает коммутировать кадры, никогда обратно копию кадра не отправляет,
просто потому что там уже его видели. Кроме того, коммутатор ещё дополнительно делает другие действия. Например, если мы знаем, где сидит получатель, коммутатор на все остальные порты, кроме порта получателя, копию кадра не отправляет. Кроме того, если коммутатор поддерживает VLANы, то те порты, которые с определённым VLANом не проассоциированы, тоже копию кадра не получат. А если коммутатор знает, что определённый порт проассоциирован с нужным VLANом, то он копию кадра получит. Может быть, в access-режиме, то есть без каких-либо дополнительных заголовков. Может быть, если это у нас транковый порт, он проассоциирован с некоторыми VLANами, со многими. И поэтому надо, когда мы отправляем туда какие-то данные, указать, в каком VLANе мы их отправляем. В этом случае копия кадра, которая будет отправляться в такой транковый порт, будет дополнительно обёрнута ещё заголовком 802.1Q или ISL. Но есть и другие правила, которые помогают коммутаторам при принятии решения,
стоит ли копию кадра отправлять в определённый порт или нет. И самый важный, наверное, для корректной работы коммутируемой сети в предприятии механизм, который нам сейчас понадобится, — это протокол Spanning Tree, который будет в некоторых случаях решать, что копии кадра в определённые порты посылать не надо. И мы с этим механизмом сейчас будем разбираться. Какая проблема есть, которую решает протокол Spanning Tree? Если мы возьмём и построим коммутируемую сеть, содержащую в себе петли, то кадры, отправляемые в такой сети, будут вести себя следующим образом. Представьте себе, что у нас есть узел А. Этот узел отправляет какой-то кадр, который должен дойти до какого-то получателя. Мы его хотим отправить, например, узлу Б. Но мы MAC-адрес Б не знаем, мы его отправляем в виде broadcast. Что происходит на уровне сети?
Узел А отправляет broadcast-кадр. Он приходит на свитч. Свитч принимает решение, что с таким кадром делать. Broadcast-кадр — что с ним делать? Его надо разбросать на все порты, кроме порта источника. Соответственно, он отбрасывает одну копию кадра в один порт, другую в другой. Эти два порта формируют петлю, как вы видите. Дальше. Другой свитч, какой-нибудь вот этот, принимает копию кадра, broadcast-кадр. Что с ним надо сделать? Правильно, одну копию отправить на каждый из портов, которые у нас на коммутаторе есть. В том числе одну копию надо отправить дальше в петлю. То же самое. Вот этот коммутатор разбросает копию кадра на все свои порты, которые у него есть, и одну копию отправит тоже в петлю. И вот этот коммутатор тоже самое сделает. Он отбросит копию кадра на все порты, которые у него есть, и одну копию кадра отправит в петлю. И получится, что на этот свитч сначала пришёл кадр, он по петле пробежался, вернулся на оригинальный свитч, и точно так же копия кадра, которая приходит с верхнего свитча,
она точно так же отправляется на все порты, которые есть на коммутаторе, плюс ещё одна копия отправляется в петлю. И эта копия кадра начинает зависать в этой петле и бегать в ней по часовой стрелке или против часовой стрелки — в нашем случае бесконечно долго. Пока у нас есть петля, кадры, которые мы отправляем в broadcast, в этой петле начинают зависать. Проблема будет не только с broadcast, а с любыми кадрами, которые отправляются в много портов и, например, отправляются во все порты, которые формируют петлю. С known unicast, с известными unicast, может быть, копии кадра отправляться не будут в петлю, потому что у нас есть дополнительное правило, которое указывает, что если мы знаем, где сидит получатель, на все остальные порты, в том числе и порты, которые формируют петлю, копии кадра отправлять не нужно. Но гипотетически, если у нас есть unknown unicast, такой unicast, для которого мы не знаем, куда девать трафик, то он точно так же в петле будет зависать.
Равным образом multicast — то же самое. Он тоже в петле будет зависать бесконечно. Как следствие, любой кадр, который отправляется в сеть, содержащую петлю, в этой петле зависает на бесконечно долгое время. Причём он зависает на самом деле в двух экземплярах. Когда абонент отправляет какой-то кадр и первый свитч принимает решение, куда надо этот кадр девать, он одну копию кадра отправит по часовой стрелке, а другую — против часовой стрелки. Одна копия кадра будет бегать в одном направлении, другая копия кадра будет бегать в другом направлении. И на обработку этих кадров потребуется выделять ресурсы. Соответственно, чем больше кадров в этой петле будет зависать, тем больше ресурсов потребуется тратить на обработку этих кадров. Возникает вопрос, что раньше произойдёт? Упадут ли в стопроцентную загрузку линки, которые формируют петлю? Упадут ли в стопроцентную загрузку матрицы коммутации на коммутаторах, которые обслуживают этот трафик?
Заранее предсказать, что конкретно послужит бутылочным горлышком, сложно, но рано или поздно какой-то из этих ресурсов закончится. Либо мощность матрицы коммутации закончится, либо полоса пропускания, которая доступна на интерфейсах. И весь трафик, который будет отправляться на эти интерфейсы, которые формируют петлю, — это фактически будут кадры, которые в broadcast зависли в этой самой петле, и по сути своей они никакой пользы не приносят. Это кадры, которые изначально предполагалось отправить одному абоненту, просто мы не знали его адрес, и этот абонент уже давным-давно получил копию кадра. Причём не одну, а бесконечно много. И в любом случае рано или поздно мы столкнёмся с ситуацией, когда ничего, кроме broadcast-кадров, которые должны были быть получены одним абонентом, по факту им они уже давно были получены, и они больше ему не интересны, — они целиком, полностью
забивают 100% полосы, доступной в петле. Никакой боевой трафик в этом случае через петлю проходить уже не может. Ресурсы все отданы под обработку этих broadcast-кадров. Вторая проблема — на абонентов будет валиться огромное количество трафика, состоящего из одинаковых broadcast-кадров, и любой абонент должен будет эти broadcast-кадры обрабатывать, потому что broadcast адресован вообще всем. Поэтому в стопроцентную загрузку будут загружены и абонентские линки. Причём, скорее всего, абонентские линки вообще во всей сети, а не только на тех коммутаторах, которые подключены к этим самым линкам, формирующим петлю. И в стопроцентную загрузку, скорее всего, упадёт процессор. Или не в стопроцентную, например, в 50% загрузку или в 25% загрузку упадёт процессор на абонентах, потому что он будет обрабатывать огромную тучу broadcast-кадров, которые ему в том числе адресованы, которые ему совершенно неинтересны. Поэтому вы просто так отдаёте какую-то часть мощности на ваших абонентах для того, чтобы они могли
обрабатывать огромное количество всяких разных broadcast-кадров, которые на них валятся. По каждому кадру же нужно принять его, посмотреть, не нам ли это адресовано, контрольную сумму проверить. Если внутри, допустим, IP лежит, то надо посмотреть, может быть, это нам пришло на уровне IP. Если, допустим, там какой-нибудь DHCP-запрос бежит, он же идёт на адрес 255.255.255.255. Вы ещё на уровне IP проверяете контрольную сумму, проверяете, что это адресовано вам, смотрите, что внутри лежит, видите какой-нибудь UDP, дальше думаете, что с ним делать, передаёте это обработчику UDP, тот говорит — там внутри DHCP. И в какой-то момент по каждому пакету вы принимаете решение, что этот пакет вам не сильно интересен. Но в любом случае производительность абонентов тоже сильно деградирует. Мало того, что на них вместо боевого трафика валится какой-то спам, то есть сеть не работает, так ещё сами компьютеры начинают тормозить. Ещё одна проблема — нестабильность базы MAC-адресов. Процедура коммутации основана
на предпосылке, что все свитчи проводят эмуляцию толстого жёлтого коаксиала с помощью процедуры MAC-learning. Они знают, кто где сидит, и они перекладывают данные между узлами, фактически фильтруя трафик на всех остальных портах. Когда приходит какой-то кадр на свитч, и он адресован некоторому абоненту, если мы знаем, где этот абонент сидит, мы этот кадр форвардим только на порт конкретного абонента. Мы фильтруем копию кадра на всех остальных портах. За счёт этого получается более эффективная коммутация, нежели если бы мы использовали чисто хабы. Недостатком этой процедуры является то, что каждый раз, когда мы видим какой-нибудь кадр, который на нас приходит, мы должны будем запоминать, за каким портом он сидит. Именно на этой процедуре будет основано понимание, кто где находится. И когда у нас есть какие-то кадры, которые зависли в петле,
например, сейчас есть некий абонент А, который отправил какой-то broadcast-кадр, он, например, отправился сначала в одну сторону петли, мы сейчас предположим, что другой стороны петли пока не существует, и он начинает бегать против часовой стрелки в этой самой петле. Он постоянно отправляется против часовой стрелки. Сначала один раз, потом второй раз, потом третий раз, и вот так сотни тысяч раз в секунду. Если вдруг какой-нибудь другой узел, например вот этот, захочет отправить кадр на узел А, он указывает в кадре, что А является получателем, и этот кадр должен будет дойти до конечного получателя. За счёт того, что процедура MAC-learning здесь будет давать непредсказуемый результат, в итоге этот кадр никогда не сможет дойти до узла А. Потому что даже если вдруг этот кадр чудом доберётся до вот этого свитча, этот свитч с существенно большей вероятностью последний кадр от MAC-адреса А получал из петли. Либо на одном порту, формирующем петлю,
либо на другом порту, формирующем петлю, если мы говорим про петлю, которая двусторонняя, в которой кадры зависают в двух направлениях. Но в любом случае кадры, которые приходят от MAC-адреса А, — это приходят кадры из петли. Они никогда, почти никогда, по сравнению со всеми остальными кадрами, не приходят от настоящего порта А. Поэтому свитч, после того как хотя бы один раз кадр через петлю прошёл и вернулся на наш свитч и потом снова начинает своё бесконечное путешествие, по факту забывает, где сидит узел А. Он думает, что все абоненты, которые когда-либо отправляли свои broadcast-кадры, которые в петле зависли, находятся за портами петли. И поэтому, даже если есть узел В, который хочет отправить кадр узлу А, он отправляет такой кадр, но этот кадр до узла А не дойдёт. Никогда конечный свитч в сторону него кадр не пошлёт. Так что такая проблема есть. Если у нас возникает петля в Ethernet, то есть возникает больше одного варианта доставки трафика от одного
абонента до другого, три симптома, которые существуют, — это шторм из широковещательных кадров, которые забивают стопроцентной загрузкой все ресурсы, которые имеются, нестабильность базы MAC-адресов и множественная повторная доставка кадров, которые в стопроцентную загрузку вводят конечные хосты, — они приводят к тому, что сеть при возникновении петли просто перестаёт работать. Может быть, чуть раньше, может быть, чуть позже. Чем более мощные свитчи формируют петлю, чем более они производительные, чем больше линки по толщине между этими свитчами, тем быстрее сеть будет ложиться. Соответственно, если вдруг петля сформирована с использованием какого-нибудь медленного 100-мегабитного свитчика или 10-мегабитного свитчика, то в принципе стопроцентную нагрузку вы получите только на этом одном свитче. Все остальные свитчи, которые будут получать такой трафик, будут гипотетически способны его переживать. От того, что где-нибудь 10 мегабит будет бегать между двумя свитчами, вы всё равно получите ту же самую
полосу в петле — 10-мегабитную — на всех своих портах, которые петлю формируют. Нигде не будет возможности нарисовать в этой петле больше, чем 10 мегабит трафика. Даже если вот этот линк 10-мегабитный, а вот это всё — 100-гигабитные линки, всё равно больше 10 мегабит там трафика бегать не будет. Но нестабильность базы MAC-адресов всё равно препятствует тому, чтобы трафик нормально ходил. Потому что даже 10 мегабит трафика, который вам рушит таблицу MAC-адресов, который рушит процедуру MAC-learning, приводит к тому, что трафик по факту не ходит нормально. Так что с петлями в Ethernet нужно бороться. Оригинальный Ethernet не предусматривал возможность возникновения петли вообще. В коаксиале, который выглядел как просто длинный провод, у которого на концах должны были быть заглушки, вы не могли никоим образом сотворить эту самую петлю, потому что просто не было физической возможности это сделать. В сети с хабами вы могли физически устроить петлю, но только сеть переставала работать. Она переставала работать на электрическом уровне, потому что если
у вас был, например, один хаб и другой хаб, и, соответственно, давайте стрелочки нарисую, что это хабы, и они были соединены двумя разными проводами. Один провод мог быть, например, 10 метров, а другой мог быть провод 11 метров. И за счёт того, что провода имеют разную длину, они всегда имеют разную длину, хотя бы чуть-чуть. Может быть, не на метр, может быть, на 20 сантиметров, но всё равно это достаточно большая разница. Даже если 10 метров, даже если 5 метров, более того скажу, даже если 5 сантиметров, даже если небольшая разница в длине между проводами есть, кадр, который придёт на свитч, точнее не кадр даже, а электрический сигнал, допустим, плюс 0,7 вольта, который придёт на свитч, он будет раскопирован, расклонирован на оба этих провода. И более короткий провод приведёт к тому, что сигнал на этом свитче будет получен чуть раньше. А сигнал на хабе, простите, на одном порту будет получен
чуть раньше, а на втором порту будет получен чуть позже. И как следствие эти сигналы наложатся друг на друга, и дальше у вас будет передаваться некий сигнал в сторону получателя на этом хабе в виде двух копий, которые накладываются одна на другую. Представим себе, что у нас есть плюс 0,7 вольт, который мы передаём. И мы начинаем передавать плюс 0,7 вольт и заканчиваем передавать через некоторое время. И если у нас есть одна копия сигнала, которая проходит по более короткой трассе, и другая копия сигнала, которая проходит по более длинной трассе, то они в итоге наложатся друг на друга. У вас в какой-то момент будет передаваться плюс 0,7 вольта, полученный из одного места. Потом, допустим, 1,4 вольта просуммированы, и потом снова плюс 0,7 вольта. Казалось бы, ничего страшного, но представьте себе, что здесь уже вплотную пойдёт следующий битик. И здесь будет передаваться минус 0,7 вольта. У нас приходит ещё пока одна копия плюс 0,7 вольта, а на другом порту уже приходит другая копия минус 0,7 вольта.
И они будут накладываться друг на друга, и у нас в итоге сигнал будет очень сильно деградировать. Если длина проводов не сильно различается, взяли, с линейкой померили, вроде бы два одинаковых патч-корда воткнули, оно, может быть, даже будет работать. Но если длина проводов различается хоть чуть-чуть, оно на чисто электрическом уровне препятствует нормальной работе системы. Поэтому в сети с хабами петли у нас тоже недопустимы. И в сети со свитчами петли недопустимы по той причине, которую я вам озвучил. Точнее, по трём причинам. Первое, что у нас при возникновении петли падает в стопроцентную загрузку какой-то ресурс, либо линки между коммутаторами, формирующие петлю, либо сами коммутаторы не успевают перекладывать столько данных. Что, впрочем, для производительных свитчей предприятия маловероятно. Но тем не менее, если вы берёте какие-то совсем маленькие, совсем старенькие свитчики, они могут уйти в стопроцентную загрузку до того, как у вас в стопроцентную загрузку
уйдут порты на этих свитчах. Такое бывает. Дальше. Нестабильность базы MAC-адресов препятствует прохождению трафика по этой сети в абсолютно любом случае. Неважно, уйдут у вас в стопроцентную загрузку свитчи, уйдут у вас в стопроцентную загрузку линки. В любом случае, трафик до конечных абонентов, если они отправляли хотя бы какой-то бродкастовый кадр, не сможет быть доставлен. И те кадры, которые будут доставляться на каждого абонента, это будут бродкасты, которые каждому узлу не сильно будут интересны. Когда изначально коммутаторы в Ethernet появились, они были нестандартной вещью. Ethernet у нас представлял собой сеть с общей шиной, либо коаксиал, либо витая пара. Точнее, тогда ещё это был только коаксиал, когда первые коммутаторы были придуманы. Чтобы вы понимали примерный масштаб событий, Ethernet, как вы помните, был придуман в 1974 году. Потом в 1978–1980 его допиливали. В 1981 году он пошёл в продакшн. В 1985 году стала появляться такая идея,
что давайте мы будем соединять несколько Ethernet-линков в одну большую систему. И устройства, которые стали перекладывать кадры между различными Ethernet-сегментами, стали называться бриджи. Если вдруг вы увидите вот такой рисуночек, я постарался нарисовать как мог, но постарался плохо. Вот такая фиговина. Будет называться мост или бридж. И заключается её работа в том, что мы сегодня знаем под словом коммутатор. Он принимает кадр с одной стороны и отправляет копию кадра с другой стороны. У бриджей, когда они только появились, было мало портов. Например, было два порта или четыре порта. Но их не было много. Потом, когда стало понятно, что идея появления бриджей она ничего такая себе, компании, которые производят сетевое оборудование, стали предлагать эти самые бриджи,
немножко ускоренные. Дело в том, что ранние версии бриджей работали с использованием центрального процессора. Они получали какой-то кадр, в этом кадре видели, кому этот кадр будет адресован, от кого он идёт, и дальше центральный процессор говорил: у меня есть таблица MAC-адресов, я запоминаю, кто за каким портом сидит, на центральном процессоре смотрю, знаю ли я, где находится MAC-получатель. Дальше бридж работал именно по тому алгоритму, который мы знаем сегодня для коммутации. Он разбрасывал копии кадра на все порты, кроме тех, куда делать не надо. Но у бриджей, в отличие от свитчей, портов было мало. Когда такие устройства стали завоёвывать популярность, стало понятно, что центральный процессор, который в конце 80-х годов, в начале 90-х может предложить индустрия, его производительность не давала сколько-то вменяемого объёма, количество трафика,
который такие бриджи могли форвардить, было небольшим. Поэтому стали появляться устройства, которые были аппаратно ускорены, и такие устройства как раз стали называться свитчи. Они получали кадр на одном порту и разбрасывали копии кадра на нескольких портах, кроме некоторых, куда копию кадра отбрасывать было не надо. Но делали они это не центральным процессором, а с использованием специализированной микросхемы, которая такую задачу умела делать и делала её весьма быстро. Так. Теперь, когда я рассказал вам, что такое бриджи и чем они отличаются от свитчей, давайте поговорим про тему нашего сегодняшнего занятия, это Spanning Tree. Это протокол, с помощью которого бриджи могут сделать так, чтобы петля в Ethernet не формировалась. Даже если вы возьмёте несколько свитчей, несколько бриджей, если хотите, и соедините их в сеть и умышленно или неумышленно устроите петлю, то Spanning Tree, работая между этими коммутаторами, сможет разобраться, какие порты формируют петлю,
и эти порты заблокирует. И при принятии коммутационного решения, если вы принимаете какой-то кадр на порту и принимаете решение, куда вы хотите копию кадра отправить, вы по умолчанию хотите отправить копию кадра на все порты, кроме некоторых. И Spanning Tree, если какие-то порты заблокирует, то на эти порты копия кадра отправляться никогда не будет. Равным образом, если мы получаем кадр на таком порту, который Spanning Tree заблокировал, мы сразу принимаем решение, что копировать этот кадр не надо вообще никуда. Протокол Spanning Tree разработан в 1985 году, то есть практически сразу, как только стали появляться первые бриджи. В оригинальном Ethernet бриджей не было, но они потом появились, и стандарт, который указывал, как этот самый бридж должен себя вести, это стандарт 802.1D 90-го года. У 802.1D был раздел, который указывал, как должен работать любой бридж, или, если хотите, любой свитч. И среди прочего там было указание, что если вы хотите сделать бридж или свитч, который будет соответствовать стандартным требованиям, то он должен поддерживать этот самый Spanning Tree протокол.
Небольшие различия есть между тем Spanning Tree, который был придуман в 1985 году, придумала его Радиа Перлман, но в 90-м году с небольшими изменениями этот протокол стал частью стандарта 802.1D. Если вы сегодня хотите изготовить свитч, по идее, если вы хотите, чтобы этот свитч был стандартный, соответствовал 802.1D, он должен поддерживать протокол Spanning Tree. Дальше. С 802.1D, который был выпущен в 90-м году, протокол начал дальше развиваться. И несмотря на то, что идея, которая в этом протоколе есть, она до сих пор остаётся примерно той же самой — мы обнаруживаем порты, которые формируют петлю, и блокируем коммутацию на них — протокол, который изначально был придуман в конце 80-х, в начале 90-х годов, оказался очень медленным. И по современным меркам он неприемлемо медленный.
Поэтому, естественно, протокол развивался, и были предложены более продвинутые версии этого протокола. Если мы говорим про стандартные версии Spanning Tree, то существует стандартная версия 802.1w или Rapid Spanning Tree. Название может пообещать вам, что этот протокол будет сильно более быстрым по сравнению с классическим Spanning Tree. И действительно, в определённых ситуациях Rapid Spanning Tree будет заметно быстрее, чем оригинальный 802.1D. Но надо заметить, что внутри Rapid Spanning Tree работают все те же самые механизмы, что и у медленного Spanning Tree. Поэтому, несмотря на то, что он в определённых ситуациях будет быстрее, сказать, что он всегда будет быстрее, наверное, нельзя. 802.1w был включён в новую редакцию 802.1D. В 2004 году единственный Spanning Tree, который допустимо делать на свитчах, это тот самый быстрый Spanning Tree.
Но некоторые производители по-прежнему ещё позволяют выбрать, в каком режиме вы хотите работать, в медленном или в быстром. Также ещё одна особенность классического Spanning Tree 802.1D заключается в том, что он не умеет работать с транками. Он умеет работать с физической топологией. Если у вас где-то в физической топологии есть петля, то он будет её блокировать. При этом транки и вообще говоря VLAN позволяют нам сделать так, чтобы некоторые физические провода относились к разным широковещательным доменам. И физически петля может быть и будет присутствовать. Может быть, глазами будет видно, что несколько свитчей, допустим, формируют петлю. У нас раз свитч, два свитч, три свитч и четыре свитч. Глаза говорят, что да, здесь вроде как петля есть. А по факту никто не говорит нам, что здесь петля по факту возможна. Потому что здесь у нас может быть транк с 10-м и 20-м VLAN. Здесь у нас 10-й VLAN, здесь 20-й VLAN, а здесь вообще 30-й.
И у нас вот это — один широковещательный домен. Вот это — другой широковещательный домен. Вот это — третий широковещательный домен. И они никак между собой петлю не формируют де-факто. Но классический Spanning Tree не различает VLAN, не различает транки, и он всё равно блокирует коммутацию на каком-то из этих портов. Тем самым по факту получится, что где-то у вас коммутация будет работать некорректно. Если вам требуется работать со Spanning Tree с учётом VLAN, то вы можете использовать стандартный протокол, который был разработан как рекомендация 802.1s и впоследствии был объединён с механизмом VLAN 802.1Q. В актуальных свитчах, которые поддерживают VLAN, если вдруг вы захотите работать со Spanning Tree, скорее всего, вам будет предложен на выбор либо протокол, который не поддерживает VLAN, то есть классический Spanning Tree, либо протокол, который поддерживает VLAN, то есть MST, Multiple Spanning Tree.
Кроме того, существуют и другие альтернативные версии классического Spanning Tree. В основном здесь следует упомянуть фирменную цисковскую реализацию, которую Cisco предложила. PVST, Per VLAN Spanning Tree. Это медленный Spanning Tree, который был немножко подпилен для того, чтобы работать с учётом VLAN. Либо PVRST, Per VLAN Rapid Spanning Tree. Это быстрый Spanning Tree, который умеет работать с VLAN. Это 802.1w, в который допилили те же самые механизмы, которые были в PVST по сравнению с медленным Spanning Tree. И быстрый Spanning Tree научился работать и с VLAN. Но эти две реализации — цисковские. И несмотря на то, что многие другие вендоры их у себя имплементировали, считается, что это всё-таки нестандартная штука. Гипотетически вы можете встретить оборудование других вендоров, на которых PVRST есть. И его можно включить, задействовать и даже бурно радоваться жизни, когда у вас внутри конкретного VLAN петли,
если будут формироваться, они будут отдельно блокироваться. Но всё же, если говорить про реальный сценарий, если у вас есть оборудование разных вендоров в вашей сети и вам требуется блокировать петли, которые там возникают, скорее всего, вы захотите использовать MST. Как будет работать Spanning Tree? Он сначала блокирует вообще всё, потом некоторым образом определяет свитч, который находится где-то в центре сети. Один свитч, который самый-самый центральный. И затем он на каждом свитче смотрит, как можно лучше всего добраться до центрального. Этот лучший способ добраться до центрального свитча будет разблокирован по окончании пересчёта топологии. Затем на каждом коммутаторе вы смотрите, есть ли какие-то порты, через которые вы можете добраться до центрального свитча несколькими разными способами. И если вдруг выяснится, что у вас есть на каком-то конкретном коммутаторе
два порта, через которые можно добраться до свитча, вы в этом случае должны будете оставить только один порт разблокированным, а другой заблокировать. Например, у нас каким-то образом этот свитч был выбран как центральный. Каждый коммутатор принимает решение, как лучше всего добраться до центрального свитча. Допустим, этот свитч говорит: у меня вот этот порт самый выгодный. Нижний свитч говорит: вот этот порт у меня самый выгодный. Он лучше всего смотрит на центральный свитч. А этот свитч смотрит на центральный двумя портами. Вот этим и вот этим. И он говорит: у меня два порта одинаково хорошие, но я должен среди них выбрать только один. Один, который будет самый выгодный. И я принимаю решение, что этот порт будет выгодный, а другой порт я заблокирую, потому что он менее выгодный способ добраться до рута. И в этом случае получается, что если все свитчи такой логикой будут руководствоваться, то у вас все свитчи блокируют линки, которые формируют петли.
И все остальные порты, которые у вас есть, через которые до рута добраться нельзя, они будут разблокированы. Разблокированы будут вот этот порт, вот этот порт, этот, этот, этот, этот и вот этот, и вот этот тоже. Разблокировано будет вообще всё, кроме тех портов, которые формируют петлю. При этом заметьте, пожалуйста, тот момент, что если у нас есть какая-то петля, которая в такой ситуации появилась, то заблокируется порт только с одной стороны. В нашем случае у нас здесь есть два коммутатора, которые смотрят в провод, который формирует петлю. Заблокирует в такой ситуации из двух свитчей свой порт только один, а другой оставит этот порт открытым и рабочим. Делается это специально для того, чтобы если вдруг у вас в этом порту есть пользователи, а если вы помните, Ethernet — это протокол, в котором у нас в канале между двумя точками могут быть ещё и другие точки. Не всегда Ethernet был протоколом, который основан был на витой паре, который по определению имеет только два конца.
Ранние версии Ethernet, они предполагали, что у вас есть много пользователей в одном канале. Поэтому даже если два свеча видят друг друга, даже если два свеча предполагают, что да, кто-то из них должен принять решение о том, что свой порт заблокируют, а другой, соответственно, скажет, я свой порт блокировать не буду, это происходит потому, что они не знают. Может быть, там в сети есть еще дополнительные какие-то узлы, которым надо оставить доступ для работы. И вот, соответственно, тот, кто ближе к сети, он, соответственно, свой порт оставит разблокированный к центру сети, к вот этому центральному корневому коммутатору. А тот, кто будет подальше, свой порт заблокирует. И если вдруг действительно в этом канале были какие-то юзеры, у них останется доступ, он не будет заблокирован, и все будут в этой ситуации счастливы. Протокол Spanning 3 — это очень старый протокол. Он придумывался задолго до того, как Ethernet вообще хотя бы приблизился к своему современному виду. И многие решения, которые в Spanning 3 есть, они были заложены тогда, когда в канале между двумя точками могло быть много пользователей.
Для того, чтобы принять решение, кто находится ближе к центру сети, кто находится дальше от центра сети, кто является центральной точкой и многие другие решения, на самом деле, на Spanning 3 будут основаны на этой штуке, у коммутаторов есть уникальный идентификатор. То есть любой бридж, любой коммутатор может иметь некий идентификатор, который будет абсолютно уникален в пределах всей сети, и он будет называться bridge ID. Этот bridge ID будет 8-байтовый или 64-битный, и он будет, если хотите, прошит на заводе. То есть у него есть какое-то дефолтное значение. Это дефолтное значение будет следующим. Младшие биты будут представлять собой 48 бит MAC-адреса. У нормальных коммутаторов обычно своего MAC-адреса нету. Но если мы хотим какие-то кадры отправлять, какие-то кадры принимать, свои собственные кадры, то нам MAC-адрес понадобится. И вот этот MAC-адрес, он прошивается на заводе, и вот он, соответственно, является правой частью bridge ID у каждого коммутатора.
Поскольку MAC-адреса прошиваются на заводе, и на заводе они будут уникальны, то, соответственно, получится, что в любом случае у вас каждый bridge ID, хотя бы за счет вот этой правой части MAC-адреса, получается уникальный. И вот на основе этого самого bridge ID у вас коммутаторы будут выбирать, кто из них будет центральный, кто из них будет находиться ближе к центральному, кто из них будет находиться дальше от центрального. И возникает определенная проблема, которая заключается в том, что MAC-адреса, они случайные, они хоть и разные, но случайные. Контролировать то, какой коммутатор получит какой MAC-адрес, будет очень сложно. Поэтому bridge ID будет составлять не только из MAC-адреса, но также из 16-битного поля, которое будет называться bridge priority. Оно будет являться левой частью bridge ID, то есть старшие 16-бит, которые больше влияют на результат, чем MAC-адрес, они как раз будут указывать на bridge priority. По умолчанию у всех коммутаторов bridge priority будет состоять из единички и 15 ноликов. То есть это 16-ти личное число 8000 или десятичное число 32768.
Если вы хотите, вы можете этот bridge priority поменять. То есть у вас bridge ID при этом тоже изменится. Но, естественно, изменится bridge priority, MAC-адрес останется тот же самый. Так вот, если вы меняете bridge priority, то он у вас может стать меньше или больше. Ну, логично, да? Чем меньше bridge priority, тем меньше bridge ID целиком. Если вдруг вам нужно будет повлиять на вот этот вот самый bridge ID, как правило, вам нужно будет его сделать либо поменьше, либо побольше. И в этом случае, как раз меняя старшие биты этого самого bridge priority, вы можете добиться нужного вам результата. Вот пример. У нас есть два коммутатора, которые связаны между собой просто прямым проводом. Даже если петли здесь нету, все равно Spanium 3 в такой топологии сработать сможет и может определить, что петель нету, блокировать ничего не требуется. Поэтому у нас в такой ситуации в любом случае все равно bridge ID на узлы назначаются, коммутаторы будут обмениваться между собой какими-то служебными данными,
и вот они после обмена этими служебными данными поймут, что все хорошо, блокировать ничего не нужно. У левого коммутатора приоритет по умолчанию 8000, 16-ти личная, и MAC-адрес вот какой-то вот там MAC-адрес, deadbeef1111. Вот в этом случае мы берем приоритет, берем MAC-адрес и склеиваем их между собой. Bridge ID у нас получается 8000 и дальше deadbeef1111. То же самое у другого коммутатора. У нас есть приоритет 8000 и MAC-адрес deadbeef2222. Да-да-да-да. Склеиваем одно с другим, получаем вот такой вот Bridge ID. В любом случае, за счет того, что MAC-адреса уникальны, Bridge ID тоже получается уникальным. Как будет работать Spanning Tree? Вот здесь много текста. Вам не нужно будет сейчас запоминать, как этот алгоритм будет выглядеть, но кратенько я по нему пробегусь. Сначала мы определяем, кто из коммутаторов будет центральной точкой сети. Это будет так называемый root bridge. Вот этот вот root bridge — это коммутатор, который должен находиться в самом-самом-самом центре.
И коммутаторы будут рассказывать друг другу, кого они считают root on. Начинается все с того, что каждый коммутатор ничего не знает про всю остальную сеть. То есть в некоторый момент времени коммутатор включается, понимает, что он только что включился, и он начинает рассказывать всем. Root — это я. И он показывает свой root bridge ID и, соответственно, рассказывает. Вот я такой-то bridge ID, я считаю root самого себя. Если вдруг это сообщение уходит в сторону соседа, и сосед считает, что он знает root bridge какой-то более достойный, он в ответ на такое сообщение отправит сообщение свое. Я знаю, что root bridge ID у нас на самом деле другой. Пожалуйста, имей это в виду. Сравнить, кто будет более достойным root, можно очень просто. У кого root bridge ID, а это просто 64-битное число, вот у кого он меньше. То есть если мы сравниваем между собой два bridge ID, и на то, кто из них более вероятный root, то определить это можно очень легко.
Поэтому если вдруг у нас все свечи в начале работы, вот мы взяли там, выключили питание во все компании, а потом снова включили, и коммутаторы начинают загружаться, потом они плюс-минус километр одновременно включаются в сеть, и начинают рассказывать друг другу, кого они считают root-ом. Начинают они все с того, что они все говорят, я буду root-ом, а потом все они понимают, что они только что сказали, что root-ом они считают самого себя, а есть какой-то сосед, который root-ом считает какой-то другой коммутатор, который будет иметь bridge ID сильно меньше. Поэтому они через небольшое время начинают рассказывать всем, что они знают какого-то более правильного root-а, ну вот тот самый bridge ID, который им кто-то прислал в качестве самого выгодного root-а вообще. Ну и поэтому через некоторое время тот коммутатор, у которого bridge ID будет самый-самый маленький, он будет известен вообще всем, и как следствие все коммутаторы будут считать центральным вот этим root-bridge ID одного и того же соседа, один и тот же коммутатор.
Дальше. Когда вы рассылаете указания, кого вы считаете root-ом, вы одновременно указываете и расстояние, на котором вы знаете этого root-а. Расстояние выражается в безразмерных единицах, я их предпочитаю называть копеечки. То есть вы указываете расстояние до root-а, или root path cost. Если вы сами себя считаете root-ом, вы указываете, что вы знаете самого себя за 0 копеечек. Если же вы получаете указание, что root – это кто-то другой, и вы считаете, что это действительно root, то вы дальше прибавляете к заявленной стоимости root path cost сообщение ту стоимость, которую вы знаете, которая у вас ассоциирована с интерфейсом, на который вы такое сообщение получили, прибавляете одно к другому, и дальше начинаете рассказывать, что я знаю root-а за какую-то там другую стоимость. Ну, просто складываете одно с другим. И вот если у вас есть несколько сообщений, приходящих от соседей, которые указывают, что они знают root-а одного и того же,
но за разную стоимость, то вы считаете, что лучший способ добраться до root-а – это тот, у которого вот этот вот самый root path cost будет меньше. Тот порт, который будет как раз получать указание до root-а с минимальной root path cost, будет объявлен корневым или root-портом, и после окончания пересчета топологии он будет разблокирован. Все остальные порты, они будут называться alternate port, это альтернативный способ добраться до root-а, они останутся заблокированными. Дальше. Если вдруг есть какие-то порты, через которые root-а вообще не видно, то есть вам там никто не присылает сообщение, что можно добраться до root-а через них, то в этом случае вы такие порты будете помечать, как designated port, и вы в таком сегменте будет называться designated bridge. Десигнед bridge – это тот самый коммутатор, который ближе всего к root-у в некотором сегменте. То есть смотрите, если у нас есть, например, некий root, дальше он смотрит на какой-то другой коммутатор,
не знаю, switch-1, и тот смотрит на какой-то там третий коммутатор, switch-2. Приходит указание я root. Это указание я root на свитче первом формирует вот это вот указание, что здесь у нас root-порт. А дальше на втором свитче не приходит указание, что я знаю root-а. И в этом случае switch-1 говорит, окей, тогда я буду designated bridge-ом, я буду свой порт помечать как designated port, и я буду в сторону этого соседа switch-2 посылать сообщение, что через меня можно добраться до root-а с некоторой стоимостью root-повкост. Вот. Все designated порты тоже будут разблокированы после окончания пересчета топологии, потому что это будет означать, что вы находитесь ближе всего к root, чем все остальные возможные ваши соседи в этом сегменте. То есть designated bridge — это тот самый switch, который находится ближе всего к root по сравнению со всеми остальными в этом проводе. Вот. Когда наши коммутаторы или бриджи обмениваются информацией о том,
кто будет являться центральным коммутатором, как до него лучше добраться, физически это все будет передаваться вот в подобного рода сообщениях. Называться они будут BPDU — Bridge Protocol Data Unit. Это те самые пакетики, которые Spanning 3 будет отправлять. Они будут передаваться между всеми, соответственно, коммутаторами, которые у нас есть в топологии, и они будут содержать всю необходимую информацию для работы Spanning 3. Начинается все с 5-байтового заголовка. Там будет указываться, что это именно Spanning 3, что Spanning 3 медленный или быстрый, тип Spanning 3-байтового заголовка. В общем, там сейчас не сильно интересно, что внутри будет, поэтому здесь, видите, в рамочку оно не вошло. В конце самый хвост BPDU-шки будет содержать 8 байт таймеров. Нам таймеры сейчас тоже пока не очень интересны. До них потом дойдем, но пока не интересно. А вот то, что посерединке между заголовком и таймерами, это будет 22 байта, которые будут называться priority vector или BPDU priority vector.
Вот BPDU-шки между собой можно сравнивать по, скажем, качественности. То та BPDU-шка, у которой вот этот priority vector числово меньше, она будет более правильной, более хорошей. Если у нас есть два коммутатора, которые находятся в одном канале, то есть они соединены общим проводом, один коммутатор может послать BPDU-шку другому и другой первому. Вот эти BPDU-шки можно между собой сравнить. Вы берете вот эти вот 22 байта, которые есть, и сравниваете. У кого меньше, тот и прав. И поэтому одна BPDU-шка будет лучше. Та BPDU-шка, которая будет лучше, будет называться словом superior. И, соответственно, та, у которой priority vector, вот эти 22 байта, будут больше, она будет называться inferior. То есть она хуже. У кого меньше, тот и прав. У кого больше, тот меньше. Тот, соответственно, то он пение прав. Вот 22 байта просто мы сравниваем между собой. Да, это большое число, но, тем не менее, все равно это просто число. То есть мы можем их взять и сравнить между собой.
И структура этого priority vector будет указывать на то, собственно говоря, что именно мы сравниваем. То есть да, мы можем сказать, что мы сравниваем между собой 22 байта, но это как-то не очень о многом нам говорит. А вот в то же время, если мы посмотрим на то, что внутри там есть, то мы поймем, почему сравниваются эти 22 байта и почему вопдушка, которая будет иметь меньший priority vector, она будет лучше. Начинается все с того, что первые 8 байт будут называться root bridge ID. Это тот bridge ID, кого вы считаете текущим рутом. Если один коммутатор посылает другому указание, я рутом считаю Васю, А другой говорит, а я рутом считаю Петю, то, соответственно, более правильная BPDU-шка — та, которая рассказывает про рута с меньшим bridge ID. И чем меньше root bridge ID, тем более доверенная такая BPDU-шка. Если один говорит, что я знаю, как добраться до рута за 10 копеек, и это Вася, а другой говорит, я знаю, как до рута добраться за 0 копеек, и это Петя, нам нет смысла сравнивать копейки,
потому что root bridge ID более важный, более приоритетный. Поэтому он идёт самым первым. И в root bridge ID у нас 8 байт. Это тот самый bridge ID, которого вы считаете сейчас рутом. Если вдруг вы получите информацию о том, что кто-то другой root bridge ID заявляет меньше, чем тот, который вы знаете сейчас, то вы перекуётесь, и следующие BPDU-шки, которые вы будете рассылать, вы будете указывать уже новый root bridge ID, который вы узнали через соседа. Дальше. Root path cost — это, как понятно, за сколько вы знаете рута. Если у нас есть некоторое количество коммутаторов, они связаны между собой. Один говорит, я, допустим, root, я знаю, как добраться до самого себя за ноль копеек. Следующий получает такую информацию через интерфейс, который, например, стоит 10 копеек. И дальше говорит, я знаю, как добраться до рута за 10 копеек. И так оно дальше будет передаваться. Этот интерфейс, например, будет стоить 15 копеек. И следующий коммутатор, который будет рассказывать про то, что он может добраться до рута, говорит, я знаю,
как добраться за 25 копеек. Это примерно как работает, например, протокол RIP. Только RIP рассказывает по каждому маршруту метрику, и этих маршрутов у RIP много. А у Spanning Tree это фактически рассказ про один единственный маршрут, как можно добраться до root'а. И метрика этого маршрута будет суммарная стоимость всех интерфейсов, которые у нас ведут до root'а самым коротким способом. Если вдруг есть вариант, как дойти до root'а подлиннее или покороче, то есть у нас, например, ещё есть обходной манёвр, можно дойти до root'а здесь за 20 копеек, здесь тоже за 20 копеек, то через верх у нас можно добраться до root'а за 25 копеек, через низ за 40. В этом случае правый коммутатор будет считать, что он может добраться до root'а естественно за 25 копеек, не за 40. И дальше будет говорить, я знаю, как добраться именно за более короткую стоимость. Root'а в этом случае будет считать одного и того же соседа, один и тот же коммутатор, но самый короткий способ добраться до него он будет естественно расценивать как тот, по которому
был получен root path cost минимальный. Дальше. Если у нас есть root path cost, это у нас 4-байтовое значение. Это когда мы отправляем какую-то BPDU-шку, мы заявляем, насколько далеко мы знаем рута. Начинаем мы все с того, что рассказываем, что знаем рута за 0 копеек. После того, как BPDU-шка на каком-то интерфейсе получена, для получения эффективной root path cost там прибавляется стоимость интерфейса, на котором это было получено. Если вдруг у нас есть коммутатор, и у него с одной стороны приходит BPDU-шка, и с другой стороны приходит BPDU-шка, и они очень похожи друг на друга. У них одинаковый root bridge ID, у них одинаковый root path cost. Нам нужно всё равно каким-то образом понять, какая из BPDU-шек будет лучше для того, чтобы определить, какой из интерфейсов в итоге будет объявлен рутовым, а какой будет заблокирован, потому что это будет альтернативный способ добраться до рута. Поэтому здесь с точки зрения топологии Spanning Tree говорит, что у нас что с одной стороны, что с другой стороны абсолютно одинаково. Но нам нужно каким-то образом выбрать один порт
из нескольких, на которых мы получаем одинаковые BPDU-шки. В этом случае Spanning Tree начинает подкидывать монетку. Он начинает говорить, что нам нужно каким-то предсказуемым образом определить тот самый один порт, который будет заблокирован. И в этом случае он будет в качестве тайбрейкера определять, кто послал BPDU-шку. Узел, который послал BPDU-шку с самым маленьким bridge ID отправителя, он и будет считаться более правильным. Его BPDU-шка будет считаться меньшей. С меньшим priority-вектором, superior BPDU-шка будет. Тоже 8 байт. Это bridge ID того, кто послал BPDU-шку. Если хотите, подпись отправителя. Сравниваться это будет в ситуации, когда у нас есть вариант абсолютно одинаковый, допустим, мы можем пойти через верх или через низ, но нам нужно каким-то одним способом определить, какой всё-таки из интерфейсов оставить заблокированным, какой разблокировать. В этом случае мы говорим, на верхнем полученная BPDU-шка получше,
на нижнем полученная BPDU-шка похуже, нижний порт мы блокируем. Сравниваем по тому, кто отправил нам соседнюю BPDU-шку. И если у вас есть сценарий вида два свитча и два провода между ними. И приходит BPDU-шка от одного и того же свитча, но на двух разных интерфейсах. В этом случае надо будет какой-то один из них заблокировать. Но root bridge ID там, естественно, приходят одинаковые. Это один и тот же свитч рассказывает про то, что он знает, как добраться до рута. Он, естественно, знает на обоих портах одинакового рута. Root path cost тоже там будет одинаковое, потому что это то, сколько заявляет сосед, стоит у него root на самом деле. Дальше мы должны будем прибавить стоимость самих интерфейсов. И если два интерфейса абсолютно одинаковые, то получится, что эффективный root path cost тоже будет одинаковый. И sender bridge ID в такой ситуации тоже нас не спасает, потому что это BPDU-шки, отправленные одним и тем же соседом. Получается, что в этой ситуации BPDU-шки считаются тоже равнозначными.
Но каким-то образом нужно будет определить, какая из них будет получше, какая похуже. В этом случае сравниваться будет sender port ID. Двухбайтовое значение. Каждый порт на отправителе будет пронумерован. И на одном порту будет, например, номер стоять один, на другом будет номер два. И в этом случае та BPDU-шка, которая отправляется соседом из-под порта с меньшим номером, будет считаться более достоверной. Этот priority-вектор нужно будет выучить наизусть, знать на экзамене. Я не знаю, делайте, что хотите, но его вы должны будете знать. И этот порядок: root bridge ID, дальше root path cost, sender bridge ID и sender port ID. Это такая волшебная пуля, которая нам позволит определить, как себя ведёт Spanning Tree в каждом конкретном случае. Если у нас есть любая топология, и мы хотим определить, кто в этой топологии будет свои порты блокировать, кто в этой топологии порты блокировать не будет, мы начинаем смотреть. Сначала все коммутаторы проверяем на то, кого они будут считать рутами.
Root bridge ID в этом случае будет самым важным критерием. Тот, кто будет обладать самым маленьким bridge ID, в итоге будет выбран рутом за всю сеть. Дальше смотрим root path cost. BPDU-шки, которые будут приходить на разных портах с указанием одного и того же рута, они будут заявлять какую-то стоимость, как можно добраться до рута. Дальше мы прибавляем к этой стоимости стоимость интерфейсов, по которым получаем BPDU-шки, и получаем итоговый root path cost. Если вдруг приходят две BPDU-шки с одинаковым root bridge ID и root path cost, сравниваем sender bridge ID. У кого меньше, тот и прав. И наконец, если вдруг у нас есть ситуация, когда два провода приходят от одного и того же соседа, сравниваем sender port ID. Каким портом отправил сосед эту BPDU-шку? BPDU-шка, отправленная из порта с меньшим номером, она будет более правильная. Но, естественно, что это самый-самый последний механизм проверки корректности BPDU-шки. На самом деле, здесь у вас может возникнуть странный вопрос, а почему 22 байта?
Какое-то странное значение, немножко некруглое. Обычно мы стараемся что-то всё круглое делать. Там 8 байт, 16 байт, 24 байта. А здесь 22. На самом деле, priority-вектор, когда мы получаем BPDU-шку, пополняется ещё двумя байтами. Они не передаются в BPDU-шке, они дорисовываются автоматически в момент получения BPDU. Там ещё есть receiving port ID. И в ситуации, если у вас есть свитч, на этом свитче, это свитч именно С поддержкой Spanning Tree, на этом свитче интерфейс смотрит, например, в сторону хаба или в сторону свитча без поддержки Spanning Tree, а от него идут два провода на наш же свитч. В этой ситуации получится, что BPDU-шка, которая отправляется со стороны соседа, она имеет одинаковый root bridge ID, одинаковый root path cost, одинаковый sender bridge ID и одинаковый sender port ID, потому что это одна и та же BPDU-шка. Но она разветвляется и приходит в виде двух разных BPDU-шек на наш коммутатор. В этой ситуации добавляется ещё одно поле — receiving port ID.
Мы свои порты пронумеровываем и говорим, что если одна и та же BPDU-шка с одинаковыми абсолютно значениями приходит на два разных наших порта, то в этом случае мы принимаем ту BPDU-шку в качестве хорошей, которая приходит на порт с меньшим номером. И, соответственно, это самый последний receiving port ID, самый последний элемент сравнения двух BPDU-шек на хорошесть. Тоже 2-байтовое значение. И если вы возьмёте эти 22 байта и ещё 2 байта добавите в priority-вектор этого receiving port ID, вы получите красивое значение 24 байта. Немножко визуализирую то, что я вам только что рассказывал. У нас начинается всё с того, что каждый коммутатор ничего не знает про своих соседей, считает себя рутом, считает, что все его порты будут designated, потому что он никоим образом не знает, что в сети существуют другие коммутаторы. Как следствие, он считает, что через его собственные порты
до рута добраться нельзя. Потому что рут — это он сам, и проще всего до рута добраться, просто на себя самого любимого посмотрев. Поэтому начинается процесс работы Spanning Tree с того, что каждый коммутатор заявляет, что он будет рутом, он начинает рассылать BPDU-шки с указанием себя самого в качестве root bridge ID. Если вдруг вы получаете BPDU-шку с указанием root bridge ID меньше, чем тот root bridge ID, которого вы считаете сейчас, то вы перековываетесь и начинаете через некоторое время рассылать BPDU-шки с указанием нового root bridge ID. То есть root bridge ID у вас в нормальной ситуации не может увеличиться, может только уменьшиться. Дальше. Если у нас есть вот такая цепочка, кольцо из коммутаторов, четыре коммутатора, и, соответственно, у них есть какие-то маки и какие-то приоритеты на них прописаны. По умолчанию все приоритеты будут 8000 шестнадцатеричные, то есть это приоритет, который ровно посерединке
между всеми возможными значениями 16-битного root priority. Максимальное значение, которое может быть в 16-битном числе, это 65536. У нас по умолчанию вкладывается число 32768. То есть это у нас FFFF шестнадцатеричные, а это у нас 8000 шестнадцатеричные. То есть ровно половинка от максимального значения. И, соответственно, если вдруг вы хотите повлиять на выбор root bridge ID, то вы можете поменять bridge priority. И тому коммутатору, который должен становиться рутовым, вы можете взять и поменьше этот самый приоритет сделать. Например, можно поставить 7000. 7000 шестнадцатеричные. Это шестнадцатеричные значения. И получается, что bridge ID у вас будет состоять из первых 16 бит 7000 и дальше MAC-адреса. Представим себе, что у нас такая ситуация
и произошла. На одном коммутаторе был поставлен приоритет не дефолтный, и на другом коммутаторе тоже был поставлен приоритет не дефолтный. И посмотрим, к чему это может привести. Сначала всё начинается с того, что каждый коммутатор считает себя рутом. Сюда отправляется BPDU-шка, сюда отправляется BPDU-шка, сюда отправляется BPDU-шка, сюда отправляется BPDU-шка, сюда отправляется BPDU-шка, сюда отправляется и сюда тоже отправляется. То есть каждый коммутатор на каждом своём порту, который у нас здесь нарисован, отправляет BPDU с указанием «я буду рутом». Но получается, что одна BPDU здесь отходит от настоящего рута, у которого приоритет 7000, а другая в ответ приходит, что «я знаю рута, у которого приоритет 8000». Поэтому через очень небольшое время, как только BPDU от соседа 7000 — давайте их пронумеруем: первый, второй, третий и четвёртый. Как только BPDU от первого доходит до второго, второй говорит «я больше не считаю рутом самого себя, я считаю рутом первого». Ну и то же самое на четвёртый. Через некоторое время приходит BPDU от первого, и четвёртый говорит «я больше себя не считаю рутом,
я считаю рутом первого». Но при этом третий, например, про первого ещё пока ничего не знает, потому что BPDU, которые отправляются, они отправляются так, волнами по некоторому таймеру, и, соответственно, в первую волну второй и четвёртый про первого узнали, а третий рассказывает, что он себя пока всё ещё считает рутом. Поэтому первый считает рутом самого себя, второй считает рутом первого, четвёртый считает рутом первого, а третий пока ещё считает рутом самого себя, потому что до него информация про первого ещё не дошла. Но на второй волне BPDU-шек уже второй и четвёртый дружно зарядят третьему BPDU-шки с указанием «я считаю рутом первого, и его bridge ID будет меньше, чем твой». Соответственно, третий в этом случае перековывается и говорит «я буду считать первого корневым бриджем», потому что у него приоритет такой же, как у меня, а MAC-адрес у меня получается больше. Поэтому мой bridge ID будет больше, чем root bridge ID этого самого первого, поэтому его я буду считать рутом.
Раньше я считал рутом самого себя, а теперь буду его. Так, далее. После того как мы поняли, как выбирается root, дальше нужно будет понять, как лучше всего добраться до рута. Это не какой-то отдельный процесс. Это тот же самый процесс. Когда вы рассказываете в BPDU-шках, кого вы считаете рутом, вы одновременно рассказываете, как до него можно будет добраться. Может быть, чуть больше времени займёт указание на все коммутаторы, как лучше всего добраться до рута, но всё равно это не какой-то отдельный процесс, типа сначала выбрали рута, а потом поняли, как до него лучше всего добираться. Это всё в одних и тех же BPDU-шках будет передаваться. То есть самая первая волна — у нас все коммутаторы, первый, второй, третий, четвёртый, считают рутом самого себя. Первая волна — первый коммутатор по-прежнему считает рутом самого себя. А давайте: первый, второй, третий и четвёртый. И, соответственно, второй получает BPDU-шку от первого и говорит: я сейчас считаю рутом первого, но я получил от него указание root path cost 0,
и я получил эту BPDU-шку на интерфейсе со стоимостью 10. Поэтому я буду заявлять в следующих волнах BPDU-шек, что я знаю, как добраться до рута первого свитча, Соответственно, я знаю, что добраться до него можно за 10 копеек. И следующая волна BPDU-шек будет разбегаться с указанием root-bridge-id 1 и root-path-cost 10, которые BPDU-шку будет отправлять второй свитч. То же самое четвертый. Он будет рассказывать, я знаю, как добраться до рута, рут у меня первый, он получил BPDU-шку на порту со стоимостью 30, и он будет говорить, я знаю, как добраться до рута за 30 копеек. Дальше вторая волна. Третий свитч получит две такие BPDU-шки и скажет, что я знаю, как добраться до рута первого через соседа номер 2. Сосед номер 2 заявил, что он знает рута за 10 копеек. Дальше я эту BPDU-шку получил через интерфейс со стоимостью 20 копеек, поэтому эффективная стоимость root-path-cost через верхнего соседа получается 30 копеек.
В то же время через низ сосед номер 4 заявляет, что он знает рута уже за 30 копеек, плюс 10 копеек стоимость самого интерфейса, получается через низ добраться до рута можно за 40 копеек. Поэтому мы root-bridge-id заменяем. Раньше мы считали рутом самого себя, а теперь мы будем считать рутом первый коммутатор. Но из двух вариантов, как можно добраться до первого, мы будем считать, что этот интерфейс смотрит на рута получше. У нас получается, что в таком раскладе вариант добраться до рута за 30 или за 40, но очевидно, что за 30 получается подешевле. Далее. Что здесь еще интересного? Эти самые стоимости портов, которые мы будем прибавлять к тому, что пришло в BPDU-шке, их можно выставлять вручную по совершенно любому правилу, которое вы захотите. Хотите — везде проставьте единицу. Хотите — везде сделайте что угодно. Но логически, следуя определенному правилу, мы можем добиться эффекта, что трафик будет ходить до рута по трассе с наилучшими характеристиками.
И чем меньше у вас стоимость конкретного интерфейса, тем лучше характеристики этого интерфейса. Смысл будет заключаться в дефолтных скоростях, которые выставляют ваши коммутаторы, в том, что единственная характеристика для Ethernet-интерфейса, которая сильно влияет на его качество, это его скорость. Если у нас есть 10-мегабитный интерфейс, он похуже. Если у нас 100-мегабитный интерфейс, он получше. Гигабитный интерфейс — совсем хорошо. Оригинальная версия Spanning Tree Protocol, предлагала следующие дефолтные значения для стоимости портов. Если у вас был 10-мегабитный интерфейс, предлагалась стоимость 100, 100-мегабитный интерфейс предлагалось иметь со стоимостью 10, и гигабитный интерфейс предлагалось иметь со стоимостью 1. Надо понимать, что в 90-м году гигабитных интерфейсов еще не существовало. Предполагалось, что может быть когда-нибудь ученые, если очень сильно повезет, придумают такие интерфейсы, которые будут работать со скоростью 1 гигабит в секунду. Но по факту все интерфейсы, которыми Ethernet располагал,
были 10-мегабитные, и стоимость для них предлагалась 100. И смысл был в том, что если у вас есть, например, 3 коммутатора, и они связаны между собой в кольцо, и один интерфейс у нас получает 10-мегабитку со стоимостью 100, другой интерфейс тоже 10-мегабитку со стоимостью 100, а здесь у нас, например, был 4-мегабитный интерфейс, допустим, где-то он его взял, и стоимость там была 250. В этом случае от одного узла до другого, узел номер 1 и узел номер 2, трафик должен был идти по наиболее дешевой трассе, он должен был идти через 2 100-копеечных интерфейса, то есть через 2 10-мегабитных. Через 4-мегабитный интерфейс он не шел бы, потому что он там получался дороже. Эта штука позволяет добиться того, чтобы у вас при дефолтных скоростях, которые были характерны для 90-го года,
трафик ходил действительно оптимально. Но в 90-м году авторы протокола не предусмотрели бурного развития отрасли и не предусмотрели того, что очень скоро, примерно в конце 90-х, гигабитные интерфейсы стали нормой. Они не просто появились, они стали продаваться на рынке, они стали доступны для приобретения, гигабитные интерфейсы стали уже не чем-то невозможным, они стали вполне себе нормой. И поэтому этот интерфейс, который имел скорость 1 гигабит, он по дефолтной формуле должен был иметь стоимость 1 копеечку, и эта самая 1 копеечка была неделима. Если вдруг вы бы хотели сказать, что у нас есть интерфейс больше, чем 1 гигабит пропускной способности, у него стоимость должна была быть меньше, чем стоимость гигабитного интерфейса, но меньше уже некуда, потому что и так 1 копейка, 0 копеек стоимость делать нельзя. Поэтому любые интерфейсы, которые имели производительность больше, чем гигабит, по такой логике получали стоимость
именно копейку. А если вы посмотрите, для этих дефолтных стоимостей работает правило. Мы берем скорость интерфейса и делим на нее референсную скорость в 1 гигабит в секунду. 1 гигабит делим на скорость интерфейса и получаем эту самую стоимость. Соответственно, здесь у нас для 4-мегабитных интерфейсов была предложена дефолтная стоимость 250, для 10-мегабитных дефолтная стоимость 100, для 16-мегабитных 62, для 100-мегабитных 10, и так далее. Все интерфейсы, которые имели скорость гигабит или больше, они в этой табличке просто отсутствовали, но для них предлагалась стоимость единичка. В 98-м году, когда стало понятно, что гигабит уже пришел, и его можно уже купить, стало понятно, что нужно эту табличку модифицировать. При этом постарались сохранить те скорости, которые были
все-таки еще на тот момент доминирующими, то есть 10-мегабитные. 4 мегабита, 10 мегабит и 16 мегабит — стоимости остались теми же самыми. Дальше. 100-мегабитному линку немножко повысили дефолтную стоимость, сказали, 100-мегабитный линк пусть имеет стоимость 19. Гигабитный линк имеет стоимость 4, 2-гигабитный 3 и 10-гигабитный 2. А все, что быстрее, чем 10 гигабит, например, 20 гигабит, это будет стоимость уже единичка, потому что на тот момент 10-гигабитных линков пока еще не планировалось. Предполагалось, что наверняка они скоро появятся, но на тот момент ничего похожего не было. На тот момент гигабит был основной проблемой. Его надо было различать. Гигабитный линк, например, 2-гигабитный линк, то есть это 2 гигабитных канала, объединенные в один логический. Они уже представляли собой проблему на тот момент, и нужно было различать один гигабитный шнурок или два гигабитных шнурка, соединенные в один, которые номинальную полосу имели вдвое больше.
И для решения той проблемы в 1998 году рекомендованные стоимости изменили на такие табличные значения. Для нас не нужно будет запоминать все возможные значения, которые там предложили, но нужно будет запомнить ключевые. Это действительно будет на экзамене, и вас будут спрашивать. В 802.1D 1998 года стоимости наиболее характерных интерфейсов: 10 мегабит, 100 мегабит, гигабит и 10 гигабит. Вот эти четыре скорости. Стоимости были предложены следующие: 100, 19, 4 и 2. Эту формулу 100, 19, 4, 2 нужно будет запомнить. В 98 году, как уже было сказано, 10 гигабит были на подходе, но все-таки на тот момент еще особо не появлялись. Но в 2001 или в 2002 году стали предлагаться 10-гигабитные оптические линки, и индустрия должна была что-то ответить на это. Поэтому в 802.1D 2004 года, то есть через 6 лет произошла ревизия стандарта,
и эти дефолтные формулы решили изменить еще раз. Стоимости, которые предлагалось по умолчанию назначать на интерфейсы в 2004 году, тоже вычислялись по формуле. Формула была 20 терабит, разделенная на скорость интерфейса. Если у вас был интерфейс, например, 10-мегабитный, то 20 терабит, разделенная на 10 мегабит, это было 2 миллиона. Если у вас 100 мегабит, то 20 терабит, деленная на 100 мегабит, это 200 тысяч. Соответственно, гигабит 20 тысяч и 10 гигабит 2000. Вот это актуальные стоимости, которые стандарт рекомендует назначать на интерфейсы. Это рекомендованные значения, никто вам не мешает этой рекомендации не следовать. Хотите — пожалуйста, изменяйте. Для тех, кто хочет использовать нестандартные стоимости, стандарт рекомендует не сильно отклоняться от них.
Логика будет заключаться в том, что если вдруг вы добавляете в сеть новый коммутатор, у него, скорее всего, стоимости будут выставляться по стандарту. Поэтому если вы добавляете новый коммутатор, и у него стоимости выставляются в логике, отличной от той, в которой вы эти самые стоимости назначали, может получиться так, что тот линк, который на коммутаторе будет сильно медленный, он будет получаться более выгодным с точки зрения Spanning Tree, и трафик пойдет по нему. Допустим, представьте себе, что вы используете стоимости вот такие, и добавляете в цепочку коммутатор, который имеет дефолтные стоимости вот такие. И получается, что у него где-нибудь есть 10-мегабитный линк. И этот линк имеет стоимость 100. В нормальной ситуации вы хотите выставлять такие стоимости с 100-мегабитным линком. Но из-за того, что у коммутатора стоимости выставлены в логике 98-го года, через 10-мегабитный линк начинает весь трафик судорожно бежать.
Потому что стоимость этого линка сильно меньше, чем стоимость всех других линков, которые у вас там есть. Это не очень здорово, когда у вас в современной сети весь трафик идет через сильно медленные интерфейсы. Поэтому в такой ситуации лучше будет, если у вас все линки будут иметь стоимости, выставленные в одной логике. И если вы где-то меняете эту самую логику, то рекомендуется от предложенных значений не сильно отклоняться. Отклоняться можно не больше, чем в 10 раз. Рекомендуется от рекомендованных значений отклоняться не больше, чем в 10 раз. Если вы, например, хотите в логике 2004 года поставить стоимость 100-мегабитному интерфейсу, то вы должны будете руководствоваться логикой, что она может быть от 20 тысяч до 2 миллионов. Такое значение. Далее. Как уже говорилось,
у нас в процессе передачи информации о том, кто будет являться рутом, заодно передается указание, как до этого рута лучше всего добраться. И самый первый процесс, который мы запускаем, это из информации, которая приходит в приходящих BPDU-шках, мы выбираем корневой коммутатор, выбираем рута. Параллельно с этим мы узнаем о том, как до этого рута можно добраться, за какую стоимость. Когда нам сосед присылает указание, что он знает, как добраться до рута, мы вычисляем все возможные варианты, как можно добраться до рута, и выбираем среди них самый дешевый. И тот самый порт, на котором получается BPDU-шка с минимальной эффективной стоимостью, он будет объявлен корневым портом, то есть root-портом. Это тот порт, на котором вы получаете самую выгодную BPDU-шку. Важный момент. Если вдруг у вас есть провод, в котором есть два коммутатора,
и один коммутатор присылает BPDU-шку, и второй коммутатор, гипотетически, тоже может присылать BPDU-шку. Одна из этих BPDU-шек будет superior, она будет лучше, а другая будет inferior. В реальности inferior BPDU-шку не посылают. Дело в том, что если вдруг у вас есть какой-то коммутатор, который присылает указание, что через него можно добраться до рута, и он будет designated bridge. Он декларирует тем самым, что может добраться до рута самым выгодным образом. Нет смысла в этот же канал посылать указание, что через вас можно добраться до рута, но невыгодным образом. Поэтому superior BPDU-шка в канал посылается, а inferior нет. Если у вас есть два коммутатора, которые связаны между собой проводом, только один из них будет посылать BPDU-шку. Применительно к нашей топологии у нас есть корневой коммутатор, действительно корневой. Начинается все с того, что все они считают себя корневыми, но по факту корневой останется только один. Он рассказывает, что может добраться до рута за 0 копеечек.
Самая первая волна, второй свитч, второй, первый, третий и четвертый. Второй свитч говорит, я знаю, как добраться до рута самого себя. И он тоже говорит, я знаю, как добраться до рута самого себя, но он говорит, я знаю, как добраться за 0 копеек. Через очень небольшое время рут действительно продолжает говорить, я все еще считаю себя рутом. А второй свитч перестает говорить, что считает рутом самого себя. Он говорит, я теперь знаю, что рутом у нас будет первый коммутатор. И он обратно в сторону первого коммутатора эту информацию не посылает. Потому что какой смысл первому коммутатору рассказывать про то, что можно добраться до него через второе. Нет смысла в этом. Поэтому в сторону РУта обратно БПДушек не посылается. И если у вас есть какой-то порт, на котором вы получаете выгодную БПДушку, то вы на этом порту БПДушку получаете, но при этом не отправляете обратно. Незачем. То есть приходит всегда БПДушка выгодная. Если приходит БПДушка не настолько выгодная, как та, которую вы могли бы отправить, то вы тогда сами посылаете БПДушку в этот
порт. Вы считаете себя самым крутым коммутатором в этом канале, и вы в этом случае игнорируете то, что кто-то вам в ответ приходит с указанием, что через него можно добраться до рута невыгодным образом. Инфериору BPDU-шки вы игнорируете. Вот. И вот, соответственно, если у нас есть один порт, на котором приходит самая выгодная BPDU-шка, то этот порт будет объявляться рутовым. Если на каких-то других портах тоже приходят BPDU-шки, то есть мы находимся дальше от рута, чем кто-то еще в общем канале с нами, то вот все альтернативные варианты, как можно добраться до рута, вы уже не объявляете рутовыми. Рутовый порт по определению только один. Тот самый порт, на котором приходит самая-самая-самая выгодная BPDU-шка. Вот. Например, у нас есть вот эта вот топология, и первая волна, соответственно, BPDU-шек указывает, что на первом и третьем, на первой, второй, третий и четвертый, на втором и четвертом свече
возникает понимание, что до рута можно добраться через вот эти вот самые интерфейсы, которые на рута напрямую смотрят. И второй свеч знает, что до первого коммутатора можно добраться за 10 копеек. Четвертый знает, что до первого можно добраться за 30 копеек. На второй волне, третий свеч узнает о том, что первый свеч является рутом, и, соответственно, понимает, что через верх можно добраться за 30 копеек, через низ можно добраться за 40 копеек. Гипотетически в этой ситуации третий свитч четвертому свитчу тоже может отправить в обдушку. И тоже, соответственно, четвертый свитч поймет, что за 40 копеек можно добраться до рута в обход. Если бы вдруг, гипотетически, у нас бы здесь, например, стоимость вот этого линка была 50 копеек, а не 30, то тогда на первой волне четвертый коммутатор знал бы о том, что до рута можно добраться за 50 копеек. На второй волне он бы рассказал, что можно добраться за 50 плюс 10. Третий сказал бы, что можно добраться за 60. И дальше на третьей волне боподушек
третий четвертому бы рассказал, а через меня можно добраться за 40. И, соответственно, четвертый коммутатор в этом случае перековался бы и сказал, я теперь знаю, как добраться до рута за 40 копеек, только рут-порт у меня будет смотреть вот туда вот. Не напрямую на рута, от которого я получаю боподушку за 50 копеек, а в обход вот по такому вот маршруту, но за 40. Ну и в такой ситуации, да, у нас получилось бы, что нужно будет три волны боподушек пережить для того, чтобы все коммутаторы, корректно построили рут-порты друг до друга. Но вот в нашем случае, в любом случае, у нас получается третий коммутатор получает рут-порт тот, на котором приходит самая выгодная боподушка. И в ситуации, когда на четвертый коммутатор приходит боподушка за 30 копеек напрямую от рута, и гипотетически могла бы приходить боподушка за 40 копеек от правого свеча, соответственно, в этом случае рут-порт у нас выбирается тот, который приходит напрямую от рута за 30 копеек. Рут-порт после окончания пересчета топологии будет разблокирован.
Альтернатив-порт — это тот порт, на котором BPD-ушка тоже приходит, но она не самая выгодная. То есть, вот, например, у нас опять та же самая топология. После первой волны верхний коммутатор и нижний коммутатор. Давайте опять их пронумеруем. Первый, второй, третий и четвертый. Вот они друг к другу просилают BPD-ушки. После первой волны второй и четвертый свитч узнают, кто будет действительно рутом. После второй волны третий узнает, кто будет рутом. И после третьей волны четвертый гарантированно узнает, как можно лучше всего добраться до рута. И вот в такой ситуации получается, что у нас есть, например, вот четвертый свитч. У него есть вариант, как можно добраться до рута. Вот здесь вот у нас приходит BPD-ушка за 30 копеек. И он отправляет BPD-ушку, что можно добраться через меня за 30 копеек. Но, соответственно, третий свитч принимает такой BPD-ушка и говорит, я знаю, как добраться до рута за 40 копеек. Через низ за 40 копеек у нас получается и через
верх за 30. Вот в этой ситуации третий свитч, он, соответственно, знает, как можно добраться до рута. Можно пойти через верх, можно пойти через низ. Но через верх 30 копеек, и BPD-ушка там приходит выгодная, поэтому верхний порт будет рутовый. А через низ получается за 40, и, соответственно, в этот нижний порт будет объявляться альтернет-портом. BPD-ушка, которая приходит на альтернет-порту, лучше, чем та, которую мы сами могли бы отправить в этот порт. Ну, по каким-то причинам в нашем случае. Вот в ситуации, когда именно именно то, что у нас на топологии нарисовано, root-pass-cost 30 на третьем свитче, и root-pass-cost 30 на четвертом свитче, они будут друг к другу отправлять, либо подушки, у которых будет одинаковый root-bridge-id. Они будут говорить, что root-bridge-id у них одинаковый, и это первые свитчи. Одинаковый root-pass-cost. Вот в этом вот сегменте, root-pass-cost, обе коммутатора будут заявлять, что он будет 30 копеек. Дальше. Sender-bridge-id. И вот здесь вот будет играть роль
то, кто, значит, там будет, каким sender-bridge-id заявлять. Вот если у нас sender-bridge-id на четвертом свитче будет меньше, то в этом случае его BPDU будет лучше, чем та, которая мог бы отправить третий свитч. Ну и, соответственно, вот в этом случае третий свитч соглашается с тем, что BPDU, которая приходит от четвертого свитча, она выгоднее, чем BPDU, которая мог бы сам третий свитч отправить в сторону четвертого. И в этом случае он в ответ ничего не отправляет, просто тихо блокирует свой порт. Alternate-порт остается заблокированный после окончания пересчета топологии. Root-порт по определению может быть только один, ну или ноль, если вы сами root-bridge. А вот alternate-портов может быть много. То есть если у вас, например, вот есть некий root-коммутатор, и вот есть другой коммутатор, и они оба 48-портовые, вот вы взяли все 48 портов, вот так вот проложили параллельно, у вас один порт будет выбран рутовым, а все остальные будут alternate-портами, они будут заблокированы. Так.
Если вдруг же у нас на третьем коммутаторе будет root-bridge-id меньше, то есть не root-bridge-id, а просто bridge-id будет меньше, чем у четвертого. Давайте первый, второй, третий, четвертый. Ну, например, здесь bridge-id у третьего коммутатора будет начинаться с priority 7000. По-моему, как раз на начальном слайде такое было, а вот здесь у нас priority будет 8000, то в этом случае bridge-id третьего коммутатора, sender-bridge-id, и sender-bridge-id четвертого коммутатора, они будут различаться, и различаться они будут в пользу третьего. То есть в этом случае третий скажет, у меня нет alternate-порта, я отправляю вкусную BPD-ушку в сторону четвертого. А четвертый скажет, я принимаю вкусную BPD-ушку вкуснее, чем я бы мог сам отправить. Поэтому я со своей стороны порт объявляю alternate-портом, и его буду блокировать. Вот. Ну, здесь вопрос, да, в том, кто заблокирует вот этот вот порт. Оба блокировать его не могут,
потому что тут могут сидеть юзеры, и этих юзеров надо кому-то обслуживать. Вот обслуживать их будет тот, кто находится ближе к RUT. Если они находятся, два коммутатора одинаково далеко от RUT, как в нашем случае, то обслуживать их будет тот, у кого sender-bridge-id меньше. То есть тот, кто посылает более вкусную BPD-ушку в порт. Тот порт, соответственно, которым мы сами отправляем BPD-ушку, потому что мы ближе всего к RUT, это будет designated порт. Это именно тот порт, который отправляет BPD-ушки. То есть по определению, если BPD-ушка отправляется, то она отправляется только потому, что мы находимся ближе к RUT, чем кто-либо еще в этом канале. Поэтому мы объявляем себя designated bridge-ом, мы объявляем свой порт designated портом, и все остальные принимают BPD-ушки о том, как мы хорошо расположены относительно к RUT, и они не отправляют нам ничего в ответ. Вот. Когда начинается пересчет топологии, все коммутаторы считают, что они будут корневыми, и у всех коммутаторов есть понимание,
что все их порты designated. Но через некоторое время это, как правило, проходит. И, соответственно, через некоторое время все коммутаторы начинают понимать, что designated порты у них на самом деле не designated, это, что в сети есть какой-то другой RUT, и до этого какого-то другого RUT можно как-то добраться. Поэтому постепенно все порты из designated переходят в какие-то другие вот роли. Но, соответственно, через некоторое время, после начала пересчета топологии, когда мы понимаем, что все, сеть устаканилась, мы должны будем разблокировать коммутацию. Но до того момента, как сеть не устаканилась, мы коммутацию в любом случае блокируем. Поэтому начинается все с того, что все коммутаторы считают себя корневыми. Мы считаем, что на всех корневых коммутаторах у нас все порты designated, но до окончания пересчета топологии все блокируется, несмотря на то, что designated порты вроде бы уже всего круто. Мы даем некоторое время коммутатору для того, чтобы понять, кто действительно он на самом деле относительно всех остальных коммутаторов топологии.
И после того, как топология будет просчитана целиком, обычно это про таймеры просто проходит, мы говорим, все окей, можно разблокировать эти порты и нормально коммутировать трафик через них. Так. Ну и последний сценарий — это бэкапный порт. То есть у нас есть четыре типа портов. Это root-порт, alternate-порт, designated-порт и backup-порт. Если их прописать в виде таблички, то у нас есть root-порт. Это порт, на котором мы принимаем BPDU-шки, и эти BPDU-шки самые выгодные. И это самый выгодный способ добраться до root-а. И есть alternate-порт. Alternate-порт — это тот порт, на котором мы принимаем вкусные BPDU-шки, так же, как на root-порту. Мы не отправляем ничего в ответ, так же, как на root-порту, но это не самая вкусная BPDU-шка, которую мы видели. И alternate-порт у нас будет заблокирован. Root-порт разблокируется после окончания пересчёта,
а alternate-порт заблокируется. Alternate-порт, по сути своей, — это запасной root. Если у нас есть root-порт, а он всегда есть, покуда мы сами не root, и есть alternate-порт, то если root-порт сдохнет, alternate-порт станет root-овым. Так что иногда говорят, что alternate-порт — это запасной root. Если у вас есть designated-порт в какой-то сегмент, и есть запасной designated-порт, это может быть ситуация примерно как на рисунке нарисована, когда вы взяли патч-корд и замкнули им два порта на свиче. Или у вас здесь есть какой-то свитч без поддержки Spanning Tree, или это может быть Hub. BPDU-шки, которые вы отправляете, они проходят по этому кольцу и доходят до вашего собственного второго порта. Этот второй порт будет объявляться бэкапным портом. Понятное дело, что нельзя разблокировать оба интерфейса. Вы тем самым сформируете петлю. Поэтому один из интерфейсов надо разблокировать, чтобы этих пользователей можно было обслужить. А второй порт надо будет заблокировать, чтобы интерфейс не устроил петлю.
Два порта в этом случае будут выбираться по очень простому принципу. Опять же, кто может отправить самую выгодную BPDU-шку? Когда мы отправляем выгодные BPDU-шки, мы указываем root-bridge-ID. И в этом случае у обеих BPDU-шек, и та, которая отправится через один порт, и та, которая отправится через другой порт, root-bridge-ID, естественно, будет одинаковый. Тот самый root-bridge-ID, которого коммутатор считает рутом. Дальше, root-path-cost. Опять же, это один и тот же свитч. Двумя своими портами отправляет BPDU-шку в один и тот же провод. Sender-bridge-ID. Опять же, это один и тот же свитч отправляет BPDU-шку, поэтому sender-bridge-ID у него одинаковый. И дальше sender-port-ID — это указание, каким портом он это отправил. И на одном порту у нас будет номер, допустим, 1, а на другом порту будет номер 2. Или, не знаю, 7 и 19. Один номер будет меньше, другой будет больше. И sender-port-ID как раз позволит нам сказать, что здесь у нас отправляется BPDU-шка получше, а здесь похуже. И BPDU-шка, которая приходит получше
на порт другой, который похуже, она будет приходить. Если мы видим, что на каком-то порту приходит BPDU-шка, которая лучше, чем та, которую мы бы сами могли отправить, и у этой BPDU-шки sender-bridge-ID такой же, как у нас, то мы в этом случае говорим, это как раз сценарий, когда у нас два порта смотрят в одну и ту же среду. Приходит BPDU-шка наша собственная на этом порту, но лучше, чем та, которую мы бы сами могли именно на этом порту отправить. В этом случае такой порт объявляется запасным designated-ом или backup-портом. Он блокируется, но если текущий designated порт возьмёт и сдохнет, backup-ный порт можно будет разблокировать, и он станет запасным designated портом, который будет обслуживать этих пользователей. После окончания пересчёта топологии backup-ный порт блокируется, так же, как и alternate. Но если вдруг текущий designated порт по каким-то причинам перестанет присылать BPDU-шки, то такой порт можно будет разблокировать.
Классический Spanning Tree, как уже было сказано, не умеет работать с VLAN-ами. Он не знает, что если вдруг глазками петлю мы наблюдаем, на самом деле проблем это может не вызывать. Классический Spanning Tree умел работать только с физической топологией. Если вдруг у нас была топология вида два коммутатора, связанные между собой двумя портами, но эти два провода относились к разным широковещательным доменам. Например, здесь VLAN 10 передавался только, а здесь VLAN 20. Spanning Tree говорил: ничего не знаю, этот коммутатор у нас объявлен рутовым, этот коммутатор у нас объявлен нерутовым. Он говорит: я здесь получаю BPDU-шку вкусную, этот порт у меня будет root-порт, здесь я получаю BPDU-шку невкусную, вкуснее, чем мог бы сам отправить, но не такую вкусную, как на root-порту. Поэтому это у нас помечается как alternate-порт и блокируется. В итоге 20-й VLAN у нас не ходит между коммутаторами. Если у вас два транка между свичами и в них разный набор VLAN-ов, та же самая история. Этот коммутатор у нас объявляется рутовым,
этот коммутатор объявляется нерутовым, он говорит: я здесь вижу BPDU-шку вкусную, здесь вижу BPDU-шку невкусную, блокирую порт целиком. Весь трафик всех VLAN-ов, которые у нас там бегают, что 30-е, что 40-е, они все блокируются независимо от VLAN-а. И получается, что у нас есть блокировка коммутации в том месте, где она не то что излишняя, она там вредит. У нас получается, какой-то трафик в порт отправляется, но не доходит до получателя. Для того, чтобы избежать проблем, вызванных таким поведением, Spanning Tree был в своё время допилен. И есть несколько вариантов протокола, которые умеют работать с VLAN-ами. Первый вариант — это, как уже говорилось, MST. Это в своё время была рабочая группа 802.1S, которая вынесла набор рекомендаций, и этот набор рекомендаций вошёл в стандарт 802.1Q, тот самый, который про транки, 2003 года.
Второй вариант — это фирменный цисковский протокол PVST, который был придуман на основе стандартного протокола 802.1D, но позволял работать с VLAN-ами. Когда вы отправляете BPDU-шку, вы указываете, в каком VLAN-е вы отправляете эту BPDU-шку. Изначальная версия стандарта была сделана на основе 802.1D 90-го года, она называлась PVST, и работала она только с VLAN-ами, которые на свитчах соединялись между свитчами по портам ISL. Если у вас был свитч с одной стороны, свитч с другой стороны, и они каким-то образом в пределах одного VLAN-а хотели передавать трафик между двумя свитчами, транки в стандартном PVST могли быть только ISL-овскими. Но потом немножко допилили этот протокол, допилили его до 802.1Q-шных транков, и этот протокол стал называться PVST+.
Разница между PVST обычным и PVST+ только в том, что в PVST+ поддерживаются VLAN-ы 802.1Q-шные. В 98-м году выходит быстрый Spanning Tree, Rapid Spanning Tree, 802.1W, и Cisco адаптирует свой PVST-протокол для того, чтобы он работал с VLAN-ами тоже. Появляется протокол PVRST, Per-VLAN Rapid Spanning Tree. У него уже плюсов нету, он в любом случае работает с транками любого типа, что VLAN-ы ISL-овские, что VLAN-ы 1Q-шные, ему всё равно. На выбор нам даётся фактически два протокола. Либо MST по 802.1S, либо PVST и его наследники. В современном мире мы, конечно же, будем работать с PVRST, потому что медленный Spanning Tree в 2019 году — это не просто грешновато. Грешновато использовать любой Spanning Tree, который будет передавать трафик
между VLAN-ами, между свичами. Но медленный Spanning Tree — это прям совсем-совсем большой грех. В случае, если мы будем использовать быстрый PVRST, мы можем работать на оборудовании Cisco, мы можем работать на оборудовании Hewlett Packard, Huawei, Arista, Juniper, ключевые игроки телеком-рынка нормально работают с этим самым PVRST. Если вы хотите работать с оборудованием других вендоров, они могут не поддерживать PVRST, поэтому вы должны будете использовать MST 802.1S или, да, тот самый 802.1Q 2003 года. Но обычно называется либо MST, либо 802.1S. Далее. В медленном Spanning Tree, который 802.1D 90-го года, было пять состояний портов.
И, на мой взгляд, эти пять состояний были нелогичны. Их надо просто запомнить. Я вам рассказывал про то, что порты могут быть root-порт, alternate-порт, designated-порт или backup-порт. Это явление из быстрого Spanning Tree, из 802.1W. В 2004 году эта штука появилась примерно. А в 90-м году этого не было. В 90-м году вместо всех этих root, alternate, backup и прочее было только то, что здесь на слайде нарисовано. Пять состояний порта или port states. На экзамене, к сожалению, про них будут вопросы. На мой взгляд, учить это немножко излишне, но тем не менее. Поскольку на экзамене будет, придётся это выучить. Первое состояние — это disabled. Если у вас порт выключен, то Spanning Tree на нём не работает. И, как следствие, коммутация на этом порту у вас не осуществляется. Ни коммутация не осуществляется на выключенном порту,
естественно, если у нас порт выключен, то копию трафика в этот порт мы не отправляем. MAC-learning на этом порту не ведётся, потому что а что его там вести, если порт выключили? Shutdown его погасили. Состояние порта disabled означает, что коммутация на этом порту не работает. Дальше есть состояние порта, которое называется blocking. Это значит, что на порту обнаружена петля, и до тех пор, пока с этой петлей что-то не произойдет, коммутацию на этом порту мы не осуществляем. Это продолжительное состояние, оно может длиться сколько угодно долго, до тех пор, пока топология у вас не изменится. Коммутация на заблокированном порту не осуществляется, кадры, которые получены в заблокированном порту, мы не отправляем в другие порты. Помните, у нас коммутатор что делает? Он кадры, полученные на любых портах, разбрасывает на все остальные порты, кроме заблокированных. Если кадр получен на заблокированном порту, он никуда не копируется. Равным образом, если кадр получен на незаблокированном порту, он не копируется в заблокированные порты.
Ни приходящие кадры мы не обрабатываем, ни в заблокированные порты мы копии кадра не отправляем. И MAC learning тоже не ведётся, потому что если кадры, которые будут приходить на заблокированном порту, будут вызывать MAC learning, то у нас будет нестабильность MAC-адресов, и будет нехорошо. Поэтому на таком порту транзитный трафик не бегает. Но на заблокированном порту активность всё равно есть. Это будет не транзитный трафик, это будет трафик самого свича. Сам свич на заблокированном порту, например, будет принимать BPDU-шки. Это не будет выключенный порт, это будет заблокированный порт. Транзитный трафик на заблокированном порту не ходит, а BPDU-шки, которые приходят на этом порту, свич будет читать. Кроме того, там будет работать, например, протокол CDP, который обнаруживает соседей. Там будет работать какой-нибудь LACP, который мы пока с вами не проходили. Там будут работать ещё другие служебные протоколы, которые не предназначены для того, чтобы проходить через матрицу коммутации.
Фактически, когда мы говорим, что у нас есть коммутатор с поддержкой VLAN-ов, мы говорим, что у нас есть гипервизор, и дальше на нём запускаются виртуальные машины. Там 10-го VLAN-а, 20-го VLAN-а. И если есть какой-то провод, этот провод сообщается с каким-нибудь одним VLAN-ом, например, с 10-м. Но на самом деле этот физический интерфейс, на котором может приходить трафик, он может сообщаться не только с этими самыми виртуальными свичами, он может сообщаться ещё с некой сущностью, которую я буду называть центральный процессор. Трафик, который может приходить на порт, он может отправляться на коммутацию, например, 10-го VLAN-а, если мы говорим, что у нас есть access-порт в 10-м VLAN-е. Или он может отправляться на процессор. Это не трафик, который предназначается для коммутации. Например, CDP-шные кадры — это кадры, которые никуда не коммутируются. Они не принадлежат никакому VLAN-у. Они не коммутируются ни по таблице никакого из VLAN-ов. Они направляются сразу на процессор. То же самое с trunk-овыми портами.
Мы говорим, если у нас есть trunk-овый порт, на котором может бегать 10-й, 20-й VLAN-ы. Гипотетически этот порт связывается с 10-м и с 20-м VLAN-ом, но с процессором тоже связывается. Поэтому если кадры CDP-шные, spanning tree-шные и какие-то ещё служебные приходят, они отправляются не на коммутацию, они отправляются на процессор. И эти служебные кадры прекрасно работают на заблокированном порту. У вас CDP будет показывать соседей, у вас приходящие BPDU-шки будут обрабатываться. Но транзитный трафик через такой заблокированный порт ходить не будет. Если вдруг у вас обнаружена смена топологии — либо коммутатор только что включился, либо коммутатор обнаружил, что в сети в активной топологии произошли какие-то изменения, добавился новый свич или удалился имеющийся, — то в этом случае мы запускаем процедуру смены топологии. На всех портах мы запускаем проверку, нет ли петли в этом проводе.
Эта проверка будет состоять из двух этапов. Первый этап — listening, второй этап — learning. В состоянии listening мы начинаем проверку на петлю, и мы не коммутируем трафик, который приходит на таком порту, он фактически заблокирован, но при этом MAC learning мы на этом порту тоже не ведём. И длится это состояние в течение таймера, который называется forward delay. По умолчанию 15 секунд. Если вы не меняете этот таймер, то состояние listening длится 15 секунд. Вы в течение этого времени дожидаетесь, чтобы ваш коммутатор гарантированно забыл всё, что у него было в таблице коммутации. Кроме того, вы дожидаетесь того, чтобы все коммутаторы перешли в состояние listening на своих портах. Таймер forward delay — это тот самый таймер, который указывает на время, необходимое для распространения информации между любыми двумя коммутаторами в сети. Forward delay — говорящее название — это время, которое нужно для того, чтобы информация между любыми двумя свичами добежала до получателя.
И вы запускаете состояние listening, вы опустошаете свою таблицу MAC-адресов, потому что там информация, возможно, неправильная. Если у вас изменилась топология, то, возможно, те MAC-и, которые у вас в таблице были, они смотрят теперь не в том направлении, в котором надо. Поэтому вы всё очищаете и 15 секунд сидите, курите бамбук. Дальше, после того как это состояние заканчивается, вы переходите в состояние learning. И в состоянии learning вы продолжаете проверку на петлю, но вы знаете, что в этом состоянии уже все коммутаторы, как минимум, вошли в состояние listening. И если вдруг в этом состоянии вы увидите какие-то кадры, которые приходят на ваши порты, это происходит не потому, что кто-то ещё не успел перейти в listening, а потому что кто-то уже успел выйти из learning. Поэтому все кадры, которые приходят на порту в состоянии learning, они уже точно приходят из-под правильных портов. Это кто-то уже расслабил свои порты, поняв, что там нет петли точно. Поэтому всем кадрам, которые приходят на порту в состоянии learning, мы можем доверять.
Поэтому MAC learning мы на этом порту ведём. Если приходят какие-то кадры, мы запоминаем, какие MAC у них приходят, и заносим их в таблицу MAC-адресов. При этом мы со своей стороны ещё не осуществляем коммутацию. У нас коммутация выключается на порту на дважды forward delay timer. На 15 секунд мы выключаем коммутацию в состоянии listening, и на 15 секунд мы выключаем коммутацию в состоянии learning. Поэтому после обнаружения пересчёта топологии мы выполняем проверку на петлю в течение дважды forward delay timer, или по умолчанию в течение 30 секунд. После 30 секунд неработоспособности порта мы переводим порт в состояние forwarding. Forwarding — это нормальная работа. Покуда мы не обнаружим, что у нас происходит где-то смена топологии, мы на этом порту коммутацию осуществляем. Кадры, которые приходят на таком порту, мы дальше разбрасываем во все порты, кроме некоторых. И MAC learning на этом порту тоже ведём. Это нормальная работа свича в протоколе 802.1D 90-го года.
Одно состояние — порт выключен, нас оно не сильно интересует. И дальше эти четыре рабочих состояния — blocking, listening, learning, forwarding. Пожалуйста, не пытайтесь предположить, что blocking — это какое-то предварительное состояние для listening и learning. Начинается работа порта, когда у вас только новый свежий коммутатор включился, с состояния listening. Мы только-только включили порт, только-только включили коммутатор, у него все порты включенные. Начинается работа с того, что порты находятся в состоянии listening. Они проверяют, не содержатся ли там петли. Сначала идёт состояние listening, потом идёт состояние learning. Если петля не обнаружена, они переходят в forwarding. Если петля обнаружена, они переходят в blocking. И blocking означает, что активно уже обнаружена петля. Мы нашли петлю. Более того, мы на этом порту получаем чужую BPDU-шку, которая вкуснее, чем та, которую мы могли бы сами отправить. И это не root-порт. Это либо alternate-порт, либо backup-порт. В этом случае у нас будет заблокирована петля.
Далее. Помимо этих пяти состояний 802.1D 90-го года, есть ещё быстрый Spanning Tree. И у него немножко всё по-другому. Состояний будет меньше, но зато появляются роли портов. Те самые root, alternate, designated и backup. Мы сейчас про них поговорим отдельно. Если говорить про таймеры, которые есть в Spanning Tree, помните, в каждой BPDU передаются таймеры. Эти таймеры передаются точно так же, как и информация про root. Когда у нас какой-то коммутатор принимает указание, что root-ом является на самом деле не тот, кого он считал, в этом случае те таймеры, которые он рассылал в своих BPDU-шках, будут заменяться таймерами, которые приходят в вкусной BPDU-шке от root-а. Может быть такое, что у нас есть несколько коммутаторов в цепочке. Допустим, у нас есть какой-нибудь один таймер — 2 секунды.
На корневом коммутаторе он будет 2 секунды, на этом коммутаторе он будет 3 секунды настроен, 4 секунды, 5 секунд. Тут 4 коммутатора, на них таймеры настроены на всех по-разному. Если у нас корневым коммутатором будет выбран самый левый, он будет рассказывать, что он root, и соседний свич, приняв информацию от root-а, будет пересылать указание о том, какой у нас таймер настроен, вместе с информацией про root. И эта информация про таймеры root-а будет распространяться дальше на все остальные свичи вместе с BPDU, в которых указывается root bridge ID. И там в конце каждой BPDU 8 байт — это настроенные таймеры. Эти таймеры как раз будут таким образом узнаваться свичами как таймеры, настроенные на root-е. Даже если у вас на каком-то свиче таймер настроен в 4 секунды, а на root-е он настроен в 2 секунды, всё равно эффективный таймер, который будет использоваться, — это тот, который используется на root-е.
Таймеров будет 4 штуки. Они не все таймеры строго говоря, но обычно их все называют таймерами. Каждый таймер 2-байтовый. 2 байта на каждый таймер, 4 таймера, всего получается 8 байт. Самый первый таймер будет называться hello time. Это как часто вы отправляете BPDU. По умолчанию он 2 секунды, и таймеры в Spanning Tree задаются в немножко кривых форматах. Вы указываете в 16-битном поле, в 2-байтовом поле, время, выраженное в долях секунды, и доли эти будут 1/256. Если вы хотите сказать, что у вас будет таймер 2 секунды, то вы должны будете указать, что вы умножаете 2 на 256. Минимальное значение, которое можно записать в это поле, — это 1/256.
Можно 2/256, можно 3/256. Но если вы хотите указать 2 секунды, то вы указываете 512 туда. Это 512/256. По стандарту указывается, что гранулярность поля hello time будет как раз 1/256 секунды. Но есть нюанс. И нюанс заключается в том, что по стандарту, прямо в самом тексте стандарта, написано, что конечный узел, который работает со Spanning Tree, то есть bridge, он не обязан такую гранулярность поддерживать. И он обязан поддерживать гранулярность хотя бы в одну секунду. Поэтому по факту на подавляющем большинстве устройств, которые будут уметь работать со Spanning Tree, hello time вы не можете настроить настолько мало, как 1/256 секунды, которую позволяет стандарт, но которую по факту оборудование может не поддерживать. Таймер HelloTime вы можете настроить только кратным 1 секунде. Ещё раз повторю. Вы гипотетически по стандарту
можете настроить таймер HelloTime, например, тот самый, который задаётся в секундах, хоть в одну 256-ю секунды. Это приблизительно четыре тысячных секунды. Но по факту вы на большинстве свитчей не можете такой таймер поставить, хотя это предписано стандартом. По факту вы должны будете использовать целочисленный таймер в секундах. Например, самое маленькое значение, которое можно записать в сам HelloTime на свитчах, это будет 1 секунда. Это приводит к тому, что если вдруг у вас будут две железки, которые друг на друга будут отправлять BPDUшки, и у них будут настроены разные таймеры, не факт, что эти железки смогут между собой синхронизировать своё состояние. Например, если говорить про конкретные примеры, есть свитчи Huawei. На Huawei вы назначаете через конфигурацию HelloTimer, как часто отправлять BPDUшки с гранулярностью
в одну сотую секунды. Потом он берёт тот ввод, который вы вводите, и конвертирует это в 256-е доли. И вы говорите: я хочу отправлять BPDUшки, например, раз в полсекунды, то есть два раза в секунду. Это приблизительно 128 двести пятьдесят шестых. Такое значение вы имеете полное право отправить по стандарту. В этом случае вы указываете, что в это 16-битное поле вы кладёте число 128. Cisco, получив такую BPDUшку, её проигнорирует. Дело в том, что с её точки зрения BPDUшка, которая приходит с таймерами, некратными секунде, она вообще не обязана обрабатывать. И она считает, что если она не обязана её обрабатывать, то она может её игнорировать. Это поведение прописано в стандарте. Поэтому, несмотря на то, что в стандарте можно поставить таймеры дробные, это очень плохая идея. Это приводит к тому, что у вас Spanning Tree начинает работать некорректно. Поэтому, несмотря на то, что таймеры двухбайтовые,
по факту вы можете указать только целочисленные значения. Эти целочисленные значения будут однобайтовые. HelloTimer — как часто посылают BPDUшки, и это будет от 1 до 255, в количестве секунд, как часто посылать эти самые BPDUшки. Очень плохая идея, если ваше оборудование не цисковское и позволяет использовать дробные таймеры, использовать такие таймеры. Потому что это приведёт к тому, что если у вас в сети будут Cisco, например, и не Cisco, в этой сети возникнет петля. Реально. Не надо так делать, это прямо плохая идея. Дальше. Forward delay. Другой таймер, 15 секунд. Я про него уже всё рассказал. Это то самое время, которое каждый порт будет проводить в состояниях listening и learning. Это время, которое необходимо абсолютно любому коммутатору для того, чтобы информация от него дошла до абсолютно любого другого коммутатора, как бы ваша сеть ни была устроена. Даже если вдруг у вас
между вашими коммутаторами какие-то линки откажут, даже если вдруг у вас сеть будет расположена как-то очень-очень криво, это время, forward delay, нужно для того, чтобы информация дошла до другого свитча гарантированно. Это означает, что если на одном свитче происходит какое-то событие, через forward delay время обязательно все свитчи будут об этом знать. И оно тоже гипотетически может быть назначено дробным, и гипотетически тоже не факт, что все узлы смогут поддержать вас в стремлении назначить дробные таймеры. Поэтому Spanning Tree протокол основной, который используется, может очень некорректно работать в ситуации, когда вы используете дробные таймеры. Не надо так делать. Так, listening и learning. Я про них уже всё рассказал. В состоянии listening вы ждёте того, чтобы все узлы в топологии перешли в listening тоже на всех портах. Поэтому из-за того, что там, возможно,
где-то есть петля, кадры, которые приходят на порт в состоянии listening, вы не коммутируете, и MAC-learning вы не проводите. Дело в том, что есть понимание, что кто-то может ещё не знать про то, что случилось с топологией. У вас есть свитч, у вас есть порт на этом свитче, на этом порту в состоянии listening приходят какие-то кадры. Это может происходить, потому что сосед ещё пока со своей стороны порт не заблокировал, в listening его не перевёл. Поэтому в состоянии listening мы ждём того, чтобы у нас все порты на всех свитчах в топологии тоже перешли как минимум в listening. Приходящие кадры мы просто отбрасываем. При этом служебные данные, которые приходят на центральный процессор и не подлежат коммутации — это BPDU, это CDP, это VTP, это DTP, это всё остальное — оно направляется на процессор, оно не коммутируется, поэтому оно прекрасно там ходит, несмотря на блокирование коммутационного трафика. Дальше. После того, как у нас закончился forward delay,
порт перешёл из listening в learning, мы понимаем, что если какие-то кадры приходят, они уже точно приходят не из петли. Поэтому кадры, которые приходят, они уже заведомо содержат актуальные MAC-адреса, поэтому в этом состоянии мы learning ведём, но мы понимаем, что не все узлы, скорее всего, со своей стороны гайки ослабили, и, скорее всего, если мы не вышли из состояния learning, то и какие-то другие узлы тоже не вышли, возможно, из listening, возможно, из learning, поэтому коммутация будет неэффективна. Не будет правильно, если мы будем кадры коммутировать: они будут отправляться на соседа, а сосед их будет отбрасывать. Поэтому в состоянии learning мы коммутацию тоже не проводим. И только после того, как дважды forward delay timer мы прождали — один раз listening, чтобы всем войти в listening, другой learning, чтобы все вышли из listening, только в этот момент мы начинаем коммутировать трафик. Соответственно, с настройками по умолчанию, это дважды по forward delay, получается, коммутация выключается
как минимум на 30 секунд. На самом деле, может быть и больше. Если у вас очень неправильная топология, если у вас очень неудачный расклад, spanning tree медленный может заблокировать коммутацию в сети на срок сильно больше, чем 30 секунд. Например, если у вас есть какая-то длинная-длинная цепочка из коммутаторов, и, соответственно, 8 коммутаторов в цепочке будет, первый коммутатор отправляет другому какую-то BPDU, и, соответственно, может быть такое, что у него произошло какое-то изменение. Допустим, включился порт, выключился порт, что-то произошло. Следующая BPDU, которую он может отправить, она может пройти через 2 секунды. Поэтому у него возникло какое-то изменение, давайте я здесь нарисую какое-то изменение, такую звездочку, и только через 2 секунды отправляется BPDU с указанием, давай пересчитывать топологию. Потом следующий коммутатор, может быть, он тоже отправил BPDU только что, и ему тоже надо 2 секунды подождать
для того, чтобы передать информацию о том, что случилось с топологией, дальше. И на каждом прыжке между свитчами у нас будет тратиться до 2 секунд. 2 секунды здесь, 4 секунды здесь, 6 секунд здесь, 8 секунд здесь, 10 секунд тут, 12 здесь, 14 секунд тут, и плюс еще время на перекладывание BPDU между портами, на информацию о том, что у нас какое-то изменение произошло, что его надо разослать дальше. Оно тоже время какое-то тратит. Поэтому здесь вносится еще какая-то доля секунды, здесь доля секунды, здесь доля секунды, здесь доля секунды, и как раз 7 прыжков между свитчами плюс немножко времени на перекладывание данных между интерфейсами получается как раз 15 секунд — этот самый forward delay timer. Так вот, у нас произошло какое-то изменение. Например, у нас отвалился root. Эта информация начинает разбегаться по всем, всем, всем, всем свитчам. Самый дальний свитч в топологии узнает про это через 15 секунд.
И, соответственно, после того, как у нас произошла смена топологии, после того, как у нас root по факту сдох, через 15 секунд самый дальний свитч об этом узнает, самый дальний свитч начинает блокировать все свои интерфейсы. Тот свитч, который объявил о смене топологии, он уже из listening все свои порты вывел, прошел в learning, но самый дальний свитч только-только вошел в listening. Информация разбегалась в течение 15 секунд, плюс 15 секунд на дальнем свитче listening, плюс еще 15 секунд на дальнем свитче learning, поэтому получается по факту 45 секунд наша сетка в какой-то степени была недоступна, если трафик шел по какой-то неудачной трассе. Плюс к тому, на самом деле, там есть еще таймер, который называется MaxAge. И этот MaxAge указывает, в течение какого времени ваша BPDU должна считаться все еще активной, и через сколько, если вдруг она перестает приходить, ее нужно считать неактивной и отсутствующей. Смысл заключается в том, что если вдруг вы потеряете
какую-то одну BPDU, это не означает, что у вас сосед полностью отвалился. Но если вы потеряете несколько BPDU подряд, это будет означать, что с соседом связь пропала. И если у вас с соседом связь пропала, это изменение в активной топологии. Если у вас BPDU отправляется от одного свитча до другого, потом от другого до третьего, потом от третьего до четвертого, начинается все это, понятное дело, от root, и свитч root говорит, что я знаю, как добраться до root, и он рядышком указывает так называемый Message Age. Это сообщение, которое отправляет root, сам root говорит, что оно абсолютно свежее, оно только что отправлено. Каждый раз, когда мы указываем, что через нас можно добраться до root, мы указываем, что BPDU, которую мы на Designated порту отправляем, имеет какой-то root path cost, мы указываем, насколько это может быть несвежая информация. И каждый коммутатор исходит из того, что при перекладывании данных между интерфейсами, BPDU,
которая приходит с одной стороны, мы дальше отправляем ее куда-то по сети в интерфейс назначения, мы в среднем тратим на это одну секунду. Поэтому каждый раз при перекладывании BPDU от root в Designated порты к Message Age от root добавляется единичка. И, соответственно, у нас первый свитч принимает BPDU, дальше рассказывает, что он знает BPDU со сроком жизни одну секунду, дальше следующий рассказывает, что он знает BPDU, которая со сроком жизни две секунды, root ее придумал две секунды назад. И вот так она дальше разбегается по сети. У нас будет также в рутовой BPDU передаваться параметр MaxAge. Это насколько долго BPDU может считаться активной, если она была получена. Если в какой-то момент BPDU от root перестает приходить, например, этот коммутатор у нас получает BPDU со сроком жизни две секунды. И в ней было написано Message Age 2
и MaxAge это таймер по умолчанию 20. В этом случае он будет после получения последней BPDU, если вдруг она перестает приходить, считать BPDU, которая была получена со сроком жизни 2, дальше от нее прибавляется таймер. Через секунду он говорит 3, через секунду 4, через секунду 5. Она была получена, и у нее начинает тикать срок жизни. И каждую секунду мы прибавляем к MessageAge единичку. Как только мы досчитаем до 20, если ничего нового не придет, мы скажем, что у нас сосед отвалился. И получается, что если вы находитесь где-то рядом с рутом и у вас рут отвалился, то он отвалился по-хитрому, чтобы не вызывать падение интерфейса до рута, что в принципе не редкость, если у вас используются топологии с общей шиной. С коаксиалом при падении соседа не отваливается канал целиком. Но вы просто от него перестаете принимать BPDU.
В этой ситуации вы дожидаетесь MessageAge от него, которое будет равно MaxAge, то есть это у вас будет там 19 секунд проходить. И через 19 секунд вы говорите, что-то у нас с рутом какие-то проблемы. И дальше вы начинаете рассылать оповещения своим соседям, которые могут находиться достаточно далеко от вас, допустим, 12 секунд. И соседи переходят в Listening & Learning. Состояние по умолчанию, с таймерами по умолчанию, максимальный срок, в течение которого Spanning Tree может сделать так, чтобы ваша сеть не работала. По крайней мере, какие-то части сети либо будут содержать отказ, либо будут содержать заблокированные порты. Это будут 19 секунд, которые мы ждем прихода BPDU от соседа, плюс 12 секунд — время, которое нам нужно, чтобы распространить информацию от нашего узла до самых дальних точек сети, плюс 15 секунд Listening Time плюс 15 секунд Learning Time. Несложно посчитать, что это 31,
и это 30. То есть это примерно одна минута. На срок до одной минуты у вас Spanning Tree может заблокировать коммутацию или не успеть отреагировать на изменения топологии, если вы очень неправильно сконструировали сеть и если вы очень неправильно поставили таймеры. Такой медленный протокол. Естественно, что в большинстве сетей такие ситуации будут крайне редки. Естественно, что у вас не будет сильно много коммутаторов в цепочке. Естественно, что у вас, скорее всего, не будет такого отказа, что root отвалился, а вы про это узнаете только потому, что BPDU перестают приходить. Чаще всего, если у вас отваливается root, то интерфейс падает, и вы сразу понимаете, что всё, через интерфейс добраться до root нельзя. Но в неприятной ситуации с максимально неудачным раскладом Spanning Tree действительно может перевести сеть в актуальное состояние
только через минуту после того, как совершится какое-то событие. Если у вас настройки по умолчанию, то чаще всего Spanning Tree будет блокировать коммутацию на 30 секунд, дважды по Forward Delay таймеру. При неудачном раскладе — минута. Тоже немало. Это самый медленный Spanning Tree со своими то ли 30 секундами, то ли минутой, то ли можно таймеры подкрутить поменьше, но все равно это исчисляется целыми секундами или даже десятками секунд недоступности сети. Он уже к 96–98 году перестал быть актуальным. Дело в том, что стало всё больше использоваться компьютеров в бизнесе, и бизнес очень негативно реагировал на то, что по любому чиху Spanning Tree начинал пересчитывать топологию. И когда он начинает пересчитывать топологию, он вам сеть кладет на 30 секунд. Соответственно, это неудобно, это вызывает потери денег. Представьте себе, что будет, если сайт Амазона периодически будет падать на 30 секунд
или на минуту — это будет очень нехорошо, это будет очень много денег теряться. Поэтому для того, чтобы обеспечить минимальный даунтайм при пересчете топологии, был придуман протокол быстрый Spanning Tree, Rapid Spanning Tree или 802.1W. Он в качестве основы использует точно тот же самый движок Spanning Tree с теми же самыми таймерами. И тут вы скажете, а в чем тогда фишка-то, если он все равно использует те же самые таймеры. Но 802.1W отказывается от идеи, что между коммутаторами, если у нас есть провод, в этом проводе могут жить абоненты. Классический 802.1D исходит из того, что если у нас есть два свича или два бриджа, между ними есть провод, кто-то должен все время следить за тем, что у нас там между этими двумя свичами еще какие-то юзеры будут сидеть, потому что когда все это дело придумывалось, коаксиал был единственный способ связи между юзерами. И поэтому у нас могло быть такое, что с одной стороны порт блокировался, но с другой стороны он должен был
оставаться разблокированным. И как следствие, если вдруг у вас было, допустим, три свича, которые связывались между собой через коаксиал, соответственно, два из них должны были принять решение, что они со своими портами делают, а третий должен был сказать, что я ближе всего круту, и, соответственно, вы вдвоем там решаете, что вы будете делать, а я свой порт точно разблокирую. Вот медленный спанинг-3, он за счет вот этих вот неопределенностей того, как устроена топология, как устроены каналы между свечами, очень много времени был вынужден отдавать на синхронизацию данных между свечами. То есть, если у нас возникал какой-то свитч, у которого случалась смена топологии, он должен был просто по определению ждать в течение форвард-дилей-таймер, чтобы информация разбежалась на все остальные свитчи. И информация разбегалась просто в отдельных бпдушках, которые просто передавались раз в две секунды. Эта штука, она гарантированно
делает так, чтобы вы распространяли информацию от любого узла до любого другого, но при этом она, естественно, очень медленная. 800-2-1-W. За счет того, что он сказал, у нас не бывает вот этого всего. Не бывает такого, чтобы в одном канале жило три свитча. У нас может быть раз свитч и два свитч, и между ними просто прямой провод, в котором нету юзеров, в котором нету еще транзитных свитчей. Если мы отправим какие-то данные в этот провод, мы можем дождаться подтверждения, которое не было возможно в медленном спаринг-три, потому что, если вы отправляете какие-то данные в провод, непонятно, сколько этих подтверждений нужно ждать. Придет одно подтверждение, или два подтверждения, или десять, а вдруг там одиннадцать свитчей в общем канале сидит. Вы же не знаете заранее. Вы не отслеживаете то, сколько у вас соседей в общем проводе есть. вот 802.1.w представил, что можно сделать так, что у нас свитчи соединяются просто прямыми point-to-point проводами. Если мы отправляем какие-то данные в этот провод, мы можем быстро
получить подтверждение, что один узел в этом проводе данный получил, и, исходя из того, что он там всего один, сказать, окей, мы все в этом проводе договорились о том, как надо будет работать. И немедленно после получения подтверждения оба узла могут со своей стороны принять решение о том, что делать со своими портами. Например, могут принять решение о том, что оба разблокируют такие порты. Или один скажет, я со своей стороны должен буду порт заблокировать. Вот это происходит за счет как раз механизма, когда вы отправляете сообщение, и получается на него немедленный ответ. В медленном Spanning 3 терминов вопрос-ответ не было. В быстром Spanning 3 они появились. Ну, точнее, там, пропозил agreement предложение и согласие с этим предложением. Вот. Ну, и за счет вот этого механизма появилось возможно сделать так, чтобы, если у нас есть там пачка коммутаторов, которые друг на друга как-то смотрят, первый говорит, я хочу стать, там, условно, рутом. Не против ли ты? Точнее, он говорит, я хочу стать диссигнейтед портом в этом сегменте.
Второй говорит, окей, я не против. И, соответственно, здесь вот эта вот пара портов, она как бы уже приняла решение, что с ним делать. Дальше второй говорит, я хочу стать диссигнейтедом и так говорит, я не против. И у нас вот в этой паре портов тоже происходит все практически мгновенно. Дальше в третьей паре портов тоже все происходит практически мгновенно. Здесь мы тратим 50 миллисекунд, здесь мы тратим 50 миллисекунд, здесь мы тратим 50 миллисекунд. В итоге, за 150 миллисекунд вот эта вот сетка согласует роли и состояние портов. Это уже будет не 30 секунд, которые нужны в медленном спайник-3, а 150 миллисекунд, что намного-намного вкуснее. Вот. Ну, соответственно, появляются в быстром Spamning 3 вот эти вот самые роли, которые мы с вами уже знаем. Root. Дальше alternate. Designated. И backup. Так. Backup. Вот. Root-порт — это тот порт,
на котором мы получаем самую вкусную боподушку. Alternate-порт — тот порт, на котором мы получаем не самую вкусную боподушку, но все же получаем и не отправляем. Designated-порт — это порт, которым мы отправляем самую вкусную боподушку в сегмент. И backup-ный порт — это тот порт, на котором мы получаем свою собственную боподушку. То есть мы туда могли бы отправлять свою собственную боподушку, но мы там же и получаем свою собственную боподушку. Поэтому мы туда ничего не отправляем. Вот. Ну и, соответственно, мы знаем, что вот эти вот роли портов у нас есть. Они появились только в 802.1.w. И посмотрим, как они соответствуют состояниям из медленного 802.1.d. У 802.1.w состояний теперь больше не 5 штук. В медленном Sparning 3 было 5 состояний. Disabled — blocking, listening, learning, forwarding. В 802.1.d. у нас состояние только 3. Это то, что по факту происходит с портом.
Вот он может либо forwardить трафик, либо не forwardить, либо не forwardить, но при этом learning. Есть состояние дискардинг, есть состояние learning, есть состояние forwarding. Понятное дело, что состояние forwarding 802.1.d. примерно соответствует состоянию forwarding 802.1.w. То есть нормальная работа, все хорошо, в портом ничего не происходит, и, в общем, паники никакой не требуется. Learning тоже, на самом деле, соответствует однозначно состоянию learning. Здесь неправильно нарисовано. Learning вот здесь. Это то же самое, что у нас происходило в медленном Spanning Tree, когда мы точно убеждались, что все остальные порты заблокировали, все остальные свитчи заблокировали свои порты, хотя бы как минимум в listening перевели. Learning — это значит, что у нас петли уже точно нет, любые кадры, которые приходят, они достоверные, и состояние learning обозначает, что на этом порту коммутацию вы не ведёте, но при этом вы learn'ете MAC-адреса. Соответственно,
discarding — это всё остальное. В listening мы не работаем с транзитным трафиком, мы не learn'ем порты, не learn'ем MAC-адреса. То же самое происходит в состоянии disabled. Мы просто игнорируем тотально входящий трафик. И blocking тоже. Мы тотально игнорируем входящий трафик. Мы его не коммутируем. Поэтому у нас здесь discarding. Здесь у нас learning. Здесь forwarding. То, что у портов есть и состояние, и роли, это нормально. Соответственно, нормальное состояние у нас будет forwarding. Ненормальное состояние — это discarding. И промежуточное состояние — это learning. В каком случае мы можем поймать порт в состоянии forwarding? В одном. Если это designated или root-порт. Если у нас есть роль, которая по факту получилась root, или роль, которая по факту получилась designated, и этот порт уже расслаблен, то есть этот порт прошёл состояние learning,
в этом случае у нас будет состояние forwarding. Поэтому root forwarding или designated forwarding. Это то, что порт уже расслабил гайки, с портом всё хорошо, выяснено, что петлю порт не содержит. Это может быть либо root forwarding, либо designated forwarding. Если у нас есть порт, который находится в состоянии learning, в какой роли это возможно встретить? Это можно встретить только в одной. Если у нас прошло 15 секунд с момента, когда мы блокировали коммутацию на порту, мы уже первый таймер forward delay прошли, и мы хотим достичь второго forward delay таймера, но при этом мы видим какие-то входящие кадры на порту, и мы хотим проводить процедуру MAC learning. Это будет возможно для designated learning. И если у нас есть порт, который находится в состоянии discarding,
здесь это может быть либо потому, что это порт alternate, то есть у нас есть какой-то root-порт и какой-то другой порт, на котором приходят BPDU-шки от root'а. Мы говорим, мы такой порт заблокируем, и это будет alternate-порт. Состояние, в котором находится alternate-порт, это состояние discarding. Также у нас есть backup-порт. Состояние, в котором находится backup-порт, это discarding. Мы не ведём коммутацию, мы не ведём MAC learning. На самом деле может быть ещё и designated discarding порт. Designated discarding — это те самые первые 15 секунд, которые однозначно соответствуют бывшему состоянию listening. Если у вас есть порт, который в медленном Spanning Tree находится в состоянии listening, то есть вы ещё не знаете, что с этим портом дальше произойдёт, вы его только что выключили, вы ждёте первый таймер forward delay для того, чтобы все остальные свитчи могли со своей стороны тоже свои порты выключить. Это будет роль designated discarding, которая как раз встречается и на быстрых портах. Если мы отправили
предложение «давай, я хочу стать designated портом», но мы не получили ничего в ответ, то в этом случае порт всё ещё designated, но discarding, потому что что с ним ещё делать? Через 15 секунд после того, как он будет designated discarding, он станет designated learning, и через 15 секунд после designated learning он станет designated forwarding. Root-порт не бывает discarding. Root-порт всегда в forwarding. Но это такая особенность протокола. Forward delay таймеры остались по 15 секунд. Там есть небольшой нюанс с таймерами, но по большому счёту forward delay таймеры в быстром Spanning Tree всё равно такие же. 15 секунд, ничего не изменилось в этом. Что здесь ещё? Отличие медленного Spanning Tree от быстрого заключается в двух вещах. Первое — это появление proposal-agreement. Они позволяют вам синхронизировать то, кто будет выбран designated
свитчом в сегменте не за hello time, не за forward delay time, не за два forward delay тайма, а за единицы миллисекунд. Ну, десятки миллисекунд. Обычное время — это порядка десятков миллисекунд. Если у вас есть какая-то топология, начинается всё с того, что root с каким-то своим соседом или со своими соседями синхронизирует своё состояние, говорит: я буду root'ом, а те говорят — окей, мы не против, быстро отвечают. Потом они начинают своим соседям рассказывать: смотри, вот он будет root'ом, а те говорят — окей, я не против. И так эта информация разбегается за очень короткое время. Можно говорить, что в нормальной топологии, которая характерна для сети предприятий, быстрый Spanning Tree сводит топологию к устоявшемуся состоянию при том, что всё корректно размечено, за время порядка ста — двухсот миллисекунд. Это меньше, чем секунда. Соответственно,
если мы говорим про быстрый Spanning Tree, в нём появилась ещё одна вещь, которая кардинально влияет на поведение этого протокола. В медленном Spanning Tree на всех портах у нас было одинаковое поведение. Сначала, если происходит какое-то изменение, все порты кладём в listening, потом в learning, потом в forwarding. Если на медленном коммутаторе появлялся новый порт, который переходил в up, это вызывало смену топологии, потому что это новый порт, на котором, возможно, будет обнаружен новый коммутатор. В медленном Spanning Tree появление нового пользователя не влияло на поведение порта, потому что новый пользователь работал в общем коаксиале. Соответственно, появление нового пользователя в общем коаксиале никаким образом не влияло на то, что у вас есть новый порт, который перешёл в up. У вас есть коаксиал с четырьмя юзерами? Прекрасно. Появляется новый пользователь в этом коаксиале. Этот порт не изменяется. Он как был один, работающий,
так и остался. В медленном Spanning Tree юзеры все работали через общую шину, через коаксиалы. И количество портов, которые вам требовалось для юзеров, было очень простое. Вам нужен был один порт на одну канальную среду. Если соответственно появлялся второй порт, живой на коммутаторе, то это означало, что у вас есть новая сетка, в которой есть новые пользователи, и, возможно, есть новый коммутатор. Поэтому если в медленном Spanning Tree какой-то порт, любой порт, переходил в up, это означало, что вы объявляете смену топологии, и все коммутаторы в топологии кладут свои порты на дважды forward delay timer. У вас появляется новый юзер, который в новом коаксиальном порту заводится. Прекрасно. Все порты кладутся. Там какой-то другой коммутатор тоже кладёт свои порты. Все коммутаторы во всей топологии
выключают свои порты. Выключают, переводят в listening, переводят в learning, и через 30 секунд говорят — окей, давайте forwarding. В быстром Spanning Tree, когда коммутаторы начали часто работать с point-to-point линками, то есть сегодня мы не работаем с общей шиной. Сегодня наши коммутаторы работают на электрическом уровне с point-to-point проводами. Провод с одной стороны втыкается в свитч, с другой стороны либо в другой свитч, либо в компьютер. Нормой является то, что если у нас поднимается новый порт, он будет смотреть на конечного абонента. Чаще всего порты, которые у нас есть на коммутаторах, смотрят на абонентов. Поэтому появление нового порта, который переходит в up, не должно бы по-хорошему вызывать смену топологии. Новый компьютер включили, а у нас вся сетка легла на 30 секунд. Новый компьютер ещё включили, ещё раз сетка умерла на 30 секунд. И самое страшное, что компьютер вам не может ответить на ваш proposal-agreement. Если с той стороны находится быстрый свитч, и порт до быстрого свитча
включается, и вы тоже быстрый свитч, вы ему отправили быстрый proposal, он вам быстро agreement'ом ответил. Соответственно, вы там не сильно выключили сеточку. Выключили на 200 миллисекунд, но ничего страшного, никто не заметил. Но если у вас компьютер включается, он на proposal не реагирует. Вы в него долбитесь этими BPDU-шками, 15 секунд долбитесь, 30 секунд долбитесь, а он вам ничего не отвечает. И только через 30 секунд после того, как порт в up перешёл, вы говорите — окей, вроде бы там всё хорошо, соответственно, можно расслабиться, можно все порты в топологии включить. Но это же не дело. Когда у нас реальная сеть, мы не можем себе позволить сделать так, чтобы появление нового компьютера в сети клало всю сетку на 30 секунд. Это просто вредительство. Поэтому в быстром Spanning Tree появляется новая сущность — edge port. Edge port — это такой порт, на котором вы включаете коммутацию сразу после включения, и появление этого порта не вызывает смену топологии. По сути, вы говорите, что нормальные порты, которые не edge,
начинают свою работу с designated discarding, потом они переходят в designated learning, и потом они переходят в designated forwarding. В норме они проходят за 15 секунд каждый этот этап. Если у нас работает proposal-agreement, они могут сразу из designated discarding перейти в designated forwarding, если сеть не против. Это произойдёт довольно быстро. Но если вы помечаете порт как edge port, то вы как администратор обещаете, что на этом порту соседнего свитча не будет, что этот порт смотрит на конечного абонента. И начало работы этого порта, edge-порта, будет не в designated discarding, а сразу в designated forwarding. При этом в такой порт вы всё равно посылаете BPDU-шки. Но если вдруг вы на этом порту BPDU-шку получите, то это означает, что вы сразу перескакиваете в designated discarding, вы объявляете смену топологии, и всё остальное, что по факту происходит. Это просто указание,
что конечный пользователь сидит за конкретным портом, он BPDU-шки не посылает. Если администратор обещает, что на каком-то порту BPDU-шки никогда приходить не будут, то мы сразу можем сказать, что окей, это будет designated порт. Он в итоге, если там с той стороны никогда BPDU-шки не приходят, всё равно неизбежно придёт к тому, что он станет designated forwarding. Поэтому просто экономим 30 секунд, делаем вид, что мы уже эти 30 секунд прошли. Но если BPDU-шка на designated forwarding порт придёт, неважно, будет ли это edge-порт или не edge-порт, BPDU-шка, которая будет приходить на наш порт, будет означать, что кто-то возражает против того, чтобы мы были designated. Тогда мы неизбежно должны будем запустить снова пересчёт топологии. В этом и заключается смысл edge-порта. Если вы включаете какой-то порт, потому что компьютер к нему подключён, на этом компьютере работает отдельный пользователь, компьютер со своей стороны BPDU-шки не отправляет, окей, ничего страшного. Порт включился, он сразу перешёл в up,
он сразу перешёл в forwarding, смена топологии не произошла, потому что мы корректно разметили эти порты. Все вроде бы счастливы. Так, это теория, которую мы в рамках ICND2 должны были пройти про Spanning Tree. Протокол несложный, но он предполагает, что вы должны будете понимать, как он устроен. Он устроен просто за счёт обмена BPDU-шками. У свитчей нет, как правило, никакого понимания, что они работают в какой-то топологии, какие-то маршруты там есть между свитчами. Они просто обмениваются BPDU-шками. И каждый свитч находится в одной из двух ролей. Либо он root, либо он не root. Если он root, он считает, что все порты, которые на нём есть, находятся в сегментах, в которых этот свитч ближе всего к root, потому что он сам root. И у него, как правило, все порты будут designated. Альтернативный вариант, соответственно,
если у него будет в каком-то сценарии порты просто закольцованы, Взяли патч-корд и в root-свитч патч-корд включили в два порта. Там у вас один порт будет помечен как backup. Для остальных всех свитчей, которые будут не root, будет какой-то один порт смотреть в сторону root самым выгодным образом, у него этот порт будет помечен как root-порт. Все остальные порты, которые тоже получают BPDU-шки от root, не отправляют, а получают BPDU-шки от root, они будут помечены как alternate-порты. И все остальные порты будут в топологии designated. Так, давайте разберемся, как это всё будет работать применительно к оборудованию Cisco.