Академический Документы
Профессиональный Документы
Культура Документы
Это первая статья из серии «Сети для самых маленьких». Мы с Максимом aka Gluck долго думали с чего начать:
маршрутизация, VLAN'ы, настройка оборудования.
В итоге решили начать с вещи фундаментальной и, можно сказать, самой важной: планирование. Поскольку цикл
рассчитан на совсем новичков, то и пройдём весь путь от начала до конца.
Предполагается, что вы, как минимум, читали о эталонной модели OSI (то же на англ.), о стеке
протоколов TCP/IP (англ.), знаете о типах существующих VLAN’ов (эту статью я настоятельно рекомендую к
прочтению), о наиболее популярном сейчас port-based VLAN и о IP адресах (более подробно). Мы понимаем, что
для новичков «OSI» и «TCP/IP» — это страшные слова. Но не переживайте, не для того, чтобы запугать вас, мы их
используем. Это то, с чем вам придётся встречаться каждый день, поэтому в течение этого цикла мы постараемся
раскрыть их смысл и отношение к реальности.
Начнём с постановки задачи. Есть некая фирма, занимающаяся, допустим, производством лифтов, идущих только
вверх, и потому называется ООО «Лифт ми ап». Расположены они в старом здании на Арбате, и сгнившие
провода, воткнутые в пожжёные и прожжёные коммутаторы времён 10Base-T не ожидают подключения новых
серверов по гигабитным карточкам. Итак, у них катастрофическая потребность в сетевой инфраструктуре и денег
куры не клюют, что даёт вам возможность безграничного выбора. Это чудесный сон любого инженера. А вы
вчера выдержали собеседование, и в сложной борьбе по праву получили должность сетевого администратора. И
теперь вы в ней первый и единственный в своём роде. Поздравляем! Что дальше?
При проектировании сети следует стараться придерживаться иерархической модели сети, которая имеет много
достоинств по сравнению с “плоской сетью”:
• упрощается понимание организации сети
• модель подразумевает модульность, что означает простоту наращивания мощностей именно там, где
необходимо
• легче найти и изолировать проблему
• повышенная отказоустойчивость за счет дублирования устройств и/или соединений
• распределение функций по обеспечению работоспособности сети по различным устройствам.
Согласно этой модели, сеть разбивается на три логических уровня: ядро сети (Core layer:
высокопроизводительные устройства, главное назначение — быстрый транспорт), уровень
распространения (Distribution layer: обеспечивает применение политик безопасности, QoS, агрегацию и
маршрутизацию в VLAN, определяет широковещательные домены), и уровень доступа (Access-layer: как правило,
L2 свичи, назначение: подключение конечных устройств, маркирование трафика для QoS, защита от колец в сети
(STP) и широковещательных штормов, обеспечение питания для PoE устройств).
В таких масштабах, как наш, роль каждого устройства размывается, однако логически разделить сеть можно.
Составим приблизительную схему:
На представленной схеме ядром (Core) будет маршрутизатор 2811, коммутатор 2960 отнесём к уровню
распространения (Distribution), поскольку на нём агрегируются все VLAN в общий транк. Коммутаторы 2950 будут
устройствами доступа (Access). К ним будут подключаться конечные пользователи, офисная техника, сервера.
Именовать устройства будем следующим образом: сокращённое название города (msk) — географическое
расположение (улица, здание) (arbat) — роль устройства в сети + порядковый номер.
Соответственно их ролям и месту расположения выбираем hostname:
Маршрутизатор 2811: msk-arbat-gw1 (gw=GateWay=шлюз)
Коммутатор 2960: msk-arbat-dsw1 (dsw=Distribution switch)
Коммутаторы 2950: msk-arbat-aswN, msk-rubl-asw1 (asw=Access switch)
Документация сети
Вся сеть должна быть строго документирована: от принципиальной схемы, до имени интерфейса.
Прежде, чем приступить к настройке, я бы хотел привести список необходимых документов и действий:
• Схемы сети L1, L2, L3 в соответствии с уровнями модели OSI (Физический, канальный, сетевой)
• План IP-адресации = IP-план
• Список VLAN
• Подписи (description) интерфейсов
• Список устройств (для каждого следует указать: модель железки, установленная версия IOS, объем
RAM\NVRAM, список интерфейсов)
• Метки на кабелях (откуда и куда идёт), в том числе на кабелях питания и заземления и устройствах
• Единый регламент, определяющий все вышеприведённые параметры и другие
Жирным выделено то, за чем мы будем следить в рамках программы-симулятора. Разумеется, все изменения
сети нужно вносить в документацию и конфигурацию, чтобы они были в актуальном состоянии.
На этой фотографии отлично видно, что промаркирован каждый кабель, значение каждого автомата на щитке в
стойке, а также каждое устройство.
Каждая группа будет выделена в отдельный влан. Таким образом мы ограничим широковещательные домены.
Также введём специальный VLAN для управления устройствами.
Номера VLAN c 4 по 100 зарезервированы для будущих нужд.
IP-план
IP-адрес Примечание VLAN
172.16.0.0/16
172.16.0.0/24 Серверная ферма 3
172.16.0.1 Шлюз
172.16.0.2 Web
172.16.0.3 File
172.16.0.4 Mail
172.16.0.5 — 172.16.0.254 Зарезервировано
172.16.1.0/24 Управление 2
172.16.1.1 Шлюз
172.16.1.2 msk-arbat-dsw1
172.16.1.3 msk-arbat-asw1
172.16.1.4 msk-arbat-asw2
172.16.1.5 msk-arbat-asw3
172.16.1.6 msk-rubl-aswl
172.16.1.6 — 172.16.1.254 Зарезервировано
172.16.2.0/24 Сеть Point-to-Point
172.16.2.1 Шлюз
172.16.2.2 — 172.16.2.254 Зарезервировано
172.16.3.0/24 ПТО 101
172.16.3.1 Шлюз
172.16.3.2 — 172.16.3.254 Пул для пользователей
172.16.4.0/24 ФЭО 102
172.16.4.1 Шлюз
172.16.4.2 — 172.16.4.254 Пул для пользователей
172.16.5.0/24 Бухгалтерия 103
172.16.5.1 Шлюз
172.16.5.2 — 172.16.5.254 Пул для пользователей
172.16.6.0/24 Другие пользователи 104
172.16.6.1 Шлюз
172.16.6.2 — 172.16.6.254 Пул для пользователей
Выделение подсетей в общем-то произвольное, соответствующее только числу узлов в этой локальной сети с
учётом возможного роста. В данном примере все подсети имеют стандартную маску /24 (/24=255.255.255.0) —
зачастую такие и используются в локальных сетях, но далеко не всегда. Советуем почитать о классах сетей. В
дальнейшем мы обратимся и к бесклассовой адресации (cisco). Мы понимаем, что ссылки на технические статьи
в википедии — это моветон, однако они дают хорошее определение, а мы попробуем в свою очередь перенести
это на картину реального мира.
Под сетью Point-to-Point подразумеваем подключение одного маршрутизатора к другому в режиме точка-точка.
Обычно берутся адреса с маской 30 (возвращаясь к теме бесклассовых сетей), то есть содержащие два адреса
узла. Позже станет понятно, о чём идёт речь.
Разумеется, сейчас есть коммутаторы с кучей портов 1Gb Ethernet, есть коммутаторы с 10G, на продвинутых
операторских железках, стоящих немалые тысячи долларов есть 40Gb, в разработке находится 100Gb (а по
слухам уже даже есть такие платы, вышедшие в промышленное производство). Соответственно, вы можете
выбирать в реальном мире коммутаторы и маршрутизаторы согласно вашим потребностям, не забывая про
бюджет. В частности гигабитный свич сейчас можно купить незадорого (20-30 тысяч) и это с запасом на будущее
(если вы не провайдер, конечно). Маршрутизатор с гигабитными портами стоит уже ощутимо дороже, чем со
100Mbps портами, однако оно того стоит, потому что FE-модели (100Mbps FastEthernet), устарели и их
пропускная способность очень невысока.
Но в программах эмуляторах/симуляторах, которые мы будем использовать, к сожалению, есть только
простенькие модели оборудования, поэтому при моделировании сети будем отталкиваться от того, что имеем:
маршрутизатор cisco2811, коммутаторы cisco2960 и 2950.
Схемы сети
На основании этих данных можно составить все три схемы сети на этом этапе. Для этого можно воспользоваться
Microsoft Visio, каким-либо бесплатным приложением, но с привязкой к своему формату, или редакторами
графики (можно и от руки, но это будет сложно держать в актуальном состоянии :)).
Не пропаганды опен сорса для, а разнообразия средств ради, воспользуемся Dia. Я считаю его одним из лучших
приложений для работы со схемами под Linux. Есть версия для Виндоус, но, к сожалению, совместимости в визио
никакой.
L1
То есть на схеме L1 мы отражаем физические устройства сети с номерами портов: что куда подключено.
L2
На схеме L2 мы указываем наши VLAN’ы
L3
В нашем примере схема третьего уровня получилась довольно бесполезная и не очень наглядная, из-за наличия
только одного маршрутизирующего устройства. Но со временем она обрастёт подробностями.
Как видите, информация в документах избыточна. Например, номера VLAN повторяются и на схеме и в плане по
портам. Тут как бы кто на что горазд. Как вам удобнее, так и делайте. Такая избыточность затрудняет обновление
в случае изменения конфигурации, потому что нужно исправиться сразу в нескольких местах, но с другой
стороны, облегчает понимание.
К этой первой статье мы не раз ещё вернёмся в будущем, равно как и вам придётся всегда возвращаться к тому,
что вы изначально напланировали.
Собственно задание для тех, кто пока только начинает учиться и готов приложить для этого усилия: много читать
про вланы, ip-адресацию, найти программы Packet Tracer и GNS3.
Что касается фундаментальных теоретических знаний, то советуем начать читать Cisco press. Это то, что вам
совершенно точно понадобится знать.
В следующей части всё будет уже по-взрослому, с видео, мы будем учиться подключаться к оборудованию,
разбираться с интерфейсом и расскажем, что делать нерадивому админу, забывшему пароль.
P.S. Спасибо соавтору статьи — Максиму aka gluck.
Сегодня мы обратимся к части немного скучной, но важной для начинающих: как подключиться, поставить или
сбросить пароль, войти по telnet. Также рассмотрим существующие программы — эмуляторы ciscо и интерфейс
оборудования.
Как и обещали, в этот раз всё по-взрослому: с видео.
Среда
Начнём с того, в какой среде будем работать.
В данный момент есть два известных пакета программ, позволяющих моделировать сеть, построенную на
оборудовании Cisco:
а) Цисковский же продукт Packet Tracer, который по идее свободно не распространяется. Это эмулятор и имеет
лишь некоторые функции Cisco IOS. Вообще говоря, он сильно ограничен и многие вещи в нём реализованы
лишь отчасти. Никаких тонких настроек. С другой стороны к настоящему моменту версия 5.3.2 поддерживает
создание GRE-туннелей, протоколов динамической маршрутизации (и в их числе даже BGP!). Притом он очень
прост в освоении и имеет в своём арсенале сервера (FTP, TFTP, DHCP, DNS, HTTP, NTP, RADIUS, SMTP, POP3),
рабочие станции и свичи. Сейчас уже есть под Linux, хотя в былые времени он прекрасно запускался и из-под
Wine.
б) Распространяемый по лицензии GNU GPL симулятор GNS3. В этом пакете необходимо загружать настоящие
образы Cisco IOS. С одной стороны это плюс – вы работаете с настоящим интерфейсом cisco и ограничены лишь
своей фантазией, существующими стандартами и производительностью рабочей станции, с другой, во-первых,
эти IOS ещё нужно суметь достать, во-вторых, это более сложный продукт для понимания, и в-третьих, в нём есть
только маршрутизаторы и «типа» коммутаторы.
Я считаю, что для знакомства с принципами лучше начать всё же с Packet Tracer'a, а потом переходить на
тяжёлую артиллерию по мере надобности. Все мы не дети малые, где взять то, что нам нужно, рассказывать не
будем.
Способы подключения
Интерфейс последних трёх идентичный – отличается лишь способ подключения. Разумеется, GUI – не наш метод.
В реальной же жизни доступны:
• Telnet/ssh
• Терминальное подключение с рабочей станции через консольный кабель
• Web-интерфейс (Cisco SDM).
Последний вариант даже не упоминайте в приличном обществе. Даже если вы адепт мыши и браузера, очень не
советую.
На своём примере при работе с другим оборудованием я сталкивался с тем, что настроенное через веб не
работает. Хоть ты тресни, но не работает. А у того же длинка вообще был баг в одной версии прошивки для
свичей: если изменить настройки VLAN в веб-интерфейсе из под линукс, то свич становится недоступным для
управления. Это официально признанная проблема).
Телнет – стандартная, всем известная утилита, как и ssh. Для доступа к cisco по этим протоколам нужно настроить
пароли доступа, об этом позже. Возможность использования ssh зависит от лицензии IOS.
Управление по консоли
Ну вот принесли вы маршрутизатор, распечатали, питание на него дали. Он томно зашумел кулерами,
подмигивает вам светодиодами своих портов. А чего дальше-то делать?
Воспользуемся один из древнейших и нестареющих способов управления практически
любым умным устройством: консоль. Для этого вам нужен компьютер, само устройство и подходящий кабель.
Тут каждый вендор на что горазд. Какие только разъёмы они не используют: RJ-45, DB-9 папа, DB-9 мама, DB-9 с
нестандартной распиновкой, DB-25.
У циски используется разъём RJ-45 на стороне устройства и DB-9 мама (для подключения к COM-порту) на
стороне ПК.
Консольный порт выглядит так:
Всегда выделен голубым цветом. С недавних пор стало возможным управление по USB.
А это консольный кабель cisco:
Раньше он поставлялся в каждой коробке, теперь зачастую стоит отдельных денег. В принципе подходит
аналогичный кабель от HP.
Проблема в том, что современные ПК зачастую не имеют COM-порта. На выручку приходят часто используемые
конвертеры USB-to-COM:
Либо редко используемые для этих целей конвертеры RS232-Ethernet
После того, как вы воткнули кабель, определили номер COM-порта, для подключения можно использовать
Hyperterminal или Putty в Виндоус и Minicom в Линукс.
Управление через консоль доступно сразу, а вот для телнета нужно установить пароль. Как это сделать?
Обратимся к PT.
Начнём с создания маршрутизатора: выбираем его на панели внизу и переносим на рабочее пространство. Даём
какое-нибудь название
Что бы вы делали, если бы это был самый взаправдашний железный маршрутизатор? Взяли бы консольный
кабель и подключились им в него и в компьютер. То же самое сделаем и тут:
Кликом по компьютеру вызываем окно настройки, в котором нас интересует вкладка Desktop. Далее выбираем
Terminal, где нам даётся выбор параметров
Впрочем, все параметры по умолчанию нас устраивают, и менять их особо смысла нет.
Если в энергонезависимой памяти устройства отсутствует конфигурационный файл (startup-config), а так оно и
будет при первом включении нового железа, нас встретит Initial Configuration Dialog prompt:
Вкратце, это такой визард, позволяющий шаг за шагом настроить основные параметры устройства (hostname,
пароли, интерфейсы). Но это неинтересно, поэтому отвечаем no и видим приглашение
Router>
Это стандартное совершенно для любой линейки cisco приглашение, которое характеризует пользовательский
режим, в котором можно просматривать некоторую статистику и проводить самые простые операции вроде
пинга. Ввод знака вопроса покажет список доступных команд:
Грубо говоря, это режим для сетевого оператора, инженера первой линии техподдержки, чтобы он ничего там не
повредил, не напортачил и лишнего не узнал.
Гораздо большие возможности предоставляет режим с говорящим названием привилегированный. Попасть в
него можно, введя команду >enable. Теперь приглашение выглядит так:
Router#
Здесь список операций гораздо обширнее, например, можно выполнить одну из наиболее часто используемых
команд, демонстрирующую текущие настройки устройства ака “конфиг” #show running-config. В
привилегированном режиме вы можете просмотреть всю информацию об устройстве.
Прежде, чем приступать к настройке, упомянем несколько полезностей при работе с cisco CLI, которые могут
сильно упростить жизнь:
— Все команды в консоли можно сокращать. Главное, чтобы сокращение однозначно указывало на команду.
Например, show running-config сокращается до sh run. Почему не до s r? Потому, что s (в пользовательском
режиме) может означать как команду show, так и команду ssh, и мы получим сообщение об ошибке % Ambiguous
command: «s r» (неоднозначная команда).
— Используйте клавишу Tab и знак вопроса. По нажатию Tab сокращенная команда дописывается до полной, а
знак вопроса, следующий за командой, выводит список дальнейших возможностей и небольшую справку по ним
(попробуйте сами в PT).
— Используйте фильтрацию вывода команды. Бывает, что команда выводит много информации, в которой
нужно долго копаться, чтобы найти определённое слово, например.
Облегчаем работу с помощью фильтрации: после команды ставим |, пишем вид фильтрации и, собственно,
искомое слово(или его часть). Виды фильтрации (ака модификаторы вывода):
Подключаемся. Для этого надо использовать кроссоверный кабель. (Хотя в реальной жизни это зачастую уже
необязательно – все карточки умеют понимать приём/передачу, однако встречаются ещё маршрутизаторы,
порты которых не поднимаются при использовании неправильного типа кабеля — так что будьте внимательны)
Как и ожидалось, циска не пускает без пароля. В реальной жизни обычно выдаёт фразу “Password required, but
none set”
Пароли
Подключение по telnet или ssh называется виртуальным терминалом (vt) и настраивается следующим образом:
Router(config)#line vty 0 4
Router(config-line)#password cisco
Router(config-line)#login
Немного об этом можно почитать здесь. Ну или чуть более по-русски, тут.
Теперь при подключении маршрутизатор запросит имя пользователя и соответствующий ему пароль.
Если вы хотите ограничить паролем доступ через консольный порт, вам понадобятся команды
Router(config)#line console 0
Router(config-line)#login
Router(config-line)#password cisco
Privilege Level
Ещё один важный момент, которому в статьях уделяют мало внимания: privelege level.
Как понятно из латинского звучания — это уровень прав пользователя. Всего существует 16 уровней: 0-15.
privilege level 0 — это команды disable, enable, exit, help и logout, которые работают во всех режимах
privilege level 1 — Это команды пользовательского режима, то есть как только вы попадаете на циску и увидите
приглашение Router> вы имеете уровень 1.
privilege level 15 — Это команды привилегированного режима, вроде, как root в Unix'ах
Пример1
Router(config)#line vty 0 4
Router(config-line)privilege level 15
После входа на маршрутизатор при такой настройке вы сразу увидите Router# со всеми вытекающими правами.
Все уровни со 2 по 14 настраиваются вручную. То есть, например, вы можете дать добро пользователю с privelege
level 2 на выполнение команды show running-config
Пример2
Настроить права для конкретного пользователя поможет уже упомянутая прежде команда username
Router(config)#username pooruser privilege 2 secret poorpass
Router(config)#privilege exec level 2 show running-config
Router(config)#enable secret level 2 l2poorpass
В первой строке назначаем уровень прав пользователю, во второй команду, разрешенную для этого уровня, в
третьей задаём пароль для входа в привилегированный режим с этим уровнем.
Ещё одно финальное внимание новичкам: не забывайте о команде write memory — это сохранение текущей
конфигурации. Впрочем, достаточно два раза обжечься, забыв сохранить, чтобы навсегда заработать
иммунитет к этому — кто кодил по ночам или писал курсовую, тот поймёт.
Используя PT, мы будем настраивать оборудование не через терминал или телнет, а непосредственно через CLI
устройства, которое вызывается кликом по иконке роутера — так удобнее:
Ну и на сладенькое: сброс пароля
Так, а что же делать, если на стол легла вам бушная циска с неизвестным паролем или вы очень невовремя
забыли его? Вообще-то это многократно описано и легко гуглится, но повторить это необходимо.
Практически на любом сетевом устройстве есть возможность сбросить пароль, имея физический доступ. Если
сделать это невозможно или это отдельная платная услуга, то скорее всего в ваших руках находится какая-то
русская поделка (не в обиду, конечно, нашим производителям, но дважды я такие строки читал в
документации:))
Итак, cisco:
1) Подключаетесь к устройству консольным кабелем,
2) Отправляете его в ребут (хоть по питанию, хоть командой #reload)
3) Когда на экране побежит такая строчка ########...###, означающая загрузку образа (40-60 секунд после
включения), необходимо отправить сигнал Break. Как это сделать в разных программах читать тут. Вы попадаете
в режим ROMMON.
4) В этом режиме введите команду: confreg 0x2142, она заставит устройство игнорировать startup-config при
загрузке.
5) Введите reset для перезагрузки
6) После загрузки running-config будет девственно чистым, а startup-config содержит по-прежнему последнюю
сохранённую конфигурацию. Сейчас самое время поменять пароль или слить конфиг.
7) Самое важное: верните обратно регистры:
Router(config)#config-register 0x2102
Если вы этого не сделаете, то вся ваша конфигурация будет актуальна до первого ребута) И хорошо, если это
устройство стоит рядом, и вы вспомните, что накосячили. Мне не повезло)
Перед тем, как вы обратитесь к практике, настоятельно рекомендуем почитать нулевую часть, где мы всё
спланировали и запротоколировали.
Теория
Для начала необходимо определится с определениями и детерминировать терминологию. В начале пути с этим
могут быть трудности, несмотря на горы википедии и прорву технических статей.
Рассмотрим самые общие термины, поскольку что такое коммутатор и маршрутизатор вы, во-первых,
представляете, во-вторых, по ходу не раз ещё их затронем. Итак, тронулись:
СКС — структурированная кабельная система — это определение вы в любом яндексе найдёте. На деле это все
провода, розетки, патчпанели и патчкорды, то есть грубо говоря, это физика вашей сети в узком смысле, в
широком — это совокупность сетей: ЛВС, телефонные сети, системы видеонаблюдения и прочее. Это отдельный
очень большой и порой сложный пласт знаний и технологий, который вообще не имеет точек пересечения с
настройкой, поэтому к нему мы более обращаться не будем. Привели мы этот термин по большей части для того,
чтобы читатель чувствовал отличие от следующего.
ЛВС = Локальная Вычислительная Сеть = LAN = Local Area Network. Актуальность слова “Вычислительная” сейчас
можно поставить под сомнение, так же, как в слове ЭВМ. Всё-таки, говоря о современных сетях и устройствах, мы
давно уже не держим в уме термин «вычисления», несмотря на то, что глубинная суть осталась неизменной. В
этом плане буржуйские термин более универсален и даёт более простое представление о своём значении.
Итак, локальная сеть — в первом приближении — это сеть вашей организации. Вот, к примеру, обслуживаем мы
сейчас сеть компании «Лифт ми Ап» с двумя офисам, так вот сети этих двух офисов и будут являться локальной
сетью.
При втором приближении, локальной называют сеть, которая находится под управлением одного сетевого
администратора. То есть, например, вы отвечаете за районный сегмент сети провайдера, в таком случае ваша
районная сеть со всеми подсетями будет являться локальной, в то время, как вышестоящая сеть и сети других
районов уже нет, так как за них отвечает уже другие люди. Вообще говоря, это уже MAN — Metropolian Area
Network — сеть уровня города. Но в какой-то степени к ней можно применить понятие LAN и уж тем более VLAN.
С точки зрения меня, как абонента этого провайдера, моя локальная сеть — это всё, что до моего домашнего
роутера. Интуитивно, наверно, все понимают о чём идёт речь.
Именно с локальными сетями мы и будем иметь дело в ближайших выпусках.
Дело в том, что все IP адреса делятся на приватные (private, он же внутренний, “серый”, локальный), и
публичные. Публичные используются в интернет, каждый адрес уникален, их распределение контролирует
организация IANA(Internet Assigned Numbers Authority).
Приватные используются для адресации хостов (ну, строго говоря, не хостов, а интерфейсов) внутри ЛВС, их
распределение никто не контролирует. Для них выделили три диапазона адресов (по одному из каждого класса):
10.0.0.0 — 10.255.255.255
172.16.0.0 — 172.31.255.255
192.168.0.0 — 192.168.255.255
Важный момент касаемо “классов адресов”, об этом уже как-то писали на хабре: классов адресов уже давно не
существует. Позже мы обстоятельно поговорим об адресации, но пока рекомендация такая: забыть про
существование классов адресов, чтобы не попасть впросак на собеседовании или в разговоре.
Это те адреса, которые вы можете использовать в своей частной сети. Они вполне могут повторяться (и
повторяются) в разных локальных сетях, и за её пределы они не выходят. Приватный адрес на то и приватный,
поэтому любой пакет с адресом из диапазонов, указанных выше, попавший к провайдеру, будет отбрасываться.
Если вернуться к нашей старой схеме то вы увидите, что для своей сети мы выбрали приватные адреса из
диапазона 172.16.0.0 — 172.31.255.255.
Достаточно подробно об IP-адресах можно почитать тут и тут.
У всех провайдеров и во внутренней сети любой крупной организации используются именно эти серые подсети.
Если только вы не государственный ВУЗ, которому в своё время выпала сеть на несколько тысяч публичных
адресов: Кемеровский Государственный Университет, к примеру, не озадачивается NAT’ом и прочей чепухой —
просто на все компьютеры университетской сети раздаются белые IP.
Если же на коммутаторе заведены VLAN’ы, то они также разделяют широковещательные домены, потому что
пакет между ними обязательно должен проходить через маршрутизатор, который отбросит широковещательные
сообщения. Таким образом, один VLAN — это один широковещательный домен.
Ещё раз: у нас есть три способа разграничить широковещательные домены:
1) Поставить маршрутизатор и разнести хосты в разные подсети,
2) Разделить сеть VLAN’ами,
3) Порвать кабель.
Ну и самая жесть, которой часто сторонятся начинающие: OSI. Open System Interconnection. Вообще в двух словах,
чтобы мозг не захламить за одно занятие. Эту модель называют эталонной, потому что в реальном мире дело не
дошло до реализации. Но она само совершенство, поэтому инженеры и админы вворачивают это слово повсюду.
В основе лежат 7 китов сетевой иерархии: 7 уровней. Сегодня коснёмся двух нижних: первый — физический —
это представление информации в виде сигналов, прямо скажем, битов. Задача этого уровня сгенерировать
электрический, оптический или радиосигнал, передать его в среду и принять его. К нему относится вся физика:
интерфейсы, кабели, антенны, медиаконвертеры (конвертеры среды), репитеры, старые хабы. В общем
низкоуровневая это работа. Это первый уровень модели OSI и стека TCP/IP.
Второй — канальный. На этом уровне работают коммутаторы. Идентификатор устройства здесь, это MAC-адрес.
У каждого узла (компьютер, маршрутизатор, ноутбук, IP-телефон, любой Wi-Fi-клиент) есть этот уникальный
адрес, который однозначно определяет устройство в локальной сети. В теории MAC-адреса не должны
повторяться вообще, но на практике такое однако случается и в рамках одного широковещательного домена
может приводить к сложноотлавливаемым проблемам.
Наиболее известным протоколом этого уровня является Ethernet. Данные на этом уровне передаются кусками,
каждый из которых называется Ethernet-фрейм (он же Ethernet-кадр, он же PDU канального уровня). Что он
представляет из себя?
Payload — это полезная нагрузка — данные сетевого уровня, которые вкладываются (инкапсулируются) в
кадр. MAC Header (Заголовок) — это служебная информация канального (второго) уровня. Самые важные пока
для нас элементы — это source MAC-address (адрес отправителя кадра) и Destination MAC-address (адрес
получателя кадра).
Сегодня мы акцентируемся на 1-м и 2-м уровнях, особенно на втором. Третьего и четвертого коснёмся в
следующих выпусках.
Вы пытаетесь пропинговать, например, адрес соседнего компьютера командой ping 192.168.1.118. Данные этого
приложения показаны фиолетовым параллелепипедом.
За это отвечает протокол ICMP. В него инкапсулируется информация от приложения — это означает, что к
данным 5-го уровня добавляется заголовок со служебной информацией 4-го уровня.
Его данные упаковываются (инкапсулируются) в IP-пакеты, где в заголовке указан IP-адрес получателя
(192.168.1.118) и IP-адрес отправителя — логические адреса.
На самом деле, нет ничего проще: запускаете какой-нибудь анализатор трафика, например,
замечательный Wireshark и Ethereal, на своём компьютере и пингуете другой хост. Вот такую картину вы сможете
лицезреть:
Вы это можете сделать прямо сейчас, читая эти строки, просто установив и запустив анализатор трафика.
В последнюю очередь сетевая карта вашего компьютера дробит фрейм на биты и отправляет их в кабель.
Если адреса отправителя в таблице до сих пор не было, то в этот момент коммутатор добавит его.
Естественно, кадр опять передаётся в виде битов — это закон электроники, и вы должны просто всегда иметь это
в виду.
Конечный хост, получив поток битов, собирает из них кадр, ещё только предполагая, что он предназначается ему.
Далее он сравнивает MAC-адрес получателя со своим и, если они совпадают, то заголовок второго уровня
отбрасывается, а IP-данные передаются на обработку вышестоящему протоколу. Если адреса не совпадают, то
кадр отбрасывается вместе со всем содержимым.
Далее сравниваются IP-адрес получателя и этого устройства. Если совпадают, то заголовок сетевого уровня
отбрасывается, и данные передаются транспортному уровню (ICMP)
Конечный хост обработал ICMP-запрос (echo-request) и готов послать ICMP-ответ (echo-reply) вашему компьютеру
с адресом 192.168.1.131 и далее пункты 1-3 повторяются уже для нового кадра
То, о чём мы писали до сих пор — это принцип работы любого коммутатора. Так делают даже простые длинки за
300 рублей.
VLAN
Ну а теперь, давайте, коллеги, финальный рывок: добавим сюда ещё VLAN’ы.
Кадры первого влана обычно не тегируются — он является родным вланом (native vlan).
Каждый коммутатор принимает теперь решение на основе этой метки-тега (или его отсутствия).
В таблицу МАС-адресов добавляется ещё столбец с номером VLAN’а и при поиске пары MAC-адрес/порт теперь
будет сравниваться тег кадра с номером VLAN’а в таблице.
2. Trunk port. У этого порта два основных применения — линия между двумя коммутаторами или от коммутатора
к маршрутизатору. Внутри такой линии, называемой в народе, что логично, транком, передаётся трафик
нескольких вланов. Разумеется, тут трафик уже идёт с тегами, чтобы принимающая сторона могла отличить кадр,
который идёт в бухгалтерию, от кадра, предназначенного для ИТ-отдела. За транковым портом закрепляется
целый диапазон вланов.
Кроме того, существует вышеупомянутый native vlan. Трафик этого влана не тегируется даже в транке, по
умолчанию это 1-й влан и по умолчанию он разрешён. Вы можете переопределить эти параметры.
Нужен он для совместимости с устройствами, незнакомыми с инкапсуляцией 802.1q. Например, вам нужно через
Wi-Fi мост передать 3 влана, и один из них является вланом управления. Если Wi-Fi-модули не понимают
стандарт 802.1q, то управлять ими вы сможете, только если этот влан настроите, как native vlan с обеих сторон.
1) Итак, от вашего компьютера с IP-адресом, например, 192.168.1.131 отправляется пакет другому компьютеру в
вашей же сети. Этот пакет инкапсулируется в кадр, и пока никто ничего не знает о вланах, поэтому кадр уходит,
как есть, на ближайший коммутатор.
2) На коммутаторе этот порт отмечен, как член, например, 2-го VLAN’а командой
Switch0#interface fa0/1
Switch(config)#interface fa0/2
Попробуем провести аналогию с реальными миром. Вы с другом, например, пакеты-туристы и летите отдыхать
дикарями самолётом авиалиний Ethernet Airlines. Но по дороге вы поссорились, и потому, когда в аэропорту
назначения, вас спрашивают в какую гостиницу вас везти, вы отвечаете “Рога”, а ваш товарищ говорит “Копыта”.
И сразу после этого вас инкапсулируют в разные кадры-машины: вас в такси с тегом “Таксопарк “На рогах”, а
вашего товарища с его грузом в КамАЗ с тегом “Транспортная компания “В копыто”. Теперь вам нельзя на
автобусные полосы, а вашему другу под знаки, запрещающие проезд грузовиков.
Так вот две гостиницы — это МАС-адреса назначения, а ограничения по маршруту — порты других вланов.
Петляя, по улочкам, вам, как IP-пакету не о чем беспокоиться — кадр-автомобиль доставит вас до места
назначения, и, грубо говоря, в зависимости от тега на каждом перекрёстке будет приниматься решение, как ехать
дальше.
FAQ:
Q: Что произойдёт, если тегированный кадр прилетит на access-порт?
A: Он будет отброшен.
Q: Что произойдёт, если нетегированный кадр прилетит на trunk-порт?
A: Он будет помещён в Native VLAN. По умолчанию им является 1-й VLAN. Но вы можете поменять его
командой switchport trunk native vlan 2
В этом случае все кадры, помеченные 2-м вланом будут уходить в этот порт нетегироваными, а нетегированные
кадры, приходящий на этот интерфейс, помечаться 2-м вланом.
Кадры с тегами других вланов останутся неизменными, проходя, через такой порт.
Q: Можно ли конечным узлам (компьютерам, ноутбукам, планшетам, телефонам) отправлять тегированные
кадры и соответственно подключать их к транковым портам?
A: Да, можно. Если сетевая карта и программное обеспечение поддерживает стандарт 802.1q, то узел может
работать с тегированными кадрами.
Q: Что будет с тегированными кадрами, если они попадут на обычный неуправляемый коммутатор или другое
устройство, не понимающее стандарт 802.1q?
A: Скорее всего, свич его отбросит из-за увеличенного размера кадра. Зависит от разных факторов:
производитель, софт (прошивка), тип форвардинга (cut-through, store-and-forward).
Практика. Настройка сети “Лифт ми Ап”
Ну и наконец-то обратимся к настройке. Вива ля практис!
Мы могли бы сейчас броситься сразу настраивать всё по порядку: полностью одно устройство, потом другое. Но
так не будет, пожалуй, понимания значения процессов.
Порты доступа (access)
Поэтому начнём с простого: настроим два порта на msk-arbat-asw3 как access для влана 101 (ПТО):
msk-arbat-asw3(config)#interface FastEthernet0/1
msk-arbat-asw3(config-if)#description PTO
msk-arbat-asw3(config)#interface FastEthernet0/2
msk-arbat-asw3(config-if)#description PTO
Заметили, что коммутатор ругается на отсутствие влана? Тут надо быть аккуратным. Некоторые версии ПО
работают несколько нелогично.
Даже если вы его не создадите, то настройки применятся и при отладке на первый взгляд всё будет нормально,
но связи не будет. Причём коварство заключается в том, что фраза Creating vlan 101 вовсе не означает, что этот
самый влан будет создан. Поэтому отправляемся в режим глобальной конфигурации и создаём его (а заодно и
все другие вланы, нужные на этом коммутаторе):
msk-arbat-asw3>enable
msk-arbat-asw3#configure terminal
msk-arbat-asw3(config)#vlan 2
msk-arbat-asw3(config-vlan)#name Management
msk-arbat-asw3(config-vlan)#vlan 3
msk-arbat-asw3(config-vlan)#name Servers
msk-arbat-asw3(config-vlan)#vlan 101
msk-arbat-asw3(config-vlan)#name PTO
msk-arbat-asw3(config-vlan)#vlan 102
msk-arbat-asw3(config-vlan)#name FEO
msk-arbat-asw3(config-vlan)#vlan 103
msk-arbat-asw3(config-vlan)#name Accounting
msk-arbat-asw3(config-vlan)#vlan 104
msk-arbat-asw3(config-vlan)#name Other
Теперь подключите компьютеры к портам FE0/1 и FE0/2, настройте на них адреса 172.16.3.2 и 172.16.3.3 с маской
подсети 255.255.255.0 и шлюзом 172.16.3.1 и проверьте связь:
После того, как это получилось, настроим порт FE0/16, как access, для 104-го влана (сеть других пользователей):
msk-arbat-asw3(config)#interface FastEthernet0/16
msk-arbat-asw3(config-if)#description Other
Подключите к нему компьютер и настройте адрес из той же подсети, что ПТО, например, 172.16.3.5 с маской
255.255.255.0.
Если вы попытаетесь теперь пропинговать этот адрес, то у вас не должно этого получиться — компьютеры
находятся в разных вланах и изолированы друг от друга:
То есть ещё раз, что происходит? От вашего компьютера приходит на 1-й порт широковещательный запрос: “Кто
такой 172.16.3.5”, потому что сам компьютер пока не знает MAC-адреса получателя. Кадр, который несёт в себе
этот запрос помечается, как принадлежащий 101-му VLAN’у в соответствии с портом, на который он поступил. И
далее, чтобы узнать где-же находится компьютер 172.16.3.5, кадр рассылается на все порты-члены 101-го VLAN’а.
А в их числе нет порта FE0/16, поэтому, естественно, этот адрес считается недостижимым, что приводит к ответу
“Request timed out”.
Внимание! Если в этом VLAN’е все-таки окажется устройство с таким IP, то это не будет тем же самым
ноутбуком Other и при этом они не буду конфликтовать друг с другом, поскольку логически находятся в
разных широковещательных доменах.
Транковые порты (trunk)
Итак, врата для вас открылись, теперь вам предстоит создать коридор — транк между тремя коммутаторами:
msk-arbat-asw3, msk-arbat-dsw1 и msk-rubl-asw1.
Uplink портом на msk-arbat-asw3 является GE1/1. Ну а поскольку нам всё равно все вланы нужно будет
пробросить, то сделаем это сейчас, то есть помимо 101 и 104 пропишем 2, 102 и 103:
msk-arbat-asw3(config)#interface GigabitEthernet1/1
msk-arbat-asw3(config-if)#description msk-arbat-dsw1
На самом деле на интерфейсе достаточно команды #switchport mode trunk, чтобы у вас через этот порт уже
пошли тегированные кадры всех вланов, потому что по умолчанию транковый порт пропускает всё. Но мы же
инженеры, а не эникейщики. Где это видано, чтобы безлимит творился за нашей спиной? Поэтому через нас
проходит только то, что мы разрешаем. Как только вы дали команду switchport trunk allowed vlan 101, через порт
не пройдёт кадр никаких вланов, кроме 101 (VLAN 1 ходит по умолчанию и нетегированным).
Внимание! Если вы хотите в транковый порт добавить ещё один влан, то вам необходимо использовать
следующий синтаксис команды:
В противном случае (написав switchport trunk allowed vlan 105) вы сотрёте все старые разрешения и
добавите новый 105-й влан. И хорошо ещё, если при этом вы не потеряете доступ на этот коммутататор.
Но за простой связи всё равно вы получите по пятое число)
Переходим к msk-arbat-dsw1. На нём необходимо создать все вланы и настроить два порта:
GE1/2 в сторону msk-arbat-asw3
FE0/1 в сторону msk-rubl-asw1:
msk-arbat-dsw1(config)#interface GigabitEthernet1/2
msk-arbat-dsw1(config-if)#description msk-arbat-asw3
msk-arbat-dsw1(config)#interface FastEthernet0/1
msk-arbat-dsw1(config-if)#description msk-rubl-asw1
msk-rubl-asw1(config)interface FastEthernet0/24
msk-rubl-asw1(config)#int FastEthernet0/1
msk-rubl-asw1(config-if)#description PTO
Снова нужно настроить вланы. И заметьте, при настройке транковых портов никаких сообщений нет.
Если вы всё настроили правильно (в чём не приходится сомневаться), то с первого порта msk-rubl-asw1 вы
увидите компьютеры ПТО, подключённые к msk-arbat-asw3.
Для уверенности проверим ещё и 104-й влан. Через транк мы его сюда уже доставили.
msk-rubl-asw1(config)#interface FastEthernet 0/16
Подключаем компьютер к 16-му порт и настраиваем на нём IP-адрес 172.16.6.3 с маской 255.255.255.0 и шлюзом
172.16.6.1. А IP-адрес ноутбука на арбате поменяйте на 172.16.6.2 с теми же маской и шлюзом.
Сеть управления
Настроим IP-адрес для управления.
В наших лабах они не понадобятся, потому что мы настраиваем устройство через окно РТ. А вот в реальной
жизни это вам жизненно необходимо.
Для этого мы создаём виртуальный интерфейс и указываем номер интересующего нас влана. А далее работаем с
ним, как с самым обычным физическим интерфейсом.
msk-arbat-dsw1:
msk-arbat-dsw1(config)#interface vlan 2
msk-arbat-dsw1(config-if)#description Management
msk-arbat-asw3:
msk-arbat-asw3(config)#vlan 2
msk-arbat-asw3(config)#interface vlan 2
msk-arbat-asw3(config-if)#description Management
msk-arbat-asw3#ping 172.16.1.2
Type escape sequence to abort.
..!!!
Первые пару пакетов могут потеряться на работу протокола ARP: определение соответствия IP-адрес — MAC-
адрес. При этом MAC-адрес, порт и номер влана добавляются в таблицу коммутатора.
Самостоятельно настройте IP-адреса сети управления на остальных коммутаторах и проверьте их доступность
Собственно вот и вся магия. Зачастую к подобного рода действиям и сводится вся настройка, если вы не
работаете в провайдере. С другой стороны, если вы работаете в провайдере, то, наверняка, такие вещи вам
объяснять не нужно.
Если желаете знать больше об этом, читайте: VTP, QinQ, зарезервированные номера VLAN
Ещё один небольшой инструмент, который может немного увеличить удобство работы: banner. Это объявление,
которое циска покажет перед авторизацией на устройство.
Switch(config)#banner motd q
It is just banner.
Switch(config)#
После motd вы указываете символ, который будет служить сигналом о том, что строка закончена. В это примере
мы поставили “q”.
Относительно содержания баннера. Существует такая легенда: хакер вломился в сеть, что-то там поломал\украл,
его поймали, а на суде оправдали и отпустили. Почему? А потому, что на пограничном роутере(между интернет и
внутренней сетью), в banner было написано слово “Welcome”. “Ну раз просят, я и зашел”)). Поэтому считается
хорошей практикой в баннере писать что-то вроде “Доступ запрещен!”.
1) Настроить hostname. Это поможет вам в будущем на реальной сети быстро сориентироваться, где вы
находитесь.
Switch(config)#hostname HOSTNAME
Switch(config)#vlan VLAN-NUMBER
Switch(config-vlan)#name NAME-OF-VLAN
Switch(config-if)#description DESCRIPTION-OF-INTERFACE
msk-arbat-asw3(config-if-range)#description FEO
Switch(config-if)#description DESCRIPTION-OF-INTERFACE
5) Не забывайте сохраняться:
Итого: чего мы добились? Все устройства в одной подсети видят друг друга, но не видят устройства из другой. В
следующем выпуске разбираемся с этим вопросом, а также обратимся к статической маршрутизации и L3-
коммутаторам.
В общем-то на этом данный урок можно закончить. В видео вы сможете ещё раз увидеть, как настраиваются
вланы. В качестве домашнего задания настройте вланы на коммутаторах для серверов.
P.S.
Важное дополнение: в предыдущей части, говоря о native vlan мы вас немного дезинформировали. На
оборудовании cisco такая схема работы невозможна.
Напомним, что нами предлагалось передавать на коммутатор msk-rubl-asw1 нетегированными кадры 101-го
влана и принимать их там в первый.
Дело в том, что, как мы уже упомянули выше, с точки зрения cisco с обеих сторон на коммутаторах должен
быть настроен одинаковый номер влана, иначе начинаются проблемы с протоколом STP и в логах можно
увидеть предупреждения о неверной настройке. Поэтому 101-й влан мы передаём на устройство обычным
образом, кадры будут тегированными и соответственно, 101-й влан тоже необходимо создавать на msk-
rubl-asw1.
Ещё раз хотим заметить, что при всём желании мы не сможем охватить все нюансы и тонкости, поэтому и не
ставим перед собой такой задачи. Такие вещи, как принцип построения MAC-адреса, значения поля Ether Type
или для чего нужен CRC в конце кадра, вам предстоит изучить самостоятельно.
Итак, поворотный момент в истории компании “Лифт ми Ап”. Руководство понимает, что компания,
производящая лифты, едущие только вверх, не выдержит борьбы на высококонкурентном рынке. Необходимо
расширять бизнес. Принято решение о покупке двух заводов: в Санкт-Петербурге и Кемерово.
Нужно срочно организовывать связь до новых офисов, а у вас ещё даже локалка не заработала.
Сегодня:
1. Настраиваем маршрутизацию между вланами в нашей сети (InterVlan routing)
2. Пытаемся разобраться с процессами, происходящими в сети, и что творится с данными
3. Планируем расширение сети (IP-адреса, вланы, таблицы коммутации)
4. Настраиваем статическую маршрутизацию и разбираемся, как она работает
5. Используем L3-коммутатор в качестве шлюза
Содержание:
• InterVlan Routing
• Планирование расширения
o IP-план
• Принципы маршрутизации
• Настройка
o Москва. Арбат
o Провайдер
o Санкт-Петербург. Васильевский остров
o Санкт-Петербург. Озерки
o Кемерово. Красная горка
• Дополнительно
• Материалы выпуска
InterVlan Routing
Чуточку практики для взбадривания.
В предыдущий раз мы настроили коммутаторы нашей локальной сети. На данный момент устройства разных
вланов не видят друг друга. То есть фактически ФЭО и ПТО, например, находятся в совершенно разных сетях и не
связаны друг с другом. Так же и серверная сеть существует сама по себе. Надо бы исправить эту досадную
неприятность.
В нашей московской сети для маршрутизации между вланами мы будем использовать роутер cisco 2811. Иными
словами он будет терминировать вланы. Кадры здесь заканчивают свою жизнь: из них извлекаются IP-пакеты, а
заголовки канального уровня отбрасываются.
0) Сначала закончим с коммутатором msk-arbat-dsw1. На нём нам нужно настроить транковый порт в сторону
маршрутизатора, чего мы не сделали в прошлый раз.
msk-arbat-dsw1(config)#interface FastEthernet0/24
msk-arbat-dsw1(config-if)# description msk-arbat-gw1
1) Назначаем имя маршрутизатора командой hostname, а для развития хорошего тона, надо упомянуть, что
лучше сразу же настроить время на устройстве. Это поможет вам корректно идентифицировать записи в логах.
Router0# conf t
Router0(config)#hostname msk-arbat-gw1
Желательно время на сетевые устройства раздавать через NTP (любую циску можно сделать NTP-сервером,
кстати)
2) Далее переходим в режим настройки интерфейса, обращённого в нашу локальную сеть и включаем его, так
как по умолчанию он находится в состоянии Administratively down.
msk-arbat-gw1(config-if)#no shutdown
3) Создадим виртуальный интерфейс или иначе его называют подинтерфейс или ещё сабинтерфейс (sub-
interface).
msk-arbat-gw1(config)#interface fa0/0.2
msk-arbat-gw1(config-if)#description Management
Логика тут простая. Сначала указываем обычным образом физический интерфейс, к которому подключена
нужная сеть, а после точки ставим некий уникальный идентификатор этого виртуального интерфейса. Для
удобства, обычно номер сабинтерфейса делают аналогичным влану, который он терминирует.
4) Теперь вспомним о стандарте 802.1q, который описывает тегирование кадра меткой влана. Следующей
командой вы обозначаете, что кадры, исходящие из этого виртуального интерфейса будут помечены тегом 2-го
влана. А кадры, входящие на физический интерфейс FastEthernet0/0 с тегом этого влана будут приняты
виртуальным интерфейсом FastEthernet0/0.2.
msk-arbat-gw1(config-if)#encapsulation dot1Q 2
5) Ну и как на обычном физическом L3-интерфейсе, определим IP-адрес. Этот адрес будет шлюзом по умолчанию
(default gateway) для всех устройств в этом влане.
msk-arbat-gw1(config)#interface FastEthernet0/0.101
msk-arbat-gw1(config-if)#description PTO
Работает и отлично, настройте пока все остальные интерфейсы. Проблем с этим возникнуть не должно.
Физика и логика процесса межвланной маршрутизации
Что происходит в это время с вашими данными? Мы рассуждали в прошлый раз, что происходит, если вы
пытаетесь связаться с устройством из той же самой подсети, в которой находитесь вы. Под той же самой
подсетью мы понимаем следующее: например, на вашем компьютере настроено следующее:
IP: 172.16.3.2
Mask: 255.255.255.0
GW: 172.16.3.1
Все устройства, адреса которых будут находиться в диапазоне 172.16.3.1-172.16.3.254 с такой же маской, как у
вас, будут являться членами вашей подсети. Что происходит с данными, если вы отправляете их на устройство с
адресом из этого диапазона? Повторим это с некоторыми дополнениями.
Для отправки данных они должны быть упакованы в Ethernet-кадр, в заголовок которого должен быть вставлен
MAC-адрес удалённого устройства. Но откуда его взять?
Для этого ваш компьютер рассылает широковещательный ARP-запрос. В качестве IP-адреса узла назначения в IP-
пакет с этим запросом будет помещён адрес искомого хоста. Сетевая карта при инкапсуляции указывает MAC-
адрес FF:FF:FF:FF:FF:FF — это значит, что кадр предназначен всем устройствам. Далее он уходит на ближайший
коммутатор и копии рассылаются на все порты нашего влана (ну, кроме, конечно, порта, из которого получен
кадр). Получатели видят, что запрос широковещательный и они могут оказаться искомым хостом, поэтому
извлекают данные из кадра. Все те устройства, которые не обладают указанным в ARP-запросе IP-адресом,
просто игнорируют запрос, а вот устройство-настоящий получатель ответит на него и вышлет первоначальному
отправителю свой MAC-адрес. Отправитель (в данном случае, наш компьютер) помещает полученный MAC в
свою таблицу соответствия IP и MAC адресов ака ARP-кэш. Как выглядит ARP-кэш на вашем компьютере прямо
сейчас, вы можете посмотреть с помощью команды arp -a
Потом ваши полезные данные упаковываются в IP-пакет, где в качестве получателя ставится тот адрес, который
вы указали в команде/приложении, затем в Ethernet-кадр, в заголовок которого помещается полученный ARP-
запросом MAC-адрес. Далее кадр отправляется на коммутатор, который, согласно своей таблице MAC-адресов,
решает, в какой порт его переправить дальше.
Но что происходит, если вы пытаетесь достучаться до устройства в другом влане? ARP-запрос ничего не вернёт,
потому что широковещательные L2 сообщения кончаются на маршрутизаторе(т.е., в пределах
широковещательного L2 домена), нужная сеть находится за ним, а коммутатор не пустит кадры из одного влана в
порт другого. И вот для этого нужен шлюз по умолчанию (default gateway) на вашем компьютере. То есть, если
устройство-получатель в вашей же подсети, кадр просто отправляется в порт с мак-адресом конечного
получателя. Если же сообщение адресовано в любую другую подсеть, то кадр отправляется на шлюз по
умолчанию, поэтому в качестве MAC-адреса получателя подставится MAC-адрес маршрутизатора.
Планирование расширения
Теперь обратимся к планированию. В нулевой части мы уже затронули эту тему, но тогда речь была только о двух
офисах в Москве, теперь же сеть растёт.
Следует сказать несколько слов об IP-адресации и делении на подсети. В нулевой части мы уже затронули
вопросы планирования, весьма вскользь, надо сказать. Вообще, в любой более или менее большой компании
должен быть некий регламент — свод правил, следуя которому вы распределяете IP-адреса везде. Сеть у нас
сейчас разрастается и разработать его очень важно.
Ну вот к примеру, скажем, что для офисов в других городах это будет так:
Это весьма упрощённый регламент, но теперь мы во всяком случае точно знаем, что у шлюза всегда будет 1-й
адрес, до 12-го мы будем выдавать коммутаторам и всяким wi-fi-точкам, а все сервера будем искать в диапазоне
172.16.х.13-172.16.х.23. Разумеется, по своему вкусу вы можете уточнять регламент вплоть до адреса каждого
сервера, добавлять в него правило формирования имён устройств, доменных имён, политику списков доступа и
т.д. Чем точнее вы сформулируете правила и строже будете следить за их выполнением, тем проще разбираться
в структуре сети, решать проблемы, адаптироваться к ситуации и наказывать виновных. Это примерно, как схема
запоминания паролей: когда у вас есть некое правило их формирования, вам не нужно держать в голове
несколько десятков сложнозапоминаемых паролей, вы всегда можете их вычислить. Вот так же и тут. Я некогда
работал в средних размеров холдинге и знал, что если я приеду в офис где-нибудь в забытой коровами деревне,
то там точно x.y.z.1 — это циска, x.y.z.2 — дистрибьюшн-свитч прокурва, а x.y.z.101 — компьютер главного
бухгалтера, с которого надо дать доступ на какой-нибудь контур-экстерн. Другой вопрос, что надо это ещё
проверить, потому что местные ИТшники такого порой наворотят, что слезами омываешься сквозь смех.
Было дело парнишка решил сам управлять всем доступом в интернет (обычно это делал я на маршрутизаторе).
Поставил proxy-сервер, случайно поднял на нём NAT и зарулил туда трафик локальной сети, на всех машинах
прописав его в качестве шлюза по умолчанию, а потом я минут 20 разбирался, как так: у них всё работает, а мы их
не видим.
IP-план
Теперь нам было бы весьма кстати составить IP-план. Будем исходить из того, что на всех трёх точках мы будем
использовать стандартную сеть с маской 24 бита (255.255.255.0) Это означает, что в них может быть 254
устройства.
Почему это так? И как вообще понять все эти маски подсетей? В рамках одной статьи мы не сможем этого
рассказать, иначе она получится длинная, как палуба Титаника и запутанная, как одесские катакомбы. Крайне
рекомендуем очень плотно познакомиться с такими понятиями, как IP-адрес, маска подсети, их представления в
двоичном виде и CIDR (Classless InterDomain Routing) самостоятельно. Мы же далее будем только
аргументировать выбор конкретного размера сети. Как бы то ни было, полное понимание придёт только с
практикой.
Вообще, очень неплохо эта тема раскрыта в этой статье: http://habrahabr.ru/post/129664/
В данный момент (вспомним нулевой выпуск) у нас в Москве использованы адреса 172.16.0.0-172.16.6.255.
Предположим, что сеть может ещё увеличиться здесь, допустим, появится офис на Воробьёвых горах и
зарезервируем ещё подсети до 172.16.15.0/24 включительно.
Все эти адреса: 172.16.0.0-172.16.15.255 — можно описать так: 172.16.0.0/20. Эта сеть (с префиксом /20) будет так
называемой суперсетью, а операция объединения подсетей в суперсети называется суммированием подсетей
(суммированием маршрутов, если быть точным, route summarization)
Теперь обратимся к Питеру. В данный момент в этом прекрасном городе у нас 2 точки и на каждой из них
подсети /24. Допустим это будут 172.16.16.0/24 и 172.16.17.0/24. Зарезервируем адреса 172.16.18.0-
172.16.23.255 для возможного расширения сети.
В Кемерово нам нет смысла оставлять такие огромные запасы /21, как в Питере (2048 адресов или 8 подсетей
/24), или тем более /20, как в Москве (4096 или 16 подсетей /24). А вот 1024 адреса и 4 подсети /24, которым
соответствует маска /22 вполне рационально.
Таким образом сеть 172.16.24.0/22 (адреса 172.16.24.0-172.16.27.255) будет у нас для Кемерово.
Тут надо бы заметить: делать такой запас в общем-то необязательно и то, что мы зарезервировали вполне
можно использовать в любом другом месте сети. Нет табу на этот счёт. Однако в крупных сетях именно так и
рекомендуется делать и связано это с количеством информации в таблицах маршрутизации.
Понимаете ли дело вот в чём: если у вас несколько подряд идущих подсетей разбросаны по разным концам сети,
то каждой из них соответствует одна запись в таблице маршрутизации каждого маршрутизатора. Если при этом
вы вдруг используете только статическую маршрутизацию, то это ещё колоссальный труд по настройке и
отслеживанию корректности настройки.
А если же они у вас все идут подряд, то несколько маленьких подсетей вы можете суммировать в одну большую.
Поясним на примере Санкт-Петербурга. При настройке статической маршрутизации мы могли бы делать так:
……
Это 8 команд и 8 записей в таблице. Но при этом пришедший на маршрутизатор пакет в любую из сетей
172.16.16.0/21 в любом случае будет отправлен на устройство с адресом 172.16.2.2.
Вместо этого мы поступим так:
Теперь ещё несколько слов о линковых сетях. В среде сетевых администраторов так называются сети точка-точка
(Point-to-Point) между двумя маршрутизаторами.
Вот опять же в примере с Питером. Два маршрутизатора (в Москве и в Петербурге) соединены друг с другом
прямым линком (неважно, что у провайдера это сотня коммутаторов и маршрутизаторов — для нас это просто
влан). То есть кроме вот этих 2-х устройств здесь не будет никаких других. Мы знаем это наверняка. В любом
случае на интерфейсах обоих устройств (смотрящих в сторону друг друга) нужно настраивать IP-адреса. И нам
точно незачем назначать на этом участке сеть /24 с 254 доступными адресами, ведь 252 в таком случае пропадут
почём зря. В этом случае есть прекрасный выход — бесклассовая IP-адресация.
Почему она бесклассовая? Если вы помните, то в нулевой части мы говорили о трёх классах подсетей: А, В и С. По
идее только их вы и могли использовать при планировании сети. Бесклассовая междоменная маршрутизация
(CIDR) позволяет очень гибко использовать пространство IP-адресов.
Мы просто берём сеть с самой маленькой возможной маской — 30 (255.255.255.252) — это сеть на 4 адреса.
Почему мы не можем взять сеть с ещё более узкой маской? Ну 32 (255.255.255.255) по понятными причинам —
это вообще один единственный адрес, сеть 31 (255.255.255.254) — это уже 2 адреса, но один из них (первый) —
это адрес сети, а второй (последний) — широковещательный. В итоге на адреса хостов у нас и не осталось
ничего. Поэтому и берём маску 30 с 4 адресами и тогда как раз 2 адреса остаются на наши два маршрутизатора.
Вообще говоря, самой узкой маской для подсетей в cisco таки является /31. При определённых условиях их
можно использовать на P-t-P-линках.
Что же касается маски /32, то такие подсети, которые суть один единственный хост, используются для
назначения адресов Loopback-интерфейсам.
Именно так мы и поступим. Для этого, собственно, в нулевой части мы и оставили сеть 172.16.2.0/24 — её мы
будем дробить на мелкие сетки /30. Всего их получится 64 штуки, соответственно можно назначить их на
64 линка.
Здесь мы поступили так же, как и в предыдущем случае: сделали небольшой резерв для Питера, и резерв для
Кемерово. Вообще резерв — это всегда очень хорошо о чём бы мы ни говорили. ;)
Принципы маршрутизации
Перед началом настройки стоит определиться с тем, для чего нужна маршрутизация вообще.
Рассмотрим такую сеть:
Вот к примеру с компьютера ПК1 — 172.16.3.2 я хочу подключиться по telnet к L3-коммутатору с адресом
172.16.17.1.
Как мой компьютер узнает что делать? Куда слать данные?
1) Как вы уже знаете, если адрес получателя из другой подсети, то данные нужно отправлять на шлюз по
умолчанию.
2) По уже известной вам схеме компьютер с помощью ARP-запроса добывает MAC-адрес маршрутизатора.
3) Далее он формирует кадр с инкапсулированным в него пакетом и отсылает его в порт. После того, как кадр
отправлен, компьютеру уже по барабану, что происходит с ним дальше.
4) А сам кадр при этом попадает сначала на коммутатор, где решается его судьба согласно таблице MAC-адресов.
А потом достигает маршрутизатора RT1.
5) Поскольку маршрутизатор ограничивает широковещательный домен — здесь жизнь этого кадра и
заканчивается. Циска просто откидывает заголовок канального уровня — он уже не пригодится — извлекает из
него IP-пакет.
6) Теперь маршрутизатор должен принять решение, что с ним делать дальше. Разумеется, отправить его на
какой-то свой интерфейс. Но на какой?
Для этого существует таблица маршрутизации, которая есть на любом рутере. Выяснить, что у нас в данный
момент находится в таблице маршрутизации, можно с помощью команды show ip route:
Каждая строка в ней — это способ добраться до той или иной сети.
Вот к примеру, если пакет адресован в сеть 172.16.17.0/24, то данные нужно отправить на устройство с адресом
172.16.2.2.
Таблица маршрутизации формируется из:
— непосредственно подключенных сетей (directly connected) — это сети, которые начинаются непосредственно
на нём. В примере 172.16.3.0/24 и 172.16.2.0/30. В таблице они обозначаются буквой C
— статический маршруты — это те, которые вы прописали вручную командой ip route. Обозначаются буквой S
— маршруты, полученные с помощью протоколов динамической маршрутизации (OSPF, EIGRP, RIP и других).
7) Итак, данные в сеть 172.16.17.0 (а мы хотим подключиться к устройству 172.16.17.1) должны быть отправлены
на следующий хоп — следующий прыжок, которым является маршрутизатор 172.16.2.2. Причём из таблицы
маршрутизации видно, что находится следующий хоп за интерфейсом FE0/1.4 (подсеть 172.16.2.0/30).
8)Если в ARP-кэше циски нет MAC-адреса, то надо снова выполнить ARP-запрос, чтобы узнать MAC-адрес
устройства с IP-адресом 172.16.2.2. RT1 посылает широковещательный кадр с порта FE0/1.4. В этом
широковещательном домене у нас два устройства, и соответственно только один получатель. RT2 получает ARP-
запрос, отбрасывает заголовок Ethernet и, понимая из данных протокола ARP, что искомый адрес принадлежит
ему отправляет ARP-ответ со своим MAC-адресом.
9) Изначальный IP-пакет, пришедший на RT1 не меняется, он инкапсулируется в совершенно новый кадр и
отправляется в порт FE0/1.4, получая при этом метку 4-го влана.
10) Полностью аналогичные действия происходят на следующем маршрутизаторе. И на следующем и
следующем (если бы они были), пока пакет не дойдёт до последнего, к которому и подключена нужная сеть.
11) Последний маршрутизатор (коим является L3-коммутатор) видит, что искомый адрес принадлежит ему
самому, а извлекая данные транспортного уровня, понимает, что это телнет и передаёт все данные верхним
уровням.
Так вот и путешествуют данные с одного хопа на другой и ни один маршрутизатор представления не имеет о
дальнейшей судьбе пакета. Более того, он даже не знает есть ли там действительно эта сеть — он просто
доверяет своей таблице маршрутизации.
Настройка
Каким образом мы организуем каналы связи? Как мы уже сказали выше, в нашем офисе на Арбате есть некий
провайдер Балаган-Телеком. Он обещает нам предоставить всё, что мы только захотим почти задарма. И мы
заказываем у него две услуги L2VPN, то есть он отдаст нам два влана на Арбате в Москве, и по одному в Питере и
Кемерово.
Вообще говоря, номера вланов вам придётся согласовывать с вашим провайдером по той простой причине, что у
него они могут быть просто заняты. Поэтому вполне возможно, что у вас будет влан, например, 2912 или 754. Но
предположим, что нам повезло, и мы вольны сами выбирать номер.
Москва. Арбат
На циске в Москве у нас два интерфейса, к одному — FE0/0 — уже подключена наша локальная сеть, а второй
(FE0/1)мы будем использовать для выхода в интернет и для подключения удалённых офисов.
Как и в самом начале создадим саб-интерфейсы. Выделим для Санкт-Петербурга и Кемерова 4 и 5-й вланы
соответственно. IP-адреса берём из нового IP-плана.
msk-arbat-gw1(config-subif)#description Saint-Petersburg
msk-arbat-gw1(config-subif)#encapsulation dot1Q 4
msk-arbat-gw1(config-subif)#description Kemerovo
msk-arbat-gw1(config-subif)#encapsulation dot1Q 5
Провайдер
Разумеется, мы не будем строить всю сеть провайдера. Вместо этого просто поставим коммутатор, ведь по сути
сеть провайдера с нашей точки зрения будет одним огромным абстрактным коммутатором.
Тут всё просто: принимаем транком линк с Арбата в один порт и с двух других портов отдаём их на удалённые
узлы. Ещё раз хотим подчеркнуть, что все эти 3 порта не принадлежат одному коммутатору — они разнесены на
сотни километров, между ними сложная MPLS-сеть с кучей коммутаторов.
Switch(config)#vlan 4
Switch(config-vlan)#vlan 5
Switch(config)#interface fa0/1
Switch(config-if)#exit
Switch(config)#int fa0/2
Switch(config-if)#int fa0/3
Каким образом здесь вам провайдер будет отдавать канал — транком или аксесом, вы решаете сообща. Как
правило, для него не составит проблем ни один из вариантов.
Но мы уже настроили транк, поэтому соответствующим образом настраиваем порт на циске:
spb-vsl-gw1(config)interface FastEthernet1/0.4
spb-vsl-gw1(config-if)description Moscow
spb-vsl-gw1(config-if)encapsulation dot1Q 4
spb-vsl-gw1(config)#int fa0/0
spb-vsl-gw1(config-if)#description LAN
msk-arbat-gw1#ping 172.16.2.2
!!!!!
msk-arbat-gw1#ping 172.16.16.1
.....
msk-arbat-gw1#sh ip route
msk-arbat-gw1#sh ip route
msk-arbat-gw1#ping 172.16.16.1
!!!!!
spb-vsl-gw1#sh ip route
Но, почему же, спросите вы, с msk-arbat-gw1 до 172.16.16.1 пинг был? Какая разница 172.16.3.1 или 172.16.3.2?
Всё просто.
Из таблицы маршрутизации всем видно, что следующий хоп — 172.16.2.2, при этом адрес из 172.16.2.1
принадлежит интерфейсу этого маршрутизатора, поэтому он и ставится в заголовок в качестве IP-адреса
отправителя, а не 172.16.3.1. Пакет отправляется на spb-vsl-gw1, тот его принимает, передаёт данные
приложению пинг, которое формирует echo-reply. Ответ инкапсулируется в IP-пакет, где в качестве адреса
получателя фигурирует 172.16.2.1, а 172.16.2.0/30 — непосредственно подключенная к spb-vsl-gw1 сеть, поэтому
без проблем пакет доставляется по назначению. То етсь в сеть 172.16.2.0/30 маршрут известен, а в 172.16.3.0/24
нет.
Для решения этой проблемы мы можем прописать на spb-vsl-gw1 маршрут в сеть 172.16.3.0, но тогда придётся
прописывать и для всех других сетей. Для всех сетей в Москве, потом в Кемерово, потом в других городах —
очень большой объём настройки. Тут стоить заметить, что по сути у нас только один выход в мир — через
Москву. Узел в Озерках — тупиковый, а других нет. То есть в основном все данные будут уходить в Москву, где
большая часть подсетей и будет выход в интернет. Чем нам это может помочь? Есть такое понятие — маршрут по
умолчанию, ещё он носит романтическое название шлюз — последней надежды. И второму есть объяснение.
Когда маршрутизатор решает, куда отправить пакет, он просматривает всё таблицу маршрутизации и, если не
находит нужного маршрута, пакет отбрасывается — это если у вас не настроен шлюз последней надежды, если
же настроен, то сиротливые пакеты отправляются именно туда — просто не глядя, предоставляя право уже
следующему хопу решать их дальнейшую судьбу. То есть если некуда отправить, то последняя надежда —
маршрут по умолчанию.
Настраивается он так:
И теперь тадааам:
В случае таких тупиковых областей довольно часто применяется именно шлюз последней надежды, чтобы
уменьшить количество маршрутов в таблице и сложность настройки.
Санкт-Петербург. Озерки
Теперь озаботимся Озерками. Здесь мы поставим L3-коммутатор. Допустим, связаны они у нас будут
арендованным у провайдера волокном (конечно, это идеализированная ситуация для маленькой компании, но
можно же помечтать). Использование коммутаторов третьего уровня весьма удобно в некоторых случаях. Во-
первых, интервлан роутинг в этом случае делается аппаратно и не нагружает процессор, в отличие от
маршрутизатора. Кроме того, один L3-коммутатор обойдётся вам значительно дешевле, чем L2-коммутатор и
маршрутизатор по отдельности. Правда, при этом вы лишаетесь ряда функций, естественно. Поэтому при выборе
решения будьте аккуратны.
spb-vsl-gw1(config-if)#description Ozerki
Поскольку мы уже запланировали сеть для Озерков 172.16.17.0/24, то можем сразу прописать туда маршрут:
В качестве некст хопа ставим адрес, который мы выделили для линковой сети на Озерках — 172.16.2.6
Switch(config)#hostname spb-ozerki-gw1
spb-ozerki-gw1(config)#interface fa0/24
spb-ozerki-gw1(config-if)#no switchport
Проверяем связь:
spb-ozerki-gw1#ping 172.16.2.5
.!!!!
Настроим ещё локальную сеть. Напомним, что Cisco и другие производители и не только производители не
рекомендуют использовать 1-й влан, поэтому, мы воспользуемся 2-м:
spb-ozerki-gw1(config)#vlan 2
spb-ozerki-gw1(config-vlan)#name LAN
spb-ozerki-gw1(config-vlan)#exit
spb-ozerki-gw1(config)#interface vlan 2
spb-ozerki-gw1(config-if)#description LAN
spb-ozerki-gw1(config-if)#description Pupkin
spb-ozerki-gw1(config-if)#switchport mode access
После этого все устройства во втором влане будут иметь шлюзом 172.16.17.1
Чтобы коммутатор превратился в почти полноценный маршрутизатор, надо дать ещё одну команду:
spb-ozerki-gw1(config)#ip routing
spb-ozerki-gw1#ping 172.16.16.1
!!!!!
А до Москвы нет:
spb-ozerki-gw1#ping 172.16.3.1
.....
Опять же дело в отсутствии маршрута. Вообще удобный инструмент для нахождения примерного места
расположения проблемы traceroute:
spb-ozerki-gw1#traceroute 172.16.3.1
2 * * *
3 * * *
4 *
Как видите, что от spb-vsl-gw1 ответ приходит, а дальше глухо. Это означает, как правило, что или на хопе с
адресом 172.16.2.5 не прописан маршрут в нужную сеть (вспоминаем, что у нас настроен там маршрут по
умолчанию, которого достаточно) или на следующем нету маршрута обратно:
msk-arbat-gw1#sh ip rou
Действительно маршрута в подсеть 172.16.17.0/24 нет. Мы можем прописать его, вы это уже умеете, а можем
вспомнить, что целую подсеть 172.16.16.0/21 мы выделили под Питер, поэтому вместо того, чтобы по
отдельности добавлять маршрут в каждую новую сеть, мы пропишем агрегированный маршрут:
msk-arbat-gw1(config)#no ip route 172.16.16.0 255.255.255.0 172.16.2.2
Проверяем:
msk-arbat-gw1#ping 172.16.17.1
!!!!!
Но странной неожиданностью для вас может стать то, что с spb-ozerki-gw1 вы не увидите Москву по-прежнему:
spb-ozerki-gw1#ping 172.16.3.1
.....
spb-ozerki-gw1#ping
Protocol [ip]:
% Invalid source
!!!!!
Дело в том, что msk-arbat-gw1 о подсети 172.16.17.0/24 знает, а о 172.16.2.4/30 нет. А именно адрес 172.16.2.6 —
адрес ближайшего к адресату интерфейса (или интерфейса, с которого отправляется IP-пакет) подставляет по
умолчанию в качестве источника. Об этом забывать не нужно.
spb-ozerki-gw1#ping 172.16.3.1
Ещё интересный опыт: а что если адрес на маршрутизаторе на Васильевском острове маршрут в подсеть
172.16.3.0/24 пропишем на Озерки, а не в Москву? Ну чисто для интереса. Что произойдёт в этом случае?
В РТ вы этого не увидите, почему-то, но в реальной жизни получится кольцо маршрутизации. Сети 172.16.3.0/24 и
172.16.16.0/21 не будут видеть друг друга:
пакет идущий с spb-ozerki-gw1 в сеть 172.16.3.0 попадает в первую очередь на spb-vsl-gw1, где сказано:
“172.16.3.0/24 ищите за 172.16.2.6”, а это снова spb-ozerki-gw1, где сказано: “172.16.3.0/24 ищите за 172.16.2.5” и
так далее. Пакет будет шастать туда-обратно, пока не истечёт значение в поле TTL.
Дело в том, что при прохождении каждого маршрутизатора поле TTL в IP-заголовке, изначально имеющее
значение 255, уменьшается на 1. И если вдруг окажется, что это значение равно 0, то пакет погибает, точнее
маршрутизатор, увидевший это, задропит его. Таким образом обеспечивается стабильность сети — в случае
возникновения петли пакеты не будут жить бесконечно, нагружая канал до его полной утилизации. Кстати, в
Ethernet такого механизма нет и если получается петля, то коммутатор только и будет делать, что плодить
широковещательные запросы, полностью забивая канал — это называется широковещательный шторм (эта
проблема решается с помощью специальной технологии\протокола STP- об этом в следующем выпуске).
В общем, если вы пускаете пинг из сети 172.16.17.0 на адрес 172.16.3.1, то ваш IP-пакет будет путешествовать
между двумя маршрутизаторами, пока не истечёт срок его жизни, пройдя при этом по линку между Озерками и
Васильевским островом 254 раза. Кстати, следствием из работы этого механизма является то, что не может
существовать связная сеть, где между узлами больше 255 маршрутизаторов. Впрочем это и не очень актуальная
потребность. Сейчас даже самый долгий трейс занимает пару-тройку десятков хопов.
Кемерово. Красная горка
Рассмотрим последний небольшой пример — маршрутизатор на палочке (router on a stick). Название навеяно
схемой подключения:
Маршрутизатор связан с коммутатором лишь одним кабелем и по разным вланам внутри него передаётся
трафик и локальной сети, и внешний. Делается это, как правило, для экономии средств (на маршрутизаторе
только один порт и не хочется покупать дополнительную плату). Подключим следующим образом:
Настройка коммутатора уже не должна для вас представлять проблем. На UpLink-интерфейсе настраиваем
оговоренный с провайдером 5-й влан транком:
Switch(config)#hostname kmr-gorka-sw1
kmr-gorka-sw1(config)#vlan 5
kmr-gorka-sw1(config-vlan)#name Moscow
kmr-gorka-sw1(config)#int fa0/24
kmr-gorka-sw1(config-if)#description Moscow
В качестве влана для локальной сети выберем vlan 2 и это ничего, что он уже используется и в Москве и в Питере
— если они не пересекаются и вы это можете контролировать, то номера могут совпадать. Тут каждый решает
сам: вы можете везде использовать, например, 2-й влан, в качестве влана локальной сети или напротив
разработать план, где номера вланов уникальны во всей сети.
kmr-gorka-sw1(config)#vlan 2
kmr-gorka-sw1(config-vlan)#name LAN
kmr-gorka-sw1(config)#int fa0/1
kmr-gorka-sw1(config-if)#description syn_generalnogo
Транк в сторону маршрутизатора, где 5-ым вланом будут тегироваться кадры внешнего трафика, а 2-м —
локального.
kmr-gorka-sw1(config)#int fa0/23
kmr-gorka-sw1(config-if)#description kmr-gorka-gw1
Настройка маршрутизатора:
Router(config)#hostname kmr-gorka-gw1
kmr-gorka-gw1(config)#int fa0/0.5
kmr-gorka-gw1(config-subif)#description Moscow
kmr-gorka-gw1(config-subif)#encapsulation dot1Q 5
kmr-gorka-gw1(config)#int fa0/0
kmr-gorka-gw1(config-if)#no sh
kmr-gorka-gw1(config)#int fa0/0.2
kmr-gorka-gw1(config-subif)#description LAN
kmr-gorka-gw1(config-subif)#encapsulation dot1Q 2
Полагаем, что маршрутизацию здесь между Москвой и Кемерово вы теперь сможете настроить самостоятельно.
Дополнительно
В случае, если с маршрутизацией не всё в порядке для траблшутинга вам понадобятся две команды:
traceroute и show ip route.
У первой бывает полезным, как вы видели, задать адрес источника. А последнюю можно применять с
параметрами, например:
* 172.16.2.2
Несмотря на то, что в таблице маршрутизации нет отдельной записи для подсети 172.16.17.0, маршрутизатор
покажет вам, какой следующий хоп.
Материалы выпуска
Новый IP-план, планы коммутации по каждой точке и регламент
№VLAN Имя VLAN Примечание
1 default не используется
2 Management Для управления устройствами
3 Servers Для серверной фермы
4 SPB Линк в СПБ
5 KMR Линк в Кемерово
6-100 Зарезервировано
101 PTO Для пользователей ПТО
102 FEO Для пользователей ФЭО
103 Accounting Для пользователей Бухгалтерии
104 Other Для других пользователей
Файл РТ с лабораторной
Конфигурация устройств см. "KAK - LAN Habr Сети для самых маленьких - конфигурация устройств.doc"
Приносим извинения за гигантские простыни, видео тоже с каждым разом становится всё длиннее и
невыносимее. Постараемся в следующий раз быть более компактными.
В прошлом выпуске мы остановились на статической маршрутизации. Теперь надо сделать шаг в сторону и
обсудить вопрос стабильности нашей сети.
Дело в том, что однажды, когда вы — единственный сетевой админ фирмы “Лифт ми Ап” — отпросились на
полдня раньше, вдруг упала связь с серверами, и директора не получили несколько важных писем. После
короткой, но ощутимой взбучки вы идёте разбираться, в чём дело, а оказалось, по чьей-то неосторожности
выпал из разъёма кабель, ведущий к коммутатору в серверной. Небольшая проблема, которую вы могли
исправить за две минуты, и даже вообще избежать, существенно сказалась на вашем доходе в этом месяце и
возможностях роста.
Оборудование, работающее на втором уровне модели OSI (коммутатор), должно выполнять 3 функции:
запоминание адресов, перенаправление (коммутация) пакетов, защита от петель в сети. Разберем по пунктам
каждую функцию.
Запоминание адресов и перенаправление пакетов: Как мы уже говорили ранее, у каждого свича есть таблица
сопоставления MAC-адресов и портов (aka CAM-table — Content Addressable Memory Table). Когда устройство,
подключенное к свичу, посылает кадр в сеть, свич смотрит MAC-адрес отправителя и порт, откуда получен кадр,
и добавляет эту информацию в свою таблицу. Далее он должен передать кадр получателю, адрес которого
указан в кадре. По идее, информацию о порте, куда нужно отправить кадр, он берёт из этой же CAM-таблицы.
Но, предположим, что свич только что включили (таблица пуста), и он понятия не имеет, в какой из его портов
подключен получатель. В этом случае он отправляет полученный кадр во все свои порты, кроме того, откуда он
был принят. Все конечные устройства, получив этот кадр, смотрят MAC-адрес получателя, и, если он адресован
не им, отбрасывают его. Устройство-получатель отвечает отправителю, а в поле отправителя ставит свой адрес, и
вот свич уже знает, что такой-то адрес находится на таком-то порту (вносит запись в таблицу), и в следующий раз
уже будет переправлять кадры, адресованные этому устройству, только в этот порт. Чтобы посмотреть
содержимое CAM-таблицы, используется команда show mac address-table. Однажды попав в таблицу,
информация не остаётся там пожизненно, содержимое постоянно обновляется и если к определенному mac-
адресу не обращались 300 секунд (по умолчанию), запись о нем удаляется.
Тут всё должно быть понятно. Но зачем защита от петель? И что это вообще такое?
Широковещательный шторм
Часто, для обеспечения стабильности работы сети в случае проблем со связью между свичами (выход порта из
строя, обрыв провода), используют избыточные линки (redundant links) — дополнительные соединения. Идея
простая — если между свичами по какой-то причине не работает один линк, используем запасной. Вроде все
правильно, но представим себе такую ситуацию: два свича соединены двумя проводами (пусть будет, что у них
соединены fa0/1 и fa0/24).
Одной из их подопечных — рабочих станций (например, ПК1) вдруг приспичило послать широковещательный
кадр (например, ARP-запрос). Раз широковещательный, шлем во все порты, кроме того, с которого получили.
Второй свич получает кадр в два порта, видит, что он широковещательный, и тоже шлет во все порты, но уже,
получается, и обратно в те, с которых получил (кадр из fa0/24 шлет в fa0/1, и наоборот).
Первый свич поступает точно также, и в итоге мы получаем широковещательный шторм (broadcast storm),
который намертво блокирует работу сети, ведь свичи теперь только и занимаются тем, что шлют друг другу один
и тот же кадр.
Как можно избежать этого? Ведь мы, с одной стороны, не хотим штормов в сети, а с другой, хотим повысить ее
отказоустойчивость с помощью избыточных соединений? Тут на помощь нам приходит STP (Spanning Tree
Protocol)
STP
Основная задача STP — предотвратить появление петель на втором уровне. Как это сделать? Да просто отрубить
все избыточные линки, пока они нам не понадобятся. Тут уже сразу возникает много вопросов: какой линк из
двух (или трех-четырех) отрубить? Как определить, что основной линк упал, и пора включать запасной? Как
понять, что в сети образовалась петля? Чтобы ответить на эти вопросы, нужно разобраться, как работает STP.
STP использует алгоритм STA (Spanning Tree Algorithm), результатом работы которого является граф в виде дерева
(связный и без простых циклов)
Для обмена информацией между собой свичи используют специальные пакеты, так называемые BPDU (Bridge
Protocol Data Units). BPDU бывают двух видов: конфигурационные (Configuration BPDU) и панические “ААА,
топология поменялась!” TCN (Topology Change Notification BPDU). Первые регулярно рассылаются корневым
свичом (и ретранслируются остальными) и используются для построения топологии, вторые, как понятно из
названия, отсылаются в случае изменения топологии сети (проще говоря, подключении\отключении свича).
Конфигурационные BPDU содержат несколько полей, остановимся на самых важных:
• идентификатор отправителя (Bridge ID)
• идентификатор корневого свича (Root Bridge ID)
• идентификатор порта, из которого отправлен данный пакет (Port ID)
• стоимость маршрута до корневого свича (Root Path Cost)
Что все это такое и зачем оно нужно, объясню чуть ниже. Так как устройства не знают и не хотят знать своих
соседей, никаких отношений (смежности/соседства) они друг с другом не устанавливают. Они шлют BPDU из всех
работающих портов на мультикастовый ethernet-адрес 01-80-c2-00-00-00 (по умолчанию каждые 2 секунды),
который прослушивают все свичи с включенным STP.
Сначала выбирается так называемый корневой мост/свич (root bridge). Это устройство, которое STP считает
точкой отсчета, центром сети; все дерево STP сходится к нему. Выбор базируется на таком понятии, как
идентификатор свича (Bridge ID). Bridge ID это число длиной 8 байт, которое состоит из Bridge Priority (приоритет,
от 0 до 65535, по умолчанию 32768+номер vlan или инстанс MSTP, в зависимости от реализации протокола), и
MAC-адреса устройства. В начале выборов каждый коммутатор считает себя корневым, о чем и заявляет всем
остальным с помощью BPDU, в котором представляет свой идентификатор как ID корневого свича. При этом, если
он получает BPDU с меньшим Bridge ID, он перестает хвастаться своим и покорно начинает анонсировать
полученный Bridge ID в качестве корневого. В итоге, корневым оказывается тот свич, чей Bridge ID меньше всех.
Такой подход таит в себе довольно серьезную проблему. Дело в том, что, при равных значениях Priority (а они
равные, если не менять ничего) корневым выбирается самый старый свич, так как мак адреса прописываются на
производстве последовательно, соответственно, чем мак меньше, тем устройство старше (естественно, если у нас
все оборудование одного вендора). Понятное дело, это ведет к падению производительности сети, так как
старое устройство, как правило, имеет худшие характеристики. Подобное поведение протокола следует
пресекать, выставляя значение приоритета на желаемом корневом свиче вручную, об этом в практической части.
Роли портов
После того, как коммутаторы померились айдями и выбрали root bridge, каждый из остальных свичей должен
найти один, и только один порт, который будет вести к корневому свичу. Такой порт называется корневым
портом (Root port). Чтобы понять, какой порт лучше использовать, каждый некорневой свич определяет
стоимость маршрута от каждого своего порта до корневого свича. Эта стоимость определяется суммой
стоимостей всех линков, которые нужно пройти кадру, чтобы дойти до корневого свича. В свою очередь,
стоимость линка определяется просто- по его скорости (чем выше скорость, тем меньше стоимость). Процесс
определения стоимости маршрута связан с полем BPDU “Root Path Cost” и происходит так:
1. Корневой свич посылает BPDU с полем Root Path Cost, равным нулю
2. Ближайший свич смотрит на скорость своего порта, куда BPDU пришел, и добавляет стоимость согласно
таблице
Скорость порта Стоимость STP (802.1d)
10 Mbps 100
100 Mbps 19
1 Gbps 4
10 Gbps 2
3. Далее этот второй свич посылает этот BPDU нижестоящим коммутаторам, но уже с новым значением Root
Path Cost, и далее по цепочке вниз
Если имеют место одинаковые стоимости (как в нашем примере с двумя свичами и двумя проводами между
ними — у каждого пути будет стоимость 19) — корневым выбирается меньший порт.
Далее выбираются назначенные (Designated) порты. Из каждого конкретного сегмента сети должен существовать
только один путь по направлению к корневому свичу, иначе это петля. В данном случае имеем в виду
физический сегмент, в современных сетях без хабов это, грубо говоря, просто провод. Назначенным портом
выбирается тот, который имеет лучшую стоимость в данном сегменте. У корневого свича все порты —
назначенные.
И вот уже после того, как выбраны корневые и назначенные порты, оставшиеся блокируются, таким образом
разрывая петлю.
*На картинке маршрутизаторы выступают в качестве коммутаторов. В реальной жизни это можно сделать с
помощью дополнительной свитчёвой платы.
Состояния портов
Чуть раньше мы упомянули состояние блокировки порта, теперь поговорим о том, что это значит, и о других
возможных состояниях порта в STP. Итак, в обычном (802.1D) STP существует 5 различных состояний:
• блокировка (blocking): блокированный порт не шлет ничего. Это состояние предназначено, как
говорилось выше, для предотвращения петель в сети. Блокированный порт, тем не менее, слушает BPDU (чтобы
быть в курсе событий, это позволяет ему, когда надо, разблокироваться и начать работать)
• прослушивание (listening): порт слушает и начинает сам отправлять BPDU, кадры с данными не
отправляет.
• обучение (learning): порт слушает и отправляет BPDU, а также вносит изменения в CAM- таблицу, но
данные не перенаправляет.
• перенаправление\пересылка (forwarding): этот может все: и посылает\принимает BPDU, и с данными
оперирует, и участвует в поддержании таблицы mac-адресов. То есть это обычное состояние рабочего порта.
• отключен (disabled): состояние administratively down, отключен командой shutdown. Понятное дело,
ничего делать не может вообще, пока вручную не включат.
Порядок перечисления состояний не случаен: при включении (а также при втыкании нового провода), все порты
на устройстве с STP проходят вышеприведенные состояния именно в таком порядке (за исключением disabled-
портов). Возникает закономерный вопрос: а зачем такие сложности? А просто STP осторожничает. Ведь на
другом конце провода, который только что воткнули в порт, может быть свич, а это потенциальная петля. Вот
поэтому порт сначала 15 секунд (по умолчанию) пребывает в состоянии прослушивания — он смотрит BPDU,
попадающие в него, выясняет свое положение в сети — как бы чего ни вышло, потом переходит к обучению еще
на 15 секунд — пытается выяснить, какие mac-адреса “в ходу” на линке, и потом, убедившись, что ничего он не
поломает, начинает уже свою работу. Итого, мы имеем целых 30 секунд простоя, прежде чем подключенное
устройство сможет обмениваться информацией со своими соседями. Современные компы грузятся быстрее, чем
за 30 секунд. Вот комп загрузился, уже рвется в сеть, истерит на тему “DHCP-сервер, сволочь, ты будешь
айпишник выдавать, или нет?”, и, не получив искомого, обижается и уходит в себя, извлекая из своих недр
айпишник автонастройки. Естественно, после таких экзерсисов, в сети его слушать никто не будет, ибо “не
местный” со своим 169.254.x.x. Понятно, что все это не дело, но как этого избежать?
Portfast
Для таких случаев используется особый режим порта — portfast. При подключении устройства к такому порту, он,
минуя промежуточные стадии, сразу переходит к forwarding-состоянию. Само собой, portfast следует включать
только на интерфейсах, ведущих к конечным устройствам (рабочим станциям, серверам, телефонам и т.д.), но не
к другим свичам.
Есть очень удобная команда режима конфигурации интерфейса для включения нужных фич на порту, в который
будут включаться конечные устройства: switchport host. Эта команда разом включает PortFast, переводит порт в
режим access (аналогично switchport mode access), и отключает протокол PAgP (об этом протоколе подробнее в
разделе агрегация каналов).
Виды STP
STP довольно старый протокол, он создавался для работы в одном LAN-сегменте. А что делать, если мы хотим
внедрить его в нашей сети, которая имеет несколько VLANов?
Стандарт 802.1Q, о котором мы упоминали в статье о коммутации, определяет, каким образом вланы
передаются внутри транка. Кроме того, он определяет один процесс STP для всех вланов. BPDU по транкам
передаются нетегированными (в native VLAN). Этот вариант STP известен как CST (Common Spanning Tree).
Наличие только одного процесса для всех вланов очень облегчает работу по настройке и разгружает процессор
свича, но, с другой стороны, CST имеет недостатки: избыточные линки между свичами блокируются во всех
вланах, что не всегда приемлемо и не дает возможности использовать их для балансировки нагрузки.
Cisco имеет свой взгляд на STP, и свою проприетарную реализацию протокола — PVST (Per-VLAN Spanning Tree) —
которая предназначена для работы в сети с несколькими VLAN. В PVST для каждого влана существует свой
процесс STP, что позволяет независимую и гибкую настройку под потребности каждого влана, но самое главное,
позволяет использовать балансировку нагрузки за счет того, что конкретный физический линк может быть
заблокирован в одном влане, но работать в другом. Минусом этой реализации является, конечно,
проприетарность: для функционирования PVST требуется проприетарный же ISL транк между свичами.
Также существует вторая версия этой реализации — PVST+, которая позволяет наладить связь между свичами с
CST и PVST, и работает как с ISL- транком, так и с 802.1q. PVST+ это протокол по умолчанию на коммутаторах Cisco.
RSTP
Все, о чем мы говорили ранее в этой статье, относится к первой реализация протокола STP, которая была
разработана в 1985 году Радией Перлман (ее стихотворение использовано в качестве эпиграфа). В 1990 году эта
реализации была включена в стандарт IEEE 802.1D. Тогда время текло медленнее, и перестройка топологии STP,
занимающая 30-50 секунд (!!!), всех устраивала. Но времена меняются, и через десять лет, в 2001 году, IEEE
представляет новый стандарт RSTP (он же 802.1w, он же Rapid Spanning Tree Protocol, он же Быстрый STP). Чтобы
структурировать предыдущий материал и посмотреть различия между обычным STP (802.1d) и RSTP (802.1w),
соберем таблицу с основными фактами:
STP (802.1d) RSTP (802.1w)
Все свичи шлют BPDU в
В уже сложившейся топологии только корневой свич шлет BPDU, остальные
соответствии с hello-таймером (2
ретранслируют
секунды по умолчанию)
Состояния портов
— блокировка (blocking) — отбрасывание (discarding),
— прослушивание (listening) заменяет disabled, blocking и
— обучение (learning) listening
— перенаправление\пересылка (forwarding) — learning
— отключен (disabled) — forwarding
Роли портов
— корневой (root), участвует в
пересылке данных
— назначенный (designated), тоже
— корневой (root), участвует в пересылке данных, ведет к корневому свичу
работает
— назначенный (designated), тоже работает, ведет от корневого свича
— дополнительный (alternate), не
— неназначенный (non-designated), не участвует в пересылке данных
участвует в пересылке данных
— резервный (backup), тоже не
участвует
Механизмы работы
Использует таймеры: Использует процесс proposal and
Hello (2 секунды) agreement (предложение и
Max Age (20 секунд) соглашение)
Forward delay timer (15 секунд)
Свич, обнаруживший изменение топологии, извещает корневой свич, Обнаружение изменений в
который, в свою очередь, требует от всех остальных очистить их записи о топологии влечет немедленную
текущей топологии в течение forward delay timer очистку записей
Начинает действовать, если не
Если не-корневой свич не получает hello- пакеты от корневого в течение Max
получает BPDU в течение 3 hello-
Age, он начинает новые выборы
интервалов
Последовательное прохождение порта через состояния Blocking (20 сек) — Быстрый переход к Forwarding для
Listening (15 сек) — Learning (15 сек) — Forwarding p2p и Edge-портов
Как мы видим, в RSTP остались такие роли портов, как корневой и назначенный, а роль заблокированного
разделили на две новых роли: Alternate и Backup. Alternate — это резервный корневой порт, а backup —
резервный назначенный порт. Как раз в этой концепции резервных портов и кроется одна из причин быстрого
переключения в случае отказа. Это меняет поведение системы в целом: вместо реактивной (которая начинает
искать решение проблемы только после того, как она случилась) система становится проактивной, заранее
просчитывающей “пути отхода” еще до появления проблемы. Смысл простой: для того, чтобы в случае отказа
основного переключится на резервный линк, RSTP не нужно заново просчитывать топологию, он просто
переключится на запасной, заранее просчитанный.
Ранее, для того, чтобы убедиться, что порт может участвовать в передаче данных, требовались таймеры, т.е. свич
пассивно ждал в течение означенного времени, слушая BPDU. Ключевой фичей RSTP стало введение концепции
типов портов, основанных на режиме работы линка- full duplex или half duplex (типы портов p2p или shared,
соответственно), а также понятия пограничный порт (тип edge p2p), для конечных устройств. Пограничные порты
назначаются, как и раньше, командой spanning-tree portfast, и с ними все понятно- при включении провода сразу
переходим к forwarding-состоянию и работаем. Shared-порты работают по старой схеме с прохождением через
состояния BLK — LIS — LRN — FWD. А вот на p2p-портах RSTP использует процесс предложения и соглашения
(proposal and agreement). Не вдаваясь в подробности, его можно описать так: свич справедливо считает, что если
линк работает в режиме полного дуплекса, и он не обозначен, как пограничный, значит, на нем только два
устройства- он и другой свич. Вместо того, чтобы ждать входящих BPDU, он сам пытается связаться со свичом на
том конце провода с помощью специальных proposal BPDU, в которых, конечно, есть информация о стоимости
маршрута к корневому свичу. Второй свич сравнивает полученную информацию со своей текущей, и принимает
решение, о чем извещает первый свич посредством agreement BPDU. Так как весь этот процесс теперь не
привязан к таймерам, происходит он очень быстро- только подключили новый свич- и он практически сразу
вписался в общую топологию и приступил к работе (можете сами оценить скорость переключения в сравнении с
обычным STP на видео). В Cisco-мире RSTP называется PVRST (Per-Vlan Rapid Spanning Tree).
MSTP
Чуть выше, мы упоминали о PVST, в котором для каждого влана существует свой процесс STP. Вланы это
довольно удобный инструмент для многих целей, и поэтому, их может быть достаточно много даже в некрупной
организации. И в случае PVST, для каждого будет рассчитываться своя топология, тратиться процессорное время
и память свичей. А нужно ли нам рассчитывать STP для всех 500 вланов, когда единственное место, где он нам
нужен- это резервный линк между двумя свичами? Тут нас выручает MSTP. В нем каждый влан не обязан иметь
собственный процесс STP, их можно объединять. Вот у нас есть, например, 500 вланов, и мы хотим
балансировать нагрузку так, чтобы половина из них работала по одному линку (второй при этом блокируется и
стоит в резерве), а вторая- по другому. Это можно сделать с помощью обычного STP, назначив один корневой
свич в диапазоне вланов 1-250, а другой- в диапазоне 250-500. Но процессы будут работать для каждого из
пятисот вланов по отдельности (хотя действовать будут совершенно одинаково для каждой половины). Логично,
что тут хватит и двух процессов. MSTP позволяет создавать столько процесов STP, сколько у нас логических
топологий (в данном примере- 2), и распределять по ним вланы. Думаем, нет особого смысла углубляться в
теорию и практику MSTP в рамках этой статьи (ибо теории там ого-го), интересующиеся могут пройти по ссылке.
Агрегация каналов
Но какой бы вариант STP мы не использовали, у нас все равно существует так или иначе неработающий линк. А
возможно ли задействовать параллельные линки по полной и при этом избежать петель? Да, отвечаем мы
вместе с циской, начиная рассказ о EtherChannel.
Иначе это называется link aggregation, link bundling, NIC teaming, port trunkinkg
Технологии агрегации (объединения) каналов выполняют 2 функции: с одной стороны, это объединение
пропускной способности нескольких физических линков, а с другой — обеспечение отказоустойчивости
соединения (в случае падения одного линка нагрузка переносится на оставшиеся). Объединение линков можно
выполнить как вручную (статическое агрегирование), так и с помощью специальных протоколов: LACP (Link
Aggregation Control Protocol) и PAgP (Port Aggregation Protocol). LACP, опеределяемый стандартом IEEE 802.3ad,
является открытым стандартом, то есть от вендора оборудования не зависит. Соответственно, PAgP —
проприетарная цисковская разработка.
В один такой канал можно объединить до восьми портов. Алгоритм балансировки нагрузки основан на таких
параметрах, как IP/MAC-адреса получателей и отправителей и порты. Поэтому в случае возникновения вопроса:
“Хей, а чего так плохо балансируется?” в первую очередь смотрите на алгоритм балансировки.
Port security
Теперь расскажем вкратце, как обеспечить безопасность сети на втором уровне OSI. В этой части статьи теория и
практическая конфигурация совмещены. Увы, Packet Tracer не умеет ничего из упомянутых в этом разделе
команд, поэтому все без иллюстраций и проверок.
Для начала, следует упомянуть команду конфигурации интерфейса switchport port-security, включающую защиту
на определенном порту свича. Затем, с помощью switchport port-security maximum 1 мы можем ограничить
количество mac-адресов, связанных с данным портом (т.е., в нашем примере, на данном порту может работать
только один mac-адрес). Теперь указываем, какой именно адрес разрешен: его можно задать вручную switchport
port-security mac-address адрес, или использовать волшебную команду switchport port-security mac-address
sticky, закрепляющую за портом тот адрес, который в данный момент работает на порту. Далее, задаем
поведение в случае нарушения правила switchport port-security violation {shutdown | restrict | protect}: порт
либо отключается, и потом его нужно поднимать вручную (shutdown), либо отбрасывает пакеты с
незарегистрированного мака и пишет об этом в консоль (restrict), либо просто отбрасывает пакеты (protect).
Помимо очевидной цели — ограничение числа устройств за портом — у этой команды есть другая, возможно,
более важная: предотвращать атаки. Одна из возможных — истощение CAM-таблицы. С компьютера злодея
рассылается огромное число кадров, возможно, широковещательных, с различными значениями в поле MAC-
адрес отправителя. Первый же коммутатор на пути начинает их запоминать. Одну тысячу он запомнит, две, но
память-то оперативная не резиновая, и среднее ограничение в 16000 записей будет довольно быстро достигнуто.
При этом дальнейшее поведение коммутатора может быть различным. И самое опасное из них с точки зрения
безопасности: коммутатор может начать все кадры, приходящие на него, рассылать, как широковещательные,
потому что MAC-адрес получателя не известен (или уже забыт), а запомнить его уже просто некуда. В этом случае
сетевая карта злодея будет получать все кадры, летающие в вашей сети.
DHCP Snooping
Другая возможная атака нацелена на DHCP сервер. Как мы знаем, DHCP обеспечивает клиентские устройства
всей нужной информацией для работы в сети: ip-адресом, маской подсети, адресом шюза по умолчанию, DNS-
сервера и прочим. Атакующий может поднять собственный DHCP, который в ответ на запрос клиентского
устройства будет отдавать в качестве шлюза по умолчанию (а также, например, DNS-сервера) адрес
подконтрольной атакующему машины. Соответственно, весь трафик, направленный за пределы подсети
обманутыми устройствами, будет доступен для изучения атакующему — типичная man-in-the-middle атака. Либо
такой вариант: подлый мошенник генерируют кучу DHCP-запросов с поддельными MAC-адресами и DHCP-сервер
на каждый такой запрос выдаёт IP-адрес до тех пор, пока не истощится пул.
Для того, чтобы защититься от подобного вида атак, используется фича под названием DHCP snooping. Идея
совсем простая: указать свичу, на каком порту подключен настоящий DHCP-сервер, и разрешить DHCP-ответы
только с этого порта, запретив для остальных. Включаем глобально командой ip dhcp snooping, потом говорим, в
каких вланах должно работать ip dhcp snooping vlan номер(а). Затем на конкретном порту говорим, что он может
пренаправлять DHCP-ответы (такой порт называется доверенным): ip dhcp snooping trust.
IP Source Guard
После включения DHCP Snooping’а, он начинает вести у себя базу соответствия MAC и IP-адресов устройств,
которую обновляет и пополняет за счет прослушивания DHCP запросов и ответов. Эта база позволяет нам
противостоять еще одному виду атак — подмене IP-адреса (IP Spoofing). При включенном IP Source Guard,
каждый приходящий пакет может проверяться на:
• соответствие IP-адреса источника адресу, полученному из базы DHCP Snooping (иными словами,
айпишник закрепляется за портом свича)
• соответствие MAC-адреса источника адресу, полученному из базы DHCP Snooping
Включается IP Source Guard командой ip verify source на нужном интерфейсе. В таком виде проверяется только
привязка IP-адреса, чтобы добавить проверку MAC, используем ip verify source port-security. Само собой, для
работы IP Source Guard требуется включенный DHCP snooping, а для контроля MAC-адресов должен быть
включен port security.
Dynamic ARP Inspection
Как мы уже знаем, для того, чтобы узнать MAC-адрес устройства по его IP-адресу, используется проткол ARP:
посылается широковещательный запрос вида “у кого ip-адрес 172.16.1.15, ответьте 172.16.1.1”, устройство с
айпишником 172.16.1.15 отвечает. Подобная схема уязвима для атаки, называемой ARP-poisoning aka ARP-
spoofing: вместо настоящего хоста с адресом 172.16.1.15 отвечает хост злоумышленника, заставляя таким
образом трафик, предназначенный для 172.16.1.15 следовать через него. Для предотвращения такого типа атак
используется фича под названием Dynamic ARP Inspection. Схема работы похожа на схему DHCP-Snooping’а:
порты делятся на доверенные и недоверенные, на недоверенных каждый ARP-ответ подвергаются анализу:
сверяется информация, содержащаяся в этом пакете, с той, которой свич доверяет (либо статически заданные
соответствия MAC-IP, либо информация из базы DHCP Snooping). Если не сходится- пакет отбрасывается и
генерируется сообщение в syslog. Включаем в нужном влане (вланах): ip arp inspection vlan номер(а). По
умолчанию все порты недоверенные, для доверенных портов используем ip arp inspection trust.
Практика
Наверное, большинство ошибок в Packet Tracer допущено в части кода, отвечающего за симуляцию STP, будте
готовы. В случае сомнения сохранитесь, закройте PT и откройте заново
Итак, переходим к практике. Для начала внесем некоторые изменения в топологию — добавим избыточные
линки. Учитывая сказанное в самом начале, вполне логично было бы сделать это в московском офисе в районе
серверов — там у нас свич msk-arbat-asw2 доступен только через asw1, что не есть гуд. Мы отбираем (пока,
позже возместим эту потерю) гигабитный линк, который идет от msk-arbat-dsw1 к msk-arbat-asw3, и подключаем
через него asw2. Asw3 пока подключаем в порт Fa0/2 dsw1. Перенастраиваем транки:
msk-arbat-dsw1(config)#interface gi1/2
msk-arbat-dsw1(config-if)#description msk-arbat-asw2
msk-arbat-dsw1(config-if)#int fa0/2
msk-arbat-dsw1(config-if)#description msk-arbat-asw3
msk-arbat-asw2(config)#int gi1/2
msk-arbat-asw2(config-if)#description msk-arbat-dsw1
msk-arbat-asw2(config-if)#no shutdown
Теперь посмотрим, как в данный момент у нас самонастроился STP. Нас интересует только VLAN0003, где у нас,
судя по схеме, петля.
msk-arbat-dsw1>en
Итак, мы видим, что Gi1/1 корневой порт, это дает некоторую вероятность того, что на другом конце линка
корневой свич. Смотрим по схеме, куда ведет линк: ага, некий msk-arbat-asw1.
И что же мы видим?
VLAN0003
Address 0007.ECC4.09E2
А теперь посмотрим на схему. Ранее, мы увидели в состоянии портов, что dsw1 блокирует порт Gi1/2, разрывая
таким образом петлю. Но является ли это оптимальным решением? Нет, конечно. Сейчас наша новая сеть
работает точь-в-точь как старая- трафик от asw2 идет только через asw1. Выбор корневого маршрутизатора
никогда не нужно оставлять на совесть глупого STP. Исходя из схемы, наиболее оптимальным будет выбор в
качестве корневого свича dsw1- таким образом, STP заблокирует линк между asw1 и asw2. Теперь это все надо
объяснить недалекому протоколу. А для него главное что? Bridge ID. И он неслучайно складывается из двух
чисел. Приоритет- это как раз то слагаемое, которое отдано на откуп сетевому инженеру, чтобы он мог повлиять
на результат выбора корневого свича. Итак, наша задача сводится к тому, чтобы уменьшить (меньше-лучше,
думает STP) приоритет нужного свича, чтобы он стал Root Bridge. Есть два пути:
msk-arbat-dsw1>enable
msk-arbat-dsw1#configure terminal
Теперь он стал корневым для влана 3, так как имеет меньший Bridge ID:
VLAN0003
Address 000B.BE2E.392C
Проверяем:
VLAN0003
Address 000B.BE2E.392C
Мы видим, что железка поставила какой-то странный приоритет. Откуда взялась эта круглая цифра, спросите вы?
А все просто- STP смотрит минимальный приоритет (т.е. тот, который у корневого свича), и уменьшает его на два
шага инкремента (который составляет 4096, т.е. в итоге 8192). Почему на два? А чтобы была возможность на
другом свиче дать команду spanning-tree vlan n root secondary (назначает приоритет=приоритет корневого-4096),
что позволит нам быть уверенными, что, если с текущим корневым свичом что-то произойдет, его функции
перейдут к этому, “запасному”. Вероятно, вы уже видите на схеме, как лампочка на линке между asw2 и asw1
пожелтела? Это STP разорвал петлю. Причем именно в том месте, в котором мы хотели. Sweet! Зайдем
проверим: лампочка — это лампочка, а конфиг — это факт.
VLAN0003
Address 000B.BE2E.392C
Cost 4
Port 26(GigabitEthernet1/2)
Address 000A.F385.D799
Aging Time 20
Теперь полюбуемся, как работает STP: заходим в командную строку на ноутбуке PTO1 и начинаем бесконечно
пинговать наш почтовый сервер (172.16.0.4). Пинг сейчас идет по маршруту ноутбук-asw3-dsw1-gw1-dsw1(ну тут
понятно, зачем он крюк делает — они из разных вланов)-asw2-сервер. А теперь поработаем Годзиллой из
SimСity: нарушим связь между dsw1 и asw2, вырвав провод из порта (замечаем время, нужное для пересчета
дерева).
Пинги пропадают, STP берется за дело, и за каких-то 30 секунд коннект восстанавливается. Годзиллу прогнали,
пожары потушили, связь починили, втыкаем провод обратно. Пинги опять пропадают на 30 секунд! Мда-а-а, как-
то не очень быстро, особенно если представить, что это происходит, например, в процессинговом центре какого-
нибудь банка.
Но у нас есть ответ медленному PVST+! И ответ этот — Быстрый PVST+ (так и называется, это не шутка: Rapid-
PVST). Посмотрим, что он нам дает. Меняем тип STP на всех свичах в москве командой конфигурационного
режима: spanning-tree mode rapid-pvst
Снова запускаем пинг, вызываем Годзиллу… Эй, где пропавшие пинги? Их нет, это же Rapid-PVST. Как вы,
наверное, помните из теоретической части, эта реализация STP, так сказать, “подстилает соломку” на случай
падения основного линка, и переключается на дополнительный (alternate) порт очень быстро, что мы и
наблюдали. Ладно, втыкаем провод обратно. Один потерянный пинг. Неплохо по сравнению с 6-8, да?
EtherChannel
Помните, мы отобрали у офисных работников их гигабитный линк и отдали его в пользу серверов? Сейчас они,
бедняжки, сидят, на каких-то ста мегабитах, прошлый век! Попробуем расширить канал, и на помощь призовем
EtherChannel. В данный момент у нас соединение идет от fa0/2 dsw1 на Gi1/1 asw3, отключаем провод. Смотрим,
какие порты можем использовать на asw3: ага, fa0/20-24 свободны, кажется. Вот их и возьмем. Со стороны dsw1
пусть будут fa0/19-23. Соединяем порты для EtherChannel между собой. На asw3 у нас на интерфейсах что-то
настроено, обычно в таких случаях используется команда конфигурационного режима default interface range
fa0/20-24, сбрасывающая настройки порта (или портов, как в нашем случае) в дефолтные. Packet tracer, увы, не
знает такой хорошей команды, поэтому в ручном режиме убираем каждую настройку, и тушим порты (лучше это
сделать, во избежание проблем)
msk-arbat-asw3(config-if-range)#no description
msk-arbat-asw3(config-if-range)#shutdown
msk-arbat-asw3(config-if-range)#channel-group 1 mode on
то же самое на dsw1:
msk-arbat-dsw1(config-if-range)#channel-group 1 mode on
поднимаем интерфейсы asw3, и вуаля: вот он, наш EtherChannel, раскинулся аж на 5 физических линков. В
конфиге он будет отражен как interface Port-channel 1. Настраиваем транк (повторить для dsw1):
msk-arbat-asw3(config)#int port-channel 1
Как и с STP, есть некая трудность при работе с etherchannel в Packet Tracer’e. Настроить-то мы, в принципе,
можем по вышеописанному сценарию, но вот проверка работоспособности под большим вопросом: после
отключения одного из портов в группе, трафик перетекает на следующий, но как только вы вырубаете второй
порт — связь теряется и не восстанавливается даже после включения портов.
Отчасти в силу только что озвученной причины, отчасти из-за ограниченности ресурсов мы не сможем раскрыть в
полной мере эти вопросы и посему оставляем бОльшую часть на самоизучение.
Материалы выпуска
Новый план коммутации
Файл PT с лабораторной.
Конфигурация устройств
STP или STP
Безопасность канального уровня
Агрегация каналов
Каково предназначение списков доступа? Казалось бы, совершенно очевидный ответ — для ограничения
доступа: кому-то что-то запретить, например. Вообще — это верно, но понимать нужно в более широком смысле:
речь не только о безопасности. То есть, изначально, вероятно, так оно и было, отсюда permit и deny при
настройке. Но на самом деле ACL — это универсальный и мощный механизм фильтрации. С их помощью можно
определить на кого навешивать определённые политики, а на кого нет, кто будет участвовать в неких процессах,
а кто нет, кого ограничиваем в скорость до 56k, а кого до 56M.
Чтобы было чуть-чуть понятнее, приведём простой пример. Опираясь на списки доступа, работает Policy-Based
Routing (PBR). Можно сделать здесь так, чтобы пакеты приходящие из сети 192.168.1.0/24 отправлялись на next-
hop 10.0.1.1, а из сети 192.168.2.0/24 на 10.0.2.1 (заметим, что обычная маршрутизация опирается на адрес
назначения пакета и автоматически все пакеты отправляются на один next-hop):
В конце статьи пример настройки PBR и ограничения скорости на основе ACL.
Виды ACL
Ладно, забудем на время эту лирику.
Вообще говоря, списки доступа бывают разными:
• Стандартные
• Расширенные
• Динамические
• Рефлексивные
• Повременные
Мы своё внимание остановим сегодня на первых двух, а более подробно обо всех вы можете прочитать у циски.
Входящий и исходящий трафик
Для почину давайте-ка разберёмся с одной вещью. Что понимать под входящим и исходящим трафиком? Это
нам в будущем понадобится. Входящий трафик — этот тот, который приходит на интерфейс извне.
Стандартный список доступа проверяет только адрес отправителя. Расширенный- адрес отправителя, адрес
получателя, а также порт. Стандартные ACL рекомендуется ставить как можно ближе к получателю (чтобы не
порезать больше, чем нужно), а расширенные- ближе к отправителю (чтобы как можно раньше дропнуть
нежелательный трафик).
Практика
Давайте сразу к практике. Что бы нам такого наограничивать в нашей маленькой сети “Лифт ми Ап”?
1. WEB-сервер. Разрешить доступ всем по порту TCP 80 (протокол HTTP). Для того устройства, с которого
будет производиться управление (у нас же есть админ) нужно открыть telnet и ftp, но ему мы дадим полный
доступ. Всем остальным отбой
2. Файловый сервер. На него у нас должны попадать резиденты Лифт ми Ап по портам для общих папок, а
все остальные по FTP.
3. Почтовый сервер. Тут у нас запущены SMTP и POP3, то есть порты TCP 25 и 110. Так же для админа
открываем доступ на управление. Других блокируем
4. Для будущего DNS-сервера нужно открыть порт UDP 53
5. В сеть серверов разрешить ICMP-сообщения
6. Поскольку сеть Other у нас для всех беспартийных, кто не вошёл в ФЭО, ПТО и Бухгалтерию, то мы их всех
ограничим, а некоторым только дадим доступ (в числе них мы и админ)
7. В сеть управления нужно пускать опять же только админа, ну и конечно себя любимого
8. Не будем строить препоны общению между собой сотрудников отделов
1) Доступ на WEB-сервер
Тут у нас работает политика запрещено всё, что не разрешено. Поэтому нам сейчас надо кое-что открыть, а всё
остальное закрыть.
Поскольку мы защищаем сеть серверов, то и лист будем вешать на интерфейс, идущий в сторону них то есть, на
FE0/0.3 Вопрос только на in или на out нам нужно это делать? Если мы не хотим пускать пакеты в сторону
серверов, которые уже оказались на маршрутизаторе, то это будет исходящий трафик. То есть адреса назначения
(destination) у нас будут в сети серверов (из них мы будем выбирать на какой именно сервер идёт трафик), а
адреса источников (source) могут быть любыми — как из нашей корпоративной сети, так и из интернета.
Ещё одно замечание: поскольку фильтровать мы будем в том числе по адресу назначения (на WEB-сервер одни
правила, на почтовый — другие), то список контроля доступа нам понадобится расширенный (extended), только
он позволяет делать это.
Правила в списке доступа проверяются по порядку сверху вниз до первого совпадения. Как только одно из
правил сработало, независимо от того permit это или deny, проверка прекращается и обработка трафика
происходит на основе сработавшего правила.
То есть если мы хотим защитить WEB-сервер, то в первую очередь нам нужно дать разрешение, потому что, если
мы в первой же строке настроим deny ip any any — то оно всегда будет срабатывать и трафик не будет ходить
вообще. Any — это специальное слово, которое означает адрес сети и обратную маску 0.0.0.0 0.0.0.0 и означает,
что под правило подпадают абсолютно все узлы из любых сетей. Другое специальное слово — host — оно
означает маску 255.255.255.255 — то есть именно один единственный указанный адрес.
Итак, первое правило: разрешить доступ всем по порту 80
Разрешаем (permit) TCP-трафик от любого узла (any) на хост (host — именно один адрес) 172.16.0.2,
адресованный на 80-й порт.
Пробуем повесить этот список доступа на интерфейс FE0/0.3:
Дело в том, что после всех правил в цисковских ACL в конце дописывается неявное deny ip any any (implicit deny).
Что для нас это означает? Любой пакет, выходящий с интерфейса и не отвечающий ни одному правилу из ACL,
подпадает под implicit deny и отбрасывается. То есть хоть пинг, хоть фтп, хоть что угодно здесь уже не пройдёт.
Идём дальше: надо дать полный доступ компьютеру, с которого будет производиться управление. Это будет
компьютер нашего админа с адресом 172.16.6.66 из сети Other.
Каждое новое правило добавляется автоматически в конец списка, если он уже существует:
Вот и всё. Проверяем с нужного узла (поскольку серверами в РТ не поддерживается телнет, проверяем на FTP):
То есть FTP-сообщение пришло на маршрутизатор и должно уйти с интерфейса FE0/0.3. Маршрутизатор
проверяет и видит, что пакет подходит под добавленное нами правило и пропускает его.
А с постороннего узла
пакет FTP не попадает ни под одно из правил, кроме неявного deny ip any any и отбрасывается.
2) Доступ на файловый сервер
Тут бы надо в первую очередь определиться с тем, кто будет “резидентом”, кому нужно дать доступ. Конечно,
это те, кто имеет адрес из сети 172.16.0.0/16 — только им и дадим доступ.
Теперь с общими папками. В большинстве современных систем уже используется для этого протокол SMB,
которому нужен порт TCP 445. На более старых версиях использовался NetBios, который кормился аж через три
порта: UDP 137 и 138 и TCP 139. Договорившись с нашим админом, настроим 445 порт (правда проверить в
рамках РТ, конечно, не получится). Но кроме этого, нам понадобятся порты для FTP — 20, 21, причём не только
для внутренних хостов, но и для соединений из интернета:
Тут мы повторно применили конструкцию range 20 21 — для того, чтобы в одной строке задать несколько портов.
Для FTP, вообще говоря, недостаточно только 21-го порта. Дело в том, что если вы откроете только его, то
авторизация у вас будет проходить, а передача файлов нет.
0.0.255.255 — обратная маска (wildcard mask). О том, что это такое, поговорим чуточку позже
3) Доступ на почтовый сервер
Продолжаем нарабатывать практику — теперь с почтовым сервером. В рамках того же списка доступа добавляем
новые нужные нам записи.
Вместо номеров портов для широкораспространённых протоколов можно указывать их имена:
4) DNS-сервер
msk-arbat-gw1(config)# ip access-list extended Servers-out
5) ICMP
Осталось исправить ситуацию с пингом. Ничего страшного нет в том, чтобы добавить правила в конец списка, но
как-то эстетически приятнее будет увидеть их вначале.
Используем несложный чит для этого. Для это можно воспользоваться текстовым редактором, например.
Скопируйте туда из show run кусок про ACL и добавьте следующие строки:
remark WEB
remark FILE
remark DNS
Первой строкой мы удаляем существующий список, далее создаём его заново и перечисляем все новые правила
в нужном нам порядке. Командой в третьей строке мы разрешили проход всех ICMP-пакетов от любых хостов на
любые хосты.
Далее просто копируем всё скопом и вставляем в консоль. Интерфейс интерпретирует каждую строку как
отдельную команду и выполняет её. Таким образом, мы заменили старый список новым.
Проверяем, что пинг есть:
Прекрасно.
Данный “чит” хорош для первоначальной конфигурации или если вы точно понимаете, что делаете. На
рабочей сети, когда вы настраиваете удалённо ACL, вы рискуете остаться без доступа на настраиваемую
железку.
Чтобы вставить правило в начало или в любое другое нужное место, вы можете прибегнуть к такому приёму:
Каждое правило в списке пронумеровано с определённым шагом и если перед словом permit/deny вы поставите
число, то правило будет добавлено не в конец, а в нужное вам место. К сожалению, такая фича не работает в РТ.
Если будет вдруг необходимо (заняты все подряд идущие числа между правилами) вы всегда можете
перенумеровать правила (в этом примере назначается номер первого правила 10(первое число) и инкремент 10):
remark WEB
remark FILE
remark MAIL
remark DNS
Сейчас наш админ имеет доступ только на WEB-сервер. Откройте ему полный доступ на всю сеть. Это первое
домашнее задание.
6) Права пользователей из сети Other
До сих пор нам нужно было не впускать кого-то куда-то, поэтому мы обращали внимание на адрес назначения и
список доступа вешали на исходящий с интерфейса трафик. Теперь нам нужно не выпускать: никакие запросы от
компьютеров из сети Other не должны выходить за пределы. Ну, конечно, кроме тех, которые мы специально
разрешим.
Тут мы не могли сначала запретить всем, а потом разрешить избранным, потому что абсолютно все пакеты
попадали бы под правило deny ip any any и permit не срабатывал бы вообще.
Применяем на интерфейс. На этот раз на вход:
msk-arbat-gw1(config)#int fa0/0.104
Обычная сеть на 256 адресов: 172.16.5.0/24, например. Что означает эта запись?
А означает она ровно следующее
IP-адрес. Десятичная запись 172 16 5 0
IP-адрес. Двоичная запись 10101100 00010000 00000101 00000000
Маска подсети. Двоичная запись 11111111 11111111 11111111 00000000
Маска подсети. Десятичная запись 255 255 255 0
IP-адрес — это параметр длиною 32 бита, поделенный на 4 части, который вы привыкли видеть в десятичной
форме.
Маска подсети также имеет длину 32 бита — она фактически шаблон, трафарет, по которому определяется
принадлежность адреса подсети. Там, где в маске стоят единицы, значение меняться не может, то есть часть
172.16.5 совершенно неизменна и она будет одинакова для всех хостов этой подсети, а вот та, где нули —
варьируется.
То есть во взятом нами примере 172.16.5.0/24 — это адрес сети, а хосты будут 172.16.5.1-172.16.5.254 (последний
255 — широковещательный), потому что 00000001 — это 1, а 11111110 — 254 (речь о последнем октете адреса).
/24 означает, что длина маски 24 бита, то есть у нас идёт 24 единицы — неизменная часть и 8 нулей.
Другой случай, когда маска у нас, например, 30 бит, а не 24.
К примеру 172.16.2.4/30. Распишем это так:
IP-адрес. Десятичная запись 172 16 2 4
IP-адрес. Двоичная запись 10101100 00010000 00000010 00000100
Маска подсети. Двоичная запись 11111111 11111111 11111111 11111100
Маска подсети. Десятичная запись 255 255 255 252
Как видите, для этой подсети могут меняться только последние два бита. Последний октет может принимать
следующие 4 значения:
00000100 — адрес подсети (4 в десятичной системе)
00000101 — адрес узла (5)
00000110 — адрес узла (6)
00000111 — широковещательный (7)
Всё, что за пределами этого — уже другая подсеть
То есть теперь вам должно быть чуть-чуть понятно, что маска подсети — это последовательность 32-х бит, где
сначала идут единицы, означающие адрес подсети, потом идут нули, означающие адрес хоста. При этом
чередоваться нули и единицы в маске не могут чередоваться. То есть маска
11111111.11100000.11110111.00000000 невозможна
00000000.00000000.00000000.11111111
Во втором примере с сетью 172.16.2.4/30 обратная маска будет выглядеть так: 30 нулей и две единицы:
Обратная маска. Двоичная запись 00000000 00000000 00000000 00000011
Обратная маска. Десятичная запись 0 0 0 3
Но на самом деле обратная маска — это несколько более богатый инструмент, здесь вы можете объединять
адреса внутри одной подсети или даже объединять подсети, но самое главное отличие, вы можете чередовать
нули и единицы. Это позволяет вам, например, отфильтровать определённый узел (или группу) в нескольких
подсетях одной строкой.
Пример 1
Дано: сеть 172.16.16.0/24
Надо: отфильтровать первые 64 адреса (172.16.16.0-172.16.16.63)
Решение: 172.16.16.0 0.0.0.63
Пример 2
Дано: сети 172.16.16.0/24 и 172.16.17.0/24
Надо: отфильтровать адреса из обеих сетей
Решение: 172.16.16.0 0.0.1.255
Пример 3
Дано: Сети 172.16.0.0-172.16.255.0
Надо: отфильтровать хост с адресом 4 из всех подсетей
Решение: 172.16.0.4 0.0.255.0
Признаться ни разу в жизни не приходилось встречаться с последним сценарием применения. Это какие-то
жутко специфические должны быть задачи.
Более подробно об обратных масках можно прочитать тут: http://habrahabr.ru/post/131712/
Работа ACL в картинках
Гипотетическая сеть:
1) На маршрутизаторе RT1 на интерфейсе FE0/1 на вход у нас разрешено всё, кроме ICMP.
2) C ACL надо быть аккуратнее. При небольшой ошибке в правиле, неправильном порядке настройки или вообще
плохо продуманном списке вы можете остаться без доступа к устройству.
Например, вы хотите закрыть доступ куда угодно для сети 172.16.6.0/24, кроме своего адреса 172.16.6.61 и
задаёте правила так:
Как только вы примените ACL на интерфейс, вы сразу потеряете доступ к маршрутизатору, потому что вы
попадаете под первое правило и второе даже не проверяется.
Вторая неприятная ситуация, которая может с вами приключиться: под ACL попадёт трафик, который не должен
был попасть.
Вообразите такую ситуацию: у нас в серверной есть FTP-сервер в пассивном режиме. Для доступа к нему вы
открыли 21-й порт в ACL Servers-out. После первичного установления соединения FTP-сервер сообщает клиенту
порт, по которому он готов передавать/принимать файлы, например, 1523-й. Клиент пытается установить TCP-
соединение на этот порт, но натыкается на ACL Servers-out, где такого разрешения нету — так и кончается сказка
про успешный трансфер. В нашем примере выше, где мы настраивали доступ на файловый сервер, мы открыли
доступ только по 20 и 21-му, потому что для примера этого достаточно. В реальной жизни придётся повозиться.
Немного примеров конфигурации ACL для распространенных случаев.
Казалось бы: хосту с адресом 1.1.1.1 разрешён доступ по 80-му порту на сервер 2.2.2.2 (первое правило). И
обратно от сервера 2.2.2.2 разрешены соединения внутрь.
Но нюанс тут в том, что компьютер 1.1.1.1 устанавливает соединение НА 80-й порт, но С какого-то другого,
например, 1054, то есть ответный пакет от сервера приходит на сокет 1.1.1.1:1054, не подпадает под правило в
ACL на IN и отбрасывается ввиду неявного deny ip any any.
Чтобы избежать такой ситуации, и не открывать всем пучком порты, можно прибегнуть к такой хитрости в ACL на
in:
4) Говоря про современный мир, нельзя обойти такой инструмент, как объектные группы (Object-group).
Допустим, надо составить ACL, выпускающий три определенных адреса в интернет по трем одинаковым портам c
перспективой расширения количества адресов и портов. Как это выглядит без знания объектных групп:
ip access-list extended TO-INTERNET
При увеличении количества параметров сопровождать такой ACL становится всё труднее и труднее, легко
ошибиться при настройке.
Зато, если обратиться к объектным группам, то это приобретает следующий вид:
tcp eq www
tcp eq 8080
tcp eq 443
host 172.16.6.66
host 172.16.6.67
host 172.16.6.68
на первый взгляд несколько угрожающе выглядит, но если разобраться, то это очень удобно.
4) Очень полезную для траблшутинга информацию можно получить из вывода команды show ip access-lists %имя
ACL%. Кроме собственно списка правил указанного ACL, эта команда показывает количество совпадений по
каждому правилу.
А дописав в конце любого правила log, мы сможем получать сообщения о каждом совпадении в консоль.
(последнее не работает в PT)
NAT
Network Address Translation — механизм в хозяйстве совершенно необходимый уже с 1994-го года. Много сессий
об него сломано и пакетов потеряно.
Нужен он чаще всего для подключения вашей локальной сети к Интернету. Дело в том, что теоретически
существует 255*255*255*255=4 228 250 625. 4 миллиарда адресов. Даже если бы у каждого жителя планеты был
всего один компьютер, адресов бы уже не хватало. А тут разве что утюги к Интернету не подключаются. Умные
люди сообразили это ещё в начале 90-х и как временное решение предложили разделить пространство адресов
на публичные (белые) и приватные (частные, серые).
К последним относятся три диапазона:
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
Их вы свободно можете использовать в своей частной сети, и поэтому, разумеется, они будут повторяться. Как же
быть с уникальностью? Кому будет отвечать WEB-сервер, которому пришёл запрос с обратным адресом
192.168.1.1? Ростелекому? Компании Татнефть? Или вашему комнатному Длинку? В большом интернете никто
ничего не знает о приватных сетях — они не маршрутизируются.
Тут и выходит на сцену NAT. По большому счёту, это обман, подстава. На натирующем устройстве ваш приватный
адрес, грубо говоря, просто подменяется на белый адрес, который и будет фигурировать далее в пакете, пока он
путешествует до WEB-сервера. А вот белые адреса очень даже хорошо маршрутизируются, и пакет точно
вернётся обратно на натирующее устройство.
Но как оно в свою очередь поймёт, что с ним делать дальше? Вот с этим и разберёмся.
Типы NAT
Статический
В этом случае один внутренний адрес преобразуется в один внешний. И при этом все запросы, приходящие на
внешний адрес будут транслироваться на внутренний. Словно бы этот хост и является обладателем этого белого
IP-адреса.
Что происходит:
1) Узел 172.16.6.5 обращается WEB-серверу. Он отправляет IP-пакет, где в качестве адреса получателя стоит
192.0.2.2, а отправителя 172.16.6.5.
2) По корпоративной сети пакет доставляется к шлюзу 172.16.6.1, где и настроен NAT
3) Согласно настроенной команде, маршрутизатор снимает текущий заголовок IP и меняет его на новый, где в
качестве адреса отправителя уже фигурирует белый адрес 198.51.100.2.
4) По большому Интернету обновлённый пакет достигает сервера 192.0.2.2.
5) Тот видит, что ответ надо слать на 198.51.100.2 И подготавливает ответный IP-пакет. В качестве адреса
отправителя собственно адрес сервера 192.0.2.2, адрес назначения — 198.51.100.2
6) Пакет обратно летит через Интернет, причём не факт, что тем же путём.
7) На натирующем устройстве указано, что все запросы на адрес 198.51.100.2 нужно перенаправлять на
172.16.6.5. Маршрутизатор снова раздевает спрятанный внутри TCP-сегмент и задаёт новый IP-заголовок (адрес
отправителя не меняется, адрес назначения 172.16.6.5).
8) По внутренней сети пакет возвращается инициатору, которому даже и невдомёк, какие чудеса с ним
творились на границе.
И так будет с каждым.
При этом если соединение инициируется из Интернета, пакеты автоматически, проходя через натирующее
устройство, попадают на внутренний хост.
Такой подход бывает полезным, когда у вас есть сервер внутри вашей сети, к которому необходим полный
доступ извне. Разумеется, этот вариант вы не можете использовать, если хотите триста хостов выпустить в
Интернет через один адрес. Такой вариант NAT’а никак не поможет сохранить белые IP-адреса, но тем не менее
он бывает полезен.
Динамический
У вас есть пул белых адресов, например, провайдер выделил вам сеть 198.51.100.0/28 c 16-ю адресами. Два из
них (первый и последний) — адрес сети и широковещательный, ещё два адреса назначаются на оборудование
для обеспечения маршрутизации. 12 оставшихся адресов вы можете использовать для NAT’а и выпускать через
них своих пользователей.
Ситуация похожа на статический NAT — один приватный адрес транслируется на один внешний, — но теперь
внешний не чётко зафиксирован, а будет выбираться динамически из заданного диапазона.
Настраивается он так:
Задали пул (диапазон) публичных адресов, из которого будет выбираться адрес для натирования
Router(config)
Задаём список доступа, который пропускает все пакеты с адресом источника 172.16.6.х, где х варьируется 0-255.
Этот вариант тоже не универсальный, своих 300 пользователей вы так же не сможете выпустить всех в Интернет,
если у вас нет 300 внешних адресов. Как только белые адреса исчерпаются, никто новый уже не сможет получить
доступ в Интернет. При этом те пользователи, что уже успели отхватить себе внешний адрес, будут работать.
Скинуть все текущие трансляции и освободить внешний адреса вам поможет команда clear ip nat translation *
Помимо динамического выделения внешних адресов, этот динамически NAT отличается от статического тем, что
без отдельной настройки проброса портов уже невозможно внешнее соединение на один из адресов пула.
Many-to-One
Следующий тип имеет несколько названий: NAT Overload, Port Address Translation (PAT), IP Masquerading, Many-
to-One NAT.
Последнее название говорит само за себя — через один внешний адрес выходит в мир много приватных. Это
позволяет решить проблему с нехваткой внешних адресов и выпустить в мир всех желающих.
Тут надо бы дать пояснение, как это работает. Как два приватных адреса транслируются в один можно
представить, но как маршрутизатор понимает кому нужно переслать пакет, вернувшийся из Интернета на этот
адрес?
Предположим, что от двух хостов из внутренней сети приходят пакеты на натирующее устройство. Оба с
запросом к WEB-серверу 192.0.2.2.
Маршрутизатор расчехляет IP-пакет от первого хоста, извлекает из него TCP-сегмент, распечатывает его и узнаёт,
с какого порта устанавливается соединение. У него есть внешний адрес 198.51.100.2, на который будет меняться
адрес из внутренней сети.
Далее он выбирает свободный порт, например, 11874. И что он делает дальше? Все данные уровня приложений
он упаковывает в новый TCP сегмент, где в качестве порта назначения по-прежнему остаётся 80 (именно на него
ждёт коннектов WEB-сервер), а порт отправителя меняется с 23761 на 11874. Этот TCP-сегмент инкапсулируется в
новый IP-пакет, где меняется IP-адрес отправителя с 172.16.6.5 на 198.51.100.2.
То же самое происходит для пакета от второго хоста, только выбирается следующий свободный порт, например
11875. “Свободный” означает, что он ещё не занят другими такими соединениями.
Локальный адрес Локальный порт Глобальный адрес Глобальный порт Адрес Порт
отправителя отправителя отправителя отправителя получателя получателя
172.16.6.5 23761 198.51.100.2 11874 192.0.2.2 80
172.16.4.5 39800 198.51.100.2 11875 192.0.2.2 80
Для WEB-сервера — это два совершенно разных запроса, которые он должен обработать каждый
индивидуально. После этого он отсылает ответ, который выглядит так:
Когда один из этих пакетов доходит до нашего маршрутизатора, тот сопоставляет данные в этом пакете со
своими записями в NAT-таблице. Если совпадение найдено, происходит обратная процедура — пакету и TCP
сегменту возвращаются его изначальные параметры только в качестве назначения:
И теперь пакеты доставляется по внутренней сети компьютерам-инициаторам, которым и невдомёк даже, что
где-то с их данными так жёстко обошлись на границе.
Каждое ваше обращение — это отдельное соединение. То есть попытались вы открыть WEB-страницу — это
протокол HTTP, использующий порт 80. Для этого ваш компьютер должен установить TCP-сессию с удалённым
сервером. Такая сессия (TCP или UDP) определяется двумя сокетами: локальный IP-адрес: локальный порт и
удалённый IP-адрес: удалённый порт. В обычной ситуации у вас устанавливается одно соединение компьютер-
сервер, в случае же NATа соединения будет как бы два:, маршрутизатор-сервер и компьютер думает, что у него
есть сессия компьютер-сервер.
Перенаправление портов
Когда мы только начали говорить про NAT, трансляция у нас была один-в-один и все запросы, приходящие извне
автоматически перенаправлялись на внутренний хост. Таким образом можно было бы выставить сервер наружу в
Интернет.
Но если у вас нет такой возможности — вы ограничены в белых адресах, или не хотите выставлять всем пучком
портов его наружу, что делать?
Вы можете указать, что все запросы, приходящие на конкретный белый адрес и конкретный порт
маршрутизатора, должны быть перенаправлены на нужный порт нужного внутреннего адреса.
Применение данной команды означает, что TCP-запрос, пришедший из интернета на адрес 198.51.100.2 по порту
80, будет перенаправлен на внутренний адрес 172.16.0.2 на тот же 80-й порт. Разумеется, вы можете
пробрасывать и UDP и делать перенаправление с одного порта на другой. Это, например, может оказаться
полезным, если у вас есть два компьютера, к которым нужен доступ по RDP извне. RDP использует порт 3389.
Один и тот же порт вы не можете пробросить на разные хосты (при использовании одного внешнего адреса).
Поэтому вы можете сделать так:
Router(config)# ip nat inside source static tcp 172.16.6.61 3389 198.51.100.2 3389
Router(config)# ip nat inside source static tcp 172.16.6.66 3389 198.51.100.2 3398
Кстати, эта команда — частный случай самой первой: ip nat inside source static 172.16.6.66 198.51.100.2. Только в
этом случае речь идёт о пробросе всего трафика, а в наших примерах — конкретных портов протокола TCP.
Вот так в общих чертах фунциклирует NAT. Про его особенности, плюсы/минусы написано куча статей, но не
отметить их нельзя.
2) Порт отправителя в пакете должен совпадать с портом для этого белого адреса в записи
ИЛИ
Но не нужно рассматривать NAT именно как файрвол — это не более, чем дополнительная его плюшка.
— В-третьих, NAT скрывает от посторонних глаз внутреннюю структуру вашей сети — при трассировке маршрута
извне вы не увидите ничего далее натирующего устройства.
— Некоторые протоколы не могут работать через NAT без костылей. Например, FTP или протоколы
туннелирования (несмотря на то, как просто я настроил FTP в лабораторке, в реальной жизни это может создать
кучу проблем)
— Другая проблема кроется в том, с одного адреса идёт много запросов на один сервер. Многие были
свидетелем этого, когда заходишь на какой-нибудь Rapidshare, а он говорит, что с вашего IP уже было
соединение, вы думаете, что “врёт, собака”, а это ваш сосед уже сосет. По этой же причине бывали проблемы c
ICQ, когда сервера отказывали в регистрации.
— Не очень актуальная сейчас проблема: нагрузка на процессор и оперативную память. Поскольку объём работы
довольно велик по сравнению с простой маршрутизацией (это надо не просто глянуть заголовок IP, надо его
снять, TCP-заголовок снять, в таблицу занести, новые заголовки прикрутить) в мелких конторах с этим бывают
проблемы.
Для больших игроков, у которых маршрутизаторы ворочают по 3-4 BGP full-view, сейчас это не составляет
проблем.
Что ещё нужно знать?
— NAT применяется в основном для обеспечения доступа в Интернет хостам с приватными адресами. Но бывает
и иное применение — связь между двумя частными сетями с пересекающимися адресными пространствами.
Например, ваша компания покупает себе филиал в Актюбинске. У вас адресация 10.0.0.0-10.1.255.255, а у них
10.1.1.0-10.1.10.255. Диапазоны явно пересекаются, настроить маршрутизацию никак не получится, потому что
один и тот же адрес может оказаться и в Актюбинске и у вас в штаб-квартире.
В таком случае на месте стыка настраивается NAT. Поскольку серых адресов у нас не мерено, можно выделить, к
примеру, диапазон 10.2.1.0-10.2.10.255 и делать трансляцию один-в-один:
10.1.1.1-10.2.1.1
10.1.1.2-10.2.1.2
…
10.1.10.255-10.2.10.255
— В больших игрушках для взрослых NAT может быть реализован на отдельной плате (и часто так и есть) и без
неё не заработает. А на офисных железках, напротив, есть почти всегда.
— С повсеместным внедрением IPv6 необходимость в NAT’e будет сходить на нет. Уже сейчас большие заказчики
начинают интересоваться функционалом NAT64 — это когда у вас выход в мир через IPv4, а внутренняя сеть уже
на IPv6
— Разумеется, это лишь поверхностный взгляд на NAT и есть ещё море нюансов, не утонуть в котором вам
поможет самообразование.
Практика NAT
Подключение к Интернету будет организовано через существующий линк, который предоставляет провайдер.
Он уходит в сеть провайдера. Напоминаем, что всё в этом облаке — это абстрактная сеть, которая на деле может
состоять из десятков маршрутизаторов и сотен коммутаторов. Но нам нужно нечто управляемое и
предсказуемое, поэтому водружаем сюда ещё маршрутизатор. С одной стороны в него линк из коммутатора, с
другой сервера в Интернете.
Для такого подключения мы поднимем ещё один влан на msk-arbat-gw1. Его номер, разумеется, согласуется с
провайдером. Пусть это будет VLAN 6
Предположим, провайдер предоставляет нам подсеть 198.51.100.0/28. Первые два адреса используются для
организации линка (198.51.100.1 и 198.51.100.2), а оставшиеся мы используем, как пул для NAT’a. Впрочем, никто
совершенно нам не мешает использовать и адрес 198.51.100.2 для пула. Так и сделаем: пул: 198.51.100.2-
198.51.100.14
Для простоты предположим, что публичные сервера у нас находятся в одной подсети:
192.0.2.0/24.
Поскольку у нас только один маршрутизатор в сети провайдера, и все сети подключены непосредственно к нему,
то необходимости настраивать маршрутизацию нету.
А вот наш msk-arbat-gw1 должен знать куда отправлять пакеты в Интернет, поэтому нам нужен маршрут по
умолчанию:
Теперь по порядку
3) Бухгалтерия
4) ФЭО
5) Other
remark PTO
remark ACCOUNTING
remark FEO
remark IAM
permit ip host 172.16.6.61 any
remark ADMIN
remark SPB_VSL_ISLAND
remark SPB_OZERKI
remark KMR
Запускаем:
Это позволит маршрутизатору понять откуда ждать пакеты, которые нужно будет обработать и куда их потом
слать.
Чтобы сервера в интернете были доступны по доменному имени, нам бы неплохо было обзавестись DNS-
сервером в нашей сети:
Естественно его, нужно прописать на тех устройствах, с которых будем проверять доступ:
Show must go on!
Из сети ПТО есть доступ только на сайт linkmeup.ru по 80-му порту (HTTP):
В сети ФЭО в мир выходит только 4.123 (финдиректор)
В бухгалтерии работают только сайты клиент-банков. Но, поскольку разрешение дано полностью на протокол IP,
то их можно и пинговать:
7) Cервера
Тут нам нужно настроить проброс портов, чтобы к ним можно было обращаться из Интернета:
a) Веб-сервер
Сейчас ничего не заработает, потому что для сети серверов у нас не настроен интерфейс на msk-arbat-gw1:
А теперь:
б) Файловый сервер
msk-arbat-gw1(config)# ip nat inside source static tcp 172.16.0.3 20 198.51.100.3 20
Вот для этого в ACL Servers-out мы открывали также и 20-21-й порты для всех
в) Почтовый сервер
msk-arbat-gw1(config)# ip nat inside source static tcp 172.16.0.4 110 198.51.100.4 110
msk-arbat-gw1(config)# ip nat inside source static tcp 172.16.6.61 3389 198.51.100.10 3389
msk-arbat-gw1(config)# ip nat inside source static tcp 172.16.6.66 3389 198.51.100.10 3398
Безопасность
На последок одно замечание. Скорее всего натирующее устройство, у вас смотрит своим ip nat outside
интерфейсом наружу — в Интернет. Поэтому на этот интерфейс не помешало бы повешать ACL, где вы запретите,
разрешите, то что вам нужно. На этом вопросе не будем останавливаться уже в данной статье.
В качестве ещё одного ДЗ ответьте на вопрос, почему нет доступа в Интернет с компьютеров эникиев в Питере и
в Кемерово. Ведь мы их добавили уже в список доступа.
Материалы выпуска
Новый IP-план, планы коммутации по каждой точке и регламент
Файл РТ с лабораторной
Конфигурация устройств
Дополнительные ссылки:
Два провайдера+NAT
Полезная информация от cisco
Наш коллега хабраюзер написал несколько статей по особенностям NAT. Особенно интересна может
быть данная статья.
Но как бы то ни было, никто не напишет о cisco лучше, чем cisco
Обратная маска
Бонусы
PBRВ режиме глобальной конфигурации.
Добавляем маршрут по умолчанию:
Создаём карту маршрутов, где обозначаем, что если пакет из сети 192.168.2.0/24, то для него назначить next-hop
10.0.2.1 (вместо 10.0.1.1)
Это лишь одно из применений мощного инструмента Policy-Based Routing, который, к сожалению, ни в каком
виде не реализован в РТ.
rate-limit
На том же примере ограничим скорость для сети 192.168.1.0/24 до 1.5 Мб/с, а для 192.168.2.0/24 до 64 кб/с.
На 10.0.1.1 можно выполнить следующие команды:
Router(config-if)# rate-limit output access-group 100 1544000 64000 64000 conform-action transmit
exceed-action drop
Router(config-if)# rate-limit output access-group 101 64000 16000 16000 conform-action transmit
exceed-action drop
Сеть “Лифт ми Ап” вместе со своим штатом разрастается вдоль и поперёк. Обслуживание ИТ-инфраструктуры
вынесли в отдельную специально созданную организацию “Линк ми Ап”.
Буквально на днях были куплены ещё четыре филиала в различных городах и инвесторы открыли для себя новые
измерения движения лифтов. А сеть выросла с четырёх маршрутизаторов сразу до десяти. При этом количество
подсетей теперь увеличилось с 9 до 20, не считая линков точка-точка между маршрутизаторами. И тут во весь
рост встаёт вопрос управления всем этим хозяйством. Согласитесь, добавлять на каждом из узлов маршруты во
все сети вручную — мало удовольствия.
Ситуация усложняется тем, что сеть в Калининграде уже имеет свою адресацию, и на ней запущен протокол
динамической маршрутизации EIGRP.
Итак, сегодня:
• Разбираемся с теорией протоколов динамической маршрутизации.
• Внедряем в сеть “Лифт ми Ап” протокол OSPF
• Настраиваем передачу (редистрибуцию) маршрутов между OSPF и EIGRP
• В этом выпуске мы добавляем раздел “Задачи”. Идентифицировать по ходу статьи их будут такие
пиктограммы:
Уровень сложности будет разный. Ко всем задачам будут ответы, которые можно посмотреть на сайте
цикла. В некоторых из них вам понадобится подумать, в других почитать документацию, в третьих разобраться в
топологии и, может, даже смотреть отладочную информацию. Если задача нереализуема в РТ, мы сделаем
специальную пометку об этом.
Например, если в такой сети разорвать линк между R2 и R3, то пакеты с R1 будут уходить по прежнему на R2, где
будут уничтожены, потому что их некуда отправить.
Протоколы динамической маршрутизации в течение нескольких секунд (а то и миллисекунд) узнают о проблемах
на сети и перестраивают свои таблицы маршрутизации, и в вышеописанном случае пакеты будут отправляться
уже по актуальному маршруту
Ещё один важный момент — балансировка трафика. Протоколы динамической маршрутизации практически из
коробки поддерживают эту фичу и вам не нужно добавлять избыточные маршруты вручную, высчитывая их.
Все протоколы маршрутизации можно разделить на две большие группы: внешние (EGP — Exterior Gateway
Protocol) и внутренние (IGP — Interior Gateway Protocol). Чтобы объяснить различия между ними, нам
потребуется термин “автономная система”. В общем смысле, автономной системой (доменом маршрутизации)
называется группа роутеров, находящихся под общим управлением.
В случае нашей обновлённой сети AS будет такой:
Так вот, протоколы внутренней маршрутизации используются внутри автономной системы, а внешние — для
соединения автономных систем между собой. В свою очередь, внутренние протоколы маршрутизации
подразделяются на Distance-Vector (RIP, EIGRP) и Link State (OSPF, IS-IS). В этой статье мы не будем пинать
трупы затрагивать протоколы RIP и IGRP в силу их почтенного возраста, а так же IS-IS в силу его отсутствия в ПТ.
Как мы видим, количество протоколов маршрутизации невелико, но все же не один-два. А что будет, если на
роутере запустить несколько протоколов одновременно? Может оказаться, что у каждого протокола будет свое
мнение о том, как лучше добраться до определенной сети. А если у нас еще и статические маршруты настроены?
Кому роутер отдаст предпочтение и чей маршрут добавит в таблицу маршрутизации? Ответ на этот вопрос связан
с новым термином: административная дистанция (на нащ вкус, довольно посредственная калька с английского
Аdministrative distance, но лучше выдумать не смогли). Аdministrative distance это целое число от 0 до 255,
выражающее “меру доверия” роутера к данному маршруту. Чем меньше AD, тем больше доверия. Вот табличка
такого доверия с точки зрения Cisco:
В сегодняшней статье мы разберём OSPF и EIGRP. Первый вам будет встречаться везде и постоянно, а второй
очень хорош в сетях, где присутствует только оборудование Cisco.
У каждого из них есть свои достоинства и недостатки. Можно сказать, что EIGRP выигрывает перед OSPF, но все
плюсы нивелируются его проприетарностью. EIGRP — фирменный протокол Cisco и больше никто его не
поддерживает.
На самом деле у EIGRP много недостатков, но об этом не особо распространяются в популярных статьях. Вот
только одна из проблем: SIA
Итак, приступим.
OSPF
Статей и видео о том, как настроить OSPF горы. Гораздо меньше описаний принципов работы. Вообще, тут такое
дело, что OSPF можно просто настроить согласно мануалам, даже не зная про алгоритмы SPF и непонятные LSA.
И всё будет работать и даже, скорее всего, прекрасно работать — на то он и рассчитан. То есть тут не как с
вланами, где приходилось знать теорию вплоть до формата заголовка.
Но инженера от эникейщика отличает то, что он понимает, почему его сеть функционирует так, а не иначе, и не
хуже самогo OSPF знает, какой маршрут будет выбран протоколом.
В рамках статьи, которая уже на этот момент составляет 8 000 символов, мы не сможем погрузиться в глубины
теории, но рассмотрим принципиальные моменты.
Очень просто и понятно, кстати, написано про OSPF на xgu.ru или в английской википедии.
Итак, OSPFv2 работает поверх IP, а конкретно, он заточен только под IPv4 (OSPFv3 не зависит от протоколов 3-го
уровня и потому может работать с IPv6).
Для начала надо сказать, что для того, чтобы между маршрутизаторами завязалась дружба (отношения
смежности) должны выполниться следующие условия:
1) в OSPF должны быть настроены одинаковые Hello Interval на тех маршрутизаторах, что подключены друг к
другу. По умолчанию это 10 секунд в Broadcast сетях, типа Ethernet. Это своего рода KeepAlive сообщения. То есть
каждые 10 секунд каждый маршрутизатор отправляет Hello пакет своему соседу, чтобы сказать: “Хей, я жив”,
2) Одинаковыми должны быть и Dead Interval на них. Обычно это 4 интервала Hello — 40 секунд. Если в течение
этого времени от соседа не получено Hello, то он считается недоступным и начинается ПАНИКА процесс
перестроения локальной базы данных и рассылка обновлений всем соседям,
3) Интерфейсы, подключенные друг к другу, должны быть в одной подсети,
4) OSPF позволяет снизить нагрузку на CPU маршрутизаторов, разделив Автономную Систему на зоны. Так
вот номера зон тоже должны совпадать,
5) У каждого маршрутизатора, участвующего в процессе OSPF есть свой уникальный индентификатор — Router
ID. Если вы о нём не позаботитесь, то маршрутизатор выберет его автоматически на основе информации о
подключенных интерфейсах (выбирается высший адрес из интерфейсов, активных на момент запуска процесса
OSPF). Но опять же у хорошего инженера всё под контролем, поэтому обычно создаётся Loopback интерфейс,
которому присваивается адрес с маской /32 и именно он назначается Router ID. Это бывает удобно при
обслуживании и траблшутинге.
6) Должен совпадать размер MTU
3) Дружба. Когда R1 получает это сообщение Hello от R2, он пролистывает список соседей и находит в нём свой
собственный Router ID, он добавляет R2 в свой список соседей.
Теперь R1 и R2 друг у друга во взаимных соседях — это означает, что между ними установлены отношения
смежности и маршрутизатор R1 переходит в состояние TWO WAY.
Далее происходит выбор DR и BDR, но мы не будем на этом останавливаться, хоть это и довольно важные вещи.
4) Затишье перед бурей. Далее все переходят в состояние EXSTART. Здесь все соседи решают между собой, кто
босс. Им становится маршрутизатор с наибольшим Router ID — R2.
5) Когда выбран Батька, соседи переходят в состояние Exchange и обмениваются DBD-сообщениями (или DD) —
Data Base Description, которые содержат описание LSDB (Link State Data Base), мол, я знаю про вот такие подсети.
Тут надо пояснить, что такое LSDB. Если перевести на русский дословно: база данных о состоянии линков. В
изначальном состоянии маршрутизатор знает только о тех линках (интерфейсах), на которых запущен процесс
OSPF. По ходу пьесы, каждый маршрутизатор собирает всю информацию о сети и составляет топологию. Именно
она и будет являться LSDB, которая должна быть одинакова на всех членах зоны.
Первым отсылает свою DBD маршрутизатор, выбранный главным на данном интерфейсе — 2.2.2.2. Следом за
ним то же делает и 1.1.1.1.
6) Получив сообщение, маршрутизаторы R1 и R2 отправляют подтверждение о приёме DBD (LSAck), а затем
сравнивают новую информацию с той, что содержится у них в LSDB и, если есть отличия, посылают LSR (Link State
Request) друг другу, тем самым переходя в новое состояние LOADING. В LSR они говорят — “Я про вот эту сеть
ничего не знаю. Расскажи мне подробнее”.
7) R2, получив LSR от R1, высылает LSU (Link State Update), которые содержат в себе LSA (Link State Advertisement)
c детальной информацией о нужных подсетях.
И вот, как только R1 получит последнюю порцию данных о всех подсетях и сформирует свою LSDB, он переходит
в своё конечное состояние FULL STATE.
К тому моменту, как все маршрутизаторы зоны придут к состоянию Full State на всех на них должна быть
полностью одинаковая LSDB — они же одну и ту же сеть изучали. То есть фактически это означает, что
маршрутизатор знает всю вашу сеть, что, как и куда подключено.
Авторы осознают, что понять и запомнить все эти аббревиатуры и правила довольно сложно, но прочитав это 5 -7
раз в разных местах с некоторой периодичностью, можно будет составить представление о том, как OSPF
работает.
8) Итак, сейчас у нас все маршрутизаторы знают всё о сети, но это знание не помогает в маршрутизации.
Следующим шагом OSPF, используя алгоритм Дейкстры (или его ещё называют SPF — Shortest Path First),
вычисляет кратчайший маршрут до каждого маршрутизатора в зоне — он ведь знает всю топологию. В этом ему
помогают метрики. Чем она ниже, тем маршрут лучше. Метрика — это стоимость движения по маршруту.
Теперь каждые 10 секунд каждый маршрутизатор будет отправлять Hello-пакеты, а каждые 30 минут
рассылаются LSA — это типа данные уже считаются устаревшими, надо бы обновить, даже если изменений не
было.
В идеальном мире на этом бы и установилось равновесие. Но мы живём в мире жестоком и равнодушном, где
инженер — это итшник, а то и компьютерщик вообще, а лифты научились ездить вниз всего три выпуска назад. И
в этом будничном мире кипят страсти: рвут оптику, вырубают питание, мыши перегрызают ножки процессоров
(или это не в этом мире?) — иными словами, топология непрестанно меняется. И чем больше сеть, тем чаще и
глобальнее изменения.
Разумеется, было бы несколько странно ждать 40 секунд (Dead Interval) и только потом начинать перестраивать
таблицу. Это было бы простительно ещё RIP’у, но не протоколу, который используется в огромном количестве
современных сетей. Итак, как только падает какой-либо из линков (или несколько), маршрутизатор изменяет
свою LSDB и генерирует LSU, присваивая ей номер больше, чем он был прежде (у каждой LSDB есть номер,
который берётся из последнего полученного LSA).
Это LSU сообщение рассылается на мультикастовый адрес 224.0.0.5. Маршрутизаторы получившие его,
проверяют номер LSA, содержащихся в LSU.
1) Если номер больше, чем номер текущей LSA маршрутизатора — LSDB меняется. (Версия LSDB старая,
информация новая),
2) Если номер такой же, ничего не происходит. Этот маршрутизатор уже получил данный LSA по какому-то
другому пути,
3) Если номер полученного LSA меньше локальной LSDB, это означает, что у маршрутизатора уже более
актуальная информация, и он посылает новый LSA (на основе своей LSDB) отправителю прежнего.
После произведённых (или непроизведённых) действий соседу, от которого пришёл LSU пересылаются LSAck
(мол, «посылку получили — всё в порядке»), а другим соседям отправляется изначальный LSU без изменений. На
данном маршрутизаторе снова запускается алгоритм SPF и, при необходимости, обновляется таблица
маршрутизации.
В общем, всё это происходит в целях поддержания актуальности информации на всех устройствах — LSDB
должна быть одинаковой у всех.
Тут надо оговориться, что маршрутизатор замечает изменения только при прямом подключении к своему соседу.
Если между ними будет, например, коммутатор, то устройство не обнаружит падения физического интерфейса и
ничего не будет делать. Для таких ситуаций есть два решения.
1) Настроить таймеры. Для OSPF их можно уменьшить до уровня миллисекунд.
2) Использовать очень крутой протокол BFD (Bidirectional Forwarding Detection). Он позволяет отслеживать
состояние линков также на миллисекундном уровне. В конфигурации BFD связывается с другими протоколами и
позволяет очень быстро сообщить кому надо, что есть проблемы на сети. Конкретно с BFD мы будем разбираться
в другой части.
Как вы заметили, на все сообщения есть подтверждения: либо это LSAck, либо ответ Hello на Hello. Это плата за
отказ от TCP — как-то ведь надо убеждаться в успешной доставке.
Всего существует 7 типов LSA, которые тесно завязаны на зоны, коих тоже 5 штук. Маршрутизаторы тоже бывают
четырёх типов. А так же есть понятия Designated Router (DR) и Backup DR (BDR), ABR и ASBR. Есть формулы расчёт
метрик и прочее, прочее. Оставляем это на самостоятельное изучение.
Практика OSPF
Помните, как мы мучились, настраивая маршрутизацию в прошлый раз: на каждом устройстве до каждой сети и
не дай бог что-нибудь забыть. Теперь это в прошлом — да здравствуют IGP!
Не будем терять время, объясняя отдельно команды, а сразу окунёмся в удивительный мир конфигурации.
Такс, имеет место сейчас следующая логическая схема:
Пока нас интересует вот это большое Сибирское кольцо через Красноярск, Хабаровск и Владивосток. Здесь и на
нашей уже построенной сети мы запустим OSPF. Там, где прежде была статика, нам придётся от неё отказаться и
плавно перейти на динамические протоколы.
Предположим, что Красноярск у нас так же подключен через «Балаган телеком», как и предыдущие точки, а
далее через разных провайдеров нам организованы линки к другим городам. Кольцо замыкается в Москве через
провайдера “Филькин сертификат”. Предположим, что везде между городами у нас куплен L2-VPN и IP-трафик
ходит прозрачно.
IP-план подсетей филиалов и линков Point-to-Point мы уже подготовили. Предположим, что и все начальные
настройки тоже выполнили на всех узлах:
• hostname
• параметры безопасности (пароли на телнет, ssh)
• IP-адреса линковых интерфейсов
• IP адреса подсетей LAN
• IP-адреса Loopback-интерфейсов.
Мы тут вводим новое понятие Loopback-интерфейса. Он будет сконфигурирован на каждом маршрутизаторе. Для
этого выделена специальная подсеть 172.16.255.0/24. Нужно оно нам сейчас для OSPF, а в будущем может
понадобиться для BGP, MPLS.
Положа руку на сердце, сам долгое время не понимал значения этих интерфейсов. Вообще говоря, это
виртуальный интерфейс, состояние которого всегда UP, независимо от состояния физических интерфейсов (если
только на нём самом shutdown не выполнили). Попытаемся объяснить одну из его ролей:
Вот, к примеру, есть у вас сервер мониторинга Nagios. В нём вы завели для наблюдения маршрутизатор R1 и для
связи с ним использовали адрес интерфейса FE0/0 — 10.1.0.1.
На первый взгляд все прекрасно — всё работает. Но предположим теперь, что этот кабель порвали.
Благодаря динамической маршрутизации, связь до роутера А не нарушится, и он будет доступен через FE0/1. А в
Nagios’е у вас будет авария, всё будет красное, повалятся смс и почта. При падении линка, IP-адрес этого
интерфейса (10.1.0.1) становится недоступен.
А вот если вы настроите в Nagios’е адрес Loopback-интерфейса, то тем или иным путём он всегда будет доступен,
опять же благодаря динамической маршрутизации.
Поскольку все приготовления уже закончились, перед нами стоит очень простая задача: пройтись по всем
маршрутизаторам и активировать процесс OSPF.
Первым словом указываем, что запускаем протокол динамической маршрутизации, далее указываем какой
именно и в последнюю очередь номер процесса (теоретически их может быть несколько на одном роутере).
Сразу после этого автоматически назначается router ID. По умолчанию это наибольший адрес Loopbaсk-
интерфейсов.
2) Не оставляем это дело на самотёк. Главное правило: Router ID обязан быть уникальным. Нет, вы, конечно,
можете их сделать и одинаковыми, но в этом случае у вас начнутся странности.
Одна из моих заявок была такой: на оборудовании заканчиваются метки LDP. Из 8 с гаком тысяч осталась только
одна свободная. Никакие новые VPN не создавались и не работали. Разбирались, разбирались и в итоге увидели
что процесс OSPF создаёт и удаляет тысячи записей в минуту в таблице маршрутизации. Топология постоянно
перестраивается и на каждое такое перестроение выделяются новые метки LDP, после чего не освобождаются. А
всё дело в случайно настроенных одинаковых Router ID.
Настраивать его можно, в принципе, как угодно, можно даже не настраивать, маршрутизатор назначит его сам,
но для порядку мы это сделаем — в будущем обслуживать будет проще. Назначаем его в соответствии с адресом
Loopback-интерфейса.
msk-arbat-gw1(config-router)#router-id 172.16.255.1
3) Теперь мы объявляем, какие сети мы будем анонсировать (передавать соседям OSPF). Обратите внимание, что
в этой команде используется wildcard-маска, как в ACL
Тут остановимся подробно. Командой network мы задаём не ту сеть, что будет вещать наш маршрутизатор, мы
определяем интерфейсы, участвующие в процессе.
Все интерфейсы маршрутизатора, IP адреса которых попадают в настроенный диапазон 172.16.0.0 0.0.255.255
(172.16.0.0-172.16.255.255), включатся в процесс.
Это означает следующее:
а) с данных интерфейсов будут рассылаться Hello-сообщения, через них будут устанавливаться отношения
соседства и отправляться обновления о топологии сети.
б) OSPF изучает подсети данных интерфейсов и именно их будет аносировать и следить за их состоянием. То есть
не 172.16.0.0 0.0.255.255, как мы настроили, а те, что удовлетворяют этому диапазону
В нашем случае не имеет значения как мы настроим:
или
или
…..
Как только вы задали команду network с правильных интерфейсов слетают слова приветствия, но отвечать на них
пока некому — соседей нет:
msk-arbat-gw1#
Теперь пропишем настройки OSPF в Кемерово (router ID=IP адрес Loopback интерфейса, взятый из IP-плана):
kmr-gorka-gw1(config)#router OSPF 1
kmr-gorka-gw1(config-router)#router-id 172.16.255.48
Здесь вы можете видеть, что были успешно установлены отношения смежности и произошёл обмен LSA. Каждый
маршрутизатор построил свою LSDB.
Кроме известных ранее сетей (C — directly connected и S — Static) у нас появились два новых маршрута с
пометкой O (OSPF). Тут всё должно быть понятно, но наблюдательный читатель спросит: “почему в таблице
маршрутизации присутствуют два маршрута в сеть 172.16.24.0. Почему не останется более предпочтительный
статический?” и будет прав. Вообще говоря, в таблицу маршрутизации попадает только лучший маршрут до сети
— по умолчанию один. Но обратите внимание, что статический Bidirectional Forwarding Detectionмаршрут идёт до
подсети 172.16.24.0/22, а полученный от OSPF до 172.16.24.0/24. Это разные подсети, поэтому обеим им нашлось
место до солнцем. Дело в том, что OSPF понятия не имеет чего вы там напланировали и какой диапазон
выделили — он оперирует реальными данными, то есть IP-адресом и маской:
interface FastEthernet0/0.2
kmr-gorka-gw1#sh ip route
На самом деле до подсети 172.16.24.0/24 трафик уже пошёл по маршруту предоставленному OSPF, потому что у
него более узкая маска (24 против 22).
Но попробуем удалить статические маршруты и посмотрим, что получится.
!!!!!
И это прекрасно.
Настроим OSPF в Питере:
spb-vsl-gw1(config)#router OSPF 1
spb-vsl-gw1(config-router)#router-id 172.16.255.32
Настройки, как видите, везде предельно простые. При этом замечу, что номер процесса OSFP на разных
маршрутизаторах не обязательно должен быть одинаковым, но лучше, если это будет так.
Дело в том, что отношения смежности устанавливаются только между непосредственно подключенными
устройствами (коммутаторы между ними не считаются), а spb-vsl-gw1 коммуницирует с kmr-gorka-gw1 через msk-
arbat-gw1, поэтому их нет в соседях друг у друга.
Последний оплот консерватизма — spb-ozerki-gw1 сдастся вам без особых проблем, как и три маршрутизатора
Сибирского кольца. Делается всё по аналогии — по сути меняется только Router ID. И не забудьте удалить
статические маршруты.
Задача №1
Между маршрутизаторами в Питере надо уменьшить время обнаружения пропажи соседа.
Маршрутизаторы должны отправлять сообщения Hello каждые 3 секунды, и считать друг друга недоступными,
если 12 секунд не было сообщение Hello от соседа.
Ответ
Прежде чем мы перейдём к тестированию резервных линков и скорости, сделаем ещё одну полезную вещь.
Если бы у нас была возможность отловить трафик на интерфейсе FE0/0.2 msk-arbat-gw1, который смотрит в
сторону серверов, то мы бы увидели, что каждые 10 секунд в неизвестность улетают сообщения Hello. Ответить
на Hello некому, отношения смежности устанавливать не с кем, поэтому и пытаться рассылать отсюда сообщения
смысла нет.
Выключается это очень просто:
msk-arbat-gw1(config)#router OSPF 1
Такую команду нужно дать для всех интерфейсов, на которых точно нет соседей OSPF (в том числе в сторону
интернета).
В итоге картина у вас будет такая:
Кроме того, эта команда повышает безопасность — никто из этой сети не прикинется маршрутизатором и не
будет пытаться поломать нас полностью.
Теперь рвём интерфейс между Москвой и Красноярском и смотрим, через сколько линк восстановится.
Не проходит и 5 секунд, как все маршрутизаторы узнали о происшествии и пересчитали свои таблицы
маршрутизации:
msk-arbat-gw1(config-subif)#do sh ip ro 172.16.128.0
Known via "OSPF 1", distance 110, metric 4, type intra area
Known via "OSPF 1", distance 110, metric 3, type intra area
msk-arbat-gw1#traceroute 172.16.128.1
Как только вы поднимете линк, маршрутизаторы снова вступают в связь, обмениваются своими базами,
пересчитываются кратчайшие пути и заносятся в таблицу маршрутизации.
На видео всё это более наглядно. Рекомендую ознакомиться.
Задача №2
После настройки OSPF на маршрутизаторах в сибирском кольце, все сети, которые находятся за
маршрутизатором в центральном офисе в Москве (msk-arbat-gw1), для Хабаровска доступны по двум
маршрутам (через Красноярск и через Владивосток). Но, так как канал через Красноярск лучше, то надо изменить
настройки по умолчанию таким образом, чтобы Хабаровск использовал канал через Красноярск, когда он
доступен. И переключался на Владивосток только если что-то случилось с каналом на Красноярск.
Ответ
Как любой хороший протокол, OSPF поддерживает аутентификацию — два соседа перед установлением
соотношений соседства могут проверять подлинность полученных OSPF-сообщений. Оставляем на
самостоятельное изучение — довольно просто.
Задача №3
С провайдером «Филькин сертификат» случилась неприятная история. Из-за их ошибки в настройках VPN на
маршрутизатор во Владивостоке начали приходить какие-то непонятные маршруты, вероятно, от другого клиента
или внутренние самого сети провайдера. Некоторые сети пересекались с локальными сетями и была потеряна
связь с некоторыми участками сети. После этого случая было решено защититься на будущее от подобных
ситуаций.
Ситуация, вообще говоря, надуманная и маловероятная, но в качестве задачки подойдёт.
На участке между Москвой и Владивостоком необходимо настроить маршрутизаторы таким образом, чтобы они,
при установке отношений соседства, проверяли ещё и установленный пароль. Пароль должен быть: MskVladPass
и передаваться он должен в виде хеша md5 (номер ключа 1).
Ответ
EIGRP
Теперь займёмся другим очень важным протоколом
Единственное, что делает EIGRP — это хранит информацию, полученную от соседа (RIP сразу же забывает то, что
не может быть использовано в данный момент). В этом смысле, он похож на BGP, который тоже хранит все в
таблице BGP и выбирает лучший маршрут оттуда. Таблица топологии (содержащая всю информацию,
полученную от соседей), дает EIGRP преимущество перед RIP – она может содержать информацию о запасном
(не используемом в данный момент) маршруте.
Метрика.
Для оценки качества определенного маршрута, в протоколах маршрутизации используется некое число,
отражающее различные его характеристики или совокупность характеристик- метрика. Характеристики,
принимаемые в расчет, могут быть разными- начиная от количества роутеров на данном маршруте и заканчивая
средним арифметическим загрузки всех интерфейсов по ходу маршрута. Что касается метрики EIGRP,
процитируем Jeremy Cioara: “у меня создалось впечатление, что создатели EIGRP, окинув критическим взглядом
свое творение, решили, что все слишком просто и хорошо работает. И тогда они придумали формулу метрики,
что бы все сказали “ВАУ, это действительно сложно и профессионально выглядит”. Узрите же полную формулу
подсчета метрики EIGRP: (K1 * bw + (K2 * bw) / (256 — load) + K3 * delay) * (K5 / (reliability + K4)), в которой:
— bw это не просто пропускная способность, а (10000000/самая маленькая пропускная способность по дороге
маршрута в килобитах) * 256
— delay это не просто задержка, а сумма всех задержек по дороге в десятках микросекунд * 256 (delay в
командах show interface, show ip eigrp topology и прочих показывается в микросекундах!)
— K1-K5 это коэффициенты, которые служат для того, чтобы в формулу “включился” тот или иной параметр.
Страшно? было бы, если бы все это работало, как написано. На деле же из всех 4 возможных слагаемых
формулы, по умолчанию используются только два: bw и delay (коэффициенты K1 и K3=1, остальные нулю), что
сильно ее упрощает — мы просто складываем эти два числа (не забывая при этом, что они все равно считаются
по своим формулам). Важно помнить следующее: метрика считается по худшему показателю пропускной
способности по всей длине маршрута.
Если K5=0, то используется следующая формула: Metric = (K1 * bw + (K2 * bw) / (256 — load) + (K3 * delay)
Интересная штука получилась с MTU: довольно часто можно встретить сведения о том, что MTU имеет
отношение к метрике EIGRP. И действительно, значения MTU передаются при обмене маршрутами. Но, как мы
можем видеть из полной формулы, никакого упоминания об MTU там нет. Дело в том, что этот показатель
принимается в расчет в довольно специфических случаях: например, если роутер должен отбросить один из
равнозначных по остальным характеристикам маршрутов, он выберет тот, у которого меньший MTU. Хотя, не все
так просто (см. комментарии).
Определимся с терминами, применяемыми внутри EIGRP. Каждый маршрут в EIGRP характеризуется двумя
числами: Feasible Distance и Advertised Distance (вместо Advertised Distance иногда можно встретить Reported
Distance, это одно и то же). Каждое из этих чисел представляет собой метрику, или стоимость (чем больше-тем
хуже) данного маршрута с разных точек измерения: FD это “от меня до места назначения”, а AD- “от соседа,
который мне рассказал об этом маршруте, до места назначения”. Ответ на закономерный вопрос “Зачем нам
надо знать стоимость от соседа, если она и так включена в FD?”- чуть ниже (пока можете остановиться и
поломать голову сами, если хотите).
У каждой подсети, о которой знает EIGRP, на каждом роутере существует Successor- роутер из числа соседей,
через который идет лучший (с меньшей метрикой), по мнению протокола, маршрут к этой подсети. Кроме того, у
подсети может также существовать один или несколько запасных маршрутов (роутер-сосед, через которого идет
такой маршрут, называется Feasible Successor). EIGRP- единственный протокол маршрутизации, запоминающий
запасные маршруты (в OSPF они есть, но содержатся, так сказать, в “сыром виде” в таблице топологии- их еще
надо обработать алгоритмом SPF), что дает ему плюс в быстродействии: как только протокол определяет, что
основной маршрут (через successor) недоступен, он сразу переключается на запасной. Для того, чтобы роутер мог
стать feasible successor для маршрута, его AD должно быть меньше FD successor’а этого маршрута (вот зачем нам
нужно знать AD). Это правило применяется для того, чтобы избежать колец маршрутизации.
Предыдущий абзац взорвал мозг? Материал трудный, поэтому еще раз на примере. У нас есть вот такая сеть:
С точки зрения R1, R2 является Successor’ом для подсети 192.168.2.0/24. Чтобы стать FS для этой подсети, R4
требуется, чтобы его AD была меньше FD для этого маршрута. FD у нас ((10000000/1544)*256)+(2100*256)
=2195456, AD у R4 (с его точки зрения это FD, т.е. сколько ему стоит добраться до этой сети) =
((10000000/100000)*256)+(100*256)=51200. Все сходится, AD у R4 меньше, чем FD маршрута, он становится FS.
*тут мозг такой и говорит: “БДЫЩЬ”*. Теперь смотрим на R3- он анонсирует свою сеть 192.168.1.0/24 соседу R1,
который, в свою очередь, рассказывает о ней своим соседям R2 и R4. R4 не в курсе, что R2 знает об этой подсети,
и решает ему рассказать. R2 передает информацию о том, что он имеет доступ через R4 к подсети 192.168.1.0/24
дальше, на R1. R1 строго смотрит на FD маршрута и AD, которой хвастается R2 (которая, как легко понять по
схеме, будет явно больше FD, так как включает и его тоже) и прогоняет его, чтобы не лез со всякими глупостями.
Такая ситуация довольно маловероятна, но может иметь место при определенном стечении обстоятельств,
например, при отключении механизма “расщепления горизонта” (split-horizon). А теперь к более вероятной
ситуации: представим, что R4 подключен к сети 192.168.2.0/24 не через FastEthernet, а через модем на 56k
(задержка для dialup составляет 20000 usec), соответственно, добраться ему стоит
((10000000/56)*256)+(2000*256)= 46226176. Это больше, чем FD для этого маршрута, поэтому R4 не станет
Feasible Successor’ом. Но это не значит, что EIGRP вообще не будет использовать данный маршрут. Просто
переключение на него займет больше времени (подробнее об этом дальше).
Соседство
Роутеры не разговаривают о маршрутах с кем попало — прежде чем начать обмениваться информацией, они
должны установить отношения соседства. После включения процесса командой router eigrp с указанием номера
автономной системы, мы, командой network говорим, какие интерфейсы будут участвовать и одновременно,
информацию о каких сетях мы желаем распространять. Незамедлительно, через эти интерфейсы начинают
рассылаться hello-пакеты на мультикаст- адрес 224.0.0.10 (по умолчанию каждые 5 секунд для ethernet). Все
маршрутизаторы с включенным EIGRP получают эти пакеты, далее каждый маршрутизатор-получатель делает
следующее:
— сверяет адрес отправителя hello-пакета, с адресом интерфейса, из которого получен пакет, и удостоверяется,
что они из одной подсети
— сверяет значения полученных из пакета K-коэффициентов (проще говоря, какие переменные используются в
подсчете метрики) со своими. Понятно, что если они различаются, то метрики для маршрутов будут считаться по
разным правилам, что недопустимо
— проверяет номер автономной системы
— опционально: если настроена аутентификация, проверяет соответствие ее типа и ключей.
Если получателя все устраивает, он добавляет отправителя в список своих соседей, и посылает ему (уже
юникастом) update-пакет, в котором содержится список всех известных ему маршрутов (aka full-update).
Отправитель, получив такой пакет, в свою очередь, делает то же самое. Для обмена маршрутами EIGRP
использует Reliable Transport Protocol (RTP, не путать с Real-time Transport Protocol, который используется в ip-
телефонии), который подразумевает подтверждение о доставке, поэтому каждый из роутеров, получив update-
пакет, отвечает ack -пакетом (сокращение от acknowledgement- подтверждение). Итак, отношение соседства
установлены, роутеры узнали друг у друга исчерпывающую информацию о маршрутах, что дальше? Дальше они
будут продолжать посылать мультикаст hello-пакеты в подтверждение того, что они на связи, а в случае
изменения топологии- update-пакеты, содержащие сведения только об изменениях (partial update).
R2 по каким-то причинам потерял связь с 192.168.2.0/24. До этой подсети у него нет запасных маршрутов (т.е.
отсутствует FS). Как всякий ответственный роутер с EIGRP, он хочет восстановить связь. Для этого он начинает
рассылать специальные сообщения (query- пакеты) всем своим соседям, которые, в свою очередь, не находя
нужного маршрута у себя, расспрашивают всех своих соседей, и так далее. Когда волна запросов докатывается
до R4, он говорит “погодите-ка, у меня есть маршрут к этой подсети! Плохонький, но хоть что-то. Все про него
забыли, а я-то помню”. Все это он упаковывает в reply-пакет и отправляет соседу, от которого получил запрос
(query), и дальше по цепочке. Понятное дело, это все занимает больше времени, чем просто переключение на
Feasible Successor, но, в итоге, мы получаем связь с подсетью.
А сейчас опасный момент: может, вы уже обратили внимание и насторожились, прочитав момент про эту
веерную рассылку. Падение одного интерфейса вызывает нечто похожее на широковещательный шторм в сети
(не в таких масштабах, конечно, но все-таки), причем чем больше в ней роутеров, тем больше ресурсов
потратится на все эти запросы-ответы. Но это еще пол-беды. Возможна ситуация и похуже: представим, что
роутеры, изображенные на картинке- это только часть большой и распределенной сети, т.е. некоторые могут
находится за много тысяч километров от нашего R2, на плохих каналах и прочее. Так вот, беда в том, что, послав
query соседу, роутер обязан дождаться от него reply. Неважно, что в ответе- но он должен прийти. Даже если
роутер уже получил положительный ответ, как в нашем случае, он не может поставить этот маршрут в работу,
пока не дождется ответа на все свои запросы. А запросы-то, может, еще где-нибудь на Аляске бродят. Такое
состояние маршрута называется stuck-in-active. Тут нам нужно познакомится с терминами, отражающими
состояние маршрута в EIGRP: active\passive route. Обычно они вводят в заблуждение. Здравый смысл
подсказывает, что active значит маршрут “активен”, включен, работает. Однако тут все наоборот: passive это “все
хорошо”, а состояние active означает, что данная подсеть недоступна, и маршрутизатор находится в активном
поиске другого маршрута, рассылая query и ожидая reply. Так вот, состояние stuck-in-active (застрял в активном
состоянии) может продолжатся до 3 минут! По истечение этого срока, роутер обрывает отношения соседства с
тем соседом, от которого он не может дождаться ответа, и может использовать новый маршрут через
R4. Подробно о проблеме
История, леденящая кровь сетевого инженера. 3 минуты даунтайма это не шутки. Как мы можем
избежать инфаркта этой ситуации? Выхода два: суммирование маршрутов и так называемая stub-конфигурация.
Вообще говоря, есть еще один выход, и он называется фильтрация маршрутов (route filtering). Но это настолько
объемная тема, что впроу отдельную статью под нее писать, а у нас и так уже пол-книги получилось в этот раз.
Поэтому на ваше усмотрение.
Как мы уже упоминали, в EIGRP суммирование маршрутов можно проводить на любом роутере. Для
иллюстрации, представим, что к нашему многострадальному R2 подключены подсети от 192.168.0.0/24 до
192.168.7.0/24, что очень удобненько суммируется в 192.168.0.0/21 (вспоминаем binary math). Роутер анонсирует
этот суммарный маршрут, и все остальные знают: если адрес назначения начинается на 192.168.0-7, то это к
нему. Что будет происходить, если одна из подсетей пропадет? Роутер будет рассылать query-пакеты с адресом
этой сети (конкретным, например, 192.168.5.0/24), но соседи, вместо того, чтобы уже от своего имени
продолжить порочную рассылку, будут сразу в ответ слать отрезвляющие реплаи, мол, это твоя подсеть, ты и
разбирайся.
Второй вариант- stub- конфигурация. Образно говоря, stub означает “конец пути”, “тупик” в EIGRP, т.е., чтобы
попасть в какую-то подсеть, не подключенную напрямую к такому роутеру, придется идти назад. Роутер,
сконфигурированный, как stub, не будет пересылать трафик между подсетями, которые ему стали известны от
EIGRP (проще говоря, которые в show ip route помечены буквой D). Кроме того, его соседи не будут отправлять
ему query-пакеты. Самый распространенный случай применения- hub-and-spoke топологии, особенно с
избыточными линками. Возьмем такую сеть: слева- филиалы, справа- основной сайт, главный офис и т.п. Для
отказоустойчивости избыточные линки. Запущен EIGRP с дефолтными настройками.
А теперь “внимание, вопрос”: что будет, если R1 потеряет связь с R4, а R5 потеряет LAN? Трафик из подсети R1 в
подсеть главного офиса будет идти по маршруту R1->R5->R2(или R3)->R4. Будет это эффективно? Нет. Будет
страдать не только подсеть за R1, но и подсеть за R2 (или R3), из-за увеличения объемов трафика и его
последствий. Вот для таких-то ситуаций и придуман stub. За роутерами в филиалах нет других роутеров, которые
вели бы в другие подсети, это “конец дороги”, дальше только назад. Поэтому мы с легким сердцем можем
сконфигурировать их как stub’ы, что, во-первых, избавит нас от проблемы с “кривым маршрутом”, изложенной
чуть выше, а во-вторых, от флуда query-пакетов в случае потери маршрута.
Существуют различные режимы работы stub-роутера, задаются они командой eigrp stub:
R1(config)#router eigrp 1
R1(config-router)#eigrp stub?
connected Do advertise connected routes
leak-map Allow dynamic prefixes based on the leak-map
receive-only Set IP-EIGRP as receive only neighbor
redistributed Do advertise redistributed routes
static Do advertise static routes
summary Do advertise summary routes
По умолчанию, если просто дать команду eigrp stub, включаются режимы сonnected и summary. Интерес
представляет режим receive-only, в котором роутер не анонсирует никаких сетей, только слушает, что ему
говорят соседи (в RIP есть команда passive interface, которая делает то же самое, но в EIGRP она полностью
отключает протокол на выбранном интерфейсе, что не позволяет установить соседство).
Практика EIGRP
“Лифт ми Ап” купили фабрику в Калининграде. Там производят мозги лифтов: микросхемы, ПО. Фабрика очень
крупная — три точки по городу — три маршрутизатора соединены в кольцо.
Но вот незадача — на них уже запущен EIGRP в качестве протокола динамической маршрутизации. Причём
адресация конечных узлов совсем из другой подсети — 10.0.0.0/8. Все другие параметры (линковые адреса,
адреса лупбэк интерфейсов) мы поменяли, но несколько тысяч адресов локальной сети с серверами,
принтерами, точками доступа — работа не на пару часов — отложили на потом, а в IP-плане зарезервировали на
будущее для Калининграда подсеть 172.16.32.0/20.
router eigrp 1
network 10.0.0.0
В EIGRP обратную маску можно задавать, указывая тем самым более узкие рамки, либо не задавать, тогда будет
выбрана стандартная маска для этого класса (16 для класса B — 172.16.0.0 и 8 для класса А — 10.0.0.0)
Такие команды даются на всех маршрутизаторах Автономной Системы. АС определяется цифрой в команде
router eigrp, то есть в нашем случае имеем АС №1. Эта цифра должна быть одинаковой на всех маршрутизаторах
(в отличии от OSPF).
klgr-center-gw1:
klgr-balt-gw1 знает о своих двух сетях 10.0.1.0/24 и 10.0.2.0/24, но вот сеть 10.0.0.0/24 он куда-то спрятал.
А вот klgr-center-gw2 знает, что подсети 10.0.0.0/8 находятся за обоими его WAN интерфейсами.
router eigrp 1
network 172.16.0.0
network 10.0.0.0
auto-summary
Во всём виновато автоматическое суммирование. Это самое большое зло EIGRP. Рассмотрим более подробно,
что происходит. klgr-center-gw1 и klgr-balt-gw1 имеют подсети из 10.0.0.0/8, они их суммируют по умолчанию,
когда передают соседям.
То есть, например, klgr-balt-gw1 передаёт не две сети 10.0.1.0/24 и 10.0.2.0/24, а одну обобщённую: 10.0.0.0/8. То
есть его сосед будет думать, что за klgr-balt-gw1 находится вся эта сеть.
Но, что произойдёт, если вдруг на balt-gw1 попадёт пакет с адресатом 10.0.50.243, о котором тот ничего не знает?
На этот случай и создаётся так называетмый Blackhole-маршрут:
Полученный пакет будет выброшен в эту чёрную дыру. Это делается во избежание петель маршрутизации.
Так вот оба эти маршрутизатора создали свои blackhole-маршруты и игнорируют чужие анонсы. Реально на такой
сети эти три девайса друг друга так и не смогут пинговать, пока… пока вы не отключите auto-summary.
router eigrp 1
no auto-summary
klgr-center-gw1:
klgr-balt-gw1
10.0.0.0/24 is subnetted, 3 subnets
klgr-center-gw2:
Задача №4
Из-за настроек различных механизмов QoS на маршрутизаторах Калининграда, было изменено значение
пропускной способности на интерфейсах, эти значения теперь не соответствуют действительности.
Поэтому было решено, что необходимо изменить подсчет метрики EIGRP на маршрутизаторах Калининграда
таким образом, чтобы учитывалась только задержка (delay) и не учитывалась пропускная способность
интерфейса (bandwidth).
Ответ
Для её осуществления нам нужна хотя бы одна точка стыка, где будут запущены одновременно два протокола.
Это может быть msk-arbat-gw1 или klgr-balt-gw1. Выберем второй.
Из в EIGRP d OSPF:
klgr-gw1(config)#router ospf 1
Вот те, что с меткой Е2 — новые импортированные маршруты. Е2 — означает, что это внешние маршруты 2-го
типа (External), то есть они были введены в процесс OSPF извне
klgr-gw1(config)#router eigrp 1
Без указания метрики (вот этого длинного набора цифр) команда выполнится, но редистрибуции не произойдёт.
Маршрут по умолчанию
Теперь самое время проверить доступ в интернет. Из Москвы он прекрасно себе работает, а вот если проверить,
например из Петербурга (помним, что мы удалили все статические маршруты):
PC>ping linkmeup.ru
Это связано с тем, что ни spb-ozerki-gw1, ни spb-vsl-gw1, ни кто-либо другой в нашей сети не знает о маршруте по
умолчанию, кроме msk-arbat-gw1, на котором он настроен статически.
Чтобы исправить эту ситуацию, нам достаточно дать одну команду в Москве:
msk-arbat-gw1(config)#router ospf 1
msk-arbat-gw1(config-router)#default-information originate
После этого по сети лавинно распространяется информация о том, где находится шлюз последней надежды.
PC>tracert linkmeup.ru
1 3 ms 3 ms 3 ms 172.16.17.1
2 4 ms 5 ms 12 ms 172.16.2.5
3 14 ms 20 ms 9 ms 172.16.2.1
4 17 ms 17 ms 19 ms 198.51.100.1
5 22 ms 23 ms 19 ms 192.0.2.2
Trace complete.
msk-arbat-gw1:
klgr-balt-gw1:
Maximum path: 4
172.16.0.0
172.16.2.42 90 4
172.16.2.38 90 4
Router ID 172.16.255.64
EIGRP 1
Maximum path: 4
4) Для отладки и понимания работы протоколов будет полезно воспользоваться следующими командами:
debug ip OSPF events
debug ip OSPF adj
debug EIGRP packets
Попробуйте подёргать разные интерфейсы и посмотреть, что происходит в дебаге, какие сообщения летят.
Задача №7
На последок комплесная задачка.
На последнем совещании Лифт ми Ап было решено, что сеть Калининграда необходимо также
переводить на OSPF.
Переход должен быть совершен без разрывов связи. Было решено, что лучшим вариантом будет параллельно с
EIGRP поднять OSPF на трёх маршрутизаторах Калининграда и после того, как будет проверено, что вся
информация о маршрутах Калининграда распространилась по остальной сети и наоборот, отключить EIGRP.
Но, так как сеть Калининграда достаточно большая, с большим количеством сетей, было решено, что
необходимо отделить её от остальной сети так, чтобы изменения в сети Калининграда не приводили к запуску
алгоритма SPF на других маршрутизаторах сети.
Ответ.
Материалы выпуска
Новый IP-план, планы коммутации по каждой точке и регламент
Файл РТ с лабораторной
Конфигурация устройств
Полезные ссылки
Наш большой помощник XGU.ru
OSPF в cisco
OSPF
Коллеги по хабру
Inter-domain Routing Loops
Особенности работы External Type 1 и External Type 2 маршрутов в OSPF. Часть 1
Особенности работы External Type 1 и External Type 2 маршрутов в OSPF. Часть 2
Другие
Cisco
В википедии
То же самое на русском
Покупка заводов в Сибири была стратегически правильным решением для компании “Лифт ми Ам”. После того,
как лифты стали ездить не только вверх, но и вниз, дела компании пошли… нет полетели, вверх. Лифты начали
разбирать, как горячие пирожки со стола. Название уже не соответствовало действительности и было принято
решение о ребрендинге. (На самом деле их замучила судебная тяжба с Моби).
Итак, под крыло ЛинкМиАп планируется взять заводы в Новосибирске, Томске и Брно. Самое время подумать о
том, как это хозяйство подключить к имеющейся сети.
В традиционном видео лишь ёмкая выжимка из статьи, посвящённая работе и настройке DMVPN.
Когда вы хотите связать несколько офисов, у вас огромнейший выбор способов и средств. Всё зависит только от
ваших возможностей, способностей, желаний и наличия оборудования.
Давайте по порядку.
В этом случае для вас всё прозрачно – вы используете свою собственную физическую линию, поэтому пропускать
через неё можете что угодно без ограничений.
Б) Второй вариант – арендовать канал у провайдера. В случае необходимости стабильного канала до другого
города – это самый распространённый и надёжный вариант. Провайдер может вам предоставить следующие
услуги:
1. Самый настоящий прямой кабель. Например, он может дать вам взаймы одно-два тёмных волокна из
своего оптического пучка. Вы вольны отправлять в него всё, что вашей душе угодно. Со стороны
провайдера это никак не контролируется, не ограничивается, он осуществляет только поддержку.
Например, в случае аварии не вам придётся искать подрядчика и сварочный аппарат, а провайдеру. И за
простой несёт ответственность он же. Если у вас это не по обоюдному согласию (читай, взаимозачёт), то,
пожалуй, самый дорогой способ.
2. L2VPN. Вы так же можете пускать в канал всё, что угодно, но в данном случае, ваш трафик пойдёт через
активное оборудование провайдера, поэтому может ограничиваться, например, по скорости.
3. Под этим термином понимается сразу несколько услуг второго уровня:
4. VLAN – в том или ином виде между филиалами вам предоставлен VLAN.
5. Псевдокабель (PWE3) – это услуга Точка-Точка, когда у вас как будто бы кабель между двумя узлами. Все
переданные вами фреймы без изменений доставляются до удалённой точки. Аналогично обратным
образом. Это возможно благодаря тому, что ваш фрейм, приходящий на маршрутизатор провайдера
инкапсулируется в PDU вышестоящего уровня, как правило, это пакет MPLS.
6. VPLS (Виртуальная частная сеть) – это симуляция локальной сети. В этом случае вся сеть провайдера для
вас будет как некий абстрактный гигантский коммутатор. Как и настоящий он будет хранить таблицу MAC-
адресов и принимать решение о том, куда отправить пришедший кадр. Реализуется это также
инкапсуляцией кадра в MPLS пакет.
7. L3VPN. В данном случае сеть провайдера – это как большой маршрутизатор с несколькими
интерфейсами. То есть стык у вас будет происходить на сетевом уровне. Вы настраиваете IP-адреса на
своих маршрутизаторах с обеих сторон, а вот маршрутизация в сети провайдера – это уже головная боль
провайдера. IP-адреса для точек стыка можете либо определять вы, либо выдать провайдер – зависит от
реализации и от вашей договорённости. Функционировать это может на основе GRE, IPSec или того же
MPLS.
Эта услуга выглядит очень простой с точки зрения клиента – как в плане настройки, так и в плане реализации – но
сложной – с точки зрения оператора.
С реализацией L2/L3 VPN на основе MPLS мы будем разбираться, но гораздо позже.
В) Ну и последний вариант: туннель через публичную сеть. Предположим, у вас есть выход в Интернет на обеих
ваших точках. Зачастую самым дешёвым способом оказывается построить туннель между этими двумя точками.
Для этого вам достаточно всего лишь иметь белые (публичные) статические адреса на всех точках (а иногда
достаточно и на одной) и оборудование, на котором это реализовать. У этого решения есть ряд недостатков,
которые мы рассмотрим ниже, но тем не менее именно на нём мы сегодня и остановимся.
Итак, ваша воля выбирать, какой вариант использовать, исходя из бюджета, целесообразности и ваших
способностей к убеждению руководства.
В рамках данного выпуска нам нужно подключить 3 офиса: в Новосибирске, Томске и Брно. Условимся, что везде
мы будем использовать только подключение к сети Интернет.
Напоминаю, что общая схема сети ЛинкМиАп выглядит сейчас уже так:
Откровенно говоря, нам это мало интересно, гораздо занимательнее вопрос, как подключать целые сети.
GRE
Generic Routing Encapsulation – очень простой протокол туннелирования.
Такс, туннелирование. Это что ещё за зверь? Грубо говоря, это означает, что берутся ваши изначальные данные
вместе со служебными заголовками (как правило, это IP, но может быть и Ethernet и ATM), упаковываются в
пакет и передаются по публичной сети, словно машина едет в туннеле через горы. На конечном узле заголовки
нового пакета снимаются, а ваши данные в исходном виде продолжают своё путешествие.
Не очень понятно, да? Разберём на примере с GRE.
Таким образом для ПК1 при общении с ПК2 не существует никакого Интернета – они оба будут думать, что
находятся в одной локальной сети.
interface Tunnel0
Поскольку туннель является виртуальным L3 интерфейсом, через который у нас будет происходить
маршрутизация, ему должен быть назначен IP-адрес, который выбирается согласно вашему IP-плану, вероятно,
из приватной сети.
Законченный вид:
interface Tunnel0
Вся основная информация здесь отражена. Обратите внимание на размер MTU – он не 1500, как ставится для
обычных физических интерфейсов. О параметре MTU мы поговорим в конце статьи
По умолчанию GRE не проверяет доступность адреса назначения и сразу отправляет туннель в Up. Но стоит
только добавить в туннельный интерфейс команду keepalive X, как маршрутизатор начинает отсылать кипалайвы
и не поднимется, пока не будет ответа.
В нашей тестовой схеме в качестве локальной сети мы просто настроили Loopback-интерфейсы – они всегда в
Up'е. Дали им адреса с маской /32. На самом же деле под ними подразумеваются реальные подсети вашего
предприятия (ну, как на картинке).
interface Loopback0
Первый говорит о том, что шлюзом по умолчанию является адрес провайдера 100.0.0.2:
R1#traceroute 200.0.0.1
Type escape sequence to abort.
Tracing the route to 200.0.0.1
1 100.0.0.2 56 msec 48 msec 36 msec
2 200.0.0.1 64 msec * 60 msec
Второй перенаправляет пакеты, адресованные хосту с адресом 10.1.1.0, на next-hop 10.2.2.2 – это адрес туннеля с
обратной стороны.
nsk-obsea-gw1:
interface Tunnel0
Такссс, Tunnel 0:
R1#sh int tun 0
Tunnel0 is up, line protocol is up
Hardware is Tunnel
Internet address is 10.2.2.1/30
MTU 1514 bytes, BW 9 Kbit, DLY 500000 usec,
reliability 255/255, txload 1/255, rxload 1/255
Encapsulation TUNNEL, loopback not set
Keepalive not set
Tunnel source 100.0.0.1, destination 200.0.0.1
А сверху новый заголовок IР. В качестве отправителя будет значиться адрес tunnel source, а в качестве получателя
– tunnel destination.
4) Новоиспечённый пакет отправляется в дивный мир по дефолтному маршруту:
R1#sh ip route
Gateway of last resort is 100.0.0.2 to network 0.0.0.0
5) Не забываем про заголовок Ethernet, при отправке провайдеру он также должен быть сформирован.
Поскольку GRE-туннель – виртуальный интерфейс 3-го уровня, он не обладает собственным MAC-адресом (как и
Loopback, например). В конечном итоге кадр уйдёт с физического интерфейса FastEthernet0/0:
R1#sh ip route 100.0.0.2
Routing entry for 100.0.0.0/30
Known via «connected», distance 0, metric 0 (connected, via interface)
Routing Descriptor Blocks:
* directly connected, via FastEthernet0/0
Route metric is 0, traffic share count is 1
Destination по традиции берётся из ARP-кэша или получается с помощью ARP-запроса от адреса 100.0.0.2:
R1#show arp
Protocol Address Age (min) Hardware Addr Type Interface
Internet 100.0.0.1 – c000.25a0.0000 ARPA FastEthernet0/0
Internet 100.0.0.2 71 c001.25a0.0000 ARPA FastEthernet0/0
6) И в таком виде новый IP-пакет передаётся в интернет. А поскольку каждый маршрутизатор не раздербанивает
пакет, а принимает решение на основе первого же заголовка IP, то никто в Интернете не будет знать о том, что
где-то там внутри кроются ваши приватные адреса 10.1.1.0 и 10.0.0.0.
Он проверяет, что у него действительно есть такой GRE-туннель, снимает заголовок GRE, и дальше это уже самый
обычный IP-пакет, с которым нужно распорядиться согласно записям в таблице маршрутизации.
1 – изначальные данные
2 – первый IP-заголовок (внутренний)
3 – заголовок GRE (с указанием, что внутри лежат данные протокола IP)
4 – новый заголовок IP (внешний, с туннельными адресами)
Если попытаться провести аналогии с осязаемым миром, то представим ситуацию, когда вы едете из деревни,
инкапсулированные в автомобиль. Доезжаете до реки, и вам надо перебраться на другой берег и там
продолжить своё путешествие в город.
На речном порту ваш автомобиль инкапсулируют в паром и переправляют через бушующие волны на другую
сторону, где ваш автомобиль извлекают, и вы продолжаете движение. Так вот этот паром и был GRE-паромом.
Сделаем три ремарки:
Во-первых, интерфейсы Loopback и адреса с маской /32 мы выбрали просто для теста, фактически это вполне бы
могли быть интерфейсы fa1/0.15 и fa0/1.16 с подсетями 172.16.15.0/24 и 172.16.16.0/24, например, или любые
другие.
Во-вторых, мы тут всё ведём речи о публичных сетях и адресах, но на самом деле, конечно, это не имеет
значения и туннели вполне можно поднимать даже внутри своей корпоративной сети, когда конечные сети и так
имеют IP-связность без туннеля.
В-третьих, несмотря на то, что теоретически обратно трафик может возвращаться и не по туннелю, создать его
необходимо, чтобы конечный узел могу успешно декапсулировать GRE-пакеты
Обычный GRE – яркий пример туннелирования, который очень просто настраивается и сравнительно легко
траблшутится.
Очевидно, вы уже догадываетесь, какие три большие проблемы подстерегают нас на этом поле?
• Безопасность. Данные, инкапсулированные в GRE, передаются тем не менее в открытом виде.
• Сложность масштабирования. Если у вас 5-7 филиалов, обслуживание такого количества туннелей ещё
кажется возможным, а если их 50? Причём туннелирование трафика зачастую производится на CPU, особенно на
младшей и средней линейках, поэтому это лишняя нагрузка на процессор.
• Все филиалы будут взаимодействовать друг с другом через центральный узел, хотя могли бы напрямую.
IPSec
Первую озвученную выше проблему призвано решить шифрование.
Для начала нужно уяснить себе, что IPSec – это не протокол, это стандарт, включающий в себя целых три
протокола, каждый со своими функциями:
1. ESP (Encapsulating Security Payload – безопасная инкапсуляция полезной нагрузки) занимается
непосредственно шифрованием данных, а также может обеспечивать аутентификацию источника и
проверку целостности данных
2. AH (Authentication Header – заголовок аутентификации) отвечает за аутентификацию источника и
проверку целостности данных
3. IKE (Internet Key Exchange protocol – протокол обмена ключами) используется для формирования IPSec SA
(Security Association, об этом чуть ниже), проще говоря, согласования работы участников защищенного
соединения. Используя этот протокол, участники договариваются, какой алгоритм шифрования будет
использоваться, по какому алгоритму будет производиться (и будет ли вообще) проверка целостности, как
аутентифицировать друг друга
Прежде чем переходить дальше, разберемся с термином SA – Security Association. SA в общем смысле
представляет собой набор параметров защищенного соединения (например, алгоритм шифрования, ключ
шифрования), который может использоваться обеими сторонами соединения. У каждого соединения
есть ассоциированный с ним SA.
Теперь по порядку, как создается защищенное соединение в IPSec:
• Для начала, участникам надо договориться, какие алгоритмы/механизмы защиты они будут использовать
для своего защищенного соединения, поэтому в дело вступает IKE. Процесс состоит из двух фаз:
o Фаза первая: участники аутентифицируют друг друга и договариваются о параметрах установки
специального соединения (тоже защищенного), предназначенного только для обмена информацией
о желаемых/поддерживаемых алгоритмах шифрования и прочих деталях будущего IPSec-туннеля.
Параметры этого мини-туннеля (правильно он называется ISAKMP Tunnel) определяются политикой
ISAKMP, в режим редактирования которой мы можем попасть из конфигурационного режима
командой crypto isakmp policy номер_политики. Если стороны пришли к соглашению,
устанавливается ISAKMP туннель (его наличие можно посмотреть командой show crypto isakmp sa),
по которому уже проходит вторая фаза IKE.
o Фаза вторая: уже доверяющие друг другу участники договариваются о том, как строить основной
туннель для данных. Они по очереди предлагают друг другу варианты, указанные в команде crypto
ipsec transform-set, и, если приходят к согласию, поднимают основной туннель. Нужно сказать, что,
после его установления, вспомогательный ISAKMP туннель никуда не пропадает – он используется
для обновления SA основного. Дело в том, что ключи, выбираемые для шифрования информации в
IPSec-туннеле, имеют некоторое “время жизни” (может выражаться как в количестве байт, так и в
секундах – что первое достигнет порогового значения), по истечение которого должны быть
заменены. Это как пароль, который вы меняете раз в час (по умолчанию lifetime IPSec SA составляет
4608000 килобайт/3600 секунд).
• Участники получили шифрованный туннель с параметрами, которые их всех устраивают, и направляют
туда потоки данных, подлежащие шифрованию, т.е., подпадающие под указанный в crypto map аксесс-
лист.
• Периодически, в соответствии с настроенным lifetime, обновляются ключи шифрования для основного
туннеля: участники вновь связываются по ISAKMP-туннелю, проходят вторую фазу и устанавливают новые
SA.
Строго говоря, в этом процессе есть нулевой шаг: некий трафик должен попасть в соответствие аксесс-листу в
крипто мапе. Только после этого будет происходить все остальное.
Теперь немного о трансформ-сете и чем отличается ESP от AH. Как будут шифроваться наши данные, идущие
через туннель, определяет команда crypto ipsec transform-set имя_сета, после которой идет название
протокола, который будет использован (ESP или AH) + алгоритм, по которому будет работать протокол.
Например, команда crypto ipsec transform-set SET1 esp-aes даст понять роутеру, что трансформ-сет с именем
“SET1”, если он будет применен, будет работать только по протоколу ESP c шифрованием алгоритмом AES. Ну
если с ESP все более-менее понятно, его дело-шифровать (обеспечивать конфиденциальность), то что такое AH и
зачем он вообще нужен? AH обеспечивает аутентификацию данных, то есть дает уверенность, что эти данные
пришли именно от того, с кем мы установили связь, и не были изменены по дороге. Если не углубляться в
подробности, работает это так: в каждый пакет между заголовком IP и заголовком транспортного уровня
вставляется заголовок AH, в котором присутствует:
• информация, по которой получатель может понять, к какой SA относится данный пакет (т.е., в том числе,
по какому алгоритму ему считать хеш для сравнения – MD5 или SHA)
• так называемый ICV (Integrity Check Value), представляющий собой хеш от пакета (на самом деле, не всего
пакета, а неизменяемых в процессе путешествия полей), который позволяет однозначно убедиться
получателю, что этот пакет не изменялся по дороге, путем вычисления хеша от той же информации и
сравнения результата со значением этого поля.
В этом режиме берётся ваш изначальный IP-пакет, шифруется полностью, вместе с заголовком IP, добавляется
служебная информация IPSec и новый заголовок IP:
*рисунок не точен и показывает лишь суть, на самом деле заголовков там больше, а так же есть трейлеры
в конце.
Сначала общую политику для фазы 1 – установление первого, вспомогательного туннеля: тип шифрования (по
умолчанию DES) и аутентификации. Аутентификацию можно делать на основе сертификатов, но мы рассмотрим
простой пример с предварительным ключом:
encr aes
authentication pre-share
Часто задаются несколько таких политик с различными комбинациями шифрования, хеша и группы DH. Чем
больше номер политики, тем позже он будет рассмотрен (в зависимости от того, кто инициирует соединение). То
есть сначала выбирается политика с наименьшим номером – не совпали на обеих сторонах, выбирается
следующая (с большим номером) и т.д. Логично, что самой безопасной должна быть первая.
Далее мы указываем параметры для обработки трафика. Алгоритм шифрования AES с использованием ESP-
заголовка и алгоритм аутентификации.
На самом деле мы указываем сразу набор протоколов, как вы видите, он и называется transform-set. При
установке IPSec-сессии маршрутизаторы обмениваются этими наборами. Они должны совпадать.
Для упрощения траблшутинга имена для transform-set обычно даются по применённым протоколам.
Вот именно тут и определяется адрес соседа IPSec, с которым потом будет устанавливаться туннель – 200.0.0.1.
Тут же привязывается набор протоколов и ACL, определяющий, какой трафик будет шифроваться и передаваться
через туннель.
Будьте внимательны при задании ACL. Он определяет параметры не только исходящего трафика, но и входящего
(в отличие от ACL для NAT, например).
То есть если придут пакеты не от 10.1.1.0, а от 10.2.2.2, он не будет обработан и дешифрован.
То бишь, если мы генерируем трафик с хоста с адресом 10.0.0.0 на 10.1.1.0, то он и только он будет шифроваться
и отправляться именно в IPSec-туннель. Любой другой пойдёт простым путём.
Заметим, что шифрование, происходит практически в самую последнюю очередь, после маршрутизации.
И это, кстати, очень важный момент. Вам недостаточно маршрута до публичного адреса пира (200.0.0.1). Нужен
маршрут до 10.1.1.0 пусть даже он дефолтный. Иначе пакет будет отброшен в соответствии с обычными
правилами маршрутизации.
Как бы странно это ни казалось, но трафик в локальную сеть у вас должен быть “зарулен”, например, в Интернет.
При этом приватные пакет, которые уже вот-вот должны быть отправлены к провайдеру и там отброшены, в
последний момент шифруется, получая публичные адреса.
Кстати, тут есть таблица с порядком следования операций, производимых над трафиком.
Последний шаг – привязка карты шифрования к интерфейсу. Пока вы этого не сделаете механизм не будет
работать.
interface FastEthernet0/0
encr aes
authentication pre-share
interface FastEthernet0/1
Вот и всё.
Но сколько бы вы после ни смотрели show crypto session или show crypto isakmp sa, вы увидите только Down.
Туннель никак не поднимается.
Interface: FastEthernet0/0
Session status: DOWN
Peer: 200.0.0.1 port 500
IPSEC FLOW: permit ip host 10.0.0.0 host 10.1.1.0
Active SAs: 0, origin: crypto map
Дело в том, что вам необходимо пустить в него трафик. В прямом смысле, например так:
R1#ping 10.1.1.0 source 10.0.0.0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.1.0, timeout is 2 seconds:
Packet sent with a source address of 10.0.0.0
.!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 60/94/160 ms
И как только вы это сделали, вас ждёт успех:
R1#sh crypto session
Crypto session current status
Interface: FastEthernet0/0
Session status: UP-ACTIVE
Peer: 200.0.0.1 port 500
IKE SA: local 100.0.0.1/500 remote 200.0.0.1/500 Active
IPSEC FLOW: permit ip host 10.0.0.0 host 10.1.1.0
Active SAs: 2, origin: crypto map
=====================
Задача №1
Задание:
1. Настроить туннель IPsec с использованием crypto-map между R4 и R1:
— Политики защиты данных такие же, как и для туннеля между R3 и R1.
2. Добавить соответствующие настройки для того чтобы R3 и R4 также могли обмениваться данными:
— Данные между филиалами за R3 и R4 должны передаваться через центральный маршрутизатор R1
Подробности задачи тут
=====================
Что произошло?
2) Согласно таблице маршрутизации пакет должен быть передан в публичную сеть в том виде, в каком он есть.
3) Но маршрутизатор видит, что это подпадает по его ACL 101 и передаёт пакет в работу IPSec'у.
4) IPSec, работая в туннельном режиме (режим по умолчанию), упаковывает исходный пакет сначала в IPSec PDU,
попутно шифруя всё и вся, а потом укомплектовывает его новым IP-заголовком. В качестве адреса назначения
маршрутизатор прописывает адрес своего IPSec-соседа – 200.0.0.1.
Это был обмен ICMP-сообщениям. Все исходные данные зашифрованы, включая старый IP, новый IP-заголовок
опирается на настройку IPSec.
5) На конечном узле маршрутизатор видит, что адрес назначения принадлежит ему, снимает заголовок IP и видит
заголовок IPSec, этому протоколу он и передаёт пакет на обработку. Последний дешифруется, удаляется вся
служебная информация, и исходный пакет путешествует дальше.
Почему мы запускали такой странный Ping? В нём мы указали адрес отправителя явно.
Если же мы попытаемся запустить Ping 10.1.1.0, то он не пройдёт, потому что маршрутизатор автоматически
подставляет в качестве отправителя адрес физического интерфейса: 100.0.0.1, который не попадает в наш ACL, и
поэтому пакет пытается уйти на шлюз последней надежды.
Какую самую главную проблему мы имеем тут? Бинго! Динамическая маршрутизация. Внедрить её в таких
условиях невозможно – все IGP требуют прямого L2-линка между соседями, чего не обеспечивает IPSec. Поэтому
в такой реализации трафик отправляется в туннель на основе ACL и карты шифрования, а не таблицы
маршрутизации.
Плюс мы имеем проблему с мультикастом, потому что задаём конкретные подсети в ACL.
=====================
Задача №2
Конфигурация: «IPsec»
Примечание:
Задача может быть решена, как теоретически, так и практически.
Если Вы будете пробовать задачу на практике, то внимательно соблюдайте условия задачи.
Условия задачи:
Маршрутизатор R1 стоит в центральном офисе и к нему будут подключены 3 филиала (для данной задачи
достаточно маршрутизаторов R1, R2, R3. R3 — в роли одного из филиалов). В филиалах используются
маршрутизаторы с разными возможностями, и необходимо использовать разные политики IPsec. Всего есть 3
различные политики.
На маршрутизаторе R3, кроме туннеля в центральный офис также есть несколько туннелей с партнерами.
Поэтому тут тоже созданы различные политики.
Трафик передается только из филиалов в центральный офис, между филиалами коммуникаций нет.
Со стороны филиала R3 в центральный офис R1 генерируются данные, которые инициируют туннель VPN.
Вопрос: Какую политику защиты данных будут использовать маршрутизаторы для построения туннеля между
собой?
То есть туннельный шифрует изначальный пакет полностью и добавляет новый заголовок IP. Транспортный же
шифрует всё, что выше уровня IP, а заголовок IP оставляет без изменений.
Грубо говоря, туннельный режим вы используете для того, чтобы связать две приватные сети через публичную,
обеспечив при этом шифрование (Что-то вроде безопасного GRE). Транспортный же актуален тогда, когда IP-
связность уже достигнута, но трафик между узлами нужно шифровать.
Удачным примером применения транспортного режима может быть схема сервер-клиент. Например, работа
клиент-банка. Сервер и так уже доступен, но трафик нужно зашифровать.
Описание проблемы:
Не передаются данные между R1 и R4.
Задание:
Найти ошибку и исправить конфигурацию так, чтобы туннель между R1 и R4 установился и передавался трафик
между R1 и R4.
А IPSec over GRE означает, наоборот, что внутри будут зашифрованные данные IPSec, а сверху заголовки GRE/IP.
Они будут не зашифрованы:
Такой вариант возможен, например, если шифрование у вас происходит на отдельном устройстве перед
туннелированием
Зачем такая пахабщина нужна, не очень понятно, поэтому обычно используется именно GRE over IPSec.
interface Tunnel0
mode transport
*Заметьте, менять, это надо на обеих сторонах, иначе соседство IPSec не установится.
Во-вторых, шифроваться должен весь трафик между филиалами, то есть тот, который идёт через туннель,
соответственно, нет необходимости прописывать все сети в ACL, поступим хитрее:
Условие выполняется, если на порт пришёл трафик с заголовком GRE и соответствующими адресами.
2) Это туннельный интерфейс, с адресом назначения 200.0.0.1. Пакет упаковывается заголовком GRE и новым IP
заголовком.
R1#sh int tun 0
Tunnel0 is up, line protocol is up
Hardware is Tunnel
Internet address is 10.2.2.1/30
MTU 1514 bytes, BW 9 Kbit, DLY 500000 usec,
reliability 255/255, txload 1/255, rxload 1/255
Encapsulation TUNNEL, loopback not set
Keepalive not set
Tunnel source 100.0.0.1, destination 200.0.0.1
Tunnel protocol/transport GRE/IP
Такая схема работы позволяет нормально внедрять протоколы динамической маршрутизации, а также
передавать мультикастовый трафик, оставляя возможность шифрования. Хулиганы уже не смогут выкрасть
секретные рецепты приготовления лифтов.
=====================
Задача №5
Схема: «GRE_over_IPSec»
Описание проблемы:
После настройки GRE over IPSec между R1 и R3, всё прекрасно работает, трафик между R1 и R3 (c 10.0.0.0 на
10.1.1.0) передается.
Однако, через несколько дней, когда администратор хотел посмотреть состояние VPN, обнаружилось, что на
маршрутизаторах вообще нет установленных SA.
Соответственно, трафик между R1 и R3 не шифруется.
Задание:
Необходимо проверить настройки, исправить конфигурацию и сделать так, чтобы трафик шифровался (трафик
между loopback-интерфейсами 10.0.0.0 и 10.1.1.0).
interface Tunnel0
Нужно правда помнить, что в этом случае инкапсулировать можно только данные IP, а не любые, как в случае
GRE.
=====================
Задача №4
Схема: «GRE_over_IPSec»
Конфигурация: «GRE_over_IPSec»
Задание:
Изменить исходную конфигурацию GRE over IPSec и настроить GRE over IPsec без использования crypto-map.
IPSec VTI
Последний пример Site-to-Site VPN с использованием IPSec, который, собственно, и рекомендован циской – VTI
(Virtual Tunnel Interface)
Настройка IPSec отличается тем, что нам уже не нужно создавать вручную crypto-map (а соответственно и ACL),
вместо него мы создаём IPSec-профиль
authentication pre-share
mode transport
interface Tunnel0
Отличие от использованных ранее Crypto map в том, что сейчас нет нужды создавать ACL – весь трафик,
попадающий в туннель, шифруется (карты шифрования тем не менее по-прежнему создаются, но уже
автоматически).
Это получился обычный Tunnel Protection без VTI. Так же широко используется.
Команда tunnel mode ipsec ipv4 указывает на использование VTI.
Отличие от обычного GRE в методах инкапсуляции – в VTI экономится 4 байта путём исключения GRE-заголовка.
Небольшое описание
Полная конфигурация маршрутизаторов для IPSec VTI.
DMVPN
Апофеоз сегодняшнего выпуска – DMVPN (Dymamic Multipoint VPN). До сих пор речь была об универсальных
вендоронезависымых вещах. К сожалению, DMVPN – вещь сугубо цисковская и открытых адекватных аналогов
пока не имеет (поправьте, если ошибаюсь).
И ещё один:
Нужно уже гораздо больше туннелей для получения полносвязной топологии. Типичная проблема со
сложностью m*(m-1)/2.
Суть такая: выбирается центральная точка Hub (или несколько). Она будет сервером, к которому будут
подключаться клиенты (Spoke) и получать всю необходимую информацию. При этом:
Абстрагируясь от нашей старой сети, возьмём в рассмотрение только Москву, сеть Интернет, которую будет
эмулировать маршрутизатор Балаган-Телеком, и собственно филиалы в Новосибирске, Томске и Брно:
Новый IP-план:
LAN:
Идея заключается в том, что на центральном узле будет один единственный динамический туннель, который мы
настроим в самом начале, а при добавлении новых удалённых точек, здесь не нужны изменения – ни добавлять
новые туннельные интерфейсы, ни перенастраивать уже существующий.
Он позволяет динамически изучать адреса удалённых точек, который желают подключиться к основной.
На нём и основана возможность реализации multipoint VPN. Хаб (центральный узел) здесь выступает как сервер
(NHS – Next-Hop Server), а все удалённые узлы будут клиентами (NHC – Next-Hop Client).
Звучит это сложно. На пальцах объяснить тоже не получится. Надо лишь один раз настроить и посмотреть, как
бегают пакеты.
Конфигурация хаба:
interface Tunnel0
ip nhrp network-id 1
По порядку:
ip nhrp network-id 1 – Определяем Network ID – просто идентификатор, который необязательно должен быть
одинаковым на всех узлах DMVPN (похож на OSPF Router-ID).
tunnel mode gre multipoint – Туннель на центральном узле будет терминировать все туннели от удалённых точек.
То есть он будет точка-многоточка (Point-to-MultiPoint).
Конфигурация филиала:
interface Tunnel0
ip nhrp network-id 1
По порядку:
*Mar 1 01:51:20.331: %OSPF-5-ADJCHG: Process 1, Nbr 172.16.255.2 on Tunnel0 from FULL to DOWN, Neighbor Down:
Dead timer expired
msk-arbat-gw1#
*Mar 1 01:51:25.435: %OSPF-5-ADJCHG: Process 1, Nbr 172.16.255.2 on Tunnel0 from LOADING to FULL, Loading Done
Что за фигня?
Смотрим дебаг, смотрим дампы
*Mar 1 01:53:44.915: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.4 from 172.16.2.1
*Mar 1 01:53:44.919: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.7 from 172.16.2.33
*Mar 1 01:53:44.923: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.5 from 172.16.2.17
*Mar 1 01:53:44.923: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.8 from 172.16.2.129
*Mar 1 01:53:44.963: OSPF: Send hello to 224.0.0.5 area 0 on Tunnel0 from 172.16.254.1
msk-arbat-gw1#
*Mar 1 01:53:54.919: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.4 from 172.16.2.1
*Mar 1 01:53:54.923: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.7 from 172.16.2.33
*Mar 1 01:53:54.927: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.5 from 172.16.2.17
*Mar 1 01:53:54.931: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.8 from 172.16.2.129
*Mar 1 01:53:54.963: OSPF: Send hello to 224.0.0.5 area 0 on Tunnel0 from 172.16.254.1
msk-arbat-gw1#
*Mar 1 01:54:04.919: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.4 from 172.16.2.1
*Mar 1 01:54:04.927: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.7 from 172.16.2.33
*Mar 1 01:54:04.931: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.5 from 172.16.2.17
*Mar 1 01:54:04.935: OSPF: Send hello to 224.0.0.5 area 0 on FastEthernet0/1.8 from 172.16.2.129
*Mar 1 01:54:04.963: OSPF: Send hello to 224.0.0.5 area 0 on Tunnel0 from 172.16.254.1
Как вы уже поняли, маршрутизатор просто не может сообразить куда посылать мультикастовые сообщения на
адрес 224.0.0.5, хаб их не получает и дёргает OSPF-сессию.
ip nhrp registration no-unique – если адрес в филиалах выдаётся динамически, эта команда обязательна.
tunnel source FastEthernet0/0 – привязка к физическому интерфейсу.
tunnel mode gre multipoint – указываем, что тип туннеля mGRE – это позволит создавать динамически туннели не
только до хаба, но и до других филиалов.
У нас ситуация простая – без NAT – и мы можем уже сейчас проверить состояние туннелей.
msk-arbat-gw1#sh int tun 0
Tunnel0 is up, line protocol is up
Hardware is Tunnel
Internet address is 172.16.254.1/24
MTU 1514 bytes, BW 9 Kbit, DLY 500000 usec,
reliability 255/255, txload 1/255, rxload 1/255
Encapsulation TUNNEL, loopback not set
Keepalive not set
Tunnel source 198.51.100.2 (FastEthernet0/1.6), destination UNKNOWN
Tunnel protocol/transport multi-GRE/IP
Key disabled, sequencing disabled
Checksumming of packets disabled
msk-arbat-gw1#ping 172.16.254.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.16.254.2, timeout is 2 seconds:
!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 176/213/284 ms
OSPF
То есть связность уже обеспечена, но работать филиалы пока не могут – не настроена маршрутизация.
Поскольку мы имеем широковещательную L2 сеть на туннельных интерфейсах, указываем явно тип сети
Broadcast на туннельных интерфейсах на всех узлах:
Кроме того в такой сети должен выбираться DR. Логично, чтобы им стал хаб. Всем Spoke-маршрутизаторам
запрещаем участие в выборах DR:
ip ospf priority 0
router ospf 1
Сети анонсируются:
msk-arbat-gw1#sh ip route
Пинг проходит
msk-arbat-gw1#ping 172.16.255.128
nsk-obsea-gw1#traceroute 172.16.255.132
nsk-obsea-gw1#sh ip nhrp br
Target Via NBMA Mode Intfc Claimed
Как видите пакеты не заходят на хаб, а идут напрямую сразу на маршрутизатор другого филиала через Интернет.
Но действительность несколько сложнее.
msk-arbat-gw1, fa0/1:
msk-arbat-gw1, fa0/1:
msk-arbat-gw1, fa0/1:
5) Хаб обладает этим знанием:
msk-arbat-gw1#sh ip nhr br
Target Via NBMA Mode Intfc Claimed
172.16.254.2/32 172.16.254.2 198.51.101.2 dynamic Tu0 < >
172.16.254.3/32 172.16.254.3 198.51.102.2 dynamic Tu0 < >
msk-arbat-gw1, fa0/1:
tmsk-lenina-gw1, fa0/0:
Несмотря на то, что во внешнем заголовке IP адрес источника – это адрес хаба, внутри фигурирует изначальный
адрес Новосибирского маршрутизатора:
tmsk-lenina-gw1, fa0/0:
9)Ну и хаб, естественно, отвечает:
tmsk-lenina-gw1, fa0/0:
nsk-obsea-gw1(config-if)#do sh ip nhr br
Target Via NBMA Mode Intfc Claimed
172.16.254.1/32 172.16.254.1 198.51.100.2 static Tu0 < >
172.16.254.3/32 172.16.254.3 198.51.102.2 dynamic Tu0 < >
tmsk-lenina-gw1(config-if)#do sh ip nh br
Target Via NBMA Mode Intfc Claimed
172.16.254.1/32 172.16.254.1 198.51.100.2 static Tu0 < >
172.16.254.2/32 172.16.254.2 198.51.101.2 dynamic Tu0 < >
12) Мы немного повторяемся, но… Интерфейс Tunnel 0 является mGRE и согласно таблицы NHRP весь трафик, для
которого следующим хопом является 172.16.254.3 должен быть инкапсулирован в GRE и внешний IP-заголовок с
адресом назначения 198.51.102.2 (В качестве адреса источника будет выбран адрес физического интерфейса –
198.51.101.2):
nsk-obsea-gw1(config-if)#do sh ip nhr br
Target Via NBMA Mode Intfc Claimed
172.16.254.1/32 172.16.254.1 198.51.100.2 static Tu0 < >
172.16.254.3/32 172.16.254.3 198.51.102.2 dynamic Tu0 < >
tmsk-lenina-gw1, fa0/0:
13) Ну и дальше пакет с адресом получателя 198.51.102.2 отправляется согласно таблице маршрутизации:
Gateway of last resort is 198.51.101.1 to network 0.0.0.0
Тут важно понимать, что несмотря на то, что общение между филиалами осуществляется в обход центрального
узла, хаб однако несёт тут жизненно важную вспомогательную функцию и без него ничего работать не будет: он
предоставляет клиентам таблицу NHRP, а также анонсирует все маршруты – филиалы распространяют
маршрутную информацию не непосредственно друг другу, а через хаб.
Актуальная на данный момент конфигурация узлов:
msk-arbat-gw1
interface Tunnel0
no ip redirects
ip nhrp network-id 1
ip ospf priority 10
nsk-obsea-gw1
interface Tunnel0
no ip redirects
ip nhrp network-id 1
ip ospf priority 0
tmsk-leneina-gw1
interface Tunnel0
no ip redirects
ip nhrp network-id 1
ip ospf priority 0
end
IPSec
authentication pre-share
От рассмотренных выше Tunnel Protection и VTI она будет отличаться использованием шаблонного адреса:
Опасность здесь в том, что установить IPSec-сессию с хабом, зная ключ, может любое устройство
mode transport
Далее созданный профиль применяется на туннельный интерфейс. Настройка на всех узлах одинаковая.
interface Tunnel0
IPSec-туннели и карты шифрования будут создаваться динамически для сеансов передачи данных между
филиалами и будут перманентными для каналов Hub-Spoke.
NAT-Traversal
Тут мы не будем вдаваться в принципы работы NAT-T Передам только суть: за счёт дополнительного UDP-
заголовка IPSec может строить туннель сквозь NAT. Это позволяет строить VPN даже на тех узлах, где у вас нет
публичного адреса.
Нет необходимости этот функционал каким-то особым образом активировать и настраивать – он работает по
умолчанию.
Усложним схему добавлением ещё одного маршрутизатора в Брно.
Допустим, это провайдерская железка, осуществляющая натирование. То есть фактически на роутере в филиале у
нас будет динамический адрес из приватного диапазона на физическом интерфейсе. GRE в чистом виде не может
построить VPN при таких условиях, IPSec может, но сложно настраивать. mGRE в связке с IPSec может легко!
Давайте посмотрим как выглядит таблица NHRP в этом случае:
msk-arbat-gw1#show ip nhrp brief
Target Via NBMA Mode Intfc Claimed
172.16.254.4/32 172.16.254.4 10.0.0.2 dynamic Tu0 < >
На туннельном интерфейсе у нас активирован IPSec, следовательно должны быть карты шифрования:
msk-arbat-gw1#show crypto map
Crypto Map «Tunnel0-head-0» 65537 ipsec-isakmp
Map is a PROFILE INSTANCE.
Peer = 198.51.103.2
Extended IP access list
access-list permit gre host 198.51.100.2 host 10.0.0.2
Current peer: 198.51.103.2
Security association lifetime: 4608000 kilobytes/3600 seconds
PFS (Y/N): N
Transform sets={
AES128-SHA,
}
Interfaces using crypto map Tunnel0-head-0:
Tunnel0
Таким образом шифрованный туннель строится между 198.51.100.2 и 198.51.103.2, дальше, данные по-прежнему
шифрованные за счёт NAT-T в туннеле идут до 10.0.0.2. А дальше вы уже знаете.
=====================
Задача №6
Сценарий:
Сеть DMVPN была полностью работоспособной, всё работало корректно.
Но после перезагрузки хаба msk-arbat-gw1 началось странное поведение.
Задание:
1. Проверить работоспособность сети.
2. Перезагрузить хаб
3. После перезагрузки проверить работоспособность сети ещё раз
4. Устранить проблему:
4.1. (минимум) Сделать сеть снова работоспособной
4.2. Сделать так, чтобы сеть восстанавливалась автоматически, после того как хаб снова появится.
MTU – Maximum Transmission Unit. Это максимальный размер блока данных, который может быть передан через
интерфейс. Это понятие находится на пересечении L2 и L3 и его интерпретация может различаться для разных
вендоров.
Например, типичный размер MTU для физического L3-интерфейса 1500. То есть, грубо говоря, IP-пакет размером
1500 байт будет обработан, а 1501 – отброшен или фрагментирован. Зачастую фрагментация пакетов запрещена,
и потому большие пакеты отбрасываются.
Если вы используете туннелирование, размер пакета увеличивается засчёт дополнительных заголовков (GRE,
IPSec и т.д.)
Например, для GRE: 24 байта (GRE, Новый IP).
Для GRE over IPSec: 56 и более байтов (зависит от режима работы и типа шифрования)
Для PPPoE: 36 (PPP, PPPoE, Ethernet)
Сам туннельный интерфейс имеет стандартный MTU 1514 и пропускает такие пакеты, но у провайдера на
физическом интерфейсе стоит MTU=1500, и на нём пакет будет отброшен:
R1#sh int tun 0
Tunnel0 is up, line protocol is up
Hardware is Tunnel
Internet address is 10.2.2.1/30
MTU 1514 bytes, BW 9 Kbit, DLY 500000 usec,
То есть вы должны учитывать не только свои настройки, но и настройки всех промежуточных узлов.
Зачастую у вас нет возможности влиять на MTU по пути.
Поэтому вы можете уменьшить MTU, на локальной стороне, использовать механизм Path MTU Discovery или
даже настраивать MSS – Maximum Segment Size (относится уже к TCP).
Подробнее о проблемах с MTU читайте тут и тут
DMVPN
www.anticisco.ru/blogs/?tag=dmvpn
xgu.ru/wiki/%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_DMVPN_%D0%BD%D0%B0
_%D0%BC%D0%B0%D1%80%D1%88%D1%80%D1%83%D1%82%D0%B8%D0%B7%D0%B0%D1%82%D0%BE%D1%80%D0
%B0%D1%85_Cisco
NHRP.
habrahabr.ru/post/84738/
blog.ine.com/tag/nhrp/
FlexVPN.
www.cisco.com/en/US/docs/ios-xml/ios/sec_conn_ike2vpn/configuration/15-2mt/sec-intro-ikev2-flex.html
habrahabr.ru/post/160555/
alexandremspmoraes.wordpress.com/2012/06/28/hello-world-simple-lan-to-lan-flex-vpn-configuration/
alexandremspmoraes.wordpress.com/2012/07/02/flex-vpn-sample-lan-to-lan-configuration-with-dynamic-routing/
До сих пор мы варились в собственном соку – VLAN’ы, статические маршруты, OSPF. Плавно росли над собой из
зелёных студентов в крепких инженеров.
Теперь отставим в сторону эти игрушки, пришло время BGP.
Сегодня мы
• Разбираемся с протоколом BGP: виды, атрибуты, принципы работы, настройка
• Подключаемся к провайдеру по BGP
• Организуем резервирование и распределение нагрузки между несколькими линками
• Рассмотрим вариант резервирования без использования BGP – IP SLA
EGP представляет только один протокол – BGP – Border Gateway Protocol. Он призван обеспечивать передачу
маршрутов между различными сетями (автономными системами).
Грубо говоря, стык между Балаган-Телекомом и его аплинковым провайдером будет точно организован через
BGP.
То есть схема применения примерно такая:
Автономномые системы – AS
BGP неразрывно связан с понятием Автономной Системы (AS – Autonomous System), которое уже не раз
встречалось в нашем цикле.
Согласно определению вики, АС — это система IP-сетей и маршрутизаторов, управляемых одним или
несколькими операторами, имеющими единую политику маршрутизации с Интернетом.
Чтобы было немного понятнее, можно, например, представить, что город – это автономная система. И как два
города связаны между собой магистралями, так и две АС связываются между собой BGP. При этом внутри
каждого города есть своя дорожная система – IGP.
Вообще глобально этим занимается IANA. Но чтобы не разорваться, она делегирует свои задачи RIR – это
региональные организации, каждая из которых отвечает за определённую часть планеты (Для Европы и России –
это RIPE NCC)
LIR’ом может стать почти любая желающая организация при наличии необходимых документов. Они нужны для
того, чтобы RIR’у не пришлось напрягаться с запросами от таких мелких контор, как ЛинкМиАп.
Ну вот, например, Балаган-Телеком мог бы быть LIR’ом. И у него мы и взяли ASN (номер АС) – 64500, например. А
у самого у него AS 64501.
До 2007 года были возможны только 16-ибитные номера AS, то есть всего было доступно 65536, номеров. 0 и
65535 – зарезервированы.
Номера 64512 до 65534 предназначены для приватных AS, которые не маршрутизируются глобально – что-то
вроде приватных IP-адресов.
Номера 64496-64511 – для использования в примерах и документации, чем мы и воспользуемся.
Сейчас возможно использование 32битных номеров AS. Этот переход значительно легче, чем IPv4->IPv6.
Опять же нельзя говорить об автономных системах без привязки к блокам IP-адресов. На практике с каждой AS
должен быть связан какой-то блок адресов.
PI и PA адреса
В пору своей профессиональной юности, читая договор с нашим LIR я посмеивался над менеджерами, которые
не могли правильно написать IP-адрес: то и дело в тексте встречалось слово “PI-адрес”.
Слава богу хватило тогда ума загуглить этот вопрос
На самом деле PI – это Provider Independent.
В обычной ситуации, когда вы подключаетесь к провайдеру, он выдаёт вам диапазон публичных адресов – так
называемые PA-адреса (Provider Aggregatable).
Получить их – раз плюнуть, но если вы не являетесь LIR’ом, то при смене провайдера придётся возвращать и PA-
адреса. Тем более фактически допускается подключение только к одному провайдеру.
И если вы решите сменить провайдера, то старые адреса уйдут вместе с ним, а новый провайдер выдаст новые.
Ну и где тут гибкость?
У LIR вы можете приобрести повайдеро-независимый блок адресов (PI) и обязательно ASN. В нашем случае пусть
это будет блок 100.0.0.0/23, который мы будем анонсировать по BGP своим соседям. И эти адреса уже чисто
наши и никакие провайдеры нам не страшны: не понравился один – ушли к другому с сохранением своих
адресов.
Получить PI-адреса всегда было не очень просто. Вам нужно подготовить массу документов, обосновать
необходимость такого блока итд.
Сейчас с исчерпанием IPv4 получить большие блоки становится всё сложнее. RIR их уже не выдаёт, а LIR раздают
последнее.
Теперь главный вопрос, который интересует всегда новичков: а зачем BGP, почему не взять пресловутый OSPF
или вообще статику?
Наверное, большие дяди могут очень подробно и обстоятельно объяснить это, мы же постараемся дать
поверхностное понимание.
– Если говорить о OSPF/IS-IS, то это Link-State алгоритмы, которые подразумевают (внимание!), что каждый
маршрутизатор знает топологию всей сети. Представляем себе миллионы маршрутизаторов в Интернете и
отказываемся от идеи использовать Link State для этих целей вообще.
Вообще OSPF при маршрутизации между area'ми является фактически distance vector протоколом.
Гипотетически, можно было бы заменить «AS» на «Area» в плане глобальной маршрутизации, но OSPF просто не
предназначен для переваривания таких объемов маршрутной информации, да и нельзя выделить в интернете
Area 0.
– IGP – это нечто интимное и каждому встречному ISP показывать его не стоит. Даже без AS ситуация, когда
клиент поднимает IGP с провайдером, крайне редкая (за исключением L3VPN). Дело в том, что IGP не имеют
достаточно гибкой системы управления маршрутами – для LS-протоколов это вообще знать всё или ничего (опять
же можно фильтровать на границе зоны, но гибкости никакой).
В итоге оказывается, что придётся открывать кому-то чужому потаённые части своей приватной сети или
настраивать хитрые политики импорта между различными IGP-процессами.
– В данный момент в интернете более 450 000 маршрутов. Если бы даже OSPF/ISIS могли хранить всю топологию
Интернета, представьте сколько времени заняла бы работа алгоритма SPF.
Вот наглядный пример, чем может быть опасно использование IGP там, где напрашивается нечто глобальное.
Поэтому нужен свой специальный протокол для взаимодействия между AS.
Во-первых, он должен быть дистанционно-векторным – это однозначно. Маршрутизатор не должен делать
расчёт маршрута до каждой сети в Интернете, он лишь должен выбрать один из нескольких предложенных.
Во-вторых, он должен иметь очень гибкую систему фильтрации маршрутов. Мы должны легко определять, что
светить соседям, а что не нужно выносить из избы.
В-третьих, он должен быть легко масштабируемым, иметь защиту от образования петель и систему управления
приоритетами маршрутов.
В-четвёртых, он должен обладать высокой стабильностью. Поскольку данные о маршрутах будут передаваться
через среду, которая не всегда может обладать гарантированным качеством (за стык отвечают по крайней мере
две организации), необходимо исключить возможные потери маршрутной информации.
Ну и логичное, в-пятых, он должен понимать, что такое AS, отличать свою AS от чужих.
Встречайте: BGP.
Вообще описание работы этого поистине грандиозного протокола мы разобьём на две части. И сегодня
рассмотрим принципиальные моменты.
IBGP необходим для передачи BGP-маршрутов внутри одной автономной системы. Да, BGP часто запускается
и внутри AS, но об этом мы плотненько поговорим в другой раз.
EBGP – это обычный BGP между автономными системами. На нём и остановимся.
Установление BGP-сессии и процедура обмена маршрутами
Возьмём типичную ситуацию, когда у нас подключение к провайдерскому шлюзу организовано напрямую.
Устройства, между которыми устанавливается BGP-сессия называются BGP-пирами или BGP-соседями.
Но в случае подключения к провайдеру, как правило, берётся всё же прямое подключение, таким образом
маршрут до соседа всегда есть, как подключенный непосредственно.
BGP-маршрутизатор (их также называют BGP-спикерами/speaker или BGP-ораторами) слушает и посылает пакеты
на 179-й TCP порт.
Когда слушает – это состояние CONNECT. В таком состоянии BGP находится очень недолго.
R2 возвращает TCP ACK, мол, всё получил, согласен и свой TCP SYN.
На R2 не запущен BGP, и R2 возвращает ACK, что получен SYN от R1 и RST, означающий, что нужно сбросить
подключение.
III) После того, как TCP-сессия установлена, BGP-ораторы начинают обмен сообщениями OPEN.
OPEN – первый тип сообщений BGP. Они отсылаются только в самом начале BGP-сессии для согласования
параметров.
В нём передаются версия протокола, номер AS, Hold Timer и Router ID. Чтобы BGP-сессия поднялась, должны
соблюдаться следующие условия:
• Версии протокола должна быть одинаковой. Маловероятно, что это будет иначе
• Номера AS в сообщении OPEN должны совпадать с настройками на удалённой стороне
• Router ID должны различаться
Также внизу вы можете увидеть поддерживает ли маршрутизатор дополнительные возможности протокола.
Получив OPEN от R1, R2 отправляет свой OPEN, а также KEEPALIVE, говорящий о том, что OPEN от R1 получен – это
сигнал для R1 переходить к следующему состоянию – Established.
Вот примеры неконсистентности параметров:
а) некорректная AS (На R2 настроена AS 300, тогда, как на R1 считается, что данный сосед находится в AS 200):
б) одинаковый Router ID
R2 отправляет в OPEN Router ID, который совпадает с ID R1:
После таких ошибок BGP переходит сначала в IDLE, а потом в ACTIVE, пытаясь заново установить TCP-сессию и
затем снова обменяться сообщениями OPEN, вдруг, что-то изменилось?
Когда сообщение Open отправлено – это состояние OPEN SENT.
Когда оно получено – это состояние OPEN CONFIRM.
Если Hold Timer различается, то выбран будет наименьший. Поскольку Keepalive Timer не передаётся в
сообщении OPEN, он будет рассчитан автоматически (Hold Timer/3). То есть Keepalive может различаться на
соседях
Вот пример: на R2 настроены таймеры так: Keepalive 30, Hold 170.
R2 отправляет эти параметры в сообщении OPEN. R1 получает его и сравнивает: полученное значение – 170, своё
180. Выбираем меньшее – 170 и вычисляем Keepalive таймер:
Это означает, что R2 свои Keepalive’ы будет рассылать каждые 30 секунд, а R1 – 56. Но главное, что Hold Timer у
них одинаковый, и никто из них раньше времени не разорвёт сессию.
Увидеть состояние OPENSENT или OPENCONFIRM практически невозможно – BGP на них не задерживается.
IV) После всех этих шагов они переходят в стабильное состояние ESTABLISHED.
Это означает, что запущена правильная версия BGP и все настройки консистентны.
Для каждого соседа можно посмотреть Uptime – как долго он находится в состоянии ESTABLISHED.
V) В первые мгновения после установки BGP-сессии в таблице BGP только информация о локальных маршрутах.
Разберём их поподробнее.
R1 передаёт маршрутную информацию на R2.
Первый плюсик в сообщении UPDATE – это атрибуты пути. Мы их подробно рассмотрим позже, но вам уже
должны быть поняты два из них. AS_PATH означает, что маршрут пришёл из AS с номером 100.
NEXT_HOP – что логично, информация для R2, что указывать в качестве шлюза для данного маршрута.
Теоретически здесь может быть не обязательно адрес R1.
Второй плюсик – это собственно информация о маршрутах – NLRI – Network Layer Reachability Information.
Собственно, наша сеть 100.0.0.0/23 тут и указана.
Ну и UPDATE от R2 к R1.
И в таблице маршрутизации:
UPDATE передаются при каждом изменении в сети до тех пор пока длится BGP-сессия. Заметьте, никаких
синхронизаций таблиц маршрутизации нет, в отличии от какого-нибудь OSPF. Это было бы технически глупо –
полная таблица маршрутов BGP весит несколько десятков мегабайтов на каждом соседе.
VI) Теперь, когда всё хорошо, каждый BGP-маршрутизатор регулярно будет рассылать сообщения KEEPALIVE. Как
и в любом другом протоколе это означает: «Я всё ещё жив». Это происходит с истечением таймера Keepalive – по
умолчанию 60 секунд.
Если BGP-сессия устанавливается нормально, но потом рвётся и это повторяется с некой периодичностью –
верный знак, что не проходят keepalive. Скорее всего, период цикла – 3 минуты (таймер HOLD по умолчанию).
Искать проблему надо на L2. Например, это может быть плохое качество связи, перегрузки на интерфейсе или
ошибки CRC.
Ещё один тип сообщений BGP – ROUTE REFRESH – позволяет запросить у своих соседей все маршруты заново без
рестарта BGP процесса.
Вопрос на засыпку: Предположим, что Uptime BGP-сессии 24 часа. Какие сообщения гарантировано не
передавались между соседями последние 12 часов?
Как видите, маршрут представляет из себя вовсе не только NextHop или просто список устройств до нужной
подсети. Это список AS. Иначе он называется AS-Path.
То есть, чтобы попасть в сеть 123.0.0.0/24 мы должны отправить пакет наружу, преодолеть AS 200 и AS 300.
AS-path нужен не просто для того, чтобы маршрутизатор R1 знал путь до конечной сети – ведь по сути Next Hop
достаточно – каждый маршрутизатор решение по-прежнему принимает на основе таблицы маршрутизации. На
самом деле тут преследуются две более важные цели:
1) Предотвращение петель маршрутизации. В AS-Path не должно быть повторяющихся номеров
На самом деле ASN может повторяться в AS-Path в двух случаях
а) Когда вы используете AS-Path Prepend, о котором ниже.
б) Когда вы хотите соединить два куска одной AS, не имеющих прямой связи друг сдругом.
2) Выбор наилучшего маршрута. Чем короче AS-Path, тем предпочтительнее маршрут, но об этом позже.
Настройка BGP и практика
В этом выпуске мы смешаем теорию с практикой, потому что так будет проще всего понять. Собственно сейчас
обратимся к нашей сети ЛинкМиАп.
Как обычно, отрезаем всё лишнее и добавляем необходимое:
Внизу наш главный маршрутизатор msk-arbat-gw1. Для упрощения настройки и понимания, мы отрешимся от
всех старых настроек и освободим интерфейсы.
Разумеется, у каждого провайдера здесь своя AS. Мы добавили ещё одну тупиковую AS – до неё и будем
проверять, пусть, это например, ЦОД в Интернете.
Для простоты полагаем, что каждая AS представлена только одним маршрутизатором, никаких ACL, никаких
промежуточных устройств.
Настройка интерфейсов:
msk-arbat-gw1
R1(config)#int fa0/0
R1(config-if)#no shutdown
R1(config)#int fa0/1
R1(config-if)#no shutdown
Теперь назначим какой-нибудь адрес на интерфейс Loopback, чтобы потом проверить связность:
R1(config)#int loopback 0
Командой neighbor мы указываем, с кем устанавливать сессию. Именно на адрес 101.0.0.1 маршрутизатор будет
отсылать сначала TCP-SYN, а потом OPEN. Также мы обязаны указать номер удалённой Автономной Системы –
64501.
Пусто. Надо указать, что есть у нас вот эта сеточка 100.0.0.0/23 и передать её провайдерам?
Для этого существует три варианта:
– определить сети командой network
– импортировать из другого источника (direct, static, IGP)
– создать аггрегированный маршрут командой aggregate-address
Забегая вперёд, заметим, что network имеет больший приоритет, а с импортированием нужно быть аккуратнее,
чтобы не хватануть лишку.
R1(config)#router bgp 64500
А дело тут в том, что в ту сеть, которую вы прописали командой network должен быть точный маршрут, иначе
она не будет добавлена в таблицу BGP – это обязательное условие. Конечно, такого маршрута нет. Откуда ему
взяться:
Поскольку реально у нас некуда прописывать такой маршрут – кроме одного Loopback-интерфейса, нигде этой
сети нет, мы можем поступить следующим образом:
Данный маршрут говорит о том, что все пакеты в эту подсеть будут отброшены. Но, не пугайтесь, нормальная
работа не будет нарушена. Если у вас есть более точные маршруты (с маской больше /23, например, /24, /30,
/32), то они будут предпочтительнее согласно правилу Longest Prefix Match.
Если настроить BGP и нужные маршруты на всех устройствах нашей схемы, то таблицы BGP и маршрутизации на
нашем бордере (border – маршрутизатор на границе сети) будут выглядеть так:
Обратите внимание, что в таблице BGP по 2 маршрута к некоторым сетям, а в таблице маршрутизации только
один. Маршрутизатор выбирает лучший из всех и только его переносит в таблицу маршрутизации. Об этом
поговорим позже.
Это необходимый минимум, после которого уже будет маленькое счастье.
=====================
Задача №1
Схема:
Условие:
Настройки маршрутизаторов несущественны. Никаких фильтров маршрутов не настроено. Почему на одном из
соседей отсутствует альтернативный маршрут в сеть 195.12.0.0/16 через AS400?
Подробности задачи тут
=====================
Full View и Default Route
Говоря о BGP и подключении к провайдерам, нельзя не затронуть эту тему. Когда ЛинкМиАп, имея уже AS и PI-
адреса, будет делать стык с Балаган-Телекомом, одним из первых вопросов от них будет: “Фул вью или
Дефолт?”. Тут главное не растеряться и не сморозить чепуху.
То, что вы видели до сих пор – это так называемый Full View – маршрутизатор изучает абсолютно все маршруты
Интернета, пусть даже в нашем случае это пять-шесть штук. В реальности их сейчас больше 400 000.
Соответственно от одного провайдера вы получите 400k маршрутов, от второго столько же. Подчас бывает и
третий резервный – плюс ещё 400k. Итого больше миллиона.
Ну не покупать же теперь маленькому недоинтерпрайзу циску старших серий только для этого?
•
•
• Вы знаете, какие к нему ведут AS. Через сайт RIPE можно посмотреть какие провайдеры обеспечивают
транзит. Вы следите за всеми изменениями. Если вдруг у кого-то что-то упадёт через первый линк (даже не у вас
или у провайдера, а где-то там, дальше), BGP это отследит и перестроит свою таблицу маршрутизации для
передачи данных через второго провайдера.
• При этом вы очень гибко можете управлять маршрутами, вмешиваясь в стандартную процедуру выбора
наилучшего пути.
• Например, весь трафик на яндекс вы будете пускать через Балаган Телеком, а на гугл через Филькин
Сертификат. Это называется распределением нагрузки.
• Достигается это путём настройки, например, приоритетов маршрутов для определённых префиксов.
•
• Full View обязателен, если ваша АС транзитная, то есть вы собираетесь по BGP подключать к себе ещё
клиентов.
• Платить за все эти плюсы приходится производительностью: высокая утилизация оперативной памяти и
весьма долгое изучение маршрутной информации после установления BGP-сессии. Например, после того, как
дёрнулся линк с вышестоящим провайдером, полное восстановление может занять несколько минут.
• Default Route
• Ну, во-первых, это, конечно, сильно экономит ресурсы вашего оборудования.
• Во-вторых, проще в обслуживании, можно сказать. Не нужно по всей своей AS гонять сотни тысяч
маршрутов.
• В-третьих, никакого представления о состоянии интернета и реальной доступности получателей нет – вы
просто слепо доверяетесь дефолту, полученному от апстрима. То есть в случае проблемы выше, вы о ней не
узнаете и часть сервисов может упасть. Но тут мы надеемся, что у вышестоящих провайдеров надёжность сети на
порядки выше и нам не о чем беспокоиться.
•
• Балансировка и распределение входящего трафика при получении маршрута по умолчанию никак не
затрагивается – проблемы те же. А вот с исходящим, конечно, всё, немного иначе, былой гибкости тут уже не
будет.
Но уж точно нет смысла принимать от одного провайдера Full View, а от другого Default – в этом случае один
линк будет всегда простаивать на исходящий трафик, потому что маршрутизатор будет выбирать более
специфический путь.
При этом от всех провайдеров вы можете брать Default плюс определённые префиксы (например, именно этого
провайдера). Таким образом до нужных ресурсов у вас будут специфические маршруты без Full View.
То есть помимо обычных маршрутов (Full View) передаётся ещё маршрут по умолчанию.
Сейчас вы уже должны начинать догадываться, что Default Route – это не противопоставление Full View. Не
обязательно здесь стоит «или то или другое» (надо бы ввести понятие хили или ксили, как английское XOR), вы
вполне можете использовать Default Route в дополнение к Full View или Default Route и часть каких-то других
маршрутов.
=====================
Задача №2
Существуют также специальные организации, которые отслеживают анонсы BGP в Интернете и, если вдруг
происходит что-то неожиданное, может уведомить владельца сети – BGPMon, Renesys, RouterViews.
Благодаря им было предотвращено несколько глобальных аварий.
На nag.ru можно почитать о самых ярких случаях, когда некорректные анонсы BGP вызывали глобальные
проблемы в Интернете, таких как ”AS 7007 Incident” и “Google's May 2005 Outage”.
Всё это примеры процессов Control Plane. То есть это подготовка сети к передаче – организация коммутации,
наполнение таблицы маршрутизации.
Часто случается так, что данные двух уровней ходят в разных направлениях, “навстречу друг другу”. Так в BGP
маршруты передаются из AS100 в AS200 для того, чтобы AS200 могла передать данные в AS100.
Более того, на разных уровнях могут быть разные парадигмы работы. Например, в MPLS Data Plane ориентирован
на создание соединения, то есть данные там передаются по заранее определённому пути – LSP.
А вот сам этот путь подготавливается по стандартным законам IP – от хоста к хосту.
Для BGP это принципиальный вопрос. Когда вы анонсируете свои маршруты, фактически вы создаёте путь
для входящего трафика. То есть маршруты исходят от вас, а трафик к вам.
Выбор маршрута
Ситуация с маршрутами у нас такая.
Есть BGP-таблица, в которой хранятся абсолютно все маршруты, полученные от соседей.
То есть если есть у нас несколько маршрутов, до сети 100.0.0.0/23, то все они будут в BGP-таблице,
независимо от “плохости” оных:
А есть знакомая нам таблица маршрутизации, хранящая только лучшие из лучших. Точно также BGP анонсирует
не все приходящие маршруты, а только лучшие. То есть от одного соседа вы никогда не получите два маршрута в
одну сеть.
Как видите, очень много критериев выбора. Причём они довольно сложные и с ходу их все понять непросто.
Втягивайтесь потихоньку.
О некоторых упомянутых атрибутах мы поговорим ниже, а конкретно на выборе маршрутов остановимся в
отдельной статье.
=====================
Задача №3
Схема: Общая схема сети
Условие: Full View на всех маршрутизаторах
Если вы сейчас посмотрите таблицу BGP на маршрутизаторе провайдера Балаган Телеком, то увидите 3 маршрута
в сеть 102.0.0.0/21 – сеть Филькина Сертификата. И один из маршрутов ведёт через нашу сети ЛинкМиАп.
Это говорит о том, что наш бордер анонсирует чужие маршруты дальше, иными словами наша AS является
транзитной.
Задание:
Настроить фильтрацию таким образом, чтобы наша AS64500 перестала быть транзитной.
Но только первые два из них позволяют фильтровать анонсируемые или принимаемые маршруты, остальные
лишь устанавливают приоритеты.
AS-Path ACL
Весьма мощный, но не самый популярный механизм.
С помощью AS-Path ACL вы можете, например, запретить принимать анонсы маршрутов, принадлежащих AS 200.
Ну вот просто не хотите – пусть они через другого провайдера будут известны, а через этого нет.
Самое сложное в таком подходе – запомнить все регулярные выражения и научиться их использовать. Сначала
голова от них кругом:
Знак Значение
. любой символ, включая пробел
* ноль или больше совпадений с выражением
+ одно или больше совпадений с выражением
? ноль или одно совпадение с выражением
^ начало строки
$ конец строки
_ любой разделитель (включая, начало, конец, пробел)
\ не воспринимать следующий символ как специальный
[] совпадение с одним из символов в диапазоне
| логическое или
1
_200_ Маршруты проходящие через AS 200
До и после номера AS идут знаки “_”, означающие, что в AS-path номер 200 может стоять в начале, середине или
конце, главное, чтобы он был.
2
^200$ Маршруты из соседней AS 200
“^” означает начало списка, а “$” – конец. То есть в AS-path всего лишь один номер AS – это означает, что
маршрут был зарождён в AS 200 и оттуда сразу был передан нам.
3
_200$ Маршруты отправленные из AS 200
“$” означает конец списка, то есть это самая первая AS, из неё маршрут и зародился, знак “_” говорит о том, что
неважно, что находится дальше, хоть ничего, хоть 7 других AS.
4
^200_ Сети находящиеся за AS 200
Знак “^” означает, что ASN 200 была добавлена последней, то есть маршрут к нам пришёл из AS 200, но это не
значит, что родился он в ней же – знак “_” говорит о том, что это может быть конец списка, а может пробел перед
следующей AS.
5
^$ Маршруты локальной AS
Список AS-path пуст, значит маршрут локальный, сгенерированный внутри нашей AS.
Пример
Вот в нашей сети отфильтруем маршруты, которые зародились в AS 64501. То есть мы будем от соседа 101.0.0.1
получать все интернетовские маршруты, но не будем получать их локальные.
Конфигурация устройств.
Префикс-листы – это просто привычные нам сеть/маска, и мы указываем разрешить такие маршруты или нет.
Синтаксис команды:
list-name – название списка. Ваш КО. Обычно указывается, как name_in или name_out. Это подсказывает нам на
входящие или исходящие маршруты будет действовать (но, конечно, на данном этапе никак не определяет).
seq – порядковый номер правила (как в ACL), чтобы проще было оперировать с ними.
deny/permit – определяем разрешать такой маршрут или нет
network/length – привычная для нас запись, вроде, 192.168.14.0/24.
А вот дальше, внимание, сложнее – возможны ещё два параметра: ge и le. Как и при настройке NAT (или в ЯП
Фортран), это означает "greater or equal" и "less or equal".
То есть вы можете задать не только один конкретный префикс, но и их диапазон.
Сделаем на всякий случай оговорку: последний пример не означает, что соседний провайдер не будет вам их
передавать – конечно, будет, ведь он-то ничего не знает о ваших политиках – а вот ваш маршрутизатор, получив
такой анонс, не добавит маршрут в свою BGP-таблицу.
Конфигурация устройств.
Route Map
До сих пор все правила применялись безусловно – на все анонсы от пира или пиру.
С помощью карт маршрутов (у других вендоров они могут называться политиками маршрутизации) мы можем
очень гибко применять правила, дифференцируя анонсы.
[match {expression}]
[set {expression}]
expression:
Критерий Команда конфигурации
Network/mask match ip address prefix-list
AS-path match as-path
BGP community match community
Route originator match ip route-source
BGP next-hop address match ip next-hop
Пример применения
Укажем, что в подсеть 120.0.0.0/24 предпочтительно ходить через Балаган Телеком, а в 103.0.0.0/22 через
Филькин Сертификат. Для этого воспользуемся атрибутом Local Preference. Чем выше значение этого параметра,
тем выше приоритет маршрута.
set local-preference 50
set local-preference 50
Сначала мы создали обычным образом prefix-list, которым выделили подсеть 120.0.0.0/24. Permit означает, что
на этот префикс в будущем будут действовать правила route-map. Как и в обычных ACL далее идёт неявное
правило deny для всего остального. В данном случае оно означает, что под действие route-map подпадёт только
120.0.0.0/24 и ничего другого.
Конфигурация устройств
=====================
Задача №4
Задание:
Исправить настройки так, чтобы исходящий трафик в сети провайдера ISP2, к его клиенту и в сеть удаленного
офиса компании, шел через провайдера ISP2.
Балансировка нагрузки
Под балансировкой обычно понимается распределение между несколькими линками трафика, направленного
в одну сеть.
maximum-paths 2
Как мы можем проверить это на нашей сети? Нам ведь нужно убедиться, что балансировка работает.
После этого один пинг пойдёт через один линк, а второй через другой. Проверено
По умолчанию никак не учитывается пропускная способность внешних каналов. Такая возможность однако
реализована и запускается командами
bgp dmzlink-bw
Конфигурация устройств
=====================
Задача №5
Задание:
Настроить балансировку исходящего трафика между маршрутами по умолчанию от провайдеров Балаган
Телеком и Филькин Сертификат в пропорции 3 к 1.
=====================
Задача №6
Задание:
Не используя атрибуты weight, local preference или фильтрацию, настроить маршрутизатор msk-arbat-gw1 так,
чтобы для исходящего трафика Балаган Телеком был основным, а Филькин Сертификат резервным.
Зато если речь идёт о Центрах Обработки Данных или хостинг-провайдерах, то ситуация обратная и вопрос
балансировки стоит очень остро.
А бывает такая ситуация, что один провайдер предоставляет более широкий канал за небольшие деньги, но при
этом путь через него длиннее и весь трафик уходит в другой – дорогой и узкий. Нам эта ситуация невыгодна и мы
бы хотели, чтобы узкий канал стал резервным.
Вот её и разберём. Но придётся взять совершенно вырожденную ситуацию. К примеру, доступ из Балаган
Телекома к сети ЛикМиАп.
Вот так выглядит таблица BGP и маршрутизации на провайдере Балаган Телеком в обычной ситуации:
Если мы хотим ухудшить основной путь (прямой линк между ними), то нужно добавить AS в список AS-Path:
Таким образом мы добились того, что трафик пойдёт намеченным нами путём.
Естественно, при падении одного из каналов трафик переключится на второй, независимо от настроенных AS-
Path Prepend’ов.
Конфигурация устройств.
2) MED
Multiexit Discriminator. В cisco он называется метрикой (Inter-AS метрика). MED является слабым атрибутом.
Слабым, потому что он проверяется лишь на шестом шаге при выборе маршрута и оказывает по сути слабое
влияние.
Если Local Preference влияет на выбор пути выхода трафика из Автономной системы, то MED передаётся в
соседние AS и таким образом влияет на пути входа трафика.
Вообще MED и Local Preference часто путают новички, поэтому опишем в табличке разницу
Local Preference MED
Определяет приоритет пути
Определяет приоритет пути для входа трафика
для выхода трафика
Действует только внутри AS. Никак не Передаётся в другие AS и намекает через какой путь передавать
передаётся в другие AS трафик предпочтительнее
Может работать при подключении к разным
Работает только при нескольких подключениях к одной AS
AS
Чем больше значение, тем выше приоритет Чем больше значение, тем ниже приоритет
Не будем на нём останавливаться, потому что используют его редко, да и наша сеть для этого не подходит –
должно быть несколько соединений между двумя AS, а у нас только по одному в каждую.
3) Анонс разных префиксов через разных ISP
Ещё один способ распределить нагрузку – раздавать разные сети разным провайдерам.
То есть наша сеть 100.0.0.0/23 известна через два пути, но в таблицу маршрутизации добавится только один.
Соответственно и весь трафик назад пойдёт одним – лучшим путём.
Но!
Мы можем разделить её на две подсети /24 и одну отдавать в Балаган Телеком, а другую в Филькин Сертификат.
Соответственно ЦОД будет знать про эти подсети через разные пути:
Во-первых, мы прописываем все свои подсети – все 3: одну большую /23 и две маленькие /24:
Для того, чтобы они могли быть анонсированы, нужно создать маршруты до этих подсетей.
А теперь создаём префикс-листы, которые разрешают каждый только одну подсеть /24 и общую /23.
Привязываем мы их на OUT – на исходящий, потому что речь о маршрутах, которые мы отправляем вовне.
Итак, соседу 101.0.0.1 (Балаган Телеком) мы будем анонсировать сети 100.0.0.0/24 и 100.0.0.0/23.
А соседу 102.0.0.1 (Филькин Сертификат) – сети 100.0.1.0/24 и 100.0.0.0/23.
Теперь осталось ответить на вопрос какого лешего мы тащили за собой большую подсеть /23? Ведь согласно
правилу Longest prefix match более точные маршруты предпочтительней, то есть /23, как бы и не нужен, когда
есть /24.
Но вообразим себе ситуацию, когда падает сеть Балаган Телеком. Что при этом произойдёт
Существуют также специальные организации, которые отслеживают анонсы BGP в Интернете и, если вдруг
происходит что-то неожиданное, может уведомить владельца сети. Подсеть 100.0.0.0/24 перестанет быть
известной в интернете – ведь только Балаган Телеком что-то знал о ней благодаря нашей настройке.
Соответственно, ляжет и часть нашей сети. Но! Нас спасает более общий маршрут 100.0.0.0/23. Филькин
Сертификат знает о нём и анонсирует его в Интернет. Соответственно, хоть ЦОД и не знает про сеть 100.0.0.0/24,
он знает про 100.0.0.0/23 и пустит трафик в сторону Филькина Сертификата.
Конфигурация устройств
4) BGP Community
C помощью BGP Community можно давать провайдеру указания, что делать с префиксом, кому передавать, кому
нет, какой local preference у себя ставить и т.д. Рассматривать этот вариант сейчас не будем, потому что тему
коммьюнити мы перенесём в следующий выпуск.
=====================
Задача №7
В такой ситуации нам приходит на помощь маршрутизация на базе политик ака PBR (Policy based routing). Эта
технология позволяет нам управлять трафиком, базируясь на следующих признаках пакета:
• Адрес источника (или комбинация адрес источника-адрес получателя)
• Информация 7 уровня (приложений) OSI
• Интерфейс, в который пришел пакет
• QoS-метки
• Вообще говоря, любая информация, используемая в extended-ACL (порт источника\получателя, протокол
и прочее, в любых комбинациях). Т.е. если мы можем выделить интересующий нас трафик с помощью
расширенного ACL, мы сможем его смаршрутизировать, как нам будет угодно.
Плюсы использования PBR очевидны: невероятная гибкость маршрутизации. Но и минусы тоже присутствуют:
• Все нужно писать руками, отсюда много работы и риск ошибки
• Производительность. На большинстве железок PBR работает медленнее, чем обычный роутинг
(исключение составляют каталисты 6500, к ним есть супервайзер с железной поддержкой PBR)
Политика, на основе которой осуществляется PBR, создается командой route map POLICY_NAME, и содержит два
раздела:
• Выделение нужного трафика. Осуществляется либо с помощью ACL, либо в зависимости от интерфейса, в
который трафик пришел. За это отвечает команда match в режиме конфигурации route map
• Применение действия к этому трафику. За это отвечает команда set
Немного практики для закрепления
R4(config)#route-map BACK
После чего заходим на интерфейс, который смотрит в сторону R5 (PBR работает с входящим трафиком!) и
применяем на нем полученную политику:
R4(config)#int fa1/0
Проверяем:
R5#traceroute 192.168.0.1
1 192.168.100.4 40 msec 40 msec 16 msec
2 192.168.3.3 52 msec 52 msec 44 msec
3 192.168.1.1 56 msec * 68 msec
Работает! А теперь посмотрим внимательно на схему и подумаем: все ли хорошо?
А вот и нет!
Следуя данному ACL, у нас заворачивается на R3 весь трафик с источником R5. А это значит, что если, например,
R5 захочет попасть на R2, он, вместо короткого и очевидного маршрута R5-R4-R2, будет послан по маршруту R5-
R4-R3-R1-R2. Поэтому, нужно очень аккуратно и вдумчиво составлять ACL для PBR, делая его максимально
специфичным.
В этом примере мы в качестве действия, применяемого к трафику, выбрали переопределение некстхопа (узла
сети, куда дальше отправится пакет). А что еще можно сделать с помощью PBR? Имеются в наличие команды:
• set ip next-hop
• set interface
• set ip default next-hop
• set default interface
С первыми двумя все относительно понятно – они переопределяют некстхоп и интерфейс, из которого пакет
будет выходить (чаще всего set interface применяется для point-to-point линков). А в случае, если мы применяем
команды set ip default next-hop или set default interface, роутер сначала смотрит таблицу маршрутизации, и, если
там имеется маршрут для проверяемого пакет, отправляет его соответственно таблице. Если маршрута нет, пакет
отправляется, как сказано в политике. К примеру, если бы мы в нашей топологии вместо set ip next-hop
192.168.3.3 скомандовали set ip default next-hop 192.168.3.3, ничего бы не поменялось, так как у R4 есть маршрут
к R1 (через R2). Но если бы он отсутствовал, трафик направлялся бы к R3.
Вообще говоря, с помощью команды set можно изменять очень много в подопытном пакете: начиная от меток
QoS или MPLS и заканчивая атрибутами BGP
=====================
Задача №8
Эта технология, по сути, есть активный мониторинг сети, т.е. генерирование некоего трафика с целью оценить ту
или иную характеристику сети. Но мониторингом все не заканчивается – роутер может, используя полученные
данные, влиять на принятие решений по маршрутизации, таким образом реагируя и разрешая проблему. К
примеру, разгружать занятой канал, распределяя нагрузку по другим.
Без лишних слов, сразу к настройке. Для начала, нам нужно сказать, что мы хотим мониторить. Создаем объект
мониторинга, назначаем ему номер:
R4(config)#ip sla 1
Нужно сказать, что синтаксис команд, относящихся к IP SLA, претерпел некоторые изменения: начиная с IOS
12.4(4)T он такой, как в статье, до этого некоторые команды писались по другому. Например, вместо ip sla 1 было
rtr 1 или вместо ip sla responder – rtr responder
Как видите, список внушительный, поэтому останавливаться не будем, для интересующихся есть
подробная статья на циско.ком.
=====================
Задача №9
Задание:
Настроить маршрутизацию таким образом, чтобы HTTP-трафик из локальной сети 10.0.1.0 шел через Балаган
Телеком, а весь трафик из сети 10.0.2.0 через Филькин Сертификат. Если в адресе отправителя фигурирует любой
другой адрес, трафик должен быть отброшен, а не маршрутизироваться по стандартной таблице маршрутизации
(задание надо выполнить не используя фильтрацию с помощью ACL, примененных на интерфейсе).
Дополнительное условие: Правила PBR должны работать так только если соответствующий провайдер доступен
(в данной задаче достаточно проверки доступности ближайшего устройства провайдера). Иначе должна
использоваться стандартная таблица маршрутизации.
Обычно, работу IP SLA рассматривают на простейшем примере icmp-echo. То есть, в случае, если мы можем
пинговать тот конец линии, трафик идет по ней, если не можем – по другой. Но мы пойдем путем чуть
посложнее. Итак, нас интересуют характеристики канала, важные для голосового трафика, например, джиттер.
Конкретнее, udp-jitter, поэтому пишем
В этой команде после указания вида проверки (udp-jitter) идет ip адрес, куда будут отсылаться пробы (т.е.
меряем от нас до 192.168.200.1 – это лупбек на R1) и порт (от балды 55555). Затем можно настроить частоту
проверок (по умолчанию 60 секунд):
R4(config-ip-sla-jitter)#frequency 10
Некоторые виды измерений в IP SLA требуют наличия “на той стороне” так называемого “ответчика” (responder),
некоторые (например, FTP, HTTP, DHCP, DNS) нет. Наш udp-jitter требует, поэтому, прежде чем запускать
измерения, нужно подготовить R1:
R4(config)#track 1 rtr 1
Настраиваем задержку:
R4(config-track)#delay up 10 down 15
Это означает: если объект мониторинга упал и не поднялся в течение 15 секунд, переводим track в
состояние down. Если объект был в состоянии down, но поднялся и находится в поднятом состоянии хотя бы 10
секунд, переводим track в состояние up.
Следующим действием нам нужно привязать track к нашей роут-мапе. Напомню, стандартный путь от R5 к R1
идет через R2, но у нас имеется роут-мапа BACK, переназначающая стандартное положение вещей в случае, если
источник R5:
R4#sh run | sec route-map
ip policy route-map BACK
route-map BACK permit 10
match ip address 100
set ip next-hop 192.168.3.3
Если мы привяжем наш мониторинг к этой мапе, заменив команду set ip next-hop 192.168.3.3 на set ip next-
hop verify-availability 192.168.3.3 10 track 1, получим обратный нужному эффект: в случае падения трека (из-за
превышения показателя джиттера в sla 1), мапа не будет отрабатываться (все будет идти согласно таблице
маршрутизации), и наоборот, в случае нормальных значений, трек будет up, и трафик будет идти через R3.
Как это работает: роутер видит, что пакет подпадает под условия match, но потом не сразу делает set, как в
предыдущем примере с PBR, а промежуточным действием проверяет сначала состояние трека 1, а затем, если он
поднят (up), уже делается set, если нет – переходит к следующей строчке роут-мапы.
Для того, чтобы наша мапа заработала, как надо, нам нужно как-то инвертировать значение трека, т.е. когда
джиттер большой, наш трек должен быть UP, и наоборот. В этом нам поможет такая штука, как track list. В IP SLA
существует возможность объединять в треке список других треков (которые, по сути, выдают на выходе 1 или 0) и
производить над ними логические операции OR или AND, а результатом этих операций будет состояние этого
трека. Кроме этого, мы можем применить логическое отрицание к состоянию трека. Создаем трек-лист:
R4(config)#route-map BACK
Цифра 10 после адреса некстхопа – это его порядковый номер (sequence number). Мы можем, к примеру,
использовать его так:
Тут такая логика: выбираем трафик, подпадающий под ACL 100, затем идет промежуточная проверка track 1, если
он up, ставим пакету некстхоп 192.168.3.3, если down, переходим к следующему порядковому номеру (20 в
данном случае), опять же промежуточно проверяем состояние трека (уже другого, 2), в зависимости от
результата, ставим некстхоп 192.168.2.2 или отправляем с миром (маршрутизироваться на общих основаниях).
Давайте теперь немножко словами порассуждаем, что же мы такое накрутили: итак, измерения джиттера у нас
идут от источника R4 к респондеру R1 по маршруту через R2. Максимальное допустимое значение джиттера на
этом маршруте у нас – 10. В случае, если джиттер превышает это значение и держится на этом уровне 15 секунд,
мы переключаем трафик, генерируемый R5, на маршрут через R3. Если джиттер падает ниже 10 и держится там
минимум 10 секунд, пускаем трафик от R5 по стандартному маршруту. Попробуйте для закрепления материала
найти, в каких командах задаются все эти значения.
Итак, мы достигли цели: теперь, в случае ухудшения качества основного канала (ну, по крайней мере, значений
udp-джиттера), мы переходим на резервный. Но что, если и там тоже не очень? Может, попробуем с помощью IP
SLA решить и эту проблему?
Попробуем выстроить логику того, что мы хотим сделать. Мы хотим перед переключением на резервный канал
проверять, как у нас обстоит дело с джиттером на нем. Для этого нам нужно завести дополнительный объект
мониторинга, который будет считать джиттер на пути R4-R3-R1, пусть это будет 2. Сделаем его аналогичным
первому, с теми же значениями. Условием переключения на резервный канал тогда будет: объект 1
down И объект 2 up. Чтобы измерять джиттер не по основному каналу, придется пойти на хитрость: сделать
loopback-интерфейсы на R1 и R4, прописать статические маршруты через R3 туда-обратно, и использовать эти
адреса для объекта SLA 2.
R1(config)#int lo1
R1(config-if)#exit
R4(config)#int lo0
R4(config-if)#ip add 192.168.31.4 255.255.255.0
R4(config-ip-sla-jitter)#exit
R4(config)#ip sla 2
R4(config-ip-sla-jitter)#threshold 10
R4(config-ip-sla-jitter)#frequency 10
R4(config-ip-sla-jitter)#exit
R4(config)#track 3 rtr 2
R4(config-track)#object 1 not
R4(config-track)#object 3
Вуаля, теперь трафик R5->R1 переключается на запасной маршрут только в том случае, если джиттер основного
канала больше 10 и, в это же время, джиттер запасного меньше 10. В случае, если высокий джиттер наблюдается
на обоих каналах, трафик идет по основному и молча страдает.
Состояние трека можно привязать также к статическому маршруту: например, мы можем командой ip route
0.0.0.0 0.0.0.0 192.168.1.1 track 1 сделать шлюзом по умолчанию 192.168.1.1, который будет связан с треком 1
(который, в свою очередь, может проверять наличие этого самого 192.168.1.1 в сети или измерять какие-нибудь
важные характеристики качества связи с ним). В случае, если связанный трек падает, маршрут убирается из
таблицы маршрутизации.
Также будет полезным упомянуть, что информацию, получаемую через IP SLA, можно вытащить через SNMP,
чтобы потом можно было ее хранить и анализировать где-нибудь в вашей системе мониторинга. Можно даже
настроить SNMP-traps.
=====================
Задача №10
На маршрутизаторе msk-arbat-gw1 настроена PBR: HTTP-трафик должен идти через провайдера Филькин
Сертификат, а трафик из сети 10.0.2.0 должен идти через Балаган Телеком.
Указанный трафик передается правильно, но не маршрутизируется остальной трафик из локальной сети, который
должен передаваться через провайдера Балаган Телеком.
Задание:
Исправить настройки таким образом, чтобы они соответствовали условиям.
IP SLA
• Параметры IP SLA
• SNMP-traps
Долго ли коротко ли длилась история linkmeup, но компания росла, развивалась. Счёт маршрутизаторов уже на
десятки, свои опто-волоконные линии, развитая сеть по городу. И было принято решение оформлять компанию,
как провайдера и предоставлять услуги доступа в Интернет для сторонних в том числе организаций.
Сама по себе задача административная — лицензии там, поиск клиентской базы, реклама, поставить СОРМ.
Разумеется, с технической стороны тоже нужны приготовления — просчитать ресурсы, мощности, порты,
подготовить политику QoS. Но всё это (за исключением QoS) — рутина.
Мы же хотим поговорить о другом — IBGP. Возможно, тема покажется вам несколько притянутой за уши, мол,
внутренний BGP — прерогатива достаточно крупных провайдеров.
Однако это не так, сейчас iBGP задействуется в ентерпрайзах чуть ли не чаще, чем в провайдерах. С целью
исключительно внутренней маршрутизации. Например, ради VPN — очень популярное приложение на базе BGP
в корпоративной среде. К примеру, возможность организовать периметры, изолированные на L3, на уже
используемой инфраструктуре очень ценна. А префиксов-то может быть каких-то полсотни, а то и десяток. Вовсе
никакой не Full View, однако все равно удобно.
Возможно, к нашей сети Linkmeup это не имеет по-прежнему отношения, но обойти стороной такую концепцию
будет совершенно непростительно. Поэтому предположим, что сеть достаточно велика, и у нас есть
необходимость в BGP в ядре.
Сегодня обсудим
• Когда нужен IBGP
• В чём отличия от EBGP
• Route Reflector’ы
• Конфедерации
• Нерассмотренные в основной статье атрибуты BGP
Традиционное видео
Задачки в этом выпуске не относятся напрямую к IBGP, это, скорее, по BGP в целом. Интересно будет как
новичкам поломать голову, так и старожилам размяться
Что такое IBGP?
Начнём с того, что вообще такое Internal BGP. По сути это тот же самый BGP, но внутри AS. Он даже настраивается
практически так же.
Основных применения два:
Резервирование. Когда есть несколько линков к провайдерам и не хочется замыкать всё на одном своём
граничном маршрутизаторе (т.н. бордере (от старославянского border — граница), ставится несколько
маршрутизаторов, а между ними поднимается IBGP для того, чтобы на них всегда была актуальная информация
обо всех маршрутах.
В случае проблем у провайдера ISP2 R2 будет знать о том, что те же самые сети доступны через ISP1. Об этом ему
сообщит R1 по IBGP.
Подключение клиентов по BGP. Если стоит задача подключить клиента по BGP, при этом у вас больше, чем один
маршрутизатор, без IBGP не обойтись.
Чтобы R4 передал Клиенту1 Full View, он должен получить его по IBGP от R1 или R2.
Поясним на примерах.
Как это могло бы быть в такой топологии, например, если не использовать технологию избежания петель:
R1 получил анонс от EBGP-соседа, передал его R2, тот передал R3, R3 передал R4. Вроде, все молодцы, все знают,
где находится сеть Интернет. Но R4 передаёт этот анонс обратно R1.
R1 получил маршрут от R4, и он по выгодности точно такой-же, как оригинальный от ISP — AS-Path-то не менялся.
Поэтому в качестве приоритетного может выбраться даже новый маршрут от R4, что, естественно, неразумно:
мало того, что маршруты будут изучены неверно, так и трафик в итоге может заloopиться и не попадёт к точке
назначения.
В случае же полносвязной топологии и правила Split Horizon, такая ситуация исключается. R1, получив анонс от
ISP1, передаёт его сразу всем своим соседям: R2, R3, R4. А те в свою очередь эти анонсы сохраняют, но передают
только EBGP-партнёрам, но не IBGP, именно потому, что получены от IBGP-партнёра. То есть все BGP-
маршрутизаторы имеют актуальную информацию и исключены петли.
Причём, не имеет значение, подключены соседи напрямую или через промежуточные маршрутизаторы. Так,
например, на вышеприведённой схеме R1 не имеет связи с R3 напрямую — они общаются через R2, однако это
не мешает им установить TCP-сессию и поверх неё BGP.
Понятие Split Horizon тут применяется в более широком смысле. Если в RIP это означало «не отсылать анонсы
обратно в тот интерфейс, откуда они пришли», в IBGP это означает «не отсылать анонсы от IBGP-
партнёров другим IBGP-партнёрам.»
2) Вторая тонкость — адрес Next Hop. В случае External BGP маршрутизатор при отправке анонса своему EBGP-
соседу сначала меняет адрес Next-Hop на свой, а потом уже отсылает. Вполне логичное действие.
Вот как анонс сети 103.0.0.0/22 выглядит при передаче от R5 к R1:
Если же маршрутизатор передаёт анонс IBGP-соседу, то адрес Next-Hop не меняется. Хм. Непонятно. Почему? Это
расходится с привычным пониманием DV-протокола маршрутизации.
Дело в том, что здесь понятие Next-Hop отличается от того, которое используется в IGP. В IBGP он сообщает о
точке выхода из локальной AS.
И тут возникает ещё один момент — важно, чтобы у получателя такого анонса был маршрут до Next-Hop — это
первое, что проверяется при выборе лучшего маршрута. Если его не будет, то маршрут будет помещён в таблицу
BGP, но его не будет в таблице маршрутизации.
В принципе, практически всё оборудование даёт возможность менять адрес Next-Hop на свой при передаче
маршрута IBGP-соседу.
На циске это делается командой "neighbor XYZ Next-Hop-self". Позже вы увидите, как это применяется на деле.
3) Третий момент: если в EBGP обычно подразумевается прямое подключение двух соседей друг к другу, то в
Internal BGP соседи могут быть подключены через несколько промежуточных устройств.
На самом деле в EBGP также можно настраивать соседей, которые находятся за несколько хопов друг от друга и
это на самом деле практикуется, например, в случае настройки Inter-AS Option C. Называется это дело MultiHop
BGP и включается командой "neighbor XYZ ebgp-multihop" в режиме конфигурации BGP.
Но для IBGP это работает по умолчанию.
Это позволяет устанавливать IBGP-партнёрство между Loopback-адресами. Делается это для того, чтобы не
привязываться к физическим интерфейсам — в случае падения основного линка, BGP-сессия не прервётся,
потому что лупбэк будет доступен через резервный.
Это самая распространённая практика.
При этом EBGP однако обычно устанавливается на линковых адресах, потому что как правило имеется только
одно подключение и в случае его падения, всё равно Loopback будет не доступен. Да и настраивать ещё какую-то
дополнительную маршрутизацию с провайдером не очень-то хочется.
=====================
Задача № 1
Схема:
В таком сценарии у нас два BGP-маршрутизатора R1 и R3, но они находятся в разных концах города и
подключены через промежуточный маршрутизатор, на котором BGP не настроен.
Условие:
IBGP-сессия прекрасно установится, несмотря даже на то, что на промежуточном маршрутизаторе BGP не
включен, и мы видим даже маршруты:
Но где пинг?
Вам нужно стараться избегать таких ситуаций, когда между IBGP-соседями будут не-BGP маршрутизаторы.
Вообще-то есть механизм, позволяющий если не исправить, то по крайней мере предупредить такую ситуацию,
— IGP Synchronization. Он не позволит добавить маршрут в таблицу, если точно такой же маршрут не известен
через IGP. Это в какой-то мере гарантирует, что на промежуточных устройствах, независимо от того, активирован
на них BGP или нет, будут нужные маршруты.
Но я не знаю тех десперадо, которые решились включить IGP Synchronization.
Во-первых, каким образом такие маршруты попадут в IGP? Только редистрибуцией. Теперь представьте себе, как
Full View медленно наполняет LSDB OSPF, проникая в отдалённые уголки памяти и заставляя процессор до
изнеможения выискивать кратчайшие маршруты. Хотите ли вы этого?
А, во-вторых, вытекающее из «во-первых», по умолчанию, IGP-synchronization выключен практически на всех
современных маршрутизаторах.
=====================
Задача № 2
Между AS64504 и AS64509 появился линк, который связывает их напрямую. Обе сети использовали OSPF
и без проблем объединили сеть в одно целое. Но, после проверки, оказалось, что трафик ходит через AS64500, а
не напрямую от AS64504 к AS64509, через OSPF.
Изменить конфигурацию BGP:
— R7 должен использовать OSPF, если трафик идет в сеть 109.0.0.0/24
— R9 должен использовать OSPF, если трафик идет в сеть 104.0.0.0/24
=====================
Задача № 3
Наш новый клиент AS 64504 подключен к нашей сети. И в дальнейшем планирует подключение к другому
провайдеру и у него уже есть свой PI-блок адресов. Но на данном этапе, есть подключение только к нашей AS и
поэтому клиент может использовать приватный номер AS.
Задание: При анонсе сети клиента вышестоящим провайдерам, удалить номер приватной AS64504.
Конфигурация и схема: базовые.
R4
interface FastEthernet1/0
R7
interface Loopback1
interface FastEthernet0/0
Тут всё просто и понятно, после настройки всех внешних соседей мы будем иметь такую ситуацию:
На остальных устройствах
Каждый BGP маршрутизатор знает только о тех сетях, которые получены им непосредственно от EBGP-соседа.
IBGP
Теперь обратимся к настройке маршрутизаторов нашей AS с точки зрения IBGP.
Во-первых, как мы говорили ранее, IBGP обычно устанавливается между Loopback-интерфейсами для повышения
доступности, поэтому в первую очередь создадим их:
На всех маршрутизаторах на интерфейсе Loopback0 настраиваем IP-адрес X.X.X.X, где Х — номер маршрутизатора
(это исключительно для примера и не вздумайте такое делать на реальной сети):
R1
interface Loopback0
R2
interface Loopback0
R3
interface Loopback0
R4
interface Loopback0
Наша задача, чтобы все знали обо всех линковых подсетях, адресах Loopback-интерфейсов и, естественно, о
наших белых адресах.
Конфигурация OSPF:
R1
router ospf 1
R2
router ospf 1
R3
router ospf 1
R4
router ospf 1
R1
Команда вида neighbor 2.2.2.2 remote-as 64500 объявляет соседа и сообщает, что он находится в AS 64500, BGP
понимает, что это та же AS, в которой он сам работает и далее считает 2.2.2.2 своим IBGP-партнёром.
Команда вида neighbor 2.2.2.2 update-source Loopback0 сообщает, что соединение будет устанавливаться с
адреса интерфейса Loopback. Дело в том, что на другой стороне (на 2.2.2.2) сосед настроен, как 1.1.1.1 и именно с
этого адреса ждёт все BGP-сообщения.
R2
R3
R4
Приехали.
Не будем долго мучить читателя и сразу посмотрим в таблицу маршрутизации, R4.
А на R7 при этом:
А? Где мои маршруты? Где все мои маршруты? R4 ничего не знает про сети Балаган-Телекома, Филькина
Сертификата, Интернета, соответственно нет их и на R7.
Помните, мы выше говорили про Next-Hop? Мол, он не меняется при передаче по IBGP?
Несмотря на то, что они пришли на R4 от R1 и R2, адреса Next-Hop на них стоят R5 и R6 — то есть не менялись.
Это значит, что трафик в сеть 103.0.0.0/22 R4 должен отправить на адрес 101.0.0.1, ну, либо на 102.0.0.1. Где они в
таблице маршрутизации? Нету их в таблице маршрутизации. Ну, и это естественно — откуда им там взяться.
В итоге добавляем в BGP ещё такую команду: neghbor 2.2.2.2 Next-Hop-self. Для каждого соседа, на каждом узле.
После этого мы видим следующую ситуацию,
Очень простой вопрос: откуда такие гигантские задержки в трассировке? А ещё часто и такая ситуация бывает:
Конфигурация устройств
=====================
Задача № 4
Необходимо настроить такие правила работы с соседними AS:
— от всех соседних AS принимаются префиксы только если в них количество автономных систем в пути не более
10 (в реальной жизни порядок этого значения может быть около 100).
— все префиксы, которые принимаются от клиентов, должны быть с маской не более 24 бит.
Конфигурация и схема: базовые.
Подробности задачи тут.
=====================
Что мы можем улучшить?
Разумеется, процесс настройки BGP. Всё-таки это трудозатраты — сделать весьма похожие настройки на каждом
узле. Для упрощения вводится понятие peer-group, которая исходя из названия позволяет объединять соседей в
группы и одной командой задавать нужные параметры сразу всем.
Дабы не быть голословными, внедрим это на нашей сети:
R1
router bgp 64500
Причём мы можем запросто копировать команды конфигурации группы соседей на другие маршрутизаторы,
меняя только адреса соседей.
Пара замечаний по Peer-group:
1) Для всех участников группы политики должны быть идентичны.
2) На самом деле cisco уже давно использует динамические Update-группы. Это позволяет сэкономить ресурсы
процессора, так как обработка проводится не по разу на каждого члена группы, а один раз на всю группу.
Фактические Peer-группы только облегчают конфигурацию, а оптимизация отдана на откуп Update-групп.
Наверняка, у молодых зелёных инженеров возник вопрос: почему нельзя информацию про публичные адреса
передавать по IBGP? Он же, вроде бы, для этого и предназначен? И даже более общий вопрос, почему нельзя
обойтись вообще одним BGP, без OSPF или IS-IS, например? (Нет, серьёзно, на форумах иногда вскипают
холивары на тему BGP vs OSPF). Ну, по сути ведь тоже протокол маршрутизации — какая разница, передавать
информацию между AS или между маршрутизаторами — есть же Internal BGP.
На это я хочу сказать, что достаточно вам будет поработать немного с BGP на реальной сети, чтобы понять всю
безумность такой затеи.
Самое главное препятствие — Full Mesh. Придётся устанавливать соседство со всеми всеми маршрутизаторами
вручную. OMG, мне дороги моя жизнь и здоровье. (Да, даже не смотря на наличие Route Reflector’ов и скриптов
— это лишние операции)
Другая проблема — медленная реакция и Дистанционно-Векторный подход к распространению маршрутной
информации.
Да и тут можно резонно возразить, что, дескать, существует BFD. Однако он уменьшит время обнаружение
проблемы, но сходимость/восстановление связности всё равно будет медленным.
Третий тонкий момент — отсутствие возможности автоматического изучения соседей. Что ведёт к ручной их
конфигурации.
Из всего вышеуказанного вытекают проблемы масштабируемости и обслуживания.
Просто попробуйте сами использовать BGP вместо IGP на сети из 10 маршрутизаторов, и всё станет ясно.
То же самое касается и распространения белых адресов — IBGP с этим справится, но на каждом маршрутизаторе
придётся вручную прописывать все подсети.
Ну например, наша сеть 100.0.0.0/23. Допустим, к маршрутизатору R3 подключены 3 клиента по линковым
адресам: 100.0.0.8/30, 100.0.0.12/30 и 100.0.0.16/0.
Так вот эти 3 подсети вам нужно будет ввести в BGP тремя командами network, в то время как в IGP достаточно
активировать протокол на интерфейсе.
Можно, конечно, прибегнуть к хитрой редистрибуции маршрутов из IGP, но это попахивает уже костылями и ещё
менее прозрачной конфигурацией.
К чему всё это мы ведём? eBGP — протокол маршрутизации, без дураков. В то же время iBGP — не совсем. Он
больше похож на приложение верхнего уровня, организующее распространение маршрутной информации по
всей сети. В неизменном виде, а не сообщая при каждой итерации соседу «вон туда через меня». У IGP такое
поведение тоже иногда встречается, но там это исключение, а тут — норма.
Я хочу подчеркнуть ещё раз, IGP и IBGP работают в паре, в связке, каждый из них выполняет свою работу.
IGP обеспечивает внутреннюю IP-связность, быструю (читай мгновенную) реакцию на изменения в сети,
оповещение всех узлов об этом как можно быстрее. Он же знает о публичных адресах нашей AS.
IBGP занимается обработкой Интернетных маршрутов в нашей AS и их транзитом от Uplink’a к клиентам и
обратно. Обычно он ничего не знает о структуре внутренней сети.
Если вам пришёл в голову вопрос «что лучше BGP или IS-IS?» — это хорошо, значит у вас пытливый ум, но вы
должны отчётливо понимать, что верный ответ тут только один — это принципиально разные вещи, их нельзя
сравнивать и выбирать мисс “технология маршрутизации 2013”. IBGP работает поверх IGP.
=====================
Задача № 5
Вышестоящая AS 604503 агрегирует несколько сетей, в том числе и нашу, в один диапазон 100.0.0.0/6. Но
этот суммарный префикс вернулся в нашу автономную систему, хотя и не должен был.
Настроить R8 так, чтобы агрегированный префикс не попадал в таблицу BGP маршрутизаторов, которые
анонсируют подсети этого префикса. Не использовать фильтрацию для этого.
Для данного маршрутизатора клиент — iBGP сосед, который специально объявлен, как RR client, и для которого
действуют особые правила. Не-клиент — iBGP сосед, который не объявлен, как RR client
RR серверов может быть (и должно быть в плане отказоустойчивости) несколько. И понятия клиент/не-клиент
строго локальны для каждого RR-сервера.
RR-сервер (или несколько) в совокупности с со своими клиентами формируют кластер.
Правила работы RR
• Если RR получил маршрут от клиента, он отправляет его всем своим клиентам, не-клиентам-соседям и
внешним (EBGP) соседям.
•
•
• Если RR получил маршрут от не-клиента, он отправляет его всем клиентам и EBGP-соседям. Не-клиентам
маршруты НЕ отправляются (потому что они эти маршруты уже получили напрямую от исходного
маршрутизатора).
•
•
• Если RR получил маршрут от EBGP-соседа, он отправляет его всем своим клиентам, не-клиентам-соседям
и внешним соседям.
•
•
• Если клиент получил маршрут от RR, он его может отправить только EBGP-соседу.
Как мы сказали выше, в сети может быть несколько Route-reflector’ов. Это нормально, это не вызовет
образование петли, потому что существует атрибут Originator ID — как только RR получит маршрут, где указан он
сам, как отправитель этого маршрута, он его отбросит. Каждый RR в таком случае будет иметь таблицу
маршрутов BGP точно такую же, как у других. Это вынужденная избыточность, позволяющая значительно
увеличить стабильность, но при этом у вас должна быть достаточная производительность самих устройств, чтобы,
например, поддерживать по паре Full View на каждом.
Но несколько RR могут собираться в кластеры и разрушать деревни обеспечивать экономию ресурсов — таблица
BGP будет делиться между несколькими RR.
Принадлежность к одному кластеру настраивается на каждом RR и определяется атрибутом Cluster ID.
И вот тут тонкий момент — считается, что Best Practice — это настройка одинакового Cluster-ID на всех RR, но на
самом деле это не всегда так. Выбирать нужно, исходя из дизайна вашей сети. Более того, часто рекомендуют
даже намеренно разделять Route Reflector’ы — как ни странно, это увеличивает стабильность сети.
Дабы не растекаться мысью по древу, просто дам ссылку на материал об этом.
RR1 получает маршруты от удалённой AS и раздаёт их своим дочерним RR (Client/RR1), которые в свою очередь
раздают их клиентам.
Это имеет смысл только в достаточно крупных сетях.
Относительно Route Reflector'ов важно понимать, что сам маршрутизатор, выполняющий функции RR не
обязательно участвует в передаче данных. Более того, часто RR специально выносят за пределы пути передачи
трафика, чтобы он выполнял исключительно обязанности по передаче маршрутов, чтобы не увеличивать
нагрузку на него.
Практика RR
Для примера предположим, что в нашей сети в качестве RR будет выступать R1.
Вот конфигурация самого простого случая RR — одинокого, без кластера.
R1
R2
R3
R4
Обратите внимание на команду "neighbor AS64500 route-reflector-client", добавившуюся в настройку R1 и то, что
конфигурация BGP на всех других устройствах полностью идентична, за исключением внешних соседей (102.0.0.1
для R2 и 100.0.0.6 для R4).
В общем-то внешне ничего не поменяется. R4, например, всё будет видеть точно также, за исключением
количества соседей:
Обратите внимание на то, что Route Reflector не меняет Next-Hop отражённых маршрутов на свой, несмотря на
наличие параметра Next-Hop-self.
Здесь видно полную подсеть, количество путей до неё, какой из них лучший, в какую таблицу он добавлен, куда
передаётся (update-group 2 — как раз наш кластер).
Далее перечисляются все эти пути, содержащие такие важные параметры, как AS-Path, Next-Hop, Origin итд, а
также информацию о том, что например, первый маршрут был получен от RR-клиента.
Эту информацию можно успешно использовать для траблшутинга. Вот так, например выглядит её вывод, когда
не настроен Next-Hop-self:
Конфигурация устройств.
Проблема резервирования
Какая сейчас с рут-рефлектором есть проблема? У всех маршрутизаторов связи установлены только с ним. И если
R1 вдруг выйдет из строя, пиши пропало — сеть ляжет.
Для этих целей, давайте настроим кластер и в качестве второго RR выберем R2.
То есть теперь на R3 и R4 нужно поднимать соседства не только с R1, но и с R2.
R1<->R2
Они необходимо для того, чтобы избежать образования петель. Если, например, маршрут прошёл несколько
кластеров и вернулся в исходный, то в параметре Cluster-List среди всех прочих, маршрутизатор увидит номер
своего кластера, и после этого удалит маршрут.
Попробуйте ответить на вопрос, зачем нужен атрибут Originator-ID? Разве Cluster-List не исчерпывает все
варианты?
Если сейчас даже сжечь R1, то связь частично ляжет только на время обнаружения проблемы и перестроения
таблиц маршрутизации (в худшем случае это 3 минуты ожидания Keepalive сообщения BGP и ещё какое-то время
на изучение новых маршрутов).
Но, если дизайн сети у вас предполагал, что RR — это самостоятельные железки, и через них не ходил трафик (то
есть они занимались исключительно распространением маршрутов), то, вполне вероятно, что перерыва трафика
не будет вовсе. Во-первых, отправитель только через 3 минуты заметит, что что-то не так с RR — в течение этого
времени маршрут у него всё-равно будет, а поскольку он ведёт не через бесславно погибший RR, трафик будет
ходить вполне благополучно. По прошествии этих трёх минут отправитель переключится на резервный RR и
получит от него новый актуальный маршрут. Таким образом связь не будет прервана.
Суть иерархических рут-рефлекторов лишь в том, что один из них является клиентом другого. Это помогает
выстроить более понятную и прозрачную схему работы, которую будет проще траблшутить далее.
На нашей сети это лишено какого бы то ни было смысла, поэтому данный случай рассматривать не будем.
Конфедерации
Другой способ решения проблемы Full-Mesh — это конфедерации или иначе их называют sub-AS, под-АС. По сути
— это маленькая виртуальная АС внутри большой настоящей АС.
Каждая конфедерация ведёт себя как взрослая AS — внутри полная связность, снаружи, как Лейбниц на душу
положит — IBGP работает тут по принципу EBGP (с некоторыми оговорками), граничные маршрутизаторы
конфедераций, ведут себя как EBGP-соседи, должны быть подключены напрямую.
Пример топологии:
Когда маршруты передаются внутри АС между конфедерациями в их AS-Path добавляется номер конфедерации
(сегменты AS_CONFED_SEQ и AS_CONFED_SET) для избежания петель. Как только маршрут покидает AS,
удаляются все эти номера, чтобы внешний мир о них не знал.
Встречается он довольно редко из-за своей слабой масштабируемости и непрозрачности, поэтому рассматривать
мы его не будем.
Более подробно можно почитать на xgu.ru.
____________________________
Атрибуты BGP
Последняя тема, которую мы затронем касательно BGP — это его атрибуты. Мы их уже начали рассматривать в
основной статье (AS-Path и Next-Hop, например). Теперь же имеющиеся знания систематизируем и дополним.
AS-path несёт в себе список всех Автономных Систем, которые нужно преодолеть для достижения цели.
Используется для выбора лучшего пути и для исключения петель маршрутизации. Когда маршрут передаётся из
одной AS в другую, в AS-path вставляется номер отправляющей AS. При передаче внутри AS параметр не
меняется.
Origin сообщает, как маршрут зародился — командой network (IGP — значение 0) или редистрибуцией
(Incomplete — значение 2). Значение 1 (EGP) — уже не встречается ввиду того, что протокол EGP не используется.
Назначается единожды маршрутизатором-папой, сгенерировавшим маршрут, и более нигде не меняется. По сути
означает степень надёжности источника. IGP — самый крутой.
Примеры:
Local Preference помогает выбрать один из нескольких маршрутов в одну сеть. Данный атрибут может
передаваться лишь в пределах одной AS. Если анонс с Local Preference приходит от EBGP-партнёра, атрибут
просто игнорируется — мы не можем с помощью Local Preference управлять маршрутами чужой AS.
Atomic Aggregate говорит о том, что префикс был получен путём агрегирования более мелких.
Опциональные передаваемые/транзитивные (Optional Transitive)
Атрибуты, которые не обязательно знать всем. Кто знает — использует, кто не знает — передаёт их дальше.
Примеры:
Aggregator. Указывает на Router ID маршрутизатора, где произошло агрегирование.
Community. Про этот атрибут мы подробно поговорим далее, в заключительной части статьи.
Опциональные непередаваемые/нетранзитивные (Optional Non-transitive)
Атрибуты, которые не обязательно знать всем. Но маршрутизатор, который их не поддерживает, их отбрасывает
и никуда дальше не передаёт.
Пример:
MED — Multi-exit Descriminator. Этим атрибутом мы можем попытаться управлять приоритетами в чужой AS.
Можем попытаться, но вряд ли что-то получится :) Часто этот атрибут фильтруется, он имеет значение только при
наличии как минимум двух линков в одну AS, он проверяется после многих очень сильных атрибутов (Local
Preference, AS-Path), да и разные вендоры могу по-разному трактовать MED.
Упомянутые прежде Cluster List и Originator-ID. Естественно, они являются опциональными, и естественно,
передавать их куда-то за пределы AS нет смысла, поэтому и непередаваемые.
=====================
Задача № 6*
Начнём с теории, Community, как было сказано выше, — это опциональный передаваемый атрибут (Optional
Transitive) размером 4 байта. Он представляет из себя запись вида AA:NN, где AA — двухбайтовый номер AS, NN
— номер коммьюнити (например, 64500:666).
=====================
Задача № 7
Наш новый клиент AS 64504 подключен к нашей сети. И пока что не планирует подключение к другому
провайдеру. На данном этапе клиент может использовать номер автономной системы из приватного диапазона.
Блок адресов, который использует клиент, будет частью нашего диапазона сетей.
Задание: Так как сеть клиента является частью нашего блока адресов, надо чтобы сеть клиента не
анонсировалась соседним провайдерам.
Не использовать фильтрацию префиксов или фильтрацию по AS для решения этой задачи.
Конфигурация и схема: Community.
Отличия только в том, что сеть, которую анонсирует AS64504: 100.0.1.0/28, а не 130.0.0.0/24
В сети тысячи примеров настройки таких базовых коммьюнити и крайне мало примеров реального
использования.
А меж тем одно из самых интересных применений этого атрибута — блэкхоулинг от старославянского black hole
— способ борьбы с DoS-атаками. Очень подробно с примером настройки о нём уже было рассказано на хабре.
Суть в том, что когда началась атака на какой-то из адресов вашей AS, вы этот адрес передаёте вышестоящему
провайдеру с комьюнити 666, и он отправляет такой маршрут в NULL — блэкхолит его. То есть до вас уже этот
паразитный трафик не доходит. Провайдер может передать такой маршрут дальше, и так, шаг за шагом, трафик
от злоумышленника или системы ботов будет отбрасываться уже на самых ранних этапах, не засоряя Интернет.
Достигается такой эффект расширяющейся чёрной дыры именно благодаря коммьюнити. То есть в обычном
случае вы анонсируете этот адрес в составе большой сети /22, например, а в случае DoS’а передаёте самый
специфичный маршрут /32, который будет, естественно, более приоритетным.
О таких атаках вы, кстати, можете послушать в шестом выпуске нашего подкаста linkmeup.
Другие примеры — управление атрибутом Local Preference в чужой AS, сообщать ему, что анонсу нужно
увеличить AS-path (AS-path prepending) или не передавать маршрут каким-либо соседям.
Насчёт последнего. Как, например, вы решите следующую задачу?
Имеется сеть, представленная на рисунке ниже. Вы хотите отдавать свои маршруты соседям из AS 100 и 200 и не
хотите 300.
Без использования коммьюнити силами только своей AS сделать это не представляется возможным.
Кстати, как бы это ни было прискорбно, но такие ограничения реально используются в нашей жизни.
Распространены ситуации, когда несколько провайдеров устанавливают между собой пиринговые отношения —
трафик между их сетями не ходит через вышестоящих провайдеров, не даёт круг через пол-России, но кого-то не
пускают — кому-то свои сети не анонсируют.
Интереснейшие статьи об Интернете и BGP и о пиринговых войнах.
Практика Community
Мы же в качестве примера рассмотрим следующую ситуацию.
Основная схема статьи дополняется ещё одним маршрутизатором клиента и двумя линками.
R7 и R9 разнесены территориально — так называемое георезервирование. Главным является его правый сайт,
левый — резервный.
Внутри своей AS он без проблем настроил передачу исходящего трафика в нужном месте — через R3. А вот со
входящим посложнее — MED не позволяет использовать религия, да и доверия ему нет.
Поэтому мы разработали схему взаимодействия, используя community. На самом деле она будет общая для всех.
Например, ниже мы установим правило — если получили маршрут с коммьюнити 64500:150, увеличить Local
Preference для него до 150. А потом такую политику применяем к нужным нам маршрутам.
match community 1
Это общий блок, который будет одинаков для всех устройств. После этого клиент может сказать, что хочет
воспользоваться этой функцией и мы применяем карту на BGP-соседа:
Применяем карту к BGP-соседу на R3:
Итак, если в анонсе от соседа 100.0.0.10 community совпадает со значением в условии, установить Local
Preference для этих маршрутов в 150.
Часто такие политики (route-map) применяются по умолчанию на всех внешних соседей. Клиентам остаётся
только настроить передачу нужной коммьюнити и даже не нужно просить о чём-то провайдера — всё сработает
автоматически.
Это наша политика по использовании коммьюнити. О ней мы сообщаем клиенту, мол, хочешь Установить для
своего маршрута Local Preference в 150 в нашей AS, используй community 64500:150
И вот он настраивает на R9:
route-map LP permit 10
Передаёт его рут-рефлектору (R1 и R2), который делает выбор и распространяет всем своим соседям:
И даже R4, которому рукой дотянуться до R7, будет отправлять трафик на R3:
вы увидите это:
Отправляться будет то же самое, но в выводах show команд будет отображаться в удобном виде.
=====================
Задача № 8
В нашей AS для настройки политик с клиентскими AS, используются community. Используются такие значения:
64500:150, 64500:100, 64500:50, 64500:1, 64500:2, 64500:3.
Кроме того, маршрутизаторы нашей AS также используют community для работы с соседними AS. Их формат:
64501:xxx, 64502:xxx.
Задание:
— все значения community приходящие от клиентов, которые не определены политикой, должны удаляться,
— значения community, которые проставлены клиентами, должны удаляться, при передаче префиксов соседним
вышестоящим AS. При этом не должны удаляться другие значения, которые проставлены маршрутизаторами
нашей AS.
Конфигурация устройств
В приведённом примере видно, что коммьюнити позволяет работать не с отдельными анонсами и для каждого
из них отдельно применять какие-то политики, а рассматривать их сразу как группу, что естественно, значительно
упрощает обслуживание.
Иными словами, коммьюнити — это группа анонсов с одинаковыми характеристиками.
При работе с community важно понимать, что настройка необходима с двух сторон — чтобы желаемое
заработало, у провайдера тоже должна быть выполнена соответствующая конфигурация.
Часто у провайдеров бывает уже выработанная политика использования коммьюнити, и они просто дают вам те
номера, которые необходимо использовать. То есть после того, как вы добавите к анонсу номер коммьюнити,
провайдеру не придётся ничего делать руками — всё произойдёт автоматически.
Исходя из этой таблички, которая опубликована на сайте Балаган-телекома, мы можем сами принять решение об
управлении трафиком.
У нас Dual-homing подключение к двум различным провайдерам — Балаган Телеком и Филькин Сертификат. У
датацентра подключение также к обоим провайдерам. Он принадлежит какому-то контент-генератору, допустим
это оператор потового видео.
По умолчанию, в нашу сеть всё ходит через Балаган-Телеком (AS64501). Канал там хоть и широкий, но его
утилизация уже достаточно высока. Мы хотим продавать домашним клиентам услугу IPTV и прогнозируем
значительный рост входящего трафика. Неплохо было бы его завернуть в Филькин Сертификат и не бояться о
том, что основной канал забьётся. При этом, естественно, весь другой трафик переносить не нужно.
В таблице BGP проверяем, где находится сеть 103.0.0.0. Видим, что это AS64503, которая достижима через обоих
провайдеров с равным числом AS в AS-Path.
Какие мысли?
Анонсировать определённые сети в Филькин Сертификат, а остальные оставить в Балаган Телеком? Негибко,
немасштабируемо.
Вешать препенды на маршруты, отдаваемые в Балаган Телеком? Тогда, скорее всего, куча другого трафика
перетечёт на Филькин Сертификат.
Попросить инженера Балаган-Телекома вручную удлинить наши маршруты при передаче их в AS64503. Уже
ближе к истине, и это даже сработает, но, скорее всего, инженер провайдера пошлёт вас… на сайт с табличкой,
где прописана их политика Community.
Собственно, всё, что нужно сделать нам — на маршрутизаторе R1 применить route-map по добавлению
коммьюнити 64500:1031 к соседу R5(напоминаем, что 103Х — это для соседа из AS 64503). Дальше всё сделает
автоматика.
Вот как R5 видит маршрут сам:
Как видите, галочка стоит напротив более короткого пути через Филькин Сертификат, чего мы и добивались.
=====================
Задача № 9
Одним из наших клиентов стала крупная компания. Платят они нам довольно много, но тут возникла
проблема с тем, что когда происходят какие-то проблемы с провайдером AS64501, то качество связи, которую
обеспечивает линк с провайдером AS64502, не устраивает клиента. Главное для нашего клиента, хорошее
качество связи к филиалам.
Так как клиент солидный, то пришлось установить пиринг с еще одним провайдером AS64513. Но он нам дорого
обходится поэтому использовать его мы будем только когда провайдер AS64501 недоступен и только для этого
важного клиента.
Задание:
Надо настроить работу сети таким образом, чтобы через провайдера AS64513 сеть клиента 150.0.0.0/24
анонсировалась только в том случае, если через провайдера AS64501 недоступна сеть 103.0.0.0/22 (она
используется для проверки работы провайдера). Кроме того, от провайдера AS64513 нам надо принимать только
сети филиалов клиента (50.1.1.0/24, 50.1.2.0/24, 50.1.3.0/24) и использовать их только если они недоступны через
провайдера AS64501. Остальной трафик клиента будет ходить через AS64502.
Конфигурация: базовая.
Подробности задачи тут.
=====================
Традиционный видеоурок:
На заре моего становления, как инженера, тема мультикаста меня неимоверно пугала, и я связываю это с
психотравмой моего первого опыта с ним.
«Так, Марат, срочно, до полудня нужно пробросить видеопоток до нашего нового здания в центре города —
провайдер отдаст его нам тут на втором этаже» — услышал я одним чудесным утром. Всё, что я тогда знал
о мультикасте, так это то, что отправитель один, получателей много, ну и, кажется, протокол IGMP там как-то
задействован.
В итоге до полудня мы пытались всё это дело запустить — я пробросил самый обычный VLAN от точки входа до
точки выхода. Но сигнал был нестабильным — картинка замерзала, разваливалась, прерывалась. Я в панике
пытался разобраться, что вообще можно сделать с IGMP, тыркался, тыркался, включал мультикаст роутинг, IGMP
Snooping, проверял по тысяче раз задержки и потери — ничего не помогало. А потом вдруг всё заработало. Само
собой, стабильно, безотказно.
Это послужило мне прививкой против мультикаста, и долгое время я не проявлял к нему никакого интереса.
И теперь с высоты оттраблшученных кейсов я понимаю, что там не могло быть никаких проблем с настройкой
сетевой части — глючило конечное оборудование.
Сохраняйте спокойствие и доверьтесь мне. После этой статьи такие вещи вас пугать не будут.
Раз уж мы решили поговорить о мультикасте, то, пожалуй, начнём этот параграф с вопроса, где и как он
используется.
Первое, что приходит на ум, — это телевидение (IPTV) — один сервер-источник отправляет трафик, который
хочет получать сразу много клиентов. Это и определяет сам термин — multicast — многоадресное вещание. То
есть, если уже известный вам Broadcast означает вещание всем, мультикаст означает вещание определённой
группе.
Второе применение — это, например, репликация операционной системы на множество компьютеров разом.
Это подразумевает загрузку больших объёмов данных с одного сервера.
Возможные сценарии: аудио и видеоконференции (один говорит — все слушают), электронная коммерция,
аукционы, биржи. Но это в теории, а на практике редко тут всё-таки используется мультикаст.
Ещё одно применение — это служебные сообщения протоколов. Например, OSPF в своём широковещательном
домене рассылает свои сообщения на адреса 224.0.0.5 и 224.0.0.6. И обрабатывать их будут только те узлы, на
которых запущен OSPF.
В данной статье для практики мы возьмём IPTV, как наиболее наглядный пример.
Пример I
Начнём с самого простого случая:
На сервере-источнике настроено вещание в группу 224.2.2.4 — это означает, что сервер отправляет трафик на IP-
адрес 224.2.2.4. На клиенте видеоплеер настроен принимать поток группы 224.2.2.4.
При этом, заметьте, клиент и сервер не обязательно должны иметь адреса из одной подсети и пинговать друг
друга — достаточно, чтобы они были в одном широковещательном домене.
Мультикастовый поток просто льётся с сервера, а клиент его просто принимает. Вы можете попробовать это
прямо у себя на рабочем месте, соединив патчкордом два компьютера и запустив, например, VLC.
Надо заметить, что в мультикасте нет никакой сигнализации от источника, мол, «Здрасьте, я Источник, не надо
немного мультикаста?».
Сервер-источник просто начинает вещать в свой интерфейс мультикастовые пакеты. В нашем примере они
напрямую попадают клиенту и тот, собственно, сразу же их и принимает.
Если на этом линке отловить пакеты, то вы увидите, что мультикастовый трафик — это ни что иное, как море UDP-
пакетов.
Мультикаст не привязан к какому-то конкретному протоколу. По сути, всё, что его определяет — адреса. Однако,
если говорить о его применении, то в абсолютном большинстве случаев используется именно UDP. Это легко
объясняется тем, что обычно с помощью многоадресной рассылки передаются данные, которые нужны здесь и
сейчас. Например, видео. Если кусочек кадра потеряется, и отправитель будет пытаться его послать повторно, как
это происходит в TCP, то, скорее всего, этот кусочек опоздает, и где его тогда показывать? Поезд ушёл. Ровно то
же самое со звуком.
Соответственно не нужно и устанавливать соединение, поэтому TCP здесь ни к чему.
Чем же так разительно отличается мультикаст от юникаста? Думаю, у вас есть уже предположение. И вы,
наверняка, правы.
В обычной ситуации у нас 1 получатель и 1 отправитель — у каждого из них один уникальный IP-адрес.
Отправитель точно знает, куда надо слать пакет и ставит этот адрес в заголовок IP. Каждый промежуточный узел
благодаря своей таблице маршрутизации точно знает, куда переслать пакет. Юникастовый трафик между двумя
узлами беспрепятственно проходит сквозь сеть. Но проблема в том, что в обычном пакете указывается только
один IP-адрес получателя.
Что делать, если у одного и того же трафика несколько получателей? В принципе можно расширить
одноадресный подход и на такую ситуацию — отправлять каждому клиенту свой экземпляр пакета. Клиенты не
заметят разницы — хоть он один, хоть их тысяча, но разница будет отчётливо различима на ваших каналах
передачи данных.
Предположим у нас идёт передача одного SD-канала с мультикаст-сервера. Пусть, он использует 2 Мб/с. Всего
таких каналов 30, а смотрит каждый канал по 20 человек одновременно. Итого получается 2 Мб/с * 30 каналов *
20 человек = 1200 Мб/с или 1,2 Гб/с только на телевидение в случае одноадресной рассылки. А есть ведь ещё HD
каналы, где можно смело умножать эту цифру на 2. И где тут место для торрентов?
Вот почему в IPv4 был заложен блок адресов класса D: 224.0.0.0/4 (224.0.0.0-239.255.255.255). Адреса этого
диапазона определяют мультикастовую группу. Один адрес — это одна группа, обычно она обозначается буквой
«G».
То есть, говоря, что клиент подключен к группе 224.2.2.4, мы имеем ввиду, что он получает мультикастовый
трафик с адресом назначения 224.2.2.4.
Пример II
Добавим в схему коммутатор и ещё несколько клиентов:
Мультикастовый сервер по-прежнему вещает для группы 224.2.2.4. На коммутаторе все 4 порта должны быть в
одном VLAN. Трафик приходит на коммутатор и по умолчанию рассылается во все порты одного VLAN'а. Значит
все клиенты получают этот трафик. На них на всех в видеопроигрывателе так же указан групповой адрес
224.2.2.4.
Собственно, все эти устройства становятся членами данной мультикастовой группы. Членство в ней
динамическое: кто угодно, в любой момент может войти и выйти из неё.
В данной ситуаци трафик будут получать даже те, кто этого в общем-то и не хотел, то есть на нём не запущен ни
плеер, ни что бы то ни было другое. Но только, если он в том же VLAN'е. Позже мы разберёмся, как с этим
бороться.
Обратите внимание, что в данном случае от сервера-источника приходит только одна копия трафика на
коммутатор, а не по отдельной копии на каждого клиента. И в нашем примере с SD каналами загрузка порта
между источником и коммутатором будет не 1,2 Гб/с, а всего 60 Мб/с (2Мб/с * 30 каналов).
Диапазон 224.0.0.0/24 зарезервирован под link-local коммуникации. Мультикастовые пакеты с такими адресами
назначения не могут выходить за пределы одного широковещательного сегмента.
Диапазон 224.0.1.0/24 зарезервирован под протоколы, которым необходимо передавать мультикаст по всей
сети, то есть проходить через маршрутизаторы.
Но пока совсем непонятно, как трафик от сервера достигает клиентов, когда между ними огромная
провайдерская сеть линкмиап? Да и откуда, собственно, будет известно, кто клиент? Мы же не можем вручную
прописать маршруты, просто потому что не знаем, где могут оказаться клиенты. Не ответят на этот вопрос и
обычные протоколы маршрутизации. Так мы приходим к пониманию, что доставка мультикаст — это нечто
совершенно новое для нас.
Вообще, чтобы доставить мультикаст от источника до получателя на данный момент существует много
протоколов — IGMP/MLD, PIM, MSDP, MBGP, MOSPF, DVMRP.
Мы остановимся на двух из них, которые используются в настоящее время: PIM и IGMP.
С помощью IGMP конечные получатели-клиенты сообщают ближайшим маршрутизаторам о том, что хотят
получать трафик. А PIM строит путь движения мультикастового трафика от источника до получателей через
маршрутизаторы.
IGMP
Снова вернёмся к дампу. Видите вот этот верхний пакет, после которого полился мультикастовый поток?
Это сообщение протокола IGMP, которое отправил клиент, когда мы на нём нажали Play. Именно так он
сообщает о том, что хочет получать трафик для группы 224.2.2.4.
IGMP — Internet Group Management Protocol — это сетевой протокол взаимодействия клиентов мультикастового
трафика и ближайшего к ним маршрутизатора.
В IPv6 используется MLD (Multicast Listener Discovery) вместо IGMP. Принцип работы у них абсолютно
одинаковый, поэтому далее везде вы смело можете менять IGMP на MLD, а IP на IPv6.
Акцентируемся пока на второй, как на самой показательной, и рассмотрим все события от подключения клиента
к группе до его выхода из неё.
Клиент будет также запрашивать группу 224.2.2.4 через проигрыватель VLC.
Роль IGMP очень проста: если клиентов нет — передавать мультикастовый трафик в сегмент не надо. Если
появился клиент, он уведомляет маршрутизаторы с помощью IGMP о том, что хочет получать трафик.
Для того, чтобы понять, как всё происходит, возьмём такую сеть:
1. Как только мы запустили приложение на клиенте и задали группу 224.2.2.4, в сеть будет отправлен пакет IGMP
Membership Report — узел «рапортует» о том, что хочет получать трафик этой группы.
В IGMPv2 Report отправляется на адрес желаемой группы, и параллельно он же указывается в самом пакете.
Данные сообщения должны жить только в пределах своего сегмента и не пересылаться никуда
маршрутизаторами, поэтому и TTL у них 1.
Часто в литературе вы можете встретить упоминание о IGMP Join. Не пугайтесь — это альтернативное название
для IGMP Membership Report.
2. Маршрутизатор получает IGMP-Report и, понимая, что за данным интерфейсом теперь есть клиенты, заносит
информацию в свои таблицы
Это вывод информации по IGMP. Первая группа запрошена клиентом. Третья и четвёртая — это служебные
группы протокола SSDP, встроенного в Windows. Вторая — специальная группа, которая всегда присутствует на
маршрутизаторах Cisco — она используется для протокола Auto-RP, который по умолчанию активирован на
маршрутизаторах.
Интерфейс FE0/0 становится нисходящим для трафика группы 224.2.2.4 — в него нужно будет отправлять
полученный трафик.
О наличии клиентов говорит первая запись (*, 224.2.2.4). А запись (172.16.0.5, 224.2.2.4) означает, что
маршрутизатор знает об источнике мультикастового потока для этой группы.
Из вывода видно, что трафик для группы 224.2.2.4 приходит через FE0/1, а передавать его надо на порт FE0/0.
Интерфейсы, в которые нужно передавать трафик, входят в список нисходящих интерфейсов — OIL — Outbound
Interface List.
Более подробно вывод команды show ip mroute мы разберём позже.
Выше на дампе вы видите, что как только клиент отправил IGMP-Report, сразу после него полетели UDP — это
видеопоток.
3. Клиент начал получать трафик. Теперь маршрутизатор должен иногда проверять, что получатели до сих пор у
него есть, чтобы зазря не вещать, если вдруг клиентов не осталось. Для этого он периодически отправляет во все
свои нисходящие интерфейсы запрос IGMP Query.
*Дамп отфильтрован по IGMP*.
По умолчанию это происходит каждые 60 секунд. TTL таких пакетов тоже равен 1. Они отправляются на адрес
224.0.0.1 — все узлы в этом сегменте — без указания конкретной группы. Такие сообщений Query
называются General Query — общие. Таким образом маршрутизатор спрашивает: «Ребят, а кто и что ещё хочет
получать?».
Получив IGMP General Query, любой хост, который слушает любую группу, должен отправить IGMP Report, как он
это делал при подключении. В Report, естественно, должен быть указан адрес интересующей его группы.
*Дамп отфильтрован по IGMP*.
Если в ответ на Query на маршрутизатор пришёл хотя бы один Report для группы, значит есть ещё клиенты, он
продолжает вещать в тот интерфейс, откуда пришёл этот Report, трафик этой самой группы.
Если на 3 подряд Query не было с интерфейса ответа для какой-то группы, маршрутизатор удаляет этот
интерфейс из своей таблицы мультикастовой маршрутизации для данной группы — перестаёт туда посылать
трафик.
По своей инициативе клиент обычно посылает Report только при подключении, потом — просто отвечает на
Query от маршрутизатора.
Интересная деталь в поведении клиента: получив Query, он не торопится сразу же ответить Report'ом. Узел берёт
тайм-аут длиной от 0 до Max Response Time, который указан в пришедшем Query:
При отладке или в дампе, кстати, можно видеть, что между получением различных Report может пройти
несколько секунд.
Сделано это для того, чтобы сотни клиентов все скопом не наводнили сеть своими пакетам Report, получив
General Query. Более того, только один клиент обычно отправляет Report.
Дело в том, что Report отсылается на адрес группы, а следовательно доходит и до всех клиентов. Получив Report
от другого клиента для этой же группы, узел не будет отправлять свой. Логика простая: маршрутизатор и так уже
получил этот самый Report и знает, что клиенты есть, больше ему не надо.
Этот механизм называется Report Suppression.
Далее в статье мы расскажем о том, почему этот механизм на деле очень редко реально работает.
4. Так продолжается веками, пока клиент не захочет выйти из группы (например, выключит плеер/телевизор). В
этом случае он отправляет IGMP Leave на адрес группы.
Маршрутизатор получает его и по идее должен отключить. Но он ведь не может отключить одного конкретного
клиента — маршрутизатор их не различает — у него просто есть нисходящий интерфейс. А за интерфейсом
может быть несколько клиентов. То есть, если маршрутизатор удалит этот интерфейс из своего списка OIL
(Outgoing Interface List) для этой группы, видео выключится у всех.
Но и не удалять его совсем тоже нельзя — вдруг это был последний клиент — зачем тогда впустую вещать?
Если вы посмотрите в дамп, то увидите, что после получения Leave маршрутизатор ещё некоторое время
продолжает слать поток. Дело в том, что маршрутизатор в ответ на Leave высылает IGMP Query на адрес группы,
для которой этот Leave пришёл в тот интерфейс, откуда он пришёл. Такой пакет называется Group Specific Query.
На него отвечают только те клиенты, которые подключены к данной конкретной группе.
Если маршрутизатор получил ответный Report для группы, он продолжает вещать в интерфейс, если не получил
— удаляет по истечении таймера.
Всего после получения Leave отправляется два Group Specific Query — один обязательный, второй контрольный.
Querier
Рассмотрим чуть более сложный случай:
В клиентский сегмент подключено два (или больше) маршрутизатора, которые могут вещать трафик. Если ничего
не сделать, мультикастовый трафик будет дублироваться — оба маршрутизатора ведь будут получать Report от
клиентов. Во избежание этого существует механизм выбора Querier — опрашивателя. Тот кто победит, будет
посылать Query, мониторить Report и реагировать на Leave, ну и, соответственно, он будет отправлять и трафик в
сегмент. Проигравший же будет только слушать Report и держать руку на пульсе.
Версия 3 поддерживает всё то, что поддерживает IGMPv2, но есть и ряд изменений. Во-первых, Report
отправляется уже не на адрес группы, а на мультикастовый служебный адрес 224.0.0.22. А адрес запрашиваемой
группы указан только внутри пакета. Делается это для упрощения работы IGMP Snooping, о котором мы
поговорим дальше.
Во-вторых, что более важно, IGMPv3 стал поддерживать SSM в чистом виде. Это так называемый Source Specific
Multicast. В этом случае клиент может не просто запросить группу, но также указать список источников, от
которых он хотел бы получать трафик или наоборот не хотел бы. В IGMPv2 клиент просто запрашивает и получает
трафик группы, не заботясь об источнике.
Итак, IGMP предназначен для взаимодействия клиентов и маршрутизатора. Поэтому, возвращаясь к Примеру II,
где нет маршрутизатора, мы можем авторитетно заявить — IGMP там — не более, чем формальность.
Маршрутизатора нет, и клиенту не у кого запрашивать мультикастовый поток. А заработает видео по той простой
причине, что поток и так льётся от коммутатора — надо только подхватить его.
Напомним, что IGMP не работает для IPv6. Там существует протокол MLD.
1. Первым делом маршрутизатор отправил свой IGMP General Query после включения IGMP на его интерфейсе,
чтобы узнать, есть ли получатели и заявить о своём желании быть Querier. На тот момент никого не было в этой
группе.
2. Далее появился клиент, который захотел получать трафик группы 224.2.2.4 и он отправил свой IGMP
Report. После этого пошёл трафик на него, но он отфильтрован из дампа.
3. Потом маршрутизатор решил зачем-то проверить — а нет ли ещё клиентов и отправил IGMP General Query ещё
раз, на который клиент вынужден ответить (4).
5. Периодически (раз в минуту) маршрутизатор проверяет, что получатели по-прежнему есть, с помощью IGMP
General Query, а узел подтверждает это с помощью IGMP Report.
6. Потом он передумал и отказался от группы, отправив IGMP Leave.
7. Маршрутизатор получил Leave и, желая убедиться, что больше никаких других получателей нет, посылает IGMP
Group Specific Query… дважды. И по истечении таймера перестаёт передавать трафик сюда.
8. Однако передавать IGMP Query в сеть он по-прежнему продолжает. Например, на тот случай, если вы плеер не
отключали, а просто где-то со связью проблемы. Потом связь восстанавливается, но клиент-то Report не
посылает сам по себе. А вот на Query отвечает. Таким образом поток может восстановиться без участия человека.
И ещё раз
IGMP — протокол, с помощью которого маршрутизатор узнаёт о наличии получателей мультикастового трафика
и об их отключении.
IGMP Report — посылается клиентом при подключении и в ответ на IGMP Query. Означает, что клиент хочет
получать трафик конкретной группы.
IGMP General Query — посылается маршрутизатором периодически, чтобы проверить какие группы сейчас
нужны. В качестве адреса получателя указывается 224.0.0.1.
IGMP Group Sepcific Query — посылается маршрутизатором в ответ на сообщение Leave, чтобы узнать есть ли
другие получатели в этой группе. В качестве адреса получателя указывается адрес мультикастовой группы.
IGMP Leave — посылается клиентом, когда тот хочет покинуть группу.
Querier — если в одном широковещательном сегменте несколько маршрутизаторов, который могут вещать,
среди них выбирается один главный — Querier. Он и будет периодически рассылать Query и передавать трафик.
PIM
Итак, мы разобрались, как клиенты сообщают ближайшему маршрутизатору о своих намерениях. Теперь
неплохо было бы передать трафик от источника получателю через большую сеть.
Если вдуматься, то мы стоим перед довольной сложной проблемой — источник только вещает на группу, он
ничего не знает о том, где находятся получатели и сколько их.
Получатели и ближайшие к ним маршрутизаторы знают только, что им нужен трафик конкретной группы, но
понятия не имеют, где находится источник и какой у него адрес.
Как в такой ситуации доставить трафик?
Существует несколько протоколов маршрутизации мультикастового трафика: DVMRP, MOSPF, CBT — все они по-
разному решают такую задачу. Но стандартом де факто стал PIM — Protocol Independent Multicast.
Другие подходы настолько нежизнеспособны, что порой даже их разработчики практически признают это. Вот,
например, выдержка из RFC по протоколу CBT:
CBT version 2 is not, and was not, intended to be backwards compatible with version 1; we do not expect this to cause
extensive compatibility problems because we do not believe CBT is at all widely deployed at this stage.
PIM имеет две версии, которые можно даже назвать двумя различными протоколами в принципе, уж сильно они
разные:
• PIM Dense Mode (DM)
• PIM Sparse Mode (SM)
Independent он потому, что не привязан к какому-то конкретному протоколу маршрутизации юникастового
трафика, и позже вы увидите почему.
Но через некоторое время в эту же ветку маршрутизатор снова пытается отправить мультикаст — вдруг там
появились получатели. Если не появились, ветка снова отрезается на определённый период. Если клиент на
маршрутизаторе появился в промежутке между этими двумя событиями, отправляется сообщение Graft —
маршрутизатор запрашивает отрезанную ветку обратно, чтобы не ждать, пока ему что-то перепадёт.
Как видите, здесь не стоит вопрос определения пути к получателям — трафик достигнет их просто потому, что он
везде.
После «обрезания» ненужных ветвей остаётся дерево, вдоль которого передаётся мультикастовый трафик. Это
дерево называется SPT — Shortest Path Tree.
Оно лишено петель и использует кратчайший путь от получателя до источника. По сути оно очень похоже на
Spanning Tree в STP, где корнем является источник.
SPT — это конкретный вид дерева — дерево кратчайшего пути. А вообще любое мультикастовое дерево
называется MDT — Multicast Distribution Tree.
Предполагается, что PIM DM должен использоваться в сетях с высокой плотностью мультикастовых клиентов, что
и объясняет его название (Dense). Но реальность такова, что эта ситуация — скорее, исключение, и зачастую PIM
DM нецелесообразен.
R2 поступает точно так же, то есть отправляет трафик в сторону R3. R3 не может определить, что это тот же самый
трафик, который он уже получил от R1, поэтому пересылает его во все свои интерфейсы. R1 получит копию
трафика от R3 и так далее. Вот она — петля.
Что же предлагает PIM в такой ситуации? RPF — Reverse Path Forwarding. Это главный принцип передачи
мультикастового трафика в PIM (любого вида: и DM и SM) — трафик от источника должен приходить по
кратчайшему пути.
То есть для каждого полученного мультикастового пакета производится проверка на основе таблицы
маршрутизации, оттуда ли он пришёл.
Останавливаться здесь и подробно рассматривать работу PIM DM мы не будем — это устаревший протокол с
массой недостатков (ну, как RIP).
Однако PIM DM может применяться в некоторых случаях. Например, в совсем небольших сетях, где поток
мультикаста небольшой.
PIM Sparse Mode
Совершенно другой подход применяет PIM SM. Несмотря на название (разреженный режим), он с успехом
может применяться в любой сети с эффективностью как минимум не хуже, чем у PIM DM.
Здесь отказались от идеи безусловного наводнения мультикастом сети. Заинтересованные узлы самостоятельно
запрашивают подключение к дереву с помощью сообщений PIM Join.
Если маршрутизатор не посылал Join, то и трафик ему отправляться не будет.
Для того, чтобы понять, как работает PIM, начнём с уже знакомой нам простой сети с одним PIM-
маршрутизатором:
С этого момента вы можете расчехлить GNS и собирать лабораторию. Достаточно подробно о том, как собрать
стенд для мультикаста я рассказал в этой статье.
R1(config)#ip multicast-routing
R1(config)#int fa0/0
R1(config-if)#int fa1/0
Cisco тут как обычно отличается своим особенным подходом: при активации PIM на интерфейсе, автоматически
активируется и IGMP. На всех интерфейсах, где активирован PIM, работает и IGMP.
В то же время у других производителей два разных протокола включаются двумя разными командами: отдельно
IGMP, отдельно PIM.
Простим Cisco эту странность? Вместе со всеми остальными?
Плюс, возможно, потребуется настроить адрес RP (ip pim rp-address 172.16.0.1, например). Об этом позже, пока
примите как данность и смиритесь.
После того, как на источнике вы запустите вещание, надо проверить таблицу ещё раз.
Запись вида (*, 225.0.1.1) называется (*, G), /читается старкомаджи/ и сообщает нам о получателях. Причём не
обязательно речь об одном клиенте-компьютере, вообще это может быть и, например, другой PIM-
маршрутизатор. Важно то, в какие интерфейсы надо передавать трафик.
Если список нисходящих интерфейсов (OIL) пуст — Null, значит нет получателей — а мы их пока не запускали.
Запись (172.16.0.5, 225.0.1.1) называется (S, G), /читается эскомаджи/ и говорит о том, что известен источник. В
нашем случае источник с адресом 172.16.0.5 вещает трафик для группы 224.2.2.4. Мультикастовый трафик
приходит на интерфейс FE0/1 — это восходящий (Upstream) интерфейс.
Итак, нет клиентов. Трафик от источника доходит до маршрутизатора и на этом его жизнь кончается. Давайте
добавим теперь получателя — настроим приём мультикаста на ПК.
ПК отсылает IGMP Report, маршрутизатор понимает, что появились клиенты и обновляет таблицу мультикастовой
маршрутизации.
Теперь она выглядит так:
Появился и нисходящий интерфейс: FE0/0, что вполне ожидаемо. Причём он появился как в (*, G), так и в (S, G).
Список нисходящих интерфейсов называется OIL — Outgoing Interface List.
(S, G): Когда мультикастовый трафик с адресом назначения 224.2.2.4 от источника 172.16.0.5 приходит на
интерфейс FE0/1, его копии нужно отправить в FE0/0 и FE1/0.
Но это был очень простой пример — один маршрутизатор сразу знает и адрес источника и где находятся
получатели. Фактически даже деревьев тут никаких нет — разве что вырожденное. Но это помогло нам
разобраться с тем, как взаимодействуют PIM и IGMP.
RX(config)#ip multicast-routing
PIM включается непосредственно на всех интерфейсах всех маршрутизаторов (в том числе на интерфейсе в
сторону Сервера-источника и клиентов):
RX(config)#int FEX/X
RX(config-if)#ip pim sparse-mode
IGMP, по идее должен включаться на интерфейсах в сторону клиентов, но, как мы уже отметили выше, на
оборудовании Cisco он включается автоматически вместе с PIM.
Первое, что делает PIM — устанавливает соседство. Для этого используются сообщения PIM Hello. При активации
PIM на интерфейсе с него отправляется PIM Hello на адрес 224.0.0.13 с TTL равным 1. Это означает, что соседями
могут быть только маршрутизаторы, находящиеся в одном широковещательном домене.
Если мы сейчас запустим в вольер клиентов с одной стороны и включим мультикастовый поток с сервера с
другой, то R1 получит поток трафика, а R4 получит IGMP Report при попытке клиента подключиться. В итоге R1 не
будет знать ничего о получателях, а R4 об источнике.
Неплохо было бы если бы информация об источнике и о клиентах группы была собрана где-то в одном месте. Но
в каком?
Такая точка встречи называется Rendezvous Point — RP. Это центральное понятие PIM SM. Без неё ничего бы не
работало. Здесь встречаются источник и получатели.
Все PIM-маршрутизаторы должны знать, кто является RP в домене, то есть знать её IP-адрес.
Чтобы построить дерево MDT, в сети выбирается в качестве RP некая центральная точка, которая,
1. отвечает за изучение источника,
2. является точкой притяжения сообщений Join от всех заинтересованных.
Существует два способа задания RP: статический и динамический. Мы рассмотрим оба в этой статье, но начнём
со статического, поскольку чего уж проще статики?
Естественно, этот адрес должен быть доступен по таблице маршрутизации со всех точек.
Ну и поскольку адрес 2.2.2.2 является RP, на интерфейсе Loopback 0 на R2 желательно тоже активировать PIM.
R2(config)#interface Loopback 0
На интерфейс FE0/1 приходит 362000 б/с, и через интерфейс FE0/0 они передаются.
Всё, это уже рабочая конфигурация и можно приступать к разбору, ведь за кулисами скрывается гораздо больше,
чем видно на сцене.
Полная конфигурация с PIM.
Разбор полётов
Ну так и как же в итоге всё работает? Как RP узнаёт где источник, где клиенты и обеспечивает связь между ними?
Поскольку всё затевается ради наших любимых клиентов, то, начав с них, рассмотрим в деталях весь процесс.
Здесь видно восходящий интерфейс FE0/1, но это не значит, что R4 получает трафик для группы 224.2.2.4. Это
говорит лишь о том, что единственное место, откуда сейчас он может получать — FE0/1, потому что именно там
находится RP. Кстати, здесь же указан и сосед, который прошёл RPF-Check — R2: 10.0.2.24. Ожидаемо.
R4 называется — LHR (Last Hop Router) — последний маршрутизатор на пути мультикастового трафика, если
считать от источника. Иными словами — это маршрутизатор, ближайший к получателю. Для Клиента1 — это R4,
для Клиента2 — это R5.
3) Поскольку на R4 пока нет мультикастового потока (он его не запрашивал прежде), он формирует сообщение
PIM Join и отправляет его в сторону RP (2.2.2.2).
PIM Join отправляется мультикастом на адрес 224.0.0.13. «В сторону RP» означает через интерфейс, который
указан в таблице маршрутизации, как outbound для того адреса, который указан внутри пакета. В нашем случае
это 2.2.2.2 — адрес RP. Такой Join обозначается ещё как Join (*,G) и говорит: «Не важно, кто источник, мне нужен
трафик группы 224.2.2.4».
То есть каждый маршрутизатор на пути должен обработать такой Join и при необходимости отправить новый Join
в сторону RP. (Важно понимать, что если на маршрутизаторе уже есть эта группа, он не будет отправлять выше
Join — он просто добавит интерфейс, с которого пришёл Join, в OIL и начнёт передавать трафик).
В нашем случае Join ушёл в FE0/1:
4) R2, получив Join, формирует запись (*, G) и добавляет интерфейс FE0/0 в OIL. Но Join отсылать уже некуда — он
сам уже RP, а про источник пока ничего не известно.
Если Клиент 2 тоже захочет получать мультикастовый трафик для той же группы, R5 отправит PIM Join в FE0/1,
потому что за ним находится RP, R3, получив его, формирует новый PIM Join и отправляет в FE1/1 — туда, где
находится RP.
То есть Join путешествует так узел за узлом, пока не доберётся до RP или до другого маршрутизатора, где уже
есть клиенты этой группы.
Итак, R2 — наш RP — сейчас знает о том, что за FE0/0 и FE1/0 у него есть получатели для группы 224.2.2.4.
Причём неважно, сколько их там — по одному за каждым интерфейсом или по сто — поток трафика всё равно
будет один на интерфейс.
Если изобразить графически то, что мы получили, то это будет выглядеть так:
Отдалённо напоминает дерево, не так ли? Поэтому оно так и называется — RPT — Rendezvous Point Tree. Это
дерево с корнем в RP, а ветви которого простираются до клиентов.
Более общий термин, как мы упоминали выше, — MDT — Multicast Distribution Tree — дерево, вдоль которого
распространяется мультикастовый поток. Позже вы увидите разницу между MDT и RPT.
5) Теперь врубаем сервер. Как мы уже выше обсуждали, он не волнуется о PIM, RP, IGMP — он просто вещает. А
R1 получает этот поток. Его задача — доставить мультикаст до RP.
В PIM есть специальный тип сообщений — Register. Он нужен для того, чтобы зарегистрировать источник
мультикаста на RP.
Итак, R1 получает мультикастовый поток группы 224.2.2.4:
R1 является FHR (First Hop Router) — первый маршрутизатор на пути мультикастового трафика или ближайший к
источнику.
6) Далее он инкапсулирует каждый полученный от источника мультикастовый пакет в юникастовый PIM Register
и отправляет его прямиком на RP.
Обратите внимание на стек протоколов. Поверх юникастового IP и заголовка PIM идёт изначальный
мультикастовый IP, UDP и данные.
Теперь, в отличие от всех других, пока известных нам сообщений PIM, в адресе получателя указан 2.2.2.2, а не
мультикастовый адрес.
На сервере 172.16.0.5 работает приложение, которое может передавать пакеты только на широковещательный
адрес 255.255.255.255, с портом получателя UDP 10999.
7) RP получает PIM Register, распаковывает его и обнаруживает под обёрткой трафик для группы 224.2.2.4.
Информацию об этом он сразу заносит в свою таблицу мультикастовой маршрутизации:
Появилась запись (S, G) — (172.16.0.5, 224.2.2.4).
Распакованные пакеты RP дальше отправляет в RPT в интерфейсы FE0/0 и FE1/0, по которому трафик доходит до
клиентов.
В принципе, на этом можно было бы и остановиться. Всё работает — клиенты получают трафик. Но есть две
проблемы:
1. Процессы инкапсуляции и декапсуляции — весьма затратные действия для маршрутизаторов. Кроме
того, дополнительные заголовки увеличивают размер пакета, и он может просто не пролезть в MTU где-то на
промежуточном узле (вспоминаем все проблемы туннелирования).
2. Если вдруг где-то между источником и RP есть ещё получатели для группы, мультикастовому трафику
придётся пройти один путь дважды.
Возьмём для примера вот такую топологию:
Трафик в сообщениях Register сначала дойдёт до RP по линии R1-R42-R2, затем чистый мультикаст вернётся по
линии R2-R42. Таким образом на линии R42-R2 будет ходить две копии одного трафика, пусть и в
противоположных направлениях.
Поэтому лучше от источника до RP тоже передавать чистый мультикаст, а для этого нужно построить дерево —
Source Tree.
8) Поэтому RP отправляет на R1 сообщение PIM Join. Но теперь уже в нём указывается для группы адрес не RP, а
источника, изученный из сообщения Register. Такое сообщение называется Join (S, G) — Source Specific Join.
Цель у него точно такая же, как у PIM Join (*, G) — построить дерево, только на этот раз от источника до RP.
Join (S, G) распространяется также узел за узлом, как обычный Join (*, G). Только Join (*, G) стремится к RP, а Join
(S, G) к S — источнику. В качестве адрес получателя также служебный адрес 224.0.0.13 и TTL=1.
Если существуют промежуточные узлы, например, R42, они также формируют запись (S, G) и список нисходящих
интерфейсов для данной группы и пересылают Join дальше к источнику.
Путь, по которому прошёл Join от RP до источника, превращается в Source Tree — дерево от источника. Но более
распространённое название — SPT — Shortest Path Tree — ведь трафик от источника до RP пойдёт по
кратчайшему пути.
9) R1 получив Join (S, G), добавляет интерфейс FE1/0, откуда пакет пришёл, в список нисходящих интерфейсов OIL
и начинает туда вещать чистый мультикастовый трафик, незамутнённый инкапсуляцией. Запись (S, G) на R1 уже
была, как только он получит первый мультикастовый пакет от Сервера-источник.
По построенному Source Tree мультикаст передаётся RP (и всем промежуточным клиентам, если они есть,
например, R42).
Но надо иметь ввиду, что сообщения Register передавались всё это время и передаются до сих пор. То есть
фактически R1 отправляет две копии трафика сейчас: один — чистый мультикаст по SPT, другой —
инкапсулированный в юникастовый Register.
Сначала R1 отправляет мультикаст в Register — пакет 231. Потом R2 (RP) хочет подключиться к дереву, отправляет
Join — пакет 232. R1 ещё какое-то время, пока обрабатывает запрос от R2, отправляет мультикаст в Register
(пакеты с 233 по 238). Далее, когда нисходящий интерфейс добавлен в OIL на R1, он начинает передавать чистый
мультикаст — пакеты 239 и 242, но пока не прекращает и Register — пакеты 241 и 243. А пакет 240 — это R2 не
выдержал и ещё раз попросил построить дерево.
10) Итак, незамутнённый мультикаст достигает RP. Она понимает, что это тот же самый трафик, который
приходит в Register, потому что одинаковый адрес группы, одинаковый адрес источника и с одного интерфейса.
Чтобы не получать две копии, он отправляет на R1 юникастовый PIM Register-Stop.
Register-Stop не означает, что R2 отказывается от трафика или не признаёт больше этот источник, это говорит
лишь о том, что надо прекратить посылать инкапсулированный трафик.
Далее идёт ожесточённая борьба — R1 продолжает передавать накопившийся в буфере трафик, пока
обрабатывает Register-Stop, и обычным мультикастом и внутри сообщений Register:
Но, рано или поздно R1 начинает вещать только чистый мультикастовый трафик.
При подготовке у меня возник, как мне казалось, закономерный вопрос: ну и к чему все эти туннелирования, PIM
Register? Почему бы не поступать с мультикастовым трафиком, как с PIM Join — отправлять хоп за хопом с TTL=1 в
сторону RP — рано или поздно ведь дойдёт? Так бы и дерево построилось бы заодно без лишних телодвижений.
Тут возникает несколько нюансов.
Во-первых, нарушается главный принцип PIM SM — трафик посылать только туда, откуда он был запрошен. Нет
Join — Нет дерева!
Во-вторых, если клиентов для данной группы нет, FHR не узнает об этом и будет продолжать слать трафик по
«своему дереву». К чему такое бездумное использование полосы пропускания? В мире связи такой протокол
просто не выжил бы, как не выжил PIM DM или DVMRP.
Таким образом мы имеем одно большое дерево MDT для группы 224.2.2.4 от Cервера-источника до Клиента
1 и Клиента 2. И это MDT составлено из двух кусков, которые строились независимо друг от друга: Source Tree от
источника до RP и RPT от RP до клиентов. Вот оно отличие MDT от RPT и SPT. MDT — это довольно общий термин,
означающий дерево передачи мультикаста вообще, в то время, как RPT/SPT — это его очень конкретный вид.
А что делать, если сервер уже вещает, а клиентов всё нет и нет? Мультикаст так и будет засорять участок между
отправителем и RP?
Нет, в этом случае также поможет PIM Register-Stop. Если на RP начали приходить сообщения Register для какой-
то группы, а для неё ещё нет получателей, то RP не заинтересован в получении этого трафика, поэтому, не
отправляя PIM Join (S, G), RP сразу посылает Register-Stop на R1.
R1, получив Register-Stop и видя, что дерева для этой группы пока нет (нет клиентов), начинает отбрасывать
мультикастовый трафик от сервера.
То есть сам сервер по этому поводу совершенно не беспокоится и продолжает посылать поток, но, дойдя до
интерфейса маршрутизатора, поток будет отброшен.
При этом RP продолжает хранить запись (S, G). То есть трафик он не получает, но где находится источник для
группы знает. Если в группе появляются получатели, RP узнаёт о них и посылает на источник Join (S, G), который
строит дерево.
Кроме того, каждые 3 минуты R1 будет пытаться повторно зарегистрировать источник на RP, то есть отправлять
пакеты Register. Это нужно для того, чтобы уведомить RP о том, что этот источник ещё живой.
У особо пытливых читателей обязан возникнуть вопрос — а как быть с RPF? Этот механизм ведь проверяет адрес
отправителя мультикастового пакета и, если трафик идёт не с правильного интерфейса, он будет отброшен. При
этом RP и источник могут находиться за разными интерфейсам. Вот и в нашем примере для R3 RP — за FE1/1, а
источник — за FE1/0.
Ответ предсказуем — в таком случае проверяется не адрес источника, а RP. То есть трафик должен придти с
интерфейса в сторону RP.
Но, как вы увидите далее, это тоже не нерушимое правило.
Важно понимать, что RP — это не универсальный магнит — для каждой группы может бытья своя RP. То есть в
сети их может быть и две, и три, и сто — одна RP отвечает за один набор групп, другая — за другой. Более того,
есть такое понятие, как Anycast RP и тогда разные RP могут обслуживать одну и ту же группу.
=====================
Задача № 2
Настроить сеть таким образом, чтобы трафик группы 239.1.1.1 не передавался в сегмент между R3 и R5, и во все
сегменты ниже R5.
Но при этом, трафик группы 239.2.2.2 должен передаваться без проблем.
В одном широковещательном домене 3 маршрутизатора. Один из них стоит выше и именно он передаёт в
сегмент мультикастовый трафик. Это R1. Для обоих маршрутизаторов (R2 и R3) его OIL содержит только одну
запись.
Если теперь R2 решит отключиться и отправит PIM Prune, то он может подставить своего коллегу R3 — R1 ведь
перестанет вещать в интерфейс вообще.
Так вот, чтобы этого не произошло, R1 и даёт таймаут в 3 секунды. За это время R3 должен успеть среагировать.
Учитывая широковещательность сети, он тоже получит Prune от R2 и поэтому, если хочет продолжать получать
трафик, он мгновенно отправляет обычный PIM Join в сегмент, уведомляя R1, что не надо удалять интерфейс.
Этот процесс называется — Prune Override. R2 как бы объегорил R1, перехватил инициативу.
Вот как выглядит таблица мультикастовой маршрутизации на R5 в самом начале, сразу после построения дерева:
Здесь нет записи (S, G), но это не значит, что мультикастовый трафик не передаётся. Просто R5 не заботится о
том, кто отправитель.
Обратите внимание по какому пути должен идти в этом случае трафик — R1-R2-R3-R5. Хотя ведь короче путь R1-
R3-R5.
Дело в том, что пока мы привязаны к RP — она корень RPT, только она поначалу знает, где кто находится. Однако
если вдуматься, то после первого же мультикастового пакета все маршрутизаторы по пути трафика будут знать
адрес источника, ведь он указан в заголовке IP.
Зрите в корень. Такое переключение может инициировать LHR (Last Hop Router) — R5. После получения первого
мультикастового пакета от R3 R5 отправляет уже знакомый нам Source Specific Join (S, G) в интерфейс FE0/1,
который указан в его таблице маршрутизации, как исходящий для сети 172.16.0.0/24.
Получив такой Join, R3 отправляет его не на RP, как делал это с обычным Join (*, G), а в сторону источника (через
интерфейс согласно таблице маршрутизации).
То есть в данном случае R3 отправляет Join (172.16.0.5, 224.2.2.4) в интерфейс FE1/0.
Далее этот Join попадает на R1. А R1 по большому счёту без разницы, кто его отправлял — RP или кто-то другой —
он просто добавляет FE1/1 в свой OIL для группы 224.2.2.4.
В этот момент между источником и получателем два пути и R3 получает два потока.
Время сделать выбор, чтобы обрезать лишнее. Причём именно R3 его делает, потому что R5 уже не сможет
различить эти два потока — они оба придут через один интерфейс.
Как только R3 зафиксировал два одинаковых потока с разных интерфейсов, он выбирает предпочтительный
согласно таблице маршрутизации. В данном случае прямой, лучше, чем через RP. В этот момент R3 посылает
Prune (S, G) в сторону RP, обрубая эту ветку RPT. И с этого момент остаётся только один поток напрямую от
источника.
Таким образом PIM построил SPT — Shortest Path Tree. Оно же Source Tree. Это кратчайший путь от клиента до
источника. Кстати, дерево от источника до RP, которое мы уже рассматривали выше, — по сути ровно то же
самое SPT.
Оно характеризуется записью (S, G). Если маршрутизатор имеет такую запись, значит он знает, что S является
источником для группы G и построено дерево SPT.
Корнем дерева SPT является источник и очень хочется сказать «кратчайший путь от источника до клиента». Но
это технически некорректно, поскольку пути от источника до клиента и от клиента до источника могут быть
разными. А именно от клиента начинает строиться ветка дерева: маршрутизатор отправляет PIM Join в сторону
источника/RP и RPF также проверяет правильность интерфейса при получении трафика.
Вы помните, что вначале этого параграфа на R5 была только запись (*, G), теперь после всех этих событий
их станет две: (*, G) и (S, G).
Между прочим, даже если вы посмотрите на мультикастовую таблицу маршрутизации R3 в ту же секунду, как
нажали Play в VLC, то увидите, что он уже получает трафик от R1 напрямую, о чём говорит наличие записи (S, G).
То есть SPT Switchover уже произошёл — это действие по умолчанию на оборудовании многих производителей
— инициировать переключение после получения первого же мультикастового пакета.
DR — Designated Router.
Это выделенный маршрутизатор, который ответственен за отправку служебных пакетов на RP.
Source DR — отвечает за принятие мультикастовых пакетов непосредственно от источника и его регистрацию на
RP.
Вот пример топологии:
Здесь ни к чему, чтобы оба маршрутизатора передавали трафик на RP, пусть они резервируют друг друга, но
ответственный должен быть только один.
Поскольку оба маршрутизатора подключены в одну широковещательную сеть, они получают друг от друга PIM-
Hello. На основе него они и делают свой выбор.
PIM Hello несёт значение приоритета данного маршрутизатора на данном интерфейсе.
Чем больше значение, тем выше приоритет. Если они одинаковы, то выбирается узел с наибольшим IP-
адресом (тоже из сообщения Hello).
Если другой маршрутизатор (не DR) в течение Holdtime (по умолчанию 105 с) не получал Hello от соседа, он
автоматически берёт на себя роль DR.
Receiver DR — то же, что Source DR, только для получателей мультикастового трафика — LHR (Last Hop Router).
Пример топологии:
Receiver DR ответственен за отправку на RP PIM Join. В вышеприведённой топологии, если оба маршрутизатора
отправят Join, то оба будут получать мультикастовый трафик, но в этом нет необходимости. Только DR отправляет
Join. Второй просто мониторит доступность DR.
Поскольку DR отправляет Join, то он же и будет вещать трафик в LAN. Но тут возникает закономерный вопрос — а
что, если PIM DR'ом стал один, а IGMP Querier'ом другой? А ситуация-то вполне возможна, ведь для Querier чем
меньше IP, тем лучше, а для DR, наоборот.
В этом случае DR'ом выбирается тот маршрутизатор, который уже является Querier и такая проблема не
возникает.
Правила выбора Receiver DR точно такие же, как и Source DR.
Выбор RP
Выше мы для простоты задавали RP вручную командой ip pim rp-address X.X.X.X.
И вот как выглядела команда show ip pim rp:
Но представим совершенно невозможную в современных сетях ситуацию — R2 вышел из строя. Это всё —
финиш. Клиент 2 ещё будет работать, поскольку произошёл SPT Switchover, а вот всё новое и всё, что шло через
RP сломается, даже если есть альтернативный путь.
Ну и нагрузка на администратора домена. Представьте себе: на 50 маршрутизаторах перебить вручную как
минимум одну команду (а для разных групп ведь могут быть разные RP).
Динамический выбор RP позволяет и избежать ручной работы и обеспечить надёжность — если одна RP станет
недоступна, в бой вступит сразу же другая.
В данный момент существует один общепризнанный протокол, позволяющий это сделать — Bootstrap. Циска в
прежние времена продвигала несколько неуклюжий Auto-RP, но сейчас он почти не используется, хотя циска
этого не признаёт, и в show ip mroute мы имеем раздражающий рудимент в виде группы 224.0.1.40.
Надо на самом деле отдать должное протоколу Auto-RP. Он был спасением в прежние времена. Но с появлением
открытого и гибкого Bootstrap, он закономерно уступил свои позиции.
Итак, предположим, что в нашей сети мы хотим, чтобы R3 подхватывал функции RP в случае выхода из строя R2.
R2 и R3 определяются как кандидаты на роль RP — так они и называются C-RP. На этих маршрутизаторах
настраиваем:
RX(config)interface Loopback 0
RX(config-if)exit
Но пока ничего не происходит — кандидаты пока не знают, как уведомить всех о себе.
Чтобы информировать все мультикастовые маршрутизаторы домена о существующих RP вводится механизм BSR
— BootStrap Router. Претендентов может быть несколько, как и C-RP. Они называются соответственно C-BSR.
Настраиваются они похожим образом.
Пусть BSR у нас будет один и для теста (исключительно) это будет R1.
R1(config)interface Loopback 0
R1(config-if)exit
Сначала из всех C-BSR выбирается один главный BSR, который и будет всем заправлять. Для этого каждый C-BSR
отправляет в сеть мультикастовый BootStrap Message (BSM) на адрес 224.0.0.13 — это тоже пакет протокола PIM.
Его должны принять и обработать все мультикастовые маршрутизаторы и после разослать во все порты, где
активирован PIM. BSM передаётся не в сторону чего-то (RP или источника), в отличии, от PIM Join, а во все
стороны. Такая веерная рассылка помогает достигнуть BSM всех уголков сети, в том числе всех C-BSR и всех C-RP.
Для того, чтобы BSM не блуждали по сети бесконечно, применяется всё тот же механизм RPF — если BSM пришёл
не с того интерфейса, за которым находится сеть отправителя этого сообщения, такое сообщение отбрасывается.
С помощью этих BSM все мультикастовые маршрутизаторы определяют самого достойного кандидата на основе
приоритетов. Как только C-BSR получает BSM от другого маршрутизатора с бОльшим приоритетом, он
прекращает рассылать свои сообщения. В результате все обладают одинаковой информацией.
На этом этапе, когда выбран BSR, благодаря тому, что его BSM разошлись уже по всей сети, C-RP знают его адрес
и юникастом отправляют на него сообщения Candidte-RP-Advertisement, в которых они несут список групп,
которые они обслуживают — это называется group-to-RP mapping. BSR все эти сообщения агрегирует и
создаёт RP-Set — информационную таблицу: какие RP каждую группу обслуживают.
Далее BSR в прежней веерной манере рассылает те же BootStrap Message, которые на этот раз содержат RP-Set.
Эти сообщения успешно достигают всех мультикастовых маршрутизаторов, каждый из
которых самостоятельно делает выбор, какую RP нужно использовать для каждой конкретной группы.
BSR периодически делает такие рассылки, чтобы с одной стороны все знали, что информация по RP ещё
актуальна, а с другой C-BSR были в курсе, что сам главный BSR ещё жив.
RP, кстати, тоже периодически шлют на BSR свои анонсы Candidate-RP-Advertisement.
Фактически всё, что нужно сделать для настройки автоматического выбора RP — указать C-RP и указать C-BSR —
не так уж много работы, всё остальное за вас сделает PIM.
Как всегда, в целях повышения надёжности рекомендуется указывать интерфейсы Loopback в качестве
кандидатов.
Завершая главу PIM SM, давайте ещё раз отметим важнейшие моменты
1. Должна быть обеспечена обычная юникастовая связность с помощью IGP или статических маршрутов. Это
лежит в основе алгоритма RPF.
2. Дерево строится только после появления клиента. Именно клиент инициирует построение дерева. Нет
клиента — нет дерева.
3. RPF помогает избежать петель.
4. Все маршрутизаторы должны знать о том, кто является RP — только с её помощью можно построить
дерево.
5. Точка RP может быть указана статически, а может выбираться автоматически с помощью протокола
BootStrap.
6. В первой фазе строится RPT — дерево от клиентов до RP — и Source Tree — дерево от источника до RP. Во
второй фазе происходит переключение с построенного RPT на SPT — кратчайший путь от получателя до
источника.
Ещё перечислим все типы деревьев и сообщений, которые нам теперь известны.
MDT — Multicast Distribution Tree. Общий термин, описывающий любое дерево передачи мультикаста.
SPT — Shortest Path Tree. Дерево с кратчайшим путём от клиента или RP до источника. В PIM DM есть только SPT.
В PIM SM SPT может быть от источника до RP или от источника до получателя после того, как произошёл SPT
Switchover. Обозначается записью (S, G) — известен источник для группы.
Source Tree — то же самое, что SPT.
RPT — Rendezvous Point Tree. Дерево от RP до получателей. Используется только в PIM SM. Обозначается
записью (*, G).
Shared Tree — то же, что RPT. Называется так потому, что все клиенты подключены к одному общему дереву с
корнем в RP.
1) Определение RP,
2) Регистрация источника на RP,
3) Переключение на дерево SPT.
Много состояний протокола, много записей в таблице мультикастовой маршрутизации. Можно ли что-то с этим
сделать?
На сегодняшний день существует два диаметрально противоположных подхода к упрощению PIM: SSM и BIDIR
PIM.
SSM
Всё, что мы описывали до сих пор — это ASM — Any Source Multicast. Клиентам безразлично, кто является
источником трафика для группы — главное, что они его получают. Как вы помните в сообщении IGMPv2 Report
запрашивается просто подключение к группе.
SSM — Source Specific Multicast — альтернативный подход. В этом случае клиенты при подключении указывают
группу и источник.
Что же это даёт? Ни много ни мало: возможность полностью избавиться от RP. LHR сразу знает адрес источника
— нет необходимости слать Join на RP, маршрутизатор может сразу же отправить Join (S, G) в направлении
источника и построить SPT.
Таким образом мы избавляемся от
• Поиска RP (протоколы Bootstrap и Auto-RP),
• Регистрации источника на RP (а это лишнее время, двойное использование полосы пропускания и
туннелирование)
• Переключения на SPT.
Поскольку нет RP, то нет и RPT, соответственно ни на одном маршрутизаторе уже не будет записей (*, G) —
только (S, G).
Ещё одна проблема, которая решается с помощью SSM — наличие нескольких источников. В ASM
рекомендуется, чтобы адрес мультикастовой группы был уникален и только один источник вещал на него,
поскольку в дереве RPT несколько потоков сольются, а клиент, получая два потока от разных источников,
вероятно, не сможет их разобрать.
В SSM трафик от различных источников распространяется независимо, каждый по своему дереву SPT, и это уже
становится не проблемой, а преимуществом — несколько серверов могут вещать одновременно. Если вдруг
клиент начал фиксировать потери от основного источника, он может переключиться на резервный, даже не
перезапрашивая его — он и так получал два потока.
Кроме того, возможный вектор атаки в сети с активированной мультикастовой маршрутизацией — подключение
злоумышленником своего источника и генерирование большого объёма мультикастового трафика, который
перегрузит сеть. В SSM такое практически исключено.
IGMPv1/v2, MLDv1 не поддерживают SSM, но имеет место такое понятие, как SSM Mapping. На ближайшем к
клиенту маршрутизаторе (LHR) каждой группе ставится в соответствие адрес источника (или несколько). Поэтому
если в сети есть клиенты, не поддерживающие IGMPv3/MLDv2, для них также будет построено SPT, а не RPT,
благодаря тому, что адрес источника всё равно известен.
SSM Mapping может быть реализован как статической настройкой на LHR, так и посредством обращения к DNS-
серверу.
Проблема SSM в том, что клиенты должны заранее знать адреса источников — никакой сигнализацией они им не
сообщаются.
Поэтому SSM хорош в тех ситуациях, когда в сети определённый набор источников, их адреса заведомо известны
и не будут меняться. А клиентские терминалы или приложения жёстко привязаны к ним.
Иными словами IPTV — весьма пригодная среда для внедрения SSM. Это хорошо описывает концепцию One-to-
Many — один источник, много получателей.
BIDIR PIM
А что если в сети источники могут появляться спонтанно то там, то тут, вещать на одинаковые группы, быстро
прекращать передачу и исчезать?
Например, такая ситуация возможна в сетевых играх или в ЦОД, где происходит репликация данных между
различными серверами. Это концепция Many-to-Many — много источников, много клиентов.
Как на это смотрит обычный PIM SM? Понятное дело, что инертный PIM SSM здесь совсем не подходит?
Вы только подумайте, какой хаос начнётся: бесконечные регистрации источников, перестроение деревьев,
огромное количество записей (S, G) живущих по несколько минут из-за таймеров протокола.
На выручку идёт двунаправленный PIM (Bidirectional PIM, BIDIR PIM). В отличие от SSM в нём напротив
полностью отказываются от SPT и записей (S,G) — остаются только Shared Tree с корнем в RP.
И если в обычном PIM, дерево является односторонним — трафик всегда передаётся от источника вниз по SPT и
от RP вниз по RPT — есть чёткое деление, где источник, где клиенты, то в двунаправленном от источника трафик
к RP передаётся также вверх по Shared Tree — по тому же самому, по которому трафик течёт вниз к клиентам.
Это позволяет отказаться от регистрации источника на RP — трафик передаётся безусловно, без какой бы то ни
было сигнализации и изменения состояний. Поскольку деревьев SPT нет вообще, то и SPT Switchover тоже не
происходит.
Вот например:
Источник1 начал передавать в сеть трафик группы 224.2.2.4 одновременно с Источником2. Потоки от них
просто полились в сторону RP. Часть клиентов, которые находятся рядом начали получать трафик сразу, потому
что на маршрутизаторах есть запись (*, G) (есть клиенты). Другая часть получает трафик по Shared Tree от RP.
Причём получают они трафик от обоих источников одновременно.
То есть, если взять для примера умозрительную сетевую игру, Источник1 это первый игрок в стрелялке, который
сделал выстрел, а Источник2 — это другой игрок, который сделал шаг в сторону. Информация об этих двух
событиях распространилась по всей сети. И каждый другой игрок (Получатель) должен узнать об обоих этих
событиях.
Если помните, то чуть раньше мы объяснили, зачем нужен процесс регистрации источника на RP — чтобы трафик
не занимал канал, когда нет клиентов, то есть RP просто отказывался от него. Почему над этой проблемой мы не
задумываемся сейчас? Причина проста: BIDIR PIM для ситуаций, когда источников много, но они вещают не
постоянно, а периодически, относительно небольшими кусками данных. То есть канал от источника до RP не
будет утилизироваться понапрасну.
Обратите внимание, что на изображении выше между R5 и R7 есть прямая линия, гораздо более короткая, чем
путь через RP, но она не была использована, потому что Join идут в сторону RP согласно таблице маршрутизации,
в которой данный путь не является оптимальным.
Выглядит довольно просто — нужно отправлять мультикастовые пакеты в направлении RP и всё, но есть один
нюанс, который всё портит — RPF. В дереве RPT он требует, чтобы трафик приходил от RP и не иначе. А у нас он
может приходить откуда угодно. Взять и отказаться от RPF мы, конечно, не можем — это единственный
механизм, который позволяет избежать образования петель.
Поэтому в BIDIR PIM вводится понятие DF — Designated Forwarder. В каждом сегменте сети, на каждой линии на
эту роль выбирается тот маршрутизатор, чей маршрут до RP лучше.
В том числе это делается и на тех линиях, куда непосредственно подключены клиенты. В BIDIR PIM DF
автоматически является DR.
Список OIL формируется только из тех интерфейсов, на которых маршрутизатор был выбран на роль DF.
Таким образом DF гарантирует, что на RP в итоге будет отправлена только одна копия мультикастового пакета и
образование петель исключено. При этом то общее дерево, в котором находится источник, естественно, получит
этот трафик ещё до попадания на RP. RP, согласно обычным правилам разошлёт трафик во все порты OIL, кроме
того, откуда пришёл трафик.
Кстати, нет нужды более и в сообщениях Assert, ведь DF выбирается в каждом сегменте. В отличие от DR он
отвечает не только за отправку Join к RP, но и за передачу трафика в сегмент, то есть ситуация, когда два
маршрутизатора передают в одну подсеть трафик, исключена в BIDIR PIM.
Пожалуй, последнее, что нужно сказать о двунаправленном PIM, это особенности работы RP. Если в PIM SM RP
выполнял вполне конкретную функцию — регистрация источника, то в BIDIR PIM RP — это некая весьма условная
точка, к которой стремится трафик с одной стороны и Join от клиентов с другой. Никто не должен выполнять
декапсуляцию, запрашивать построение дерева SPT. Просто на каком-то маршрутизаторе вдруг трафик от
источников начинает передаваться в Shared Tree. Почему я говорю «на каком-то»? Дело в том, что в BIDIR PIM RP
— абстрактная точка, а не конкретный маршрутизатор, в качестве адреса RP вообще может выступать
несуществующий IP-адрес — главное, чтобы он был маршрутизируемый (такая RP называется Phantom RP).
Расчехлили SSH, проверили CPU, проверили утилизацию интерфейсов и волосы дыбом — загрузка почти под
100% на всех интерфейсах одного VLAN'а. Петля! Но откуда ей взяться, если никаких работ не проводилось?
Минут 10 проверки и вы заметили, что на восходящем интерфейсе к ядру у вас много входящего трафика, а на
всех нисходящих к клиентам — исходящего. Для петли это тоже характерно, но как-то подозрительно: внедрили
мультикаст, никаких работ по переключению не делали и скачок только в одном направлении.
Проверили список мультикастовых групп на маршрутизаторе — а там подписка на все возможные каналы и все
на один порт — естественно, тот, который ведёт в этот сегмент.
Дотошное расследование показало, что компьютер клиента заражён и рассылает IGMP Query на все
мультикастовые адреса подряд.
Потери пакетов начались, потому что коммутаторам пришлось пропускать через себя огромный объём трафика.
Это вызвало переполнение буферов интерфейсов.
Главный вопрос — почему трафик одного клиента начал копироваться во все порты?
Причина этого кроется в природе мультикастовых MAC-адресов. Дело в том, пространство мультикастовых IP-
адресов специальным образом отображается в пространство мультикастовых MAC-адресов. И загвоздка в том,
что они никогда не будут использоваться в качестве MAC-адреса источника, а следовательно, не будут изучены
коммутатором и занесены в таблицу MAC-адресов. А как поступает коммутатор с кадрами, адрес назначения
которых не изучен? Он их рассылает во все порты. Что и произошло.
Это действие по умолчанию.
Мультикастовые MAC-адреса
Так какие же MAC-адреса получателей подставляются в заголовок Ethernet таких пакетов? Широковещательные?
Нет. Существует специальный диапазон MAC-адресов, в которые отображаются мультикастовые IP-адреса.
Эти специальные адреса начинаются так: 0x01005e и следующий 25-й бит должен быть 0 (попробуйте
ответить, почему так). Остальные 23 бита (напомню, всего их в МАС-адресе 48) переносятся из IP-адреса.
Здесь кроется некоторая не очень серьёзная, но проблема. Диапазон мультикастовых адресов определяется
маской 224.0.0.0/4, это означает, что первые 4 бита зарезервированы: 1110, а оставшиеся 28 бит могут меняться.
То есть у нас 2^28 мультикастовых IP-адресов и только 2^23 MAC-адресов — для отображения 1 в 1 не хватает 5
бит. Поэтому берутся просто последние 23 бита IP-адреса и один в один переносятся в MAC-адрес, остальные 5
отбрасываются.
Фактически это означает, что в один мультикастовый MAC-адрес будет отображаться 2^5=32 IP-адреса.
Например, группы 224.0.0.1, 224.128.0.1, 225.0.0.1 и так до 239.128.0.1 все будут отображаться в один MAC-адрес
0100:5e00:0001.
Есть также другие мультикастовые MAC-адреса, которые никак не относятся к IPv4-мультикаст (клик). Все они,
кстати, характеризуются тем, что последний бит первого октета равен 1.
Естественно, ни на одной сетевой карте, не может быть настроен такой MAC-адрес, поэтому он никогда не будет
в поле Source MAC Ethernet-кадра и никогда не попадёт в таблицу MAC-адресов. Значит такие кадры должны
рассылаться как любой Unknown Unicast во все порты VLAN'а.
Всего, что мы рассматривали прежде, вполне достаточно для полноценной передачи любого мультикастового
трафика от потокового видео до биржевых котировок. Но неужели мы в своём почти совершенном мире будем
мирится с таким безобразием, как широковещательная передача того, что можно было бы передать избранным?
Вовсе нет. Специально для перфекционистов придуман механизм IGMP Snooping.
IGMP Snooping
Идея очень простая — коммутатор «слушает» проходящие через него IGMP-пакеты.
Для каждой группы отдельно он ведёт таблицу восходящих и нисходящих портов.
Если с порта пришёл IGMP Report для группы, значит там клиент, коммутатор добавляет его в список нисходящих
для этой группы.
Если с порта пришёл IGMP Query для группы, значит там маршрутизатор, коммутатор добавляет его в список
восходящих.
Гениальность этой идеи заканчивается тогда, когда мы задумываемся о её природе. Механизм предполагает, что
коммутатор должен прослушивать трафик на 3-м уровне.
Впрочем, IGMP Snooping ни в какое сравнение не идёт с NAT по степени игнорирования принципов сетевого
взаимодействия. Тем более, кроме экономии в ресурсах, он несёт в себе массу менее очевидных возможностей.
Да и в общем-то в современном мире, коммутатор, который умеет заглядывать внутрь IP — явление не
исключительное.
=====================
Задача № 3
В этом случае можно настроить проксирование IGMP-запросов. Тогда коммутатор не просто «слушает»
проходящие пакеты, он их перехватывает.
Правила работы IGMP Snooping могут отличаться для разных производителей. Поэтому рассмотрим их
концептуально:
1) Если на коммутатор приходит самый первый запрос Report на группу, он отправляется вверх к
маршрутизатору, а интерфейс вносится в список нисходящих. Если же такая группа уже есть, интерфейс просто
добавляется в список нисходящих, а Report уничтожается.
2) Если на коммутатор приходит самый последний Leave, то есть других клиентов нет, этот Leave будет отправлен
на маршрутизатор, а интерфейс удаляется из списка нисходящих. В противном случае просто удаляется
интерфейс, Leave уничтожается.
3) Если IGMP Query приходит от маршрутизатора, коммутатор перехватывает его, отправляет в ответ IGMP Report
для всех групп, которые в данный момент имеют получателей.
А дальше, в зависимости от настроек и производителя, либо этот же самый Query рассылается во все клиентские
порты, либо коммутатор блокирует запрос от маршрутизатора и сам выступает в роли Querier, периодически
опрашивая всех получателей.
Таким образом снижается и доля лишнего служебного трафика в сети и нагрузка на маршрутизатор.
Multicast VLAN Replication
Сокращённо MVR. Это механизм для тех провайдеров, кто практикует VLAN-per-user, например.
Вот типичный пример сети, где MVR жизненно необходим:
5 клиентов в разных VLAN'ах, и все хотят получать мультикастовый трафик одной группы 224.2.2.4. При этом
клиенты должны оставаться изолированными друг от друга.
IGMP Snooping учитывает, разумеется и VLAN'ы. Если пять клиентов в разных VLAN'ах запрашивают одну группу
— это будет пять разных таблиц. Соответственно и к маршрутизатору идут 5 запросов на подключение к группе. И
каждый сабинтерфейс из этих пяти на маршрутизаторе будет добавлен отдельно в OIL. То есть получив 1 поток
для группы 224.2.2.4 он отправит 5 копий, несмотря на то, что все они идут в один сегмент.
Для решения этой проблемы и был разработан механизм Multicast VLAN Replication.
Вводится дополнительный VLAN — Multicast VLAN — в нём, соответственно, будет передаваться мультикастовый
поток. Он «проброшен» непосредственно до последнего коммутатора, где трафик из него копируется во все
клиентские интерфейсы, которые хотят получать этот трафик — это и есть репликация.
В зависимости от реализации репликация из Multicast VLAN может производиться в User-VLAN или в
определённые физические интерфейсы.
А что с IGMP-сообщениями? Query от маршрутизатора, естественно, приходит по мультикастовому VLAN'у.
Коммутатор их рассылает в клиентские порты. Когда Report или Leave приходит от клиента, коммутатор
проверяет откуда именно (VLAN, интерфейс) и, если необходимо, перенаправляет в мультикастовый VLAN.
Таким образом обычный трафик изолирован и по-прежнему ходит до маршрутизатора в пользовательском
VLAN'е. А мультикастовый трафик и IGMP-пакеты передаются в Multicast VLAN.
На оборудовании Cisco MVR и IGMP Snooping настраиваются независимо. То есть можно отключить один и
второй будет работать. Вообще же MVR основан на IGMP Snooping и на коммутаторах других производителей
для работы MVR может быть обязательным включение IGMP Snooping.
Кроме того, IGMP Snooping позволяет осуществлять на коммутаторах фильтрацию трафика, ограничивать
количество групп, доступных пользователю, включение IGMP Querier, статическую настройку восходящих портов,
перманентное подключение к какой-либо группе (этот сценарий есть в сопутствующем видео), быструю реакцию
на изменение топологии путём рассылки дополнительных Query, SSM-Mapping для IGMPv2 итд.
Заканчивая разговор об IGMP Snooping, хочется повторить — это необязательный функционал — всё и без него
будет работать. Но это сделает сеть более предсказуемой, а жизнь инженера спокойнее.
Однако все плюсы IGMP Snooping можно обернуть и против себя. Один такой выдающийся случай можно
почитать по ссылке.
К слову у той же Cisco есть протокол CGMP — аналог IGMP, который не нарушает принципы работы коммутатора,
но он проприетарный и не сказать, что широко распространённый.
Итак, мой неутомимый читатель, мы приближаемся к концу выпуска и напоследок хочется показать, как может
быть реализована услуга IPTV на стороне клиента.
Самый простой способ, к которому мы уже не раз обращались в этой статье — запустить плеер, который может
принять мультикастовый поток из сети. На нём можно вручную задать IP-адрес группы и наслаждаться видео.
Другой программный вариант, который часто используют провайдеры — специальное приложение, обычно
весьма кастомное, в котором зашит набор каналов, используемых в сети провайдера. Нет необходимости что-то
задавать вручную — нужно просто переключать каналы кнопками.
Оба эти способа дают возможность смотреть потоковое видео только на компьютере.
Третий же вариант позволяет использовать телевизор, причём как правило, любой. Для этого в доме клиента
ставит так называемый Set-Top-Box (STB) — коробочка, устанавливаемая на телевизор. Это шелезяка, которая
включается в абонентскую линию и разделяет трафик: обычный юникаст она отдаёт в Ethernet или WiFi, чтобы
клиенты имели доступ в Интернет, а мультикастовый поток передаётся на телевизор через кабель (DVI, RGB,
антенный итд.).
Часто вы, кстати, можете увидеть рекламу, где провайдер предлагает свои приставки для подключения
телевидения — это и есть те самые STB
=====================
Задача № 4
Напоследок нетривиальная задачка по мультикасту (авторы не мы, в ответах будет ссылка на оригинал).
Незатронутыми в статье остались междоменная маршрутизация мультикастового трафика (MSDP, MBGP, BGMP),
балансировка нагрузки между RP (Anycast RP), PGM, проприетарные протоколы. Но, я думаю, имея как точку
старта эту статью, разобраться в остальном не составит труда.
Все термины, касающиеся мультикаста, вы можете найти в телекоммуникационном глоссарии lookmeup.
За помощь в подготовке статьи спасибо JDima.
За техническую поддержку спасибо Наташе Самойленко.
КДПВ нарисована Ниной Долгополовой — замечательным художником и другом проекта.
В пуле статей СДСМ ещё много интересного до окончания, поэтому не нужно хоронить цикл из-за долгого
отсутствия выпуска — с каждой новой статьёй сложность значительно возрастает. Впереди почти весь MPLS, IPv6,
QoS и дизайн сетей.
Сеть нашей воображаемой компании linkmeup растёт. У неё есть уже магистральные линии в различных городах,
клиентская база и отличный штат инженеров, выросших на цикле СДСМ.
Но всё им мало. Услуги ШПД — это хорошо и нужно, но есть ещё огромный потенциальный рынок
корпоративных клиентов, которым нужен VPN.
Думали ребята над этим, ломали голову и пришли к выводу, что никак тут не обойтись без MPLS.
Если мультикаст был первой темой, которая требовала некоторого перестроения понимания IP-сетей, то, изучая
MPLS, вам точно придётся забыть почти всё, что вы знали раньше — это особенный мир со своими правилами.
Сегодня в выпуске:
• Что такое MPLS
• Передача трафика в сети MPLS
• Терминология
• Распространение меток
o Методы распространение меток
DU против DoD
Ordered Control против Independent Control
Liberal Label Retention Mode против Conservative Label Retention Mode
PHP
o Протоколы распространения меток
LDP
Практика
Применение чистого MPLS в связке с BGP
RSVP-TE
Практика
• ВиО
• Полезные ссылки
Традиционное видео
Да всё так. Достоинства и недостатки IP вытекают из того, что он появился позже классических сетей и
невероятно гибкий. Сейчас повсеместно идёт переход на пакетную коммутацию, в основу которой лёг IP на
сетевом уровне, а на канальном всё большую популярность набирает Ethernet.
Это хорошо, ведь теперь на базе одной опорной сети и сети доступа можно предоставлять ШПД, IP-телефонию,
IPTV и другие возможные услуги.
То же самое прослеживается и в сетях мобильных операторов. Сети второго поколения на заре были целиком на
основе коммутации каналов. Ядро сетей 3G в большинстве своём уже IP, но услуги телефонии по-прежнему
могут предоставляться в режиме коммутации каналов. Сети же 4G это уже полноценные IP-сети, где передача
голоса — это лишь одно из приложений, также, как и ШПД.
Однако существует ещё огромное число сегментов, где используются старые технологии. Например, где-то есть
ATM, в другом месте нужно PDH передать из одной части сети в другую, а тут клиент захотел, чтобы его кусок
Ethernet-сети оказался доступным с другого конца города так, словно он подключен непосредственно — иными
словами VPN.
Как это решалось раньше: нужен ATM между двумя географическими точками — строй канал между ними на
базе ATM, PDH — строй PDH.
А хочется-то делать всё это через одну сеть, а не строить отдельную для каждого типа трафика.
Для этого и были придуманы в своё время GRE, PPPoE, PPPoA, ATM over Ethernet, TDM over IP и многочисленные
другие over'ы. Можно насоздавать ещё тысячу других, чтобы покрыть уже все комбинации, и настанет
вселенское счастье в хаосе стандартов (к слову, некоторые мелкие производители по такому пути и пошли).
В середине 90-х горячим головам из нескольких компаний (IBM, Toshiba, Cisco, Ipsilon) пришло в голову создать
механизм, который позволил бы при маршрутизации заглядывать не внутрь пакета и прочёсывать таблицу
маршрутизации в поисках лучшего пути, а ориентироваться по некой метке. Выстрелило у Cisco, и механизм был
назван незамысловато: TAG Switching.
Причём цель, которую преследовали разработчики, заключалась в том, чтобы позволить высокоскоростным
коммутаторам передавать трафик исключительно аппаратно. Дело в том, что аппаратная IP-маршрутизация
долгое время была малодоступным удовольствием, и применять её на недорогих коммутаторах было
нецелесообразно, а принимать решение на основе метки можно было бы просто и быстро.
Но в то же время появились сверхбольшие интегральные схемы (пусть я и не согласен с этим термином —
английский VLSI гораздо лучше описывает суть), и задача экономии на анализе содержимого пакета стала не
такой уж и актуальной. Кроме того появилось понятие FIB, которое предполагает, что для каждого пакета не
нужно осуществлять поиск адресата в таблице маршрутизации и соответственно привлекать центральный
процессор — вся горячая информация уже на линейной плате.
То есть по сути необходимость в таком механизме отпала.
Но внезапно стало понятно, что у коммутации по меткам есть незапланированный потенциал — совершенно
неважно, что находится под меткой — IP, Ethernet, ATM, Frame Relay. А ещё она даёт возможность отвязаться от
ограничений IP-маршрутизации.
Отсюда и берёт своё начало технология, утверждённая IETF — MPLS — MultiProtocol Label Switching. Шёл 1997-й
год.
И эта, кажущаяся, возможно, незначительной, деталь дала начало новой эре в телекоммуникациях. Сегодня
MPLS вы найдёте в любом более или менее крупном провайдере.
О каждом из них мы поговорим в отдельных статьях — это чудовищно огромные темы. Но коротко мы затронем
их в конце статьи.
MPLS
Сам по себе чистый MPLS применяется редко. Выигрыш в производительности незначительный, потому что
разница между тем, чтобы заглянуть в FIB/поменять некоторые поля в заголовках и посмотреть таблицу
меток/поменять метку в заголовке MPLS не такая уж большая. Используются, конечно, его приложения,
перечисленные выше.
Но в этой статье мы всё-таки сконцентрируемся именно на чистом MPLS, чтобы понимать как это работает в
самом базовом виде.
Ниже мы рассмотрим также одно применение чистого MPLS.
Несмотря на то, что MPLS не привязывается к типу сети, на которой он будет работать, в наше время он живёт в
симбиозе только с IP. То есть сама сеть строится поверх IP, но переносить при этом она может данные многих
других протоколов.
Но давайте уже перейдём к сути, и сначала я хочу сказать, что MPLS не заменяет IP-маршрутизацию, а работает
поверх неё.
Сейчас она в полностью рабочем состоянии, но без всяких намёков на MPLS. То есть R1, например, видит R6 и
может пинговать его Loopback.
ПК1 посылает ICMP-запрос на сервер 172.16.0.2. ICMP-запрос — это IP-пакет. На R1 согласно базовым принципам
пакет уходит через интерфейс FE0/0 на R2 — так сказала Таблица Маршрутизации.
R2 после получения пакета проверяет адрес назначения, просматривает свою FIB, видит следующий
маршрутизатор и отправляет пакет в интерфейс FE0/0.
И этот процесс повторяется раз за разом. Каждый маршрутизатор самостоятельно решает судьбу пакета.
Когда IP-пакет от ПК1 попадает в сеть MPLS первый маршрутизатор навешивает метку, дальше этот пакет идёт к
точке назначения, а каждый следующий маршрутизатор меняет одну метку на другую. При выходе из сети MPLS
метка снимается и дальше передаётся уже чистый IP-пакет, каким он был в самом начале.
Это основной принцип MPLS — маршрутизаторы коммутируют пакеты по меткам, не заглядывая внутрь пакета
MPLS. Первый — добавляет, последний — удаляет.
Давайте рассмотрим шаг за шагом передачу пакета данных от ПК1 до узла назначения:
2. Пакет доходит до R1. Он добавляет метку 18. Она вставляется между заголовком IP и Ethernet.
Эту информацию он может взять из FIB:
По FIB видно, что пакет с адресатом 6.6.6.6 нужно снабдить меткой 18 и отправить в интерфейс FE0/0.
Собственно это он и делает: добавляет заголовок и прописывает в него 18:
3. R2 получает этот пакет, в заголовке Ethernet видит, что это MPLS-пакет (Ethertype 8847), считывает метку и
обращается к своей таблице меток:
Читаем по буквам: если пакет MPLS пришёл с меткой 18, её нужно поменять на 20 и отправить пакет в интерфейс
FE0/0.
Дамп после R2.
4. R5 совершает аналогичные действия — видит, что пришёл пакет с меткой 20, её нужно поменять на 0 и
отправить в FE1/0. Без всякого обращения к таблице маршрутизации.
5. R6, получив пакет MPLS, видит в своей таблице, что теперь метку надо снять. А, сняв её, видит уже, что адресат
пакета — 172.16.0.2 — это Directly Connected сеть. Дальше пакет передаётся обычным образом по таблице
маршрутизации уже безо всяких меток.
То есть целиком процесс выглядит так:
Из выпуска о BGP мы знаем, что на каждом маршрутизаторе в нашей AS должен быть настроен BGP. Иначе мы не
сможем передавать трафик соседних AS и наших клиентов, через нашу AS. Каждый маршрутизатор должен знать
все маршруты.
Но это не все хорошие новости. Кроме того, что BGP теперь можно не настраивать на каждом маршрутизаторе в
AS, маршрутизаторам также не нужно создавать метку для каждого префикса BGP. Достаточно знать как
добраться до IP-адреса, который указан как next-hop. То есть, если сессия BGP настроена между Loopback0 R1 и
Loopback0 R6, то в таблице меток ничего не изменится, даже если каждый из них передает по BGP сотни тысяч
маршрутов:
Мы немного забежали вперед, но теперь, когда стало понятнее какие преимущества дает даже базовый MPLS,
мы можем окунуться в понятийный аппарат в мире MPLS.
Терминология
Label — метка — значение от 0 до 1 048 575. На основе неё LSR принимает решение, что с пакетом делать: какую
новую метку повешать, куда его передать.
Является частью заголовка MPLS.
Label Stack — стек меток. Каждый пакет может нести одну, две, три, да хоть 10 меток — одну над другой.
Решение о том, что делать с пакетом принимается на основе верхней метки. Каждый слой играет какую-то свою
роль.
Например, при передаче пакета используется транспортная метка, то есть метка, организующая транзит от
первого до последнего маршрутизатора MPLS.
Другие могут нести информацию о том, что данный пакет принадлежит определённому VPN.
В этом выпуске метка всегда будет только одна — больше пока не нужно.
Push Label — операция добавления метки к пакету данных — совершается в самом начале — на первом
маршрутизаторе в сети MPLS (в нашем примере — R1).
Swap Label — операция замены метки — происходит на промежуточных маршрутизаторах в сети MPLS — узел
получает пакет с одной меткой, меняет её и отправляет с другой (R2, R5).
Pop Label — операция удаления метки — выполняется последним маршрутизатором — узел получает пакет MPLS
и убирает верхнюю метку перед передачей его дальше (R6).
На самом деле метка может добавляться и удаляться где угодно внутри сети MPLS.
Всё зависит от конкретных сервисов. Правильнее будет сказать, что метка добавляется первым маршрутизатором
пути (LSP), а удаляется последним.
Но в этой статье для простоты мы будем говорить о границах сети MPLS.
Кроме того, удаление верхней метки ещё не означает, что остался чистый IP-пакет, если речь идёт о стеке меток.
То есть если над пакетом с тремя метками совершили операцию Pop Label, то меток осталось две и дальше он по-
прежнему обрабатывается, как MPLS. А в нашем примере была одна, а после не останется ни одной — и это уже
дело IP.
LSR — Label Switch Router — это любой маршрутизатор в сети MPLS. Называется он так, потому что выполняет
какие-то операции с метками. В нашем примере это все узлы: R1, R2, R3, R4, R5, R6.
LSR делится на 3 типа:
Intermediate LSR — промежуточный маршрутизатор MPLS — он выполняет операцию Swap Label (R2, R5).
Ingress LSR — «входной», первый маршрутизатор MPLS — он выполняет операцию Push Label (R1).
Egress LSR — «выходной», последний маршрутизатор MPLS — он выполняет операцию Pop Label (R6).
LER — Label Edge Router — это маршрутизатор на границе сети MPLS.
В частности Ingress LSR и Egress LSR являются граничными, а значит они тоже LER.
LSP — Label Switched Path — путь переключения меток. Это однонаправленный канал от Ingress LSR до Egress LSR,
то есть путь, по которому фактически пройдёт пакет через MPLS-сеть. Иными словами — это последовательность
LSR.
Важно понимать, что LSP на самом деле однонаправленный. Это означает, что, во-первых, трафик по нему
передаётся только в одном направлении, во-вторых, если существует «туда», не обязательно существует
«обратно», в-третьих, «обратно» не обязательно идёт по тому же пути, что «туда». Ну, это как туннельные
интерфейсы в GRE.
Это похоже немного на IP-маршрутизацию. Несмотря на то, что существует путь от точки А до точки Б, таблица
маршрутизации знает только следующий узел, куда надо отправлять трафик. Но разница в том, что LSR не
принимает решение о каждом пакете на основе адреса назначения — путь определён заранее.
И одно из самых важный понятий, с которым необходимо разобраться — FEC — Forwarding Equivalence Class.
Мне оно почему-то давалось очень тяжело, хотя по сути — всё просто. FEC — это классы трафика. В простейшем
случае идентификатором класса является адресный префикс назначения (грубо говоря, IP-адрес или подсеть
назначения).
Например, есть потоки трафика от разных клиентов и разных приложений, которые идут все на один адрес — все
эти потоки принадлежат одному классу — одному FEC — используют один LSP.
Если мы возьмём другие потоки от других клиентов и приложений на другой адрес назначения — это будет
соответственно другой класс и другой LSP.
В теории помимо адреса назначения FEC может учитывать, например, метки QoS, адрес источника,
идентификатор VPN или тип приложений. Важно понимать тут, что пакеты одного FEC не обязаны следовать на
один и тот же адрес назначения. И в то же время, если даже и два пакета следуют в одно место, не обязательно
они будут принадлежать одному FEC.
Я поясню для чего всё это нужно. Дело в том, что для каждого FEC выбирается свой LSP — свой путь через сеть
MPLS. И тогда, например, для WEB-сёрфинга вы устанавливаете приоритет QoS BE — это будет один FEC — а для
VoIP — EF — другой FEC. И далее можно указать, что для FEC BE LSP должен идти широким, но долгим и
негарантированным путём, а для FEC EF — можно узким, но быстрым.
К сожалению или к счастью, но сейчас в качестве FEC может выступать только IP-префикс. Такие вещи, как
маркировка QoS не рассматриваются.
Если вы обратите внимание на таблицу меток, FEC там присутствует, поскольку параметры замены меток
определяются как раз таки на основе FEC, но делается это только в первый момент времени — когда эти метки
распределяются. Когда же по LSP бежит реальный трафик, никто, кроме Ingress LSR, уже не смотрит на него —
только метки и интерфейсы. Всю работу по определению FEC и в какой LSP отправить трафик берёт на себя
Ingress LSR — получив чистый пакет, он его анализирует, проверяет какому классу тот принадлежит и навешивает
соответствующую метку. Пакеты разных FEC получат разные метки и будут отправлены в соответствующие
интерфейсы.
Пакеты одного FEC получают одинаковые метки.
То есть промежуточные LSR — это молотилки, которые для всего транзитного трафика только и делают, что
переключают метки. А всю интеллектуальную работу выполняют Ingress LSR.
LIB — Label Information Base — таблица меток. Аналог таблицы маршрутизации (RIB) в IP. В ней указано для
каждой входной метки, что делать с пакетом — поменять метку или снять её и в какой интерфейс отправить.
LFIB — Label Forwarding Information Base — по аналогии с FIB — это база меток, к которой обращается сетевой
процессор. При получении нового пакета нет нужды обращаться к CPU и делать lookup в таблицу меток — всё
уже под рукой.
Одна из первоначальных идей MPLS — максимально разнести Control Plane и Data Plane — ушла в небытие.
Разработчикам хотелось, чтобы при передаче пакета через маршрутизатор не было никакого анализа — просто
прочитал метку, поменял на другую, передал в нужный интерфейс.
Чтобы добиться этого, как раз и было два разнесённых процесса — относительно долгое построение пути
(Control Plane) и быстрая передача по этому пути трафика (Data Plane)
Но с появлением дешёвых чипов (ASIC, FPGA) и механизма FIB обычная IP-передача тоже стала быстрой и
простой.
Для маршрутизатора без разницы, куда смотреть при передаче пакета — в FIB или в LFIB.
А вот что, несомненно, важно и полезно — так это, что безразличие MPLS к тому, что передаётся под его
заголовком — IP, Ethernet, ATM. Не нужно городить GRE или какие-то другие до боли в суставах неудобные VPN.
Но об этом ещё поговорим.
Заголовок MPLS
Весь заголовок MPLS — это 32 бита. Формат полей и их длина фиксированы. Часто весь заголовок называют
меткой, хотя это не совсем и верно.
=====================
Задача № 1
В сети настроена простая политика QoS, в которой IP-пакеты, которые идут с хоста 10.0.17.7 на адрес
6.6.6.6, маркируются и передаются по сети MPLS. Для маркировки пакетов используется поле EXP, значение
поля 3.
Схема
На маршрутизаторе R6 настроена политика QoS, которая классифицирует пакеты по полю EXP.
Но, при проверке оказалось, что политика на R6 не отрабатывает. То есть, нет пакетов, приходящих со
значением EXP 3 и все пакеты попадают в class default.
S — Bottom of Stack — индикатор дна стека меток длиной в 1 бит. Заголовков MPLS на пакете может быть
несколько, например, внешняя для коммутации в сети MPLS, а внутренняя указывает на определённый VPN.
Чтобы LSR понимал с чем он имеет дело. В бит S записывается «1», если это последняя метка (достигнуто дно
стека) и «0», если стек содержит больше одной метки (ещё не дно). То есть LSR не знает, сколько всего меток в
стеке, но знает, одна она или больше — да этого и достаточно на самом-то деле. Ведь любые решения
принимаются на основе только самой верхней метки, независимо от того, что там под ней. Зато, снимая метку,
он уже знает, что дальше сделать с пакетом: продолжить работу с процессом MPLS или отдать его какому-то
другому (IP, Ethernet, ATM, FR итд).
Вот к этой фразе: “Зато, снимая метку, он уже знает, что дальше сделать с пакетом” — надо дать пояснение. В
заголовке MPLS, как вы заметили, нет информации о содержимом (как Ethertype в Ethernet’е или Protocol в IP).
Это с одной стороны хорошо — внутри может быть что угодно — выше гибкость, а с другой стороны, как без
анализа содержимого теперь определить, какому процессу передавать всё это хозяйство?
А тут небольшая хитрость — маршрутизатор, как вы увидите дальше, всегда сам выделяет метку и передаёт её
своим соседям, поэтому он знает, для чего её выделял — для IP или для Ethernet или ещё для чего-то. Поэтому
он просто добавляет эту информацию в свою таблицу меток. И в следующий раз, когда делает операцию Pop
Label, он уже из таблицы (а не из пакета) знает, что дальше делать.
В общем, стек тут в классическом понимании — последним положили, первым взяли (LIFO — Last Input — First
Output).
В итоге, несмотря на то, что длина заголовка MPLS фиксированная, самих заголовков может быть много — и все
они располагаются друг за другом.
TTL — Time To Live — полный аналог IP TTL. Даже той же самой длиной обладает — 8 бит. Единственная задача —
не допустить бесконечного блуждания пакета по сети в случае петли. При передаче IP-пакета через сеть MPLS
значение IP TTL может быть скопировано в MPLS TTL, а потом обратно. Либо отсчёт начнётся опять с 255, а при
выходе в чистую сеть IP значение IP TTL будет таким же, как до входа.
Как видите, заголовок MPLS втискивается между канальным уровнем и теми данными, которые он несёт — в
случае IP — сетевым. Поэтому метафорически MPLS называется технологией 2,5 уровня, а заголовок — Shim-
header — заголовок-клин.
К слову, метка не обязательно должна быть в заголовке MPLS. Согласно решению IETF, она может
встраиваться в заголовки ATM, AAL5, Frame Relay.
0: IPv4 Explicit NULL Label. «Явная пустая метка». Она используется на самом последнем пролёте MPLS — перед
Egress LSR — для того, чтобы уведомить его, что эту метку 0 можно снять, не просматривая таблицу меток (точнее
LFIB).
Для тех FEC, что зарождаются локально (directly connected) Egress LSR выделяет метку 0 и передаёт своим
соседям — предпоследним LSR (Penultimate LSR).
При передаче пакета данных предпоследний LSR меняет текущую метку на 0.
Когда Egress LSR получает пакет, он точно знает, что верхнюю метку нужно просто удалить.
Так было не всегда. Изначально предлагалось, что метка 0 может быть только на дне стека меток и при
получении пакета с такой меткой, LSR должен вообще очистить упоминания об MPLS и начать обрабатывать
данные.
В какой-то момент теоретики под давлением практиков согласились, что это нерационально и реального
применения им придумать не удалось, поэтому отказались от обоих условий.
Так что теперь метка 0 не обязательно последняя (нижняя) и при операции Pop Label удаляется только она, а
нижние остаются и пакет дальше обрабатывается в соответствии с новой верхней меткой.
1: Метка Router Alert Label — аналог опции Router Alert в IP — может быть где угодно, кроме дна стека. Когда
пакет приходит с такой меткой, он должен быть передан локальному модулю, а дальше он коммутируется в
соответствии с меткой, которая была ниже — реальной транспортной, при этом наверх стека снова должна быть
добавлена метка 1.
2: IPv6 Explicit NULL Label — то же, что и 0, только с поправкой на версию протокола IP.
3: Implicit Null. Фиктивная метка, которая используется для оптимизации процесса передачи пакета MPLS на
Egress LSR. Эта метка может анонсироваться, но никогда не используется в заголовке MPLS реально. Рассмотрим
её попозже.
4-15: Зарезервированы.
В зависимости от вендора, могут быть зафиксированы и другие значения меток, например, на оборудовании
Huawei метки 16-1023 используются для статических LSP, а всё, что выше — в динамических. В Cisco доступные
метки начинаются уже с 16-й.
=====================
Задача № 2
На следующей схеме все маршрутизаторы, кроме R5, это маршрутизаторы Huawei. R5 — Cisco.
Схема
Для приведенной ниже конфигурации маршрутизатора R5, необходимо настроить его таким образом,
чтобы распределение значений меток соответствовало Huawei. Речь о том, что в Huawei динамические
метки начинаются с 1024, а в Cisco с 16.
Конфигурация R5
Подробности задачи тут.
=====================
В целом стало понятно, как передаётся трафик и как в этом участвуют метки MPLS.
Но метки не берутся от балды — никому не нужен дополнительный хаос в преддверии Нового Года.
Специальные протоколы распределяют метки между Egress LSR и Ingress LSR, создавая LSP.
Распространение меток
Во-первых, как вы уже поняли, на некоторых устройствах можно всё сделать вручную — виват усердие и
старание!
Но в эпоху автоматических стиральных машин существует три базовых протокола для распространения меток —
LDP, RSVP-TE и MBGP.
Если коротко, то LDP — самый простой и понятный способ — опирается на маршрутную информацию узлов.
RSVP-TE — это развитие некогда разработанного, но непопулярного протокола RSVP — используется в MPLS-TE
для построения LSP, удовлетворяющих определённым условиям. Для его работы нужны IGP, поддерживающие
Traffic Engineering (OSPF, ISIS).
MBGP — близкий родственник BGP, но это протокол из немного другой истории, он передаёт метки для других
целей. Поэтому и стоит он в стороне от LDP и RSVP-TE.
Поговорим о каждом из них, но перед этим несколько слов о том, как LSR обращаются с метками вообще.
Методы распространения меток
Первый очевидный факт — метки распространяются в направлении от получателя трафика к отправителю, а
точнее от Egress LER к Ingress LER. Первый неочевидный факт — в MPLS Downstream — это от отправителя к
получателю, а Upstream от получателя к отправителю. Я для себя определил это так: LSP «растёт» из FEC вверх к
Ingress LER, как дерево, а пользовательский трафик «спускается» к получателю по LSP, как дождевая вода по
веткам. То есть метки распространяются навстречу трафику.
DU против DoD
Во-первых, маршрутизатор может распространять метки всем своим соседям сразу же и без лишних вопросов, а
может выдавать по запросу от вышестоящих (мы помним, да, какое направление называется Upstream?)
Первый режим называется DU — Downstream Unsolicited. Как только LSR узнаёт про FEC, он рассылает всем
своим MPLS-соседям метки для этого FEC.
Выглядит это примерно так:
Все LSR узнают обо всех FEC по всем возможным путям. Сначала соответствие FEC-метка расходится по всей сети
от соседа к соседу, почти как это происходит с сообщениями BootStrap в PIM SM. А потом каждый LSR выбирает
только тот, который пришёл по лучшему пути, и его использует для LSP — точно так же работает Reverse Path
Forwarding в том же PIM SM.
Быстро, просто, понятно, хотя и не всегда нужно, чтобы все знали обо всём.
Второй режим — DoD — Downstream-on-Demand. LSR знает FEC, у него есть соседи, но пока они не спросят, какая
для данного FEC метка, LSR сохраняет молчание.
Этот способ удобен, когда к LSP предъявляются какие-то требования, например, по ширине полосы. Зачем слать
метку просто так, если она тут же будет отброшена? Лучше вышестоящий LSR запросит у нижестоящего: мне
нужна от тебя метка для данного FEC — а тот: «ок, на».
Режим выделения меток специфичен для интерфейса и определяется в момент установки соединения. В сети
могут быть использованы оба способа, но на одной линии, соседи должны договориться только об одном
конкретном.
Ordered Control против Independent Control
Во-вторых, LSR может дожидаться, когда со стороны Egress LER придёт метка данного FEC, прежде чем
рассказывать вышестоящим соседям. А может разослать метки для FEC, как только узнал о нём.
Первый режим называется Ordered Control
Гарантирует, что к моменту передачи данных весь путь вплоть до выходного LER будет построен.
То есть метки передаются неупорядоченно. Удобен тем, что трафик можно начинать передавать ещё до того, как
весь путь построен. Этим же и опасен.
PHP
Нет, это не тот PHP, о котором вы подумали. Речь о Penultimate Hop Popping. Все
инженеры немного оптимизаторы, вот и тут ребята подумали: а зачем нам два раза обрабатывать заголовки
MPLS — сначала на предпоследнем маршрутизаторе, потом ещё на выходном.
И решили они, что метку нужно снимать на предпоследнем LSR и назвали сие действо — PHP.
Для PHP существует специальная метка — 3.
Возвращаясь к нашему примеру, для FEC 6.6.6.6 и 172.16.0.2 R6 выделяет метку 3 и сообщает её R5.
При передаче пакета на R6 R5 должен назначить ему фиктивную метку — 3, но фактически она не применяется и
в интерфейс отправляется голый IP-пакет (стоит заметить, что PHP работает только в сетях IP) — то есть
процедура Pop Label была выполнена ещё на R5.
Сервисные метки служат для разделения различных сервисов. Тут на арену выходят MBGP и отросток LDP —
tLDP.
В частности MBGP позволяет, например, пометить, что вот такой-то маршрут принадлежит такому-то VPN. Потом
он этот маршрут передаёт, как vpn-ipv4 family своему соседу с меткой, чтобы тот смог потом отделить мух от
котлет.
Так вот, чтобы он мог отделить, ему и нужно сообщить о соответствии метка-FEC.
Но это действие другой пьесы, которую мы сыграем ещё через полгода-год.
Обязательным условием работы всех протоколов динамического распределения меток является базовая
настройка IP-связности. То есть на сети должны быть запущены IGP.
Ну, вот теперь, когда я вас окончательно запутал, можно начинать распутывать.
Итак, как проще всего распределить метки? Ответ — включить LDP.
LDP
Протокол с очень прозрачным названием — Labed Distribution Protocol — имеет соответствующий принцип
работы.
Рассмотрим его на сети linkmeup, которую мы мурыжим весь выпуск:
1. После включения LDP LSR делает мультикастовую рассылку UDP-дейтаграмм во все интерфейсы на адрес
224.0.0.2 и порт 646, где активирован LDP — так происходит поиск соседей.
TTL таких пакетов равен 1, поскольку LDP-соседство устанавливается между непосредственно подключенными
узлами.
Вообще говоря, это не всегда так — LDP сессия может устанавливаться для определённых целей и с
удалённым узлом, тогда это называется tLDP — Targeted LDP. О нём мы поговорим в других выпусках.
2. Когда соседи обнаружены, устанавливается TCP соединение с ними, тоже по порту 646 — Initialization.
Дальнейшие сообщения (кроме Hello) передаются уже с TTL равным 255.
3. Теперь LSR периодически обмениваются сообщениями Keepalive адресно по TCP и по-прежнему не оставляют
попыток найти соседей с помощью Hello.
4. В какой-то момент один из LSR обнаруживает в себе вторую личность — Egress LSR — то есть он является
выходным для какого-то FEC. Это факт, о котором нужно сообщить миру.
В зависимости от режима он ждёт запроса на метку для данного FEC, либо рассылает его сразу же.
Эта информация передаётся в сообщении Label Mapping Message. Исходя из названия, оно несёт в себе
соответствие FEC и метки.
R5 получает информацию о соответствии FEC 6.6.6.6/32 и метки 3 (implicit null) и записывает её в свою таблицу
меток. Теперь, когда ему нужно будет отправить данные на 6.6.6.6 он будет знать, что нужно удалить верхний
заголовок MPLS и отправить оставшийся пакет в интерфейс FE1/0.
Далее он выбирает входную метку для данного FEC, записывает эту информацию в свою таблицу меток и
отправляет её вышестоящим соседям.
Теперь R5 знает, что если пришёл пакет MPLS с меткой 20, его нужно передать в интерфейс FE1/0, сняв метку, то
есть выполнив процедуру PHP.
R2 получает от R5 информацию о соответствии FEC-метка (6.6.6.6 — 20), вносит её в таблицу и, создав свою
входную метку (18), передаёт её ещё выше. И так далее, пока все LSR не получат свою выходную метку.
Таким образом у нас построен LSP от R1 до R6. R1 при отправке пакета на 6.6.6.6/32 добавляет к нему метку 18
(Push Label) и посылает его в порт FE0/0. R2, получив пакет с меткой 18, меняет метку на 20 (Swap Label) и
отправляет его в порт FE0/0. R5 видит, что для пакета с меткой 20, надо выполнить PHP (выходная метка — 3 —
implicit null), снимает метку (Pop Label) и отправляет данные в порт FE1/0.
При этом параллельно оказались построены LSP от R2 до R6, от R5 до R6, от R4 до R6 итд. То есть ото всех LSR —
просто я не показал это на иллюстрации.
Если у вас хватит сил, то на гифке ниже можно весь процесс посмотреть в динамике.
Естественно, вы понимаете, что не только R6 вдруг начал рассылать свои соответствия FEC-метка, но и все другие
— R1 про 1.1.1.1/32, R2 — 2.2.2.2/32 итд. Все эти сообщения молниеносно разносятся по сети MPLS, строя десятки
LSP. В результате каждый LSR будет знать про все существующие FEC и будет построен соответствующий LSP.
Опять же на гифке выше процесс показан не до конца, R1 потом передаёт информацию на R3, R3 на R4, R4 на R5.
И если мы посмотрим на R5, то увидим, что для FEC 6.6.6.6/32 у нас не одна выходная метка, как ожидалось, а 3:
Более того, сам R6 запишет метку для FEC 6.6.6.6, которую получит от R5:
Inuse — правильная — imp-null в сторону R6. Но две других из кольца — от R2 и R4. Это не ошибка и не петля —
просто R2 и R4 сгенерировали эти метки для известного им из таблицы маршрутизации FEC 6.6.6.6/32.
Возникает два вопроса:
1) Как он планирует ими воспользоваться? Они же бестолковые. Ответ: а никак. Не может быть в нашей сети
такой ситуации, когда 2.2.2.2 или 4.4.4.4 будут следующими узлами на пути к 6.6.6.6 — IGP так маршрут не
построит. А значит и использованы метки не будут. Просто LDP-то глупый — его сообщения разбредаются по всей
сети, пробиваясь в каждую щёлочку. А умный LSR уже решит каким пользоваться.
2) Что насчёт петель? Не будут сообщения LDP курсировать по сети пока TTL не истечёт?
А тут всё просто — получение нового сообщения Label Mapping Message не инициирует создание нового —
полученное соответствие просто записывается в таблицу LDP. То есть в нашем случае R5 уже придумал один раз
метку для FEC 6.6.6.6/32 и разослал её своим вышестоящим соседям и она уже не поменяется, пока процесс LDP
не перезагрузится.
Возможно, вы уже заметили, что при настройке LDP есть возможность включить функционал Loop Detection,
но спешу вас успокоить — это для сетей, где нет TTL, например, ATM. Этот функционал переключит LDP в
режим DoD.
Самое важное, что нужно понимать относительно LDP — он не использует в своей работе протоколы
динамической маршрутизации — по принципу работы он похож на PIM DM: наводняет всю сеть метками, но при
этом он опирается на информацию из таблицы маршрутизации LSR. И если на R1 придёт две метки для одного
FEC от разных соседей, то он выберет для LSP только ту, которая получена через лучший интерфейс до этого FEC
по информации из ТМ.
Это означает три вещи:
• Вы вольны выбирать IGP, который вам больше нравится, хоть RIP .
• LDP всегда строит только один (лучший) маршрут и не может построить, например, резервный.
• При изменении топологии сети LSP перестроится в соответствии с обновившейся таблицей
маршрутизации, то есть сначала должен сойтись IGP, и только потом поднимется LSP.
И вообще после включения LDP трафик будет ходить так же, как и без него, с той лишь разницей, что появляются
метки MPLS.
В том числе LDP, как и IP, поддерживает ECMP, просто алгоритмы вычисления хэша, а соответственно и
балансировки могут отличаться.
Интересная статья от Ивана Пепельняка на тему LDP и видео о том, как протокол работает.
R1(config)#ip cef
R1(config)#mpls ip
Первая — это уже стандарт де факто и де юре почти на любом сетевом оборудовании — она запускает механизм
CEF на маршрутизаторе, вторая стартует MPLS и LDP глобально (тоже может быть дана по умолчанию).
Router ID (а в более общей (нецисковской) терминологии LSR ID) в MPLS выбирается незамысловато:
1. Самый большой адрес Loopback-интерфейсов
2. Если их нет — самый большой IP-адрес, настроенный на маршрутизаторе.
Естественно, не стоит доверять автоматике — настроим LSR ID вручную:
Если не добавлять ключевое слово «force», Router ID изменится только при переустановлении LDP-
сессии. «Force» заставляет маршрутизатор сменить Router ID насильно и при необходимости (если тот
поменялся) переустанавливает соединение LDP.
R1(config-if)#mpls ip
R1(config-if)#mpls ip
Cisco здесь опять использует свой принцип ленивого инженера — минимум усилий со стороны персонала.
Команда mpls ip включает на интерфейсе LDP одновременно с MPLS, желаем мы этого или нет. Точно так же
команда ip pim sparse-mode включает IGMP на интерфейсе, как я описывал это в статье про мультикаст.
После активации LDP маршрутизатор начинает прощупывать почву по UDP:
Проверяки посылаются на мультикастовый адрес 224.0.0.2.
R2(config)#ip cef
R2(config)#mpls ip
R2(config-if)#mpls ip
R2(config-if)#mpls ip
и наслаждаемся результатом.
R2 тоже ищет соседей.
Теперь они соседи, что легко проверяется командой show mpls ldp neighbor.
Но как так, спросите вы? Разве достаточно иметь метки только в Loopback?
Если вспомнить о том, что мы рассматривали вначале статьи, что BGP префиксы не получают свои метки, и что
метки нужны только для next-hop, то становится понятно, что меток для Loopback вполне хватит.
Для того чтобы добраться до других сетей внутри нашей AS, нам достаточно IGP.
=====================
Задача № 3
Если в Cisco по умолчанию анонсируются метки для всех сетей (кроме полученных по BGP), то в Juniper, по
умолчанию анонсируется только loopback.
Схема
Для приведенной ниже конфигурации маршрутизатора R5, донастроить его так, чтобы настройки
маршрутизатора Cisco, соответствовало настройкам по умолчанию в Juniper.
Конфигурация R5
Обратите внимание, что LDP на R3 ещё не поднят, то есть R1 анонсировал метку для FEC 3.3.3.3, не дождавшись
её от R5, это говорит о том, что используется Independent Control.
А то, что не было явного запроса от R2 на данный FEC, говорит о том, что режим — Downstrean unsolicited.
Далее узлы будут продолжать мониторить новых соседей с помощью LDP Hello поверх UDP и обмениваться LDP
Keepalive уже адресно:
Теперь с помощью команды show mpls forwarding-table можно посмотреть, какие метки назначились для
каждого FEC:
На второй строчке уже рассмотренный FEC 3.3.3.3, и мы видим, что для него локальная метка — 17, то есть R1
всем будет говорить, что для FEC 3.3.3.3 метка 17, что и было в дампе.
А вот outgoing tag или выходная метка — Untagged — это означает что пакеты пересылаются чистым IP (без
каких-либо оговорок на стек). Причём Untagged означает, что между R1 и R3 вообще никакого MPLS нет —
правильно: мы же его не включили на R3.
А вот с R2 (первая строка) ситуация другая. Локальная метка 16 — это то, что R1 будет передавать всем. А
выходная — Pop tag. То есть при передаче пакета на R2 R1 должен снять метку. В нашем случае это означает, что
будет передан чистый IP (но в более общем случае снимается только верхняя метка). В чём же разница с FEC
3.3.3.3? А разница в том, что между R1 и R2 есть MPLS и то, что мы видим — это тот самый PHP — Penultimate Hop
Popping. Пакет, адресованный 2.2.2.2 всё равно будет обработан на R2, поэтому чтобы не плодить сущности сверх
необходимого R1 услужливо снимет метку.
И тут возникает интересный вопрос, откуда R1 знает, что он предпоследний из могикан? Ведь мы же выше
говорили, что LDP не пользуется протоколами маршрутизации, поэтому он и знать не может, что адрес 2.2.2.2
настроен на непосредственно подключенном R2 — он видит только то, что 2.2.2.2 доступен через 10.0.12.2.
Для узлов R5 и R6 у нас есть метки, хотя на них MPLS не включали, но это лишь потому, что маршрут до них лежит
через R2, а R2 сгенерировал соответствие FEC-метка для них. В таком случае пакеты на R6 будут
идти с заголовком MPLS между R1 и R2 и без него дальше.
Заметьте, если бы использовался Ordered Control, R2 не смог бы отправить метку для R5 и R6, и пакеты ходили бы
только по IP.
Предлагаю закончить настройку MPLS+LDP на всех элементах нашей скромной сети. Процессы там ничем не
отличаются — те же Neighbor Discovery, Initialization, обмен метками, PHP.
mpls ip
interface Loopback0
ip router isis
!
interface FastEthernet0/0
description to R2
ip router isis
mpls ip
interface FastEthernet0/1
description to R3
ip router isis
mpls ip
router isis
net 10.0000.0000.0001.00
R2:
R5:
Значит
1. Когда R1 получает пакет MPLS с меткой 21, он должен передать его в интерфейс Fa0/0 и поменять метку на 18.
2. Когда R2 получает пакет MPLS с меткой 18, он должен передать его в интерфейс Fa0/0 и поменять метку на 20.
3. Когда R5 получает пакет MPLS с меткой 20, он должен передать его в интерфейс Fa1/0 и снять метку — PHP.
В этом случае LSR даже не задумываются о том, чтобы глянуть что-то в таблице маршрутизации или в ip cef — они
просто жонглируют метками.
Таблица коммутации, которую мы уже смотрели командой show mpls forwarding table — это LFIB (Lable
Forwarding Information Base) — почти что прописная истина для передачи данных — это Data Plane. Но что же
там с Control Plane? Вряд ли LDP знает столько же? Наверняка у него ещё есть козыри в рукаве?
Так и есть:
На иллюстрации выше вы можете видеть слово «tib». TIB — это Tag Information Base, которая правильно
называется Label Information Base — LIB.
Это пережиток почившего в бозе TDP — прародителя LDP.
Обратите внимание, что везде по 2 remote binding — это два пути получения меток. Например, до R2 можно
добрать от R1 напрямую, а можно через R3-R4-R5-R2.
То есть, понимаете да? Мало того, что он из каждой записи в таблице маршрутизации делает FEC, так этот
негодяй ещё и Liberal Retention Mode использует для удержания меток.
Давайте подытожим: по умолчанию LDP в Cisco работает в следующих режимах:
• DU
• Independent Control
• Liberal Retention Mode
• В качестве FEC выбираются все записи в таблице маршрутизации
Короче говоря, щедроты его не знают границ.
Есть ещё команда show mpls ip binding. Она показывает нечто похожее и позволяет кроме того быстро узнать,
какой путь сейчас активен, то есть как построен LSP:
И последний, пожалуй, вопрос, который возникает в связи со всеми этими LSP — когда маршрутизатор сам
является Ingress LSR, как он понимает, что нужно делать с пакетами, как выбрать LSP?
А для этого вот и придётся заглянуть в IP CEF. Вообще именно на Ingress LSR ложится всё бремя обработки пакета,
определения FEC и назначения правильных меток.
И тут уже вы должны заметить, что в LDP понятия LER, Ingress LSR, Egress LSR — это не роль каких-то конкретных
узлов или характеристика местоположения узла в сети. Они неотделимы от FEC и LSP, индивидуальны для них. То
есть для каждого конкретного FEC есть один или несколько Egress LSR и множество Ingress LSR (как правило, все
маршрутизаторы), до которых ведут LSP.
Даже скажем так, понятия LER возникают когда мы говорим о конкретном LSP, тогда мы можем сказать, кто
является Ingress, кто Egress.
MPLS и BGP
До сих пор мы говорили о том как MPLS взаимодействует с IGP-протоколами. Мы убедились, что ничего
сложного в этом нет и что настройки также довольно простые.
Но самое интересное кроется во взаимодействии MPLS с BGP. В этом выпуске мы лишь слегка затронем эту тему.
Но в следующих, мы поговорим подробнее о том, какую роль играет BGP, и как с помощью него и MPLS мы
можем организовывать различные типы VPN.
Сейчас же нам надо разобраться как MPLS и BGP взаимодействуют на самом базовом уровне.
Главное отличие BGP от IGP заключается в том, что MPLS не создает метки для маршрутов BGP. Если вспомнить о
том, какое количество маршрутов передает BGP, то становится понятно, что это очень хорошая идея. Как же тогда
состыковать MPLS и BGP?
Все просто:
1. создаем метки только для адресов, которые будут указаны как next-hop для маршрутов, которые мы
получаем по BGP (тут надо не забыть про next-hop-self для IBGP-соседей).
2. Когда нашему Ingress LSR понадобится передать пакеты по маршруту, который был получен по BGP,
отправляем их к next-hop, который указан в маршруте и используем ту метку, которая была создана для него.
Теперь, вместе того чтобы настраивать BGP на каждом маршрутизаторе в нашей AS, мы можем настраивать его
только на пограничных маршрутизаторах, к которым подключены клиенты или другие провайдеры.
Если нам надо добраться с R1 до сетей Филькин Сертификат, мы смотрим, что они доступны через R6 и
«пролетаем» через MPLS до адреса 6.6.6.6. А когда мы добираемся до R6, он уже знает куда идти дальше.
Аналогично будет и наоборот, в Балаган-Телеком.
Конфигурацию для этой схемы и пару команд с выводом информации, можно найти по ссылке.
=====================
Задача № 4
В сети настроены MPLS и OSPF. MPLS настроен во всей сети, кроме соединения между R7 и R1.
Между маршрутизаторами R1-R2-R3-R4-R5-R6 трафик должен передаваться силами MPLS.
В сети также настроен BGP, который работает между R1 и R6.
Задание:
Восстановить работу сети, чтобы с R7 пинговался адрес 100.0.0.1.
Ограничения:
Нельзя менять настройки BGP.
Схема
RSVP-TE
LDP хорош. Работает он просто и понятно. Но есть такая технология, как MPLS TE — Traffic Engineering. И ей
недостаточно лучшего маршрута, который может обеспечить LDP.
Управление трафиком подразумевает, что вы можете направить трафик между узлами как вам угодно, учитывая
различные ограничения.
Например, в нашей сети клиент имеет две точки подключения своих узлов — на R1 и на R6. И между ними он
просит предоставить ему VPN с гарантированной шириной канала в 100 Мб/с. Но при этом у нас в сети ещё и
обычные ШПДшники видео гоняют с вконтактика и дюжина других клиентов, которые VPN арендуют, но полосу
им резервировать не надо.
Если не вмешаться в эту ситуацию, где-нибудь на R2 может возникнуть перегруз, и 100 Мб/с для дорогого
клиента не достанется.
MPLS TE позволяет пройти по всей сети от отправителя до получателя и зарезервировать ресурсы на каждом
узле. Если вы знакомы с концепцией IntServ, то да, это именно она — организовать QoS на всём протяжении
пути, вместо того, чтобы позволить каждому маршрутизатору самому принимать решение для проходящего
пакета.
Собственно, протокол RSVP (Resource ReSerVation Protocol) изначально (в 1993-м году) и был задуман для
организации IntServ в IP-сетях. Он должен был донести информацию о QoS для какого-то конкретного потока
данных до каждого узла и заставить его зарезервировать ресурсы.
1) Узел-источник хочет отправить поток данных со скоростью 5 Мб/с. Но перед этим он посылает RSVP запрос на
резервирование полосы до получателя — Path Message. Это сообщение содержит некие идентификаторы
потока, по которым узел потом сможет идентифицировать принадлежность полученных IP-пакетов потоку, и
требуемую ширину полосы.
2) Сообщение Path передаётся от узла к узлу до самого получателя. Куда его послать, определяется на основе
таблицы маршрутизации.
3) Каждый маршрутизатор, получив Path, проверяет свои ресурсы. Если у него есть достаточно свободной
полосы, он настраивает свои внутренние алгоритмы так, чтобы пакеты потока были обработаны как следует и
пропускной способности всегда хватало.
4) Если же у него нет необходимых 5 Мб/с (занято другими потоками), он отказывает в выделении ресурсов и
возвращает соответствующее сообщение отправителю.
5) Пакет Path доходит до получателя потока, тот отправляет назад сообщение Resv, подтверждая выделение
ресурсов на всём протяжении пути.
6) Изначальный отправитель, получив Resv, понимает, что всё для него готово, и он может отправлять данные.
На самом деле под этими четырьмя простыми шагами лежат гораздо более сложные процессы, но нам это не
интересно.
А вот что нам интересно — так это расширение RSVP для Traffic Engineering, или проще — RSVP TE, которое было
разработано специально для MPLS TE.
Его задача такая же, как у LDP — распределить метки между LSR и скомпилировать в итоге LSP от получателя до
отправителя. Но теперь, как вы уже поняли, появляются нюансы — LSP должен удовлетворять определённым
условиям.
RSVP TE позволяет строить основной и запасной LSP, резервировать ресурсы на всех узлах, обнаруживать аварии
на сети, строить заранее обходные пути, делать быстрое перенаправление трафика, избегать каналов, которые
физически проходят по одному пути.
Но всё это мы будем обсуждать в статье о MPLS TE через пару выпусков. А сегодня же мы сосредоточимся на
принципах, согласно которым RSVP TE строит LSP.
От смены протокола не меняется то, что LSP — однонаправленный, соответственно и ресурсы будут
резервироваться только в одном направлении. Хочешь в другом — создавай обратный LSP.
Для начала мы отбросим функционал резервирования ресурсов — пусть наша задача только создать LSP, то есть
распределить метки между LSR.
Чтобы это стало возможно, стандартный RSVP расширяется добавлением нескольких объектов. Рассмотрим
простейший вариант.
0) R1 нужен LSP до FEC 6.6.6.6/32. Это выглядит как интерфейс Tunnel на R1, у которого адрес назначений 6.6.6.6 и
тип Traffic Engineering.
1) Он посылает сообщение RSVP Path в направлении 6.6.6.6. В этом сообщении появляется новый объект — Label
Request. Сообщение Path провоцирует узел выделить метку для данного FEC — то есть это запрос метки.
2) Следующий узел формирует новое сообщение Path и также отправляет его в сторону 6.6.6.6. Итд.
3) Path достигает Egress LSR. Тот видит, что пакет-то ему адресован, выделяет метку и отправляет источнику
сообщение Resv. В последнем тоже добавлен новый объект — Label. В нём Egress LSR передаёт свою метку для
этого FEC предпоследнему, предпоследний предпредпоследнему свою итд.
4) Resv достигает источника, распределяя по пути метки. Таким образом создан LSP, а источник уведомлён, что
всё готово.
Метки запрашиваются вниз по течению (сообщение Path от отправителя к получателю), а передаются вверх по
течению (сообщение Resv от получателя к отправителю).
При этом обратите ваше внимание на то, что это уже самый что ни на есть Downstream on Demand + Ordered
Control. Path выступает запросом метки, а Resv идёт от получателя шаг за шагом и, пока метку не выслал
нижестоящий LSR, вышестоящий не может её отправить своим соседям.
Стоп! Мы говорили, что RSVP TE в отличие от LDP позволяет строить как мы хотим, не привязываясь к таблице
маршрутизации и IGP, а тут пока просто «в направлении 6.6.6.6».
И вот тут мы подошли вплотную к фундаментальному отличию RSVP TE от LDP. RSVP TE очень тесно связан с
протоколами динамической маршрутизации, он не просто опирается на результат их работы — он адаптирует их
под себя, эксплуатирует в прямом смысле слова.
Во-первых, годятся только протоколы, основанные на алгоритмах по состоянию связи (link-state), то есть OSPF и
ISIS.
Во-вторых, OSPF и ISIS расширяются введением новых элементов в протоколы. Так в OSPF появляется новый
тип LSA — Opaque LSA, а в ISIS — новые TLV IS Neighbor и IP Reachability.
В-третьих, для расчёта пути между Ingress LSR и Egress LSR используется специальная модификация алгоритма
SPF — CSPF (Constrained Shortest Path First).
Теперь подробнее.
Сообщение Path в принципе передаётся юникастом адресно. То есть адрес отправителя у него — адрес R1, а
получателя — 6.6.6.6. И оно могло бы дойти и просто по таблице маршрутизации.
Но фактически Path передаётся по сети не как FIB на душу положит на каждом узле, ведь мы тогда не сможем ни
резервирование обеспечить, ни поиск запасных маршрутов. Нет, он следует определённому пути.
Этот путь определяется на Ingress LSR с точностью до каждого узла.
Чтобы построить этот путь, RSVP TE нужно знать топологию сети. Понимаете да, к чему мы приближаемся? Сам
RSVP не утруждает себя её изучением, да и зачем, когда её можно получить у OSPF или ISIS. И тут же становится
очевидно, почему сюда не подходят RIP, IGRP и EIGRP — ведь они не изучают топологию, максимум на что они
способны — это Feasible Successor.
Но классический алгоритм SPF на входе имеет топологию сети, а на выходе может выдать только наибыстрейший
маршрут с учётом метрик и AD, хотя просчитать может и все возможные пути.
И тут на сцену выходит CSPF. Именно этот алгоритм может посчитать лучший путь, второй по приоритетности путь
и, например, ещё какой-нибудь запасной, чтобы хоть как-то добраться, пусть и через Китай.
То есть RSVP TE может обращаться к CSPF с просьбой вычислить для него какой-либо путь между двумя узлами.
Ну хорошо, а зачем для этого менять сами протоколы IGP? Вооот. А это уже Constraints — ограничения. RSVP TE
может предъявлять требования к пути — ширина полосы пропускания, минимально доступная ширина, тип
линии или даже узлы, через которые LSP должен пролегать. Так вот, чтобы CSPF мог учитывать ограничения, он
должен знать и о них и о доступных ресурсах на узлах всей сети. Входными данными для него являются
ограничения, заданные в туннеле и топология сети — логично будет, если топология будет содержать кроме
префиксов и метрик ещё и информацию о доступных ресурсах.
Для этой цели маршрутизаторы обмениваются между собой через сообщения OSPF и ISIS не только базовой
информацией, но и характеристиками линий, интерфейсов итд. Как раз в новых типах сообщений и передаётся
эта информация.
Например, в OSPF для этого ввели 3 дополнительных типа LSA:
• Type 9 — link-local scope
• Type 10 — area-local scope
• Type 11 — AS scope
Opaque значит непрозрачный (для OSPF). Это специальные типы LSA, которые никак не учитываются в самом
OSPF при расчёте таблицы маршрутизации. Их могут использовать любые другие протоколы для своих нужд. Так
TE их использует для построения своей топологии (она называется TED — Traffic Egineering Database). Но
теоретически за TE они не закреплены — если вы напишете своё приложение для маршрутизаторов, которое
будет требовать обмена какой-то информацией о топологии, вы тоже можете использовать Opaque LSA.
Точно так же работает и ISIS. Новые сообщения: IS-IS TLV 22 (Extended IS Reachability), 134 (Traffic Engineering
router ID), 135 (Extended IP reachability).
0) На R1 мы включили MPLS TE и настроили ISIS (OSPF) на передачу данных для поддержки TE. Маршрутизаторы
обменялись информацией о доступных ресурсах. На этом шаге сформирована TED. RSVP молчит.
1) Мы создали туннельный интерфейс, где указали его тип (Traffic Engineering), адрес назначения (6.6.6.6) и
необходимые требования по ресурсам. LSR запускает CSPF: нужно вычислить кратчайший путь от R1 до 6.6.6.6 с
учётом накладываемых условий. На этом шаге мы получаем оптимальный путь — список узлов от источника до
получателя (R2, R5, R6).
2) Результат предыдущего шага скармливается RSVP и трансформируется в объект ERO. R1 компилирует RSPV
Path, куда, естественно, добавляет ERO. Адресат пакета — 6.6.6.6. Кроме того, имеется и объект Label Request,
сообщающий о том, что при получении пакета нужно выделить метку для данного FEC (6.6.6.6/32).
ERO — Explicit Route Object — специальный объект сообщения RSVP Path. Он содержит список узлов, через
которые суждено пройти этому сообщению.
3) Сообщение RSVP Path передаётся специальным образом — не по таблице маршрутизации, а по списку ERO. В
нашем случае лучший маршрут IGP и ERO совпадают, поэтому пакет посылается на R2.
4) R2, получив RSVP Path, проверяет наличие требуемых ресурсов и, если они есть, выделяет метку MPLS для FEC
6.6.6.6/32. Старый пакет Path уничтожается и создаётся новый, причём объект ERO меняется — из него удаляется
сам R2. Делается это для того, чтобы следующий узел не пытался вернуть пакет на R2. То есть новый ERO
выглядит уже так: (R5, R6). В соответствии с ним R2 отправляет обновлённый Path на R5.
5) R5 совершает аналогичные операции: проверяет ресурсы, выделяет метку, удаляет себя из ERO, пересоздаёт
пакет Path и передаёт в интерфейс, через который ему известен следующий объект ERO — R6.
6) R6, получив пакет, понимает, что он виновник всей суматохи. Он уничтожает Path, выделяет метку для FEC
6.6.6.6 и вставляет её как объект Label в ответное сообщение Resv.
Заметьте, до этого шага метки только выделялись, но не распространялись, теперь же они начинают
анонсироваться тем LSR, которые их запрашивали.
7) Сообщение RESV продвигается к R1 (Ingress LSR), оставляя за собой растущий хвост LSP. Resv должно пройти
через те же узлы, что Path, но в обратном порядке.
8) В конце концов LSP от R1 до 6.6.6.6 сформирован. Данные по нему могут передаваться только от R1 к R6. Чтобы
позволить передачу данных в обратном направлении, нужно создать туннельный интерфейс на R6 с адресом
назначения 1.1.1.1 — все действия будут точно такими же.
Возникает вопрос — почему адресат пакета Path 6.6.6.6, если передаётся он узел за узлом и их адреса известны?
Вопрос этот не праздный — он ведёт нас к одной важной особенности. Объект ERO может на самом деле
содержать не все узлы от Ingress LSR до Egress LSR — некоторые могут быть опущены. Поэтому каждый LSR
должен знать, куда в итоге направляется сообщение. И происходить это может не потому что Ingress LSR лень
просчитать весь путь.
Проблема в зонах IGP. Вы знаете, что и в OSPF и в ISIS существует это понятие для того, чтобы упростить
маршрутизацию. В больших сетях (сотни и тысячи узлов) встаёт проблема широковещательных рассылок
служебных пакетов и просчёт огромного количества комбинация алгоритмом SPF. Поэтому один глобальный
домен делится на зоны маршрутизации.
И вся загвоздка в том, что если внутри зоны IGP и является протоколом по состоянию связи (link-state), то между
ними — он самый настоящий дистанционно-векторный — топология сети строится только внутри зоны, любые
внутренние маршрутизаторы не знают, как устроены другие зоны — они только поставлены в известность, что
для того, чтобы попасть в ту или иную сеть, им нужно отправлять пакеты на конкретный ABR.
Иными словами, если у вас сеть поделена на зоны, то с MPLS TE возникают затруднения — CSPF не может
просчитать весь путь, потому что в его топологии адресат из другой зоны — это облако, а не конкретный узел.
И тут на помощь приходит Explicit Path (не путать с объектом ERO). Это самый, что ни на есть, прямой способ
управления путём построения LSP — администратор может самостоятельно и явно задать те узлы, через которые
нужно проложить LSP. Ingress LSR должен точно следовать таким указаниям. Это вносит в жизнь алгоритма CSPF
ещё немного разнообразия.
Как Explicit Path помогает пробить зону? Давайте на примере.
Когда этот Explicit Path мы скармливаем CSPF, он строит тот кусок, который может, то есть в пределах Area 0: от
R1 до R3.
То, что он насчитал, заносится в ERO, плюс в него добавляются и ещё один узел из Explicit-path — R5. Получается:
R1, R2, R3. Path отправляется по сети согласно ERO, доходит до R3. Тот видит, что он в общем-то не адресат, а
только перевалочный пункт, берёт заданные условия по требуемым ресурсам и адрес узла-получателя из Explicit-
path и запускает CSPF. Последний выдаёт полный список узлов до адресата (R3, R4, R5), который преобразуется в
ERO, и дальше всё происходит по стандартному сценарию.
То есть в случае нахождения Ingress LSR и Egress LSR в разных зонах вычисление пути выполняется отдельно для
каждой зоны, а контрольной точкой является ABR.
Следует понимать, что Explicit Path используется не только для этого случая, но это вообще удобный инструмент,
ведь вы можете явно указать, как нужно проложить LSP или наоборот, через какие узлы не надо прокладывать
LSP.
Этого и много другого мы коснёмся детально в выпуске, посвящённом MPLS TE.
Меня могут упрекнуть в лукавстве, сказав, что не настолько уж и обязателен Link-State IGP. Ну вот хочется на
моноцисочной сети запустить EIGRP, сил нет. Или вообще некрофильные позывы заставляют откопать RIP. И что
теперь? Отказаться от TE?
В общем есть спасение, но только на оборудовании Cisco — называется оно Verbatim.
Ведь для чего нам нужен Link-State протокол? Он собирает информацию о топологии TE, а CSPF строит путь от
Ingress LSR до Egress LSR. Таак. Отлично. А что если мы возьмём и состряпаем Explicit Path, где перечислим все
узлы один за другим? Ведь тогда не надо ничего считать.
На самом деле, как бы подробно вы ни составили явный путь, он всё равно будет передан CSPF.
Но такое поведение можно отключить. Как раз для случаев, описанных выше.
Поможет такая команда:
То ест данный путь будет взят как заведомо верный безо всяких проверок и пересчётов CSPF.
Такой сценарий стоит под большим вопросом, а его плюсы весьма призрачны. Однако возможность есть, и не
говорите потом, что я вам про неё не рассказал.
Практика RSVP TE
Команда mpls ip была нам нужна для работы LDP. Теперь в ней больше нет нужды — удаляем её и начинаем
с чистого листа.
Теперь нам понадобится mpls traffic-eng tunnels. Она глобально включает поддержку TE-туннелей и собственно
RSVP TE:
R1(config)#router isis
Как видите передаётся информация о LSR-ID, расширенная информация о соседях (которые поддерживают TE),
расширенная информация о интерфейсах.
Туннельные интерфейсы — вещь очень универсальная на маршрутизаторах. Они могут использоваться для L2TP,
GRE, IPIP и, как видите, для MPLS TE.
ip unnumbered Loopback0 означает, что отправной точкой туннеля должен быть адрес интерфейса Loopback0.
tunnel destination 6.6.6.6 — универсальная для туннельных интерфейсов команда, определяет точку
терминации, окончания туннеля.
tunnel mode mpls traffic-eng — задаёт тип. Именно здесь и определяется алгоритм работы туннеля, как его
строить.
tunnel mpls traffic-eng path-option 10 dynamic — эта команда позволяет CSPF построить путь динамически, без
задания промежуточных узлов.
Обратите внимание, что R6 присвоил метку 0 — Expliсit Null. Вообще это нормальная ситуация — делается это
для того, чтобы метка MPLS между R5 и R6 была (для обработки пакета согласно значению в поле EXP,
например), но R6 сразу же понял, что метку 0 надо сбрасывать и обрабатывать то, что под ней, а не производил
поиск в таблице меток.
Проблема в том, что в пакете меток может быть больше одной (например, для VPN), но согласно RFC 3032 (да и
мы раньше об этом говорили) R5 должен удалить весь стек меток, сколько бы их ни было, и передать пакет с
одной меткой 0. При этом, конечно, всё сломается.
На самом деле, требование того, чтобы метка 0 была единственной в стеке, выглядит неоправданным —
применений этому нет. Поэтому в RFC 4182 это ограничение убрали. Теперь метка 0 может быть не единственной
в стеке.
Интересная особенность — PHP. Несмотря на то, что для этого есть специальная метка — 3 — LSR совершит PHP
даже при получении метки 0. Подробнее у того же Пепельняка.
Explicit Path
Давайте теперь попробуем поменять путь — трафик должен пройти через R1-R3-R4-R5-R6.
Проще простого: нужно всего-лишь настроить explicit-path:
Заметьте, что приоритет мы ему поставили выше, чем предыдущему правилу — 5 против 10. То есть сначала
будет использоваться explicit-path, а если с ним какие-то проблемы, тогда R1 попытается построить LSP
динамически (уж как-нибудь).
interface Tunnel1
ip unnumbered Loopback0
no routing dynamic
ВиО
В1: Чем отличаются RSVP TE LSP и LDP LSP?
Строго говоря, с точки зрения как вышестоящиех протоколов, так и самого MPLS таких понятий нет вообще. LSP —
он и есть LSP — это просто путь коммутации меток.
Можно выделить термин CR-LSP (ConstRaint-based LSP) — он строится RSVP TE. В этом плане разница в том, что
CR-LSP удовлетворяет условиям заданным в туннельном интерфейсе.
В2: Как соотносятся Explicit Path и ERO?
Если для туннеля задан Explicit Path, то RSVP формирует ERO, учитывая требования Explicit Path. При этом даже
если вы в Explicit-Path пропишите каждый узел до Egress LSR, RSVP всё равно загонит данные в CSPF.
В3: Если один из промежуточных узлов не будет поддерживать LDP (RSVP TE) или протокол будет выключен на
интерфейсе/платформе, будет ли построен LSP так, например, чтобы на этом узле он переходил в IP, а потом на
следующем снова в MPLS?
В случае RSVP TE Ingress LSR не будет иметь данного узла в TED и не сможет выстроить путь до Egress LSR,
соответственно не пошлёт Path, соответственно, не будет и меток и LSP.
Трафик через туннель передаваться не сможет.
Если же речь о LDP, то ситуация интереснее. Например, если на R2 выключить LDP на интерфейсе FE0/0 (в
сторону R5), то
1) на R1 будет метка для FEC 6.6.6.6/32. Причём их будет 2: одна через R2, другая — через R3, поскольку согласно
таблице маршрутизации лучший — через R2, то и LSP будет лежать в сторону R2.
2) на R2 метка будет, но только одна — в сторону 1.1.1.1. Это не лучший путь, поэтому он не будет использован.
То есть здесь LSP от R1 к FEC 6.6.6.6/32 прекращает своё существование.
3) на R5 метка для FEC 6.6.6.6/32 будет
То есть, вроде бы, мы получаем разорванный LSP: {R1-R2, R5-R6}. Но на самом деле, это не так. LSP на то и Label
Switched, чтобы на протяжении всего пути на нём менялись метки, а у нас получается от R1 до R2 MPLS, от R2 до
R5 IP, а от R5 до R6 опять MPLS. LSP для FEC 6.6.6.6/32 здесь нет. Обычный трафик тут пройдёт, в принципе, но
если говорить о каких-то применениях MPLS, таких, например, как VPN, то это работать не будет.
В4: Хорошо, зачем нужен MPLS будет понятно из следующих статей — пока это вообще какая-то искусственная
ерунда, чтобы усложнить жизнь инженера, но зачем мне MPLS TE-то? Ведь трафик можно направить нужным мне
путём с помощью метрик IGP.
Начнём с того, что это тема будущих выпусков. Но…
Вообще говоря, если вы хотите определять путь, по которому пойдёт трафик, то это действительно можно
сделать путём хитрой настройки стоимости линков, интерфейсов итд. Но обслуживание такой системы доставит
вам те ещё хлопоты с одной стороны, а с другой у вас всё равно не получится направить два разных потока
разными путями. То есть если стоит задача разгрузить сеть путём распределения трафика, то с помощью метрик
вы просто перенесёте проблему с одного плеча на другое.
А вот если у вас будет несколько разных LSP и вы сможете направить в них трафик, то это пожалуйста. Хотя в
плане простоты поддержки TE тоже вызывает вопросы.
Ну и вообще подумайте, если вам нужны для двух клиентов гарантированные каналы 40 Мб/с и 50 Мб/с
соответственно, как вы будете отслеживать утилизацию линий? Ну хорошо, один раз вы вычислили и настроили
каким-то чудесным образом маршрутизацию и QoS так, чтобы обеспечить нужный уровень услуги, но вдруг у вас
срезают в трёх местах 3 километра оптики разом и вы неделю не можете починить. И у вас даже есть три
резервных канала по 50Мб/с, но трафик обоих клиентов попёр в одно место, наплевав на все ваши
формальные SLA.
В5: Так чем всё-таки отличаются метки Explicit Null и Implicit Null? Нужно ли мне о них действительно знать?
Нужно. Первоначально предполагается, что по сети MPLS пакет всегда коммутируется по меткам от первого до
последнего LSR. А на последнем пролёте метка будет «0», чтоб Egress LSR сразу знал, что её нужно снять. Эта
метка позволяет не потерять приоритет, заданный в поле TC заголовка MPLS, который копируется по мере
передачи пакета по сети. В итоге даже последний маршрутизатор обработает данные в правильных очередях.
В концепции с использованием метки «3» решили отказаться от лишних действий на Egress LSR. Если вас не
волнует QoS (или вы скопировали приоритет, например, в поле DSCP), то острой нужды в транспортной метке на
последнем пролёте нет — главное отправить в правильный интерфейс, а там Egress LSR разберётся. Если там был
чистый IP-пакет — отдать его процессу IP, если был какой-нибудь E1, передать поток в нужный интерфейс, если
стек меток, то сделать lookup в LFIB и посмотреть, какие дальнейшие действия нужно предпринять.
В6: Для одного FEC LSR всегда будет выделять одну и ту же метку всем своим соседям?
Существует понятие пространства меток:
• пространство меток интерфейса
• пространство меток слота
Важно понимать, что технология MPLS никак не регламентирует протокол распространения меток, но конечные
результаты на конкретной сети вполне могут различаться при использовании разных протоколов. Вышестоящие
протоколы и приложения используют LSP безотносительно того, кем и как они построены.
Кстати нередко в современных сетях встречается сценарий LDP over TE. В этом случае RSVP-TE используется для
организации транспорта и реализации Traffic Engineering, а LDP для обмена метками VPN, например.
Ingress LSR, записывая в заголовок MPLS первую метку, определяет весь путь пакета. Промежуточные
маршрутизаторы просто меняют одну метку на другую. Содержимое может быть совершенно любым. Как раз вот
эта мультипротокольность позволяет MPLS служить основой для разнообразных сервисов VPN.
Полезные ссылки
• Замечательнейший документ для тех, кто в общих чертах представляет, что такое MPLS: MPLS for
Dummies.
• Набор русских переводов RFC, весьма не плох:
o Введение в MPLS, TE и QoS
o Архитектура MPLS
o Кодирование меток в MPLS
o LDP
o RSVP-TE
• Отчаянно рекомендую к чтению все публикации Джефа Дойла. Я искренне завидую его способности
настолько просто даже на английском языке объяснять сложные вещи.
o Understanding the Role of FECs in MPLS
o Understanding MPLS Label Stacking
o Understanding Signaling in MPLS Networks
o Understanding MPLS Label Distribution
o Understanding MPLS Explicit and Implicit Null Labels
o Understanding MPLS CSPF
Но до сих пор только призрачно прорисовывается применение его в реальной жизни. И это плохо.
Этой статьёй начнём исправлять ситуацию. Вообще же читателя ждёт череда из трёх статей: L3VPN, L2VPN, Traffic
Engineering, где мы постараемся в полной мере рассказать, для чего нужен MPLS на практике.
Содержание выпуска
Итак, linkmeup — уже больше не аутсорсинг по поддержке хоть и крупной, но единственной компании, мы —
провайдер. Можно даже сказать федеральный провайдер, потому что наша оптика ведёт во все концы страны. И
наши многочисленные клиенты хотят уже не только высокоскоростной доступ в Интернет, они хотят VPN.
Сегодня разберёмся, что придётся сделать на нашей сети (на которой уже меж тем настроен MPLS), чтобы
удовлетворить эти необузданные аппетиты.
Традиционное видео:
Как организовать взаимодействие двух отдалённых узлов в сети Интернет? Очень просто, если они имеют
публичные адреса — IP для этого и был придуман. Они могут общаться напрямую. В любом случае, чтобы
соединить две точки в Интернете, нужно два публичных адреса — по одному с каждой стороны. А если у нас
адреса частные (10/8, 172.16/20, 192.168/16)?
Тогда они будут «натиться» с одной стороны, а потом «разначиваться» с другой стороны. А NAT — штука, скажу я
вам, ой, какая неприятная.
Поэтому существует VPN. Virtual Private Network — это набор технологий и протоколов, который позволяет
подключить что-то к вашей частной сети через чужую сеть, в частности, через Интернет.
Например, Томский филиал компании linkmeup можно подключить к головному офису в Москве с помощью VPN
через Интернет, как мы и делали в выпуске про VPN.
То есть другие филиалы через VPN вы будете видеть так, как если бы они находились в соседней комнате и
подключены вы к ним через шнурок, коммутатор или маршрутизатор. Соответственно и общаться узлы могут по
своим приватным адресам, а не по публичным.
В этом случае ваши личные данные с частными адресами упаковываются в пакеты с публичными адресами и как
в туннеле летят через Интернет.
Это называется клиентский VPN, потому что клиент сам озабочен его конфигурацией и поднятием.
Единственный его посредник — Интернет.
Его мы разобрали в 7-м выпуске и о нём же в блоге linkmeup есть огромная статья нашего читателя — Вадима
Семёнова.
Другой возможный вариант — провайдерский VPN. В этом случае провайдер предоставляет клиенту несколько
точек подключения, а внутри своей сети строит каналы между ними.
От клиента тогда требуется только оплачивать провайдеру этот канал.
Провайдерский VPN, в отличие от клиентского позволяет обеспечить определённое качество услуг. Обычно при
заключении договора подписывается SLA, где оговариваются уровень задержки, джиттера, процент потерь
пакетов, максимальный период недоступности сервисов итд. И если в клиентском VPN вы можете только уповать
на то, что в интернете сейчас всё спокойно, и ваши данные дойдут в полном порядке, то в провайдерском, вам
есть с кого спросить.
VRF — он строго локален для маршрутизатора — за его пределами VRF не существует. Соответственно VRF на
одном маршрутизаторе никак не связан с VRF на другом.
Раз уж мы рассматриваем все примеры на оборудовании Cisco, то будем придерживаться их терминологии.
VRF Lite
Так называется создание провайдерского VPN без MPLS.
Вот, например, так можно настроить VPN в пределах одного маршрутизатора:
Интерфейсы FE0/0 и FE0/1 принадлежат VPN C3PO Electronic, интерфейсы FE1/0 и FE1/1 — VPN TAR's Robotics.
Внутри одного VPN узлы общаются без проблем, между собой — уже никак.
Вот так выглядят их таблицы маршрутизации на провайдерском маршрутизаторе:
То есть R1 и R2 будут общаться друг с другом через одну пару интерфейсов в глобальной таблице
маршрутизации, через другую пару в VRF TARS' Robotics и через третью в VRF C3PO Electronic. Разумеется, это
могут быть сабинтерфейсы.
Аналогично между R2-R3.
Таким образом, получаются две виртуальные сети, которые друг с другом не пересекаются. Учитывая этот факт, в
каждой такой сети нужно поднимать свой процесс IGP, чтобы обеспечить связность.
В данном случае будет один процесс для физического маршрутизатора, один для TARS' Robotics, один для C3PO
Electric. Соответственно, каждый из них будет сигнализироваться отдельно от других по своим собственным
интерфейсам.
Если говорить о передаче данных, то пакет, придя от узла из сети TARS's Robotics, сразу попадает в
соответствующий VRF, потому что входной интерфейс R1 является его членом. Согласно FIB данного VRF он
направляется на R2 через выходной интерфейс. На участке между R1 и R2 ходят самые обычные IP-пакеты,
которые и не подозревают, что они принадлежат разным VPN. Вся разница только в том, что они идут по разным
физическим интерфейсам, либо несут разный тег в заголовке 802.1q. R2 принимает этот пакет интерфейсом,
который также член VRF TARS's Robotics.
R2 варит пакет в нужном FIB и отправляет дальше, согласно IGP. И так до самого выхода пакета ну другой стороне
сети.
Как узел определяет, что полученный пакет относится к определённому VPN? Очень просто: данный интерфейс
привязан («прибинден») к конкретному VRF.
Как вы уже, вероятно, заметили, эти интерфейсы помечены на иллюстрации колечками соответствующего цвета.
Точно также выходные интерфейсы привязаны к VPN, и соответствующие таблицы маршрутизации знают, какие
за ними сети находятся.
Учитывайте, что всё, что мы говорим о таблицах маршрутизации, касается и FIB — в каждом VPN свой
собственный FIB.
Между маршрутизаторами пакеты не окрашены. Пакеты разных VPN не смешиваются, потому что идут либо по
разных физическим интерфейсам, либо по одному, но имеют разные VLAN-теги (каждому VRF соответствует свой
выходной саб-интерфейс).
Вот он простой и прозрачный VPN — для клиента сформирована самая что ни на есть частная сеть.
Но этот способ удобен, пока у вас 2-3 клиента и 2-3 маршрутизатора. Он совершенно не поддаётся
масштабированию, потому что один новый VPN означает новый VRF на каждом узле, новые интерфейсы, новый
пул линковых IP-адресов, новый процесс IGP/BGP.
А если точек подключения не 2-3, а 10, а если нужно ещё резервирование, а каково это поднимать IGP с
клиентом и обслуживать его маршруты на каждом своём узле?
MPLS L3VPN
MPLS VPN позволяет избавиться от вот этих неприятных шагов:
1) Настройка VRF на каждом узле между точками подключения
2) Настройка отдельных интерфейсов для каждого VRF на каждом узле.
3) Настройка отдельных процессов IGP для каждого VRF на каждом узле.
4) Необходимость поддержки таблицы маршрутизации для каждого VRF на каждом узле.
Да как так-то?
Вообще говоря, TARS Robotics как заказчику, совершенно без разницы, как мы организуем L3VPN — да пусть мы
хоть на поезде возим их пакеты, лишь бы в SLA укладывались. Но в рамках данной статьи, конечно, внутри нашей
сети работает MPLS.
Вот какой подход предлагает MPLS VPN: коммутация в пределах магистральной сети осуществляется, как мы
описывали в предыдущей статье, по одной метке MPLS, а принадлежность конкретному VPN определяется
другой — дополнительной меткой.
Подробнее:
На диаграмме железо-углерод видно, как преображается пакет по ходу движения от ПК1 до ПК2:
Помните, чем хорош MPLS? Тем, что никому нет дела до того, что находится под меткой. Поэтому в пределах
магистральной сети не важно, какие адресные пространства у клиента, то есть, какой IP-пакет кроется под
заголовком MPLS.
Поскольку пакет коммутируется по меткам, а не маршрутизируется по IP-адресам — нет нужды поддерживать и
таблицу маршрутизации VPN на промежуточных узлах.
То есть у нас получается такой удобный MPLS-туннель, который сигнализируется, как вы увидите дальше,
автоматически.
Итак, в промежутке между R1 и R3 (то есть в облаке MPLS) ни у кого нет понимания, что такое VPN – пакеты VPN
движутся по метками до пункта назначения, и только он уже должен волноваться, что с ними делать дальше. Это
убирает необходимость поднимать VRF на каждом узле и, соответственно, поддерживать таблицу
маршрутизации, FIB, список интерфейсов итд.
Учитывая, что весь дальнейший путь пакета определяется на первом MPLS-маршрутизаторе (R1), отпадает нужда
и в индивидуальном протоколе маршрутизации в каждом VPN, хотя остаётся вопрос, как найти выходной
маршрутизатор, на который мы ответим дальше.
Чтобы лучше понять, как передаётся трафик, нужно выяснить значение меток в пакете.
Роль меток MPLS
Если мы вернёмся к изначальной схеме с VRF-Lite, то проблема в том, что серый цвет IP-пакета (индикатор
принадлежности к VPN TARS' Robotics) существует только в пределах узла, при передаче его на другой эта
информация переносится в тегах VLAN. И если мы откажемся от сабинтерфейсов на промежуточных узлах,
начнётся каша. А сделать это нужно во благо всего хорошего.
Чтобы этого не произошло в сценарии с MPLS, Ingress LSR на пакет навешивает специальную метку MPLS —
Сервисную — она идентификатор VPN. Egress LSR (последний маршрутизатор — R3) по этой метке понимает, что
IP-пакет принадлежит VPN TARS's Robotics и просматривает соответствующий FIB.
То есть очень похоже на VLAN, с той разницей, что только первый маршрутизатор должен об этом заботиться.
Но на основе сервисной метки пакет не может коммутироваться по MPLS-сети — если мы где-то её поменяем, то
Egress LSR не сможет распознать, какому VPN она принадлежит.
И тут на выручку приходит стек меток, который мы так тщательно избегали в прошлом выпуске.
Сервисная метка оказывается внутренней — первой в стеке, а сверху на неё ещё навешивается транспортная.
То есть по сети MPLS пакет путешествует с двумя метками — верхней — транспортной и нижней — сервисной).
Для чего нужно две метки, почему нельзя обойтись одной сервисной? Пусть бы, например, одна метка на Ingress
LSR задавал один VPN, другая — другой. Соответственно дальше по пути они бы тоже коммутировались как
обычно, и Egress LSR точно знал бы какому VRF нужно передать пакет.
Вообще говоря, сделать так можно было бы, и это бы работало, но тогда в магистральной сети для каждого VPN
был бы отдельный LSP. И если, например, у вас идёт пучок в 20 VPN с R1 на R3, то пришлось бы создавать 20 LSP.
А это сложнее поддерживать, это перерасход меток, это лишняя нагрузка на транзитные LSR. Да и, строго говоря,
это то, от чего мы тут пытаемся уйти.
Кроме того, для разных префиксов одного VPN могут быть разные метки — это ещё значительно увеличивает
количество LSP.
Куда ведь проще создать один LSP, который будет туннелировать сразу все 20 VPN?
Транспортная метка
Таким образом, нам необходима транспортная метка. Она верхняя в стеке.
Сервисная метка
Нижняя метка в стеке — сервисная. Она является уникальным идентификатором префикса в конкретном VPN.
Она добавляется Ingress LSR и больше не меняется нигде до самого Egress LSR, который в итоге её снимает.
FEC для Сервисной метки — это префикс в VPN, или, грубо говоря, подсеть назначения изначального пакета. В
примере ниже FEC – 192.168.1.0/24 для VRF C3PO и 172.16.1.0/24 для VRF TARS.
То есть Ingress LSR должен знать, какая метка выделена для этого VPN. Как это происходит — предмет
дальнейших наших с вами исследований.
Вот так выглядит целиком процесс передачи пакетов в различных VPN'ах:
Обратите внимание, что для двух разных VPN отличаются сервисные метки – по ним выходной маршрутизатор
узнаёт, в какой VRF передавать пакет.
А транспортные в данном случае одинаковые для пакетов обоих VRF, потому что они используют один LSP –
R1↔R2↔R3.
Терминология
Пока мы не ушли слишком далеко, надо ввести терминологию.
Когда речь заходит о MPLS VPN, появляется несколько новых терминов, которые, впрочем, вполне очевидны:
CE — Customer Edge router — граничный маршрутизатор клиента, который подключен в сеть провайдера.
PE — Provider Edge router — граничный маршрутизатор провайдера. Собственно к нему и подключаются CE. На
PE зарождается VPN, на нём они и кончаются. Именно на нём расположены интерфейсы, привязанные к VPN.
Именно PE назначает и снимает сервисные метки. Именно PE являются Ingress LSR и Egress LSR.
PE должны знать таблицы маршрутизации каждого VPN, ведь это они принимают решение о том, куда посылать
пакет, как в пределах провайдерской сети, так и в плане клиентских интерфейсов.
P — Provider router — транзитный маршрутизатор, который не является точкой подключения — пакеты VPN
проходят через него без каких-либо дополнительных обработок, иными словами просто коммутируются по
транспортной метке. P нет нужды знать таблицы маршрутизации VPN или сервисные метки. На P нет
интерфейсов привязанных к VPN.
На самом деле роль P-PE индивидуальна для VPN. Если в одном VPN R1 и R3 — это PE, а R2 — P, то в другом они
могут поменять свои роли.
Вот, например, на схеме ниже роли синих маршрутизаторов отличаются для зелёного клиента и для
фиолетового:
Стек меток — набор MPLS заголовков, навешанных на один пакет. Каждый из них выполняет какую-то свою роль.
В нашей реальности мало кто из вендоров поддерживает больше шести меток в стеке.
В целом мы закончили с тем, как передаются данные, то есть как работает Forwading Plane.
Давайте подытожим:
Маршрутизатор PE навешивает на клиентский трафик две метки — внутреннюю сервисную, которая не меняется
до самого конца путешествия и по ней последний PE понимает, какому VRF принадлежит пакет, и внешнюю
транспортную, по которой пакет передаётся через сеть провайдера — эта метка меняется на каждом P-
маршрутизаторе и снимается на последнем PE или предпоследнем P.
Благодаря наличию сервисной метки и VRF трафик различных VPN изолирован друг от друга как в пределах
маршрутизаторов, так и в каналах.
Протоколы маршрутизации
Итак, мы имеем два типа сетей и стыки между ними:
• Клиентская IP-сеть;
• Магистральная сеть провайдера с запущенным на ней MPLS.
Граница этих сетей находится на PE. То есть одной своей половиной он уже клиентский, а другой —
провайдерский. Не зря бытует народная мудрость: Как PE ни настраивай, он всё равно на клиентов смотрит.
MPLS настраивается только на магистральных интерфейсах.
Напоминаю, речь о L3VPN. А тут нужно заботиться о IP-связности. Причём теперь у нас куча ограничений.
Разберёмся, какие протоколы на каких участках нам пригодятся.
Во-первых, нужно обеспечить базовую IP-связность внутри магистральной сети провайдера. Чтобы были
известны все Loopback-адреса, линковые сети, служебные префиксы, возможно, какие-то выходы вовне.
Для этого запускается IGP (ISIS, OSPF).
Уже поверх связной сети поднимается MPLS.
Так мы обеспечили работоспособность магистральной сети.
Во-вторых, у клиента в филиалах может стоять не по одному маршрутизатору, а какие-никакие сети. Эти сети
тоже надо маршрутизировать внутри себя как минимум.
Очевидно, что внутри своей собственной сети клиент волен распространять маршрутную информацию, как ему
угодно. Мы как провайдер на это повлиять не можем, да нам и без разницы.
Так обеспечивается передача маршрутов в пределах сетей клиентов.
В-третьих, клиенту нужно как-то сообщать своим маршруты провайдеру. На стыке CE-PE клиенту и провайдеру
уже нужно договариваться о том, какой протокол будет использоваться.
Хотя, едва ли у клиента какой-то свой самописный протокол IGP. Наверняка, это OSPF/ISIS/RIP. Поэтому обычно
провайдер идёт навстречу и выбирает тот, который удобен клиенту.
Тут надо понимать, что вот этот протокол взаимодействия с клиентом работает в VPN и никак не пересекается с
IGP самого провайдера. Это разные независимые процессы.
Зачастую на этом стыке работает BGP, поскольку позволяет гибко фильтровать префиксы по различным
атрибутам.
Так провайдер получает маршруты клиентов.
До сих пор всё было понятно.
В-четвёртых, и это самое интересное — осталось передать маршруты одного филиала другому через
магистральную сеть. При этом их надо по пути не потерять, не перепутать с чужими, доставить в целости и
сохранности. Тут нам поможет расширение протокола BGP — MBGP — Multiprotocol BGP (Часто его называют
MP-BGP). О нём мы сейчас и поговорим.
Итак, аэропорт Магадана — это PE/Ingress LSR, аэропорт Шэньчжэня — это другой PE/Egress LSR, аэропорт
Москвы — P/Intermediate LSR.
Особенно интересно будет выглядеть PHP в этой фантазии.
MBGP
Сейчас ответим на два вопроса: как маршруты передаются в провайдерской сети от одного PE к другому и как
обеспечивается изоляция.
В общем-то до сих пор не придумано ничего лучше для передачи маршрутов на удалённые узлы, чем BGP: и
гибкость передачи самих маршрутов, и масса инструментов по влиянию на выбор маршрута, и политики
получения и передачи маршрутов, и Community, сильно упрощающие групповые действия над маршрутами.
К его помощи и прибегают при реализации MPLS L3VPN. Поэтому его второе имя MPLS BGP VPN.
Вы ведь помните, как это происходит? BGP устанавливает сессию со своими соседями через TCP на порт 179. Это
позволяет в качестве соседей выбирать не напрямую подключенный маршрутизатор, а те, что находятся в
нескольких хопах. Так и работает IBGP, где в пределах магистральной сети предполагается связь «каждый с
каждым».
Когда несколько маршрутов, ведущих в одну сеть, приходят на узел, BGP просто выбирает из них лучший и
инсталлирует его в таблицу маршрутизации.
То есть в целом нам ничего не стоит передать маршрут VPN через сеть на другой её конец.
BGP должен взять маршруты из VRF на одном узле, доставить их на другой и там экспортировать в правильный
VRF.
Вот только загвоздка в том, что BGP изначально ориентирован на работу с публичными адресами, которые
предполагаются уникальными во всём мире. А клиенты-негодяи обычно хотят передавать маршруты в частные
сети (RFC1918) и, как назло, они запросто могут пересекаться как с сетями других VPN, так и со внутренним
адресным пространством самого провайдера.
То есть, если, например, R3 получит два маршрута в сеть 10.10.10.10/32 (один от TARS's Robotics, другой от C3PO
Electronic), он выберет только один — с лучшими показателями, как предписывает стандарт — он думает, что это
два маршрута в одну и ту же сеть.
Естественно, нам это не подходит. Нужно, чтобы выполнялось два условия:
1) Маршруты разных VPN были уникальными и не смешивались при передаче между PE.
2) Маршруты в конечной точке должны быть переданы правильному VRF.
Этим проблемам было найдено элегантное решение. Начнём с п.1 — уникальность маршрутов.
В нашем примере 10.10.10.10/32 от TARS's Robotics должен чем-то отличаться от 10.10.10.10/32 от C3PO
Electronic.
BGP невероятно гибкий протокол (не зря ведь он стал единственным протоколом внешнего шлюза). Он легко
масштабируется и с помощью так называемых Address Family он может передавать маршруты не только IPv4, но
и IPv6 и IPX (да только кому он нужен). Хочешь передать что-то новое — заведи свою Address Family,
И создал IETF новый Address Family. И дал он имя ему VPNv4 (или VPN-IPv4).
Route Distinguisher
Для того, чтобы различать маршруты различных VPN, обычный IPv4 префикс дополняется специальной
приставкой длиной 8 байтов — RD — Route Distinguisher.
Тогда маршрут от C3PO будет выглядеть так: 64500:100:10.10.10.10/32, а от TARS так: 64500:200:10.10.10.10/32. И
теперь это совершенно разные вещи, которые процесс BGP сможет друг от друга отличить.
Навеяно.
0:64500:100:10.10.10.10/32
или
1:100.0.0.1:100:10.10.10.10/32.
Какой выберете вы, не имеет значения, даже если в пределах сети вы будете использовать оба подхода
одновременно. Даже для одного VRF на разных маршрутизаторах. Главная задача RD — разделить префиксы.
То есть если совсем простым языком: совершенно не важно, что вы настроите, главное, чтобы вы были уверены,
что BGP никогда не спутает маршруты разных VPN.
Хотя систематизация ещё никому не мешала.
Обычно используют тип 0, Административное поле — это номер AS провайдера, а Выделенный номер вы
выбираете самостоятельно. При настройке RD первые «0:» или «1:» (тип RD) сокращаются и получается
так: 64500:100 и 100.0.0.1:100.
Cisco позволяет использовать типы 0 и 1.
Да, RD придётся настроить вручную и самому следить за его уникальностью. Но по-другому тут и не получится —
сами маршрутизаторы не умеют отслеживать, есть ли на других узлах уже такой RD или нет. А если и есть, то не
тот же ли самый это VPN?
1) Приходит от CE анонс новой сети. Пусть это будет 10.10.10.10/32, как мы и договаривались. PE добавляет этот
маршрут в таблицу маршрутизации конкретного VRF. Заметьте, что в таблице маршрутизации хранится обычный
IPv4 маршрут — никаких VPNv4. А это и не нужно: VRF изолированы друг от друга, как мы уже говорили раньше
— это отдельный, пусть и виртуальный маршрутизатор.
2) BGP заметил, что появился новый префикс в VPN. Из конфигурации VRF он видит какой RD нужно использовать.
Компилирует из RD и нового IPv4-префикса, VPNv4-префикс. Получается так:
C3PO: 64500:100:10.10.10.10/32
или так:
TARS: 64500:200:10.10.10.10/32
3) Создавая BGP Update, маршрутизатор вставляет туда полученный VPNv4-префикс, адрес Next Hop и прочие
атрибуты BGP. Но кроме всего прочего, он добавляет в поле NLRI информацию о метке. Эта метка привязана к
маршруту, или точнее говоря, VPNv4-префикс — это FEC, а в NLRI передаётся связка данного FEC и метки.
По-английски это называется Labeled Route — по-русски, пожалуй, маршрут, снабжённый меткой. Так данный
PE уведомляет своих соседей, что если те получили от CE IP-пакет в эту сеть, ему нужно назначить
такую сервисную метку.
Обратите также внимание на адрес Next Hop — это Loopback PE. И это очень правильно — Ingress PE должен
знать, до какого Egress PE нужно отправить пришедший пакет с данными, то есть знать его Loopback, а дальше
хоть потоп.
4) Дальше BGP Update передаётся всем соседям, настроенным в секции VPNv4 family.
5) Удалённый PE получает этот Update, видит в NLRI, что это не обычный IPv4 маршрут, а VPNv4. Помните, да:
если придёт два маршрута в одну сеть от разных клиентов — они не перепутаются, потому что имеют разные RD.
Далее Egress PE определяет, в какой VRF этот маршрут нужно экспортировать и, собственно, делает это. Так
маршрут появляется в таблице маршрутизации и FIB нужного VRF, а оттуда уходит в сеть клиента.
Теперь, когда PE получает от CE пакет с данными, который следует в сеть 10.10.10.10/32, в FIB этого VPN он
находит сервисную метку (22) и Next-Hop (1.1.1.1). Инкапсулирует IP в MPLS, дальше ищет в уже глобальном FIB
транспортную метку для Next Hop.
Сама транспортная метка как и прежде доставляется протоколами LDP или RSVP-TE, а сервисная — MBGP.
Дело в том, что единственная роль RD — разнообразить жизнь BGP, то есть сделать маршруты уникальными.
Несмотря на то, что он настраивается для VRF, он не является каким-то его уникальными идентификатором и на
всех точках подключения это значение может быть даже разным. Поэтому PE не может определить в какой VRF
засунуть маршрут на основе RD.
Да и это было бы не совсем в традициях BGP — разбирать переданный адрес, анализировать его перед тем, как
куда-то анонсировать. Для этих целей у нас есть политики.
То есть в классическом BGP, пришлось бы вешать политики на экспорт маршрутов в VRF для каждого отдельно. И
мы бы вручную отфильтровывали куда нужно пристроить каждый маршрут.
Один шаг в сторону упрощения — использование community. При отправке маршрута с одного PE на другой
можно устанавливать определённый community — свой для каждого VRF, а на удалённой по этому community
уже настраивать экспорт в соответствующий VRF. Это уже выглядит удобно и убедительно.
В MBGP зашли ещё немного дальше — идею community развили до понятия Route Target. По сути, это то же
community — RT даже передаётся в атрибуте Extended Community, только все политики работают автоматически.
Формат RT, точно такой же, как у обычного Extended Community. Например:
64500:100
То есть он похож на первый тип RD. Отчасти поэтому RD и RT так часто путают.
На одной стороне в VRF настраивается RT на экспорт маршрута — тот RT, с которым он будет путешествовать к
удалённому PE. На другой именно это же значение RT устанавливается на импорт. И наоборот.
Обычно, если задача — просто организовать услугу VPN для одного клиента, то RT на экспорт и на импорт
совпадают на всех точках подключения.
Красиво? Элегантно? Но это ещё не всё. Гибкость BGP и здесь проявляется в очередной раз. С помощью
механизма RT вы можете импортировать маршруты как вам заблагорассудится как в пределах одного VPN, так и
между различными VPN.
2) Допустим, помимо наших двух VPN появился третий — R2D2. У него есть какие-то свои задачи, но ещё они
поддерживают сервера с прошивками для микропроцессоров, шаблонами, дополнительными модулями итд,
которые необходимы C3PO Electronic. При этом он не хочет светить в мир своими серверами, а для клиентов
обеспечить доступ через сеть провайдера.
И тогда с помощью RT можно обеспечить взаимодействие между различными VPN. Для этого в C3PO Electronic
мы настраиваем такой RT на импорт, который в VPN R2D2 был указан на экспорт. И, соответственно, наоборот.
Правда в этом случае нужно следить за тем, не пересекаются ли используемые подсети. Ведь несмотря на все RD
и RT, BGP выберет только один маршрут в каждую подсеть в VRF.
VRF-Lite
Так и пойдём от простого к сложному. Начнём с ситуации, когда один клиент имеет два подключения в один
маршрутизатор:
Linkmeup:
C3PO_1:
Соответственно, они видят всю сеть провайдера и будут видеть сети других клиентов.
Обратите внимание, что после выполнения команды ip vrf forwarding C3PO, IOS удалил IP-адреса с интерфейсов,
теперь их нужно настроить повторно. Это произошло для того, чтобы удалить указанные подсети из глобальной
таблицы маршрутизации.
Linkmeup(config-if)#interface FastEthernet0/1
После повторной настройки адреса эти подсети появятся уже в таблице маршрутизации VRF.
Linkmeup(config-if)#interface FastEthernet1/1
Вот и славно. VRF TARS и C3PO полностью изолированы от сети провайдера и друг от друга:
Теперь растягиваем удовольствие на сеть linkmeup:
* Следует понимать, что VRF — это строго локальное для узла понятие. Вполне можно устанавливать разные
имена VRF на разных маршрутизаторах.
Второй шаг — создать цепочку линковых сетей между всеми узлами и привязать каждую пару интерфейсов к
нужному VRF.
Мы не стали указывать на схеме линковые адреса, чтобы не загромождать её. Для порядка выберем префиксы
10.0/16 для собственно сети провайдера (VLAN1), 192.168/16 для C3PO Electronic (Vlan 2) и 100.0/16 для TARS’
Robotics (Vlan 3).
Linkmeup_R1:
Linkmeup_R1(config)#interface FastEthernet0/0
Linkmeup_R1(config-if)#description To C3PO_Electronic_1
Linkmeup_R1(config)#interface FastEthernet0/1
Linkmeup_R1(config-if)#description To Linkmeup_R2
Linkmeup_R1(config)#interface FastEthernet0/1.2
Linkmeup_R1(config-subif)#description to Linkmeup_R2_vrf_C3PO
Linkmeup_R1(config-subif)#encapsulation dot1Q 2
Linkmeup_R1(config)#interface FastEthernet0/1.3
Linkmeup_R1(config-subif)#description To Linkmeup_R2_in_TARS
Linkmeup_R1(config-subif)#encapsulation dot1Q 3
Linkmeup_R1(config)#interface FastEthernet1/0
Linkmeup_R1(config-if)#description To TARS_1
Linkmeup_R1(config-if)#ip vrf forwarding TARS
Linkmeup_R1(config)#router isis 1
Linkmeup_R1(config-router)#net 10.0000.0000.0001.00
Linkmeup_R1(config)#interface FastEthernet0/1
Но, как и было сказано раньше — это очень инертное решение, поэтому переходим к MPLS BGP VPN.
MPLS L3VPN
Я предлагаю в этот раз не брать уже готовую сеть, где уже всё преднастроено. Сейчас интереснее будет пройти
этот путь с нуля, пусть и только вехами, не вдаваясь в детали.
C3PO_2:
На клиентских узлах настроены линковые адреса с провайдером и интерфейс Loopback (как и прежде, мы
используем этот интерфейс, чтобы имитировать сеть, дабы не плодить маршрутизаторы). То есть если
на C3PO_2 мы увидим сеть 192.168.255.1/32, это значит, что мы увидели бы и всю сеть полностью.
В качестве локального протокола динамической маршрутизации используется OSPF. Собственно, именно он
позволит сообщить адрес Loopback-интерфейса всем заинтересованным.
Linkmeup_R1:
Linkmeup_R1(config)#interface Loopback0
Linkmeup_R1(config-if)#description To Linkmeup_R2
Linkmeup_R2:
Linkmeup_R2(config)#interface Loopback0
Linkmeup_R2(config)#interface FastEthernet0/0
Linkmeup_R2(config-if)#description To Linkmeup_R1
Linkmeup_R2(config)#interface FastEthernet0/1
Linkmeup_R2(config-if)#description To Linkmeup_R3
Linkmeup_R3:
Linkmeup_R3(config)#interface Loopback0
Linkmeup_R3(config)#interface FastEthernet0/0
Linkmeup_R3(config-if)#description To Linkmeup_R2
2) Теперь поднимаем ISIS в качестве IGP — он свяжет всю сеть linkmeup, распространив маршрутную
информацию о линковых и Loopback-адресах.
Linkmeup_R1:
Linkmeup_R1(config)#router isis 1
Linkmeup_R1(config-router)#net 10.0000.0000.0001.00
Linkmeup_R2:
Linkmeup_R2(config)#router isis 1
Linkmeup_R2(config-router)#net 10.0000.0000.0002.00
Linkmeup_R3:
Linkmeup_R3(config)#router isis 1
Linkmeup_R3(config-router)#net 10.0000.0000.0002.00
На этом шаге получили глобальную таблицу маршрутизации — необходимая платформа для следующего шага.
Linkmeup_R1:
Linkmeup_R1(config)#mpls ip
Linkmeup_R1(config-if)#mpls ip
Linkmeup_R2:
Linkmeup_R2(config)#mpls ip
Linkmeup_R2(config-if)#mpls ip
Linkmeup_R2(config)#interface FastEthernet 0/1
Linkmeup_R2(config-if)#mpls ip
Linkmeup_R3:
Linkmeup_R3(config)#mpls ip
Linkmeup_R3(config-if)#mpls ip
Это базис для VPN. Эти LSP — это набор транспортных меток.
Мы выбрали здесь LDP, чтобы не усложнять конфигурацию. С RSVP-TE ещё поразбираемся в статье про Traffic
Engineering.
Linkmeup_R1:
Linkmeup_R1(config-vrf)# rd 64500:100
Linkmeup_R3:
Linkmeup_R3(config-vrf)# rd 64500:100
Это позволяет нам обособить все данные одного клиента от других и от сети самого провайдера.
Здесь же указываем RD и RT. Поскольку задача у нас простая — связать все филиалы C3PO Electronic, то сделаем
RD и RT совпадающими. Причём RT на Import и RT на Export тоже будут одинаковыми. Поскольку это обычная
практика, существует даже специальная директива — both — тогда создаются оба RT сразу одинаковыми.
В 8-м выпуске мы выбрали номер AS для сети linkmeup — 64500. Он и используется в качестве
административного поля.
Выделенный номер выбирается произвольно, но отслеживается, чтобы не было совпадения с другим, уже
использованным.
Linkmeup_R1:
Linkmeup_R1(config)#interface FastEthernet0/0
Linkmeup_R3:
Linkmeup_R3(config)#interface FastEthernet0/1
В таблицах маршрутизации VRF C3PO должны появиться настроенные сети, как Directly connected.
6) Нужно поднять протокол маршрутизации с клиентом. В нашем случае это будет OSPF, хотя с равным успехом
это мог бы быть и ISIS или EBGP. Данный процесс никак не должен пересекаться с глобальной таблицей
маршрутизации, поэтому помещаем его в VRF:
Linkmeup_R1:
Linkmeup_R3:
Как видите, Linkmeup_R1 видит 192.168.255.1, но не видит удалённый Loopback – 192.168.255.2. Аналогично
и Linkmeup_R3 видит только маршруты со своей стороны. Это потому, что через сеть провайдера пока не
передаются маршруты клиента.
Linkmeup_R1:
Linkmeup_R3:
Вторая часть — настройка Address Family VPNv4 — это то, что позволит с Linkmeup_R1 на Linkmeup_R3 передать
клиентские маршруты. Заметьте, что мы активируем передачу community, потому что этот атрибут используется
RT.
Linkmeup_R1:
Третья часть — это Address Family для данного конкретного VRF. Он работает с обычными IPv4 префиксами, но из
VRF C3PO Electronic. Он нужен для того, чтобы передавать маршруты между MBGP и OSPF.
Linkmeup_R1:
Linkmeup_R3:
Linkmeup_R1:
Linkmeup_R1(config)#router ospf 2
Linkmeup_R3:
Linkmeup_R3(config)#router ospf 2
Маршруты на PE:
Маршруты на CE:
Вот и славно.
Linkmeup_R1(config-vrf)#rd 64500:200
Linkmeup_R1(config-if)#description To TARS_1
Здесь указано, что TARS’ Robotics будет анонсировать свою сеть 172.16.255.1/32.
OSPF по-прежнему может быть нужен, но он уже будет использоваться для маршрутизации внутри этого филиала
и только.
На PE всё то же самое, только не будет нового процесс OSPF (потому что с клиентом теперь EBGP, вместо OSPF) и
меняется address family ipv4 vrf TARS:
Linkmeup_R1:
Linkmeup_R1(config-router-af)#redistribute connected
7) Всё, что касается MBGP — то же самое. От того, что мы поменяли протокол взаимодействия с клиентом, в нём
ничего не перевернётся.
То есть уже сейчас всё должно заработать (если, конечно, вторая сторона настроена):
Полная конфигурация всех узлов с комментариями и без.
Что же мы натворили?
Вы видите здесь метку 22 для FEC 192.168.255.1 и адрес Next Hop 1.1.1.1.
Как её понимает маршрутизатор?
В ТМ VRF C3PO он заносит информацию о том, какой Next Hop:
Рекурсивно вычислить, как доступен 1.1.1.1:
Но, как обычно FIB содержит всю актуальную информацию без многократных обращений к ТМ:
FIB говорит нам: упаковать пакет с DIP 192.168.255.1 в стек меток {17, 22} и отправить его в сторону 10.0.23.2 в
интерфейс FE0/0.
Здесь мы поработаем с RT — сделаем так, чтобы маршруты из VPN C3PO передавались в R2D2 протоколом BGP.
Ну, и обратно — куда без этого?
Конфигурация маршрутизатора R2D2:
R2D2(config)#interface Loopback0
R2D2(config)#interface FastEthernet0/0
R2D2(config-if)#description To Linkmeup
R2D2(config)#router ospf 1
Linkmeup_R3(config-vrf)#rd 64500:300
Linkmeup_R3(config-router)#interface FastEthernet1/1
Linkmeup_R3(config-router-af)#redistribute ospf 3
Для интереса вы можете добавить на TARS_2 Loopback 1 с адресом 10.20.22.22/32 — такой же, как у Loopback
0 R2D2 и посмотреть что из этого получится.
Если вдруг, вы не знали, как работает обычная трассировка, то стыд вам я вкратце расскажу.
Вы отправляете получателю пакеты с постепенно увеличивающимся значением TTL. Обычно это UDP, но может
быть и ICMP и даже TCP.
Сначала это 1. Пакет доходит до непосредственно подключенного маршрутизатора, тот уменьшает TTL, видит,
что теперь он равен нулю, формирует сообщение «time exceeded in transit» и посылает его вам обратно. Так по
адресу отправителя вы знаете первый хоп.
Потом это 2. Пакет доходит до второго маршрутизатора. Происходит то же самое, так вы узнали следующий хоп.
Наконец TTL достигает N, узел назначения получает пакет, видит, что это к нему, формирует ответ (в соответствии
с протоколом), по которому вы понимаете, что всё, кончено, и концы в консоль.
Кроме того, можно добавить, что на каждой итерации вы посылаете не один, а несколько пакетов (как правило,
три).
Пока пакет коммутируется по меткам значения каких-бы то ни было полей любых заголовков глубже MPLS не
имеют никакого значения. В том числе и TTL. Маршрутизаторы ориентируются на TTL в заголовке MPLS.
В первом сценарии вы сможете увидеть каждый маршрутизатор на пути к получателю. Результат трассировки
будет таким:
Механика же следующая:
1. На первом шаге ничего не меняется. TARS_1 отправляет ICMP-запрос с TTL=1. R1 его получает, уменьшает
TTL до нуля и отправляет на TARS_1 «time exceeded in transit». Первый хоп (R1) готов.
2. TARS_1 отправляет ICMP-запрос с TTL=2.
1. R1 его получает, уменьшает до 1, навешивает сервисную метку, навешивает транспортную метку,
записывает в поле TTL значение 1, отправляет пакет с метками на R2.
2. R2 его получает, уменьшает TTL до 0. Тут бы ему отправить обратно «time exceeded in transit». Но
не по Сеньке шапка – нет у него ни сервисной метки для этого VPN, ни маршрута до отправителя – он же всего
лишь ничем не примечательный P-маршрутизатор.
3. Таким образом он формирует новый пакет, содержащий «time exceeded in transit». В этом пакете
адрес отправителя принадлежит R2, а адрес получателя – TARS_1.
4. Далее R2 навешивает на него ту же самую сервисную метку, что была и до этого, затем добавляет
транспортную метку в сторону R3 и отправляет его на R3 (опять же можно сказать, что транспортную метку он не
добавляет — PHP). То есть можно сказать, что он аккуратно вскрыл MPLS-мешок, выпотрошил IP-пакет, засунул
на его место что-то новое и отправил дальше.
5. Пакет доходит до R3. Тот его раздевает, обнаруживает, что получатель – TARS_1, чья сеть известна
где-то там за VPN'ом, за R1. Он упаковывает его в MPLS с сервисной и транспортной метками и шлёт назад.
3. TARS_1 отправляет ICMP-запрос с TTL=3. Он доходит до R3, который видит значение MPLS TTL, равное в
данный момент 1, уменьшает его до 0 и возвращает «time exceeded in transit»
4. TARS_1 отправляет ICMP-запрос с TTL=4. R3 уменьшает MPLS TTL до 1, снимает метку, копирует значение
MPLS TTL в IP TTL. А дальше пакет благополучно доходит до TARS_2, тот отправляет ответ об успешном
завершении. Трассировка закончена.
А что, если у меня есть закономерное желание, чтобы клиенты не видели топологию моей сети своими
трассировками? Надо запретить, скажете вы. Как отец двухгодовалой дочки, я вам говорю: не нужно запрещать.
Можно и нужно поступить хитрее – я просто не буду внутри своей сети уменьшать TTL MPLS до нуля.
Для этого используется второй сценарий — установить TTL MPLS в 255. В этом случае при трассировке с TARS_1
вы увидите следующий путь: R1↔R3↔TARS_2.
1. TARS_1 отправляет ICMP-запрос с TTL=1. R1 его получает, уменьшает TTL до нуля и отправляет на
TARS_1 «time exceeded in transit». Первый хоп (R1) готов.
2. TARS_1 отправляет ICMP-запрос с TTL=2.
1. R1 его получает, уменьшает до 1, навешивает сервисную метку, навешивает транспортную метку,
записывает в поле TTL значение 255, отправляет пакет с метками на R2.
2. R2 его получает, уменьшает TTL до 254, меняет транспортную метку (или в данном случае снимает
– POP Label) и отправляет на R3.
3. R3, сняв все метки, видит, что TTL истёк и отправляет «time exceeded in transit» обратно источнику
(естественно, упаковывая в сервисную и транспортную метки)
3. TARS_1 отправляет ICMP-запрос с TTL=3. Он благополучно доходит до TARS_2, тот отправляет успешный
ответ. Трассировка закончена.
И сколько бы ни было транзитных P-маршрутизаторов, TTL=3 будет достаточно всегда при трассировке с TARS_1
на TARS_2.
ВиО
Замечательная глава Вопросы и Ответы. Мне очень нравится, потому что сюда можно засунуть всё, чему не
хватило места в основной статье.
В2: Почему MBGP — это MultiProtocol BGP, а не, например, MPLS BGP? Что в нём многопротокольного?
Задача BGP — передавать маршруты. Исторически и классически — это IPv4. Но помимо обычных префиксов BGP
может передавать и массу других: IPv6, IPX, Multicast, VPN. Каждый тип префиксов настраивается как отдельный
Address Family — то есть группа адресов одного типа. Собственно вот за эту возможность передавать
маршрутные данные разных протоколов такой BGP и получил имя MBGP.
В4: Так в чём всё-таки разница между RD и RT? Почему недостаточно только одного из них? И я правильно понял:
RD не является идентификатором VPN, как и RT?
Да, ни RD, ни RT однозначно не идентифицируют VPN. Как для одного VPN на разных маршрутизаторах могут
быть настроены разные RD/RT, так и для двух разных теоретически могут быть одинаковые RD/RT.
Ещё раз:
RD — Route Distinguisher — его основная и единственная задача — сделать так, чтобы маршруты не смешались в
MBGP — два одинаковых маршрута из разных VPN должны быть таки двумя разными маршрутами. RD не говорит
PE, куда нужно экспортировать маршрут и существует/работает только при передаче маршрута.
RT — Route Target. Он не помогает разделить маршруты разных VPN, но он позволяет экспортировать их в те VRF,
в которые надо. То есть он имеет значение в момент импорта маршрута из VRF в самом начале и в момент
экспорта в VRF на другом конце в самом конце. Передаётся в Extended Community.
Одного RD не хватит, потому что PE не будут знать, как правильно распорядиться маршрутами.
А одного RT не хватит, потому что маршруты смешаются при передаче и потеряются все, кроме одного.
Можно было бы оставить только RD, например, и на его основе решать, куда маршрут передать, но это и не
гибко и идёт в разрез с принципами BGP.
В5: Молодой, человек, мы крупный оператор, мы занимаемся серьёзными вещами — строим Adnvanced LTE,
пока поддерживаем 2G, у нас нет клиентов, которые хотят VPN, ваша гигантская статья бесполезна для нас.
Вовсе не зря. Как минимум ещё одно применение — это разделение своих собственных услуг в пределах своей
же сети.
Например, если вы оператор сотовой связи и предоставляете услуги в сетях 2G, 3G, 4G и строите уже вовсю 5G, то
свою сеть Mobile Backhaul (MBH) вы можете разбить на 5 VPN: по одной для каждого поколения радиосвязи и
одну для сети управления элементами. Это позволит к каждой сети применять свои правила маршрутизации,
качества обслуживания, политики обработки трафика. А если совместить это ещё и с Traffic Engineering…
Причём тут даже не надо будет настраивать взаимосвязь между VPN в пределах MBH — каждая сеть
изолирована от абонента до Core Network: у 2G в ядре стоит BSC, у 3G — RNC, у 4G — MME. И только в ядре сети
на специальном маршрутизаторе или файрволе можно их скрестить.
А вот ещё пример: столь популярная ныне технология MVNO — Mobile Virtual Network Operator — когда одна
сеть MBH используется для двух и более операторов. Здесь уже однозначно нужно будет разделять и
властвовать.
Но как ни крути, да, MPLS VPN — это всё-таки преимущественно игрушка больших воротил телекома или
интерпрайза.
В6: Не возьму в толк: как Egress PE, получив пакет с одной меткой, то есть если произошёл PHP, определяет что
эта метка VPN, а не транспортная, и, соответственно, что по метке нужно передать его в VRF, а не скоммутировать
куда-то дальше?
Всё очень просто — пространство меток для VPN, для LSP, для всевозможных FRR и CSC — общее. Не может быть
такого, что для VPN и для LSP была выделена одна и та же метка. Ну а каждой метке при её создании ставится в
соответствие её роль и действия при её получении.
Итак, есть оператор связи, который предоставляет своему клиенту L3VPN. Ни с того ни с сего, с бухты да барахты
понадобился ему ещё и Интернет.
Самое очевидное решение — прокинуть ещё один кабель — в одном VPN, в другом Интернет.
Допустим, это сложно. Тогда можно поднять сабинтерфейс и передавать фотки вконтактике в отдельном VLAN'е.
Допустим, там сложный арендованный канал, где можно прокинуть только 1 VLAN или оборудование клиента не
умеет VLAN (стоит обычный компьютер), что тогда?
Итак, провайдер в тот же самый VPN продаёт и доступ в Интернет, через то же самое подключение, через те же
адреса. Это значит, что в сети провайдера придётся где-то настроить доступ из приватной сети, в публичную, а
следовательно обеспечить пересечение маршрутной информации.
Всё это непотребство имеет своё название — Route Leaking — маршруты протекают из VRF в глобальную
таблицу. Название функционала говорящее — прибегать к Route Leaking'у особенно через статические маршруты
нужно только в крайних случаях, ибо жуткий костыль.
Начнём со статики.
NAT на CE
Провайдер выдаёт клиенту пул публичных адресов, в который тот транслирует свои внутренние. Всё, что остаётся
сделать провайдеру — настроить маршрутизацию между VRF и глобальной таблицей.
Учитывая, что трансляция будет на CE, нужно выбрать только один филиал, пусть это будет TARS_2 — там как раз
у нас линковая сеть публичная — 100.0.1.0/30.
Как видите, для этого теста нам нужно что-то в качестве Интернета и компьютер, которому доступ туда нужен.
В GNS есть такой чудесный объект, как VPCS, который прекрасно подходит на эту роль.
На TARS_2 нужно настроить NAT, ниже его конфигурация:
TARS_2(config)#interface Loopback0
TARS_2(config)#interface FastEthernet0/0
TARS_2(config-if)#description To Linkmeup
TARS_2(config)#interface FastEthernet0/1
TARS_2(config-if)#description To LAN
access-list 100 состоит из двух строк — первая запрещает трансляцию адресов для пакетов, которые идут из своей
сети в свою же сеть, находящуюся на другом конце провайдера.
Вторая строка разрешает трансляцию только для адресов своей сети. Если вдруг вы пропишите permit ip any any,
то сразу же упадёт BGP-сессия с Linkmeup_R3.
Подробности по настройке NAT были освещены в пятой части СДСМ.
Конфигурация Интернета:
Internet(config)#interface Loopback0
Internet(config)#interface FastEthernet0/0
Internet(config-if)#description To linkmeup
Настройки BGP на Internet точно такие же, как были в Балаган-Телекоме в восьмом выпуске, мы только
позволили себе некоторые вольности с IP-адресами.
Интерфейс Loopback 0 на узле с именем Internet олицетворяет собой весь интернет. Пинг до него и будем
проверять.
Соответствующим образом настроен и Linkmeup_R1 для связи с Internet:
Linkmeup_R1(config)#interface FastEthernet1/1
Linkmeup_R1(config-if)#description To Balagan-Telecom
Что же касается доступа в Интернет из VPN, то в данном случае конфигурацию нужно менять только на
ближайшем к CE PE — в нашем случае Linkmeup_R3.
1. Создадим маршрут по умолчанию для VRF TARS. Это для того, чтобы пакеты, пришедшие от TARS_2 не были
отброшены и знали куда двигаться.
2. Теперь его нужно сообщить клиенту, чтобы у того тоже появился маршрут по умолчанию (хотя он мог бы
настроить его и самостоятельно).
Результат:
Итак, маршруты туда, то есть в Интернет, у нас уже есть, теперь что касается обратно.
Зачем нам это нужно? Чтобы был маршрут, логично ведь. Если из Интернета пакет прилетит на Linkmeup_R3, а на
нём не будет маршрута к 100.0.1.0/30 в глобальной таблице маршрутизации (в VRF-то он, конечно, будет), пакет
будет отброшен.
Было:
Маршрут-то есть, да только не туда. Пакет не будет отброшен, но и до адресата не дойдёт.
Стало:
4. Далее об этой сети нужно сообщить BGP-соседям — о ней должны узнать все. В частности нас
интересует Linkmeup_R1.
Результат:
BGP в принципе и прежде знал об этой сети, но только в address-family ipv4 vrf TARS, куда она попадала с
помощью команды redistribute connected. В глобальной же таблице маршрутизации её не было.
Это говорит о том, что заработал Route Leaking, то есть доступ из VRF в глобальную таблицу маршрутизации и
наоборот работает.
Проверка доступности Интернета с компьютера — это формальность, которая покажет, что мы правильно
настроили NAT. Фактически вся магия происходит на Linkmeup_R3, а знакомая нам трансляция на TARS_2, то есть
вещи это по большому счёту не связанные, и, если Интернет доступен с TARS_2, он будет доступен и с PC1.
Однако мы проверим:
Интернет доступен. Ура!
Если вам интересно, давайте проследим, что происходит с пакетом по пути от PC1 до Internet.
VRF-Aware NAT
Более правильный и чуть более масштабируемый вариант — настройка трансляции на Egress PE — на выходе в
Интернет. В этом случае у нас есть центральный узел, где выполняются все операции, а клиенту не нужно делать
ничего.
Единственное неудобство: несмотря на то, что, возможно, ни один клиент не подключен к Egress PE
непосредственно, этому маршрутизатору придётся поддерживать все VRF, из которых нужно получать доступ в
Интернет. Собственно, поэтому он и VRF-Aware.
Egress PE в нашем случае — Linkmeup_R1, который является шлюзом в интернет для всей сети linkmeup —
никаких абсолютно дополнительных настроек на других узлах.
Пусть PC2 из сети C3PO Electronic (C3PO_2) хочет получить доступ в Интернет.
PC1 из TARS’ Robotics не трогаем и оставляем без изменений — они со своими белыми адресами — отдельная
история, хотя их тоже вполне можно натить таким же образом.
1) Итак, во-первых на Linkmeup_R1 должен быть VRF C3PO. Он уже есть, но если бы не было, нужно было бы,
чтобы было бы.
Конфигурация VRF типичная и она не поменялась:
Linkmeup_R1(config-vrf)#rd 64500:100
2) Настраиваем NAT
Включаем ip nat inside в ту сторону, откуда получаем пакеты для трансляции, то есть в сторону P-
маршрутизатора Linkmeup_R2:
Linkmeup_R1(config)#$ip nat inside source list 100 interface FastEthernet1/1 vrf C3PO overload
3) В BGP, как и в прошлый раз, прописываем отправку маршрута по умолчанию в данный VRF:
Linkmeup_R1(config-router-af)#redistribute static
Linkmeup_R1(config-router-af)#default-information originate
Поосторожней с редистрибьюцией в продакшне. Используй только вместе с фильтрацией.
Заметьте, что здесь недостаточно одной только команды redistribute static, чтобы забрать и анонсировать
маршрут по умолчанию. Для этого дополнительно придётся выполнить явно команду default-information
originate.
Чтобы этот маршрут анонсировался BGP, нужно, чтобы он был в таблице маршрутизации:
Проверяем:
Common Services
До сих пор мы обсуждали задачу передачи трафика из VPN в публичные сети и обратно.
Ещё один подход к предоставлению доступа в Интернет — вывести его в отдельный VRF.
Строго говоря — он наиболее масштабируемый, потому что нет необходимости настраивать что-то
индивидуально для каждого клиентского VRF.
Важное условие — NAT происходит в сети клиента и в VRF Internet импортируются только маршруты к публичным
префиксам клиента.
Common Services, который часто называют Shared Services — это продолжение вопроса о взаимодействии между
VRF, который мы рассмотрели ранее. Основная идея в том, что экспорт/импорт совершается засчёт особой
настройки route-target. Только на этот раз нужно ограничить список передаваемых префиксов, чтобы избежать
пересечения адресных пространств и разрешить только публичные маршруты.
Рассмотрим задачу снова на примере TARS, потому что у них уже есть публичные сети.
Linkmeup_R1(config-vrf)#rd 64500:1
Обратите внимание, что route-target на импорт и на экспорт в этот раз разные и сейчас станет понятно почему.
2) Перенести интерфейс в сторону Интернета в VRF:
Linkmeup_R1(config-router-af)#default-information originate
Итак, помимо собственного RT, который обеспечивает обмен маршрутной информацией с другими филиалами
(64500:200), здесь настроены и те RT, которые и для VRF Internet, но наоборот:
• то, что было на экспорт в VRF Internet (64500:22), то стало на импорт в VRF TARS
• то, что было на импорт в VRF Internet (64500:11), то стало на экспорт в VRF TARS
Почему так? Почему нельзя просто дать route-target both 64500:1, например, на всех VRF?
Основная идея концепции Common Service — предоставить доступ к нужному VRF клиентам, но не позволить им
общаться друг с другом напрямую, чтобы обеспечить изоляцию, как того требует определение VPN.
Если настроить одинаковый RT на всех VRF, то маршруты будут спокойно ходить между ними.
При указанной же выше конфигурации у всех клиентских VRF есть RT 64500:22 на импорт (все будут получать
маршруты Internet), и также у них есть RT 64500:11 на экспорт, но только у VRF Internet есть такой RT 64500:11 на
импорт — только VRF Internet будет получать маршруты клиентов. Друг с другом они обмениваться не смогут.
Главное, чтобы Internet не занялся филантропией и не начал маршрутизировать клиентский трафик.
Итак, в результате наших операций мы можем видеть следующее:
На Linkmeup_R1 есть маршрут до сети 100.0.0.0/30, но есть и лишние маршруты до частных сетей:
Тут как обычно поможет фильтрация. А если конкретно, то воспользуемся prefix-list + route-map:
Первые три строки запрещают анонсы всех частных сетей. Четвёртая разрешает все остальные.
В нашем случае вполне можно было бы обойтись одной строкой: ip prefix-list 1 permit 100.0.0.0/23 le 32 — вся
подсеть Linkmeup, но приведённый нами пример более универсальный — он допускает существование других
публичных сетей и соответственно один prefix-list может быть применён для всех VRF.
Следующая конструкция применяет расширенное community к тем префиксам, что попали в prefix-list 1, иными
словами устанавливает RT:
После обновления маршрутов BGP (можно форсировать командой clear ip bgp all 64500) видим, что в VRF Internet
остался только публичный маршрут:
Все виды доступа в Интернет из VRF описаны в данной статье. Но она настолько запутанная, что именно поэтому
я и решил посвятить отдельный микровыпуск СДСМ вопросу настройки этого функционала.
Долго ли коротко ли, но шестерни в очередной раз провернулись и linkmeup встал на ступень Tier 2. И несколько
достаточной платёжоспособности энтерпрайзов проявили заинтересованность в организации связи между
своими филиалами через сети linkmeup.
L3VPN, который мы рассмотрели в прошлом выпуске, покрывает собой огромное количество сценариев,
необходимых большинству заказчиков. Огромное, но не все. Он позволяет осуществлять связь только на сетевом
уровне и только для одного протокола — IP. Как быть с данными телеметрии, например, или трафиком от
базовых станций, работающих через интерфейс E1? Существуют также сервисы, которые используют Ethernet, но
тоже требуют связи на канальном уровне. Опять же ЦОДы между собой любят на языке L2 общаться.
Вот и нашим клиентам вынь да положь L2.
Традиционно раньше всё было просто: L2TP, PPTP да и всё по большому счёту. Ну в GRE ещё можно было
спрятать Ethernet. Для всего прочего строили отдельные сети, вели выделенные линии ценою в танк
(ежемесячно).
Однако в наш век конвергентных сетей, распределённых ЦОДов и международных компаний это не выход, и на
рынок выплеснулось некоторое количество масштабируемых технологий випиэнирования на канальном уровне.
Возможность инкапсулировать трафик любого канального уровня в MPLS называется AToM — Any Transport over
MPLS.
Вот список поддерживаемых AToM протоколов:
• ATM Adaptation Layer Type-5 (AAL5) over MPLS
• ATM Cell Relay over MPLS
• Ethernet over MPLS
• Frame Relay over MPLS
• PPP over MPLS
• High-Level Data Link Control (HDLC) over MPLS
Терминология
Традиционно термины будут вводиться по мере необходимости. Но о некоторых сразу.
PE — Provider Edge — граничные маршрутизаторы MPLS-сети провайдера, к которым подключаются клиентские
устройства (CE).
CE — Customer Edge — оборудование клиента, непосредственно подключающееся к маршрутизаторам
провайдера (PE).
AC — Attached Circuit — интерфейс на PE для подключения клиента.
VC — Virtual Circuit — виртуальное однонаправленное соединение через общую сеть, имитирующее
оригинальную среду для клиента. Соединяет между собой AC-интерфейсы разных PE. Вместе они составляют
цельный канал: AC→VC→AC.
PW — PseudoWire — виртуальный двунаправленный канал передачи данных между двумя PE — состоит из пары
однонаправленных VC. В этом и есть отличие PW от VC.
VPWS. Точка-точка
VPWS — Virtual Private Wire Service.
В основе любого решения MPLS L2VPN лежит идея PW — PseudoWire — виртуальный кабель, прокинутый из
одного конца сети в другой. Но для VPWS сам этот PW и является уже сервисом.
Эдакий L2-туннель, по которому можно беззаботно передавать всё, что угодно.
Ну, например, у клиента в Котельниках находится 2G-базовая станция, а контроллер — в Митино. И эта БС может
подключаться только по Е1. В стародавние времена пришлось бы протянуть этот Е1 с помощью кабеля,
радиорелеек и всяких конвертеров.
Сегодня же одна общая MPLS-сеть может использоваться, как для этого Е1, так и для L3VPN, Интернета,
телефонии, телевидения итд.
(Кто-то скажет, что вместо MPLS для PW можно использовать L2TPv3, но кому он нужен с его
масштабируемостью и отсутствием Traffic Engineering'а?)
VPWS сравнительно прост, как в части передачи трафика, так и работы служебных протоколов.
VPWS Data Plane или передача пользовательского трафика
Туннельная метка — то же, что и транспортная, просто длинное слово «транспортное» не помещалось в
заголовок.
0. Между R1 и R6 уже построен транспортный LSP с помощью протокола LDP или RSVP TE. То есть R1 известна
транспортная метка и выходной интерфейс к R6.
1. R1 получает от клиента CE1 некий L2 кадр на AC интерфейс (то может оказаться Ethernet, TDM, ATM итд. — не
имеет значения).
2. Этот интерфейс привязан к определённому идентификатору клиента — VC ID — в некотором смысле аналогу
VRF в L3VPN. R1 даёт кадру сервисную метку, которая сохранится до конца пути неизменной. VPN-метка является
внутренней в стеке.
3. R1 знает точку назначения — IP-адрес удалённого PE-маршрутизатора — R6, выясняет транспортную метку и
вставляет её в стек меток MPLS. Это будет внешняя — транспортная метка.
4. Пакет MPLS путешествует по сети оператора через P-маршрутизаторы. Транспортная метка меняется на новую
на каждом узле, сервисная остаётся без изменений.
5. На предпоследнем маршрутизаторе снимается транспортная метка — происходит PHP. На R6 пакет приходит с
одной сервисной VPN-меткой.
6. PE2, получив пакет, анализирует сервисную метку и определяет, в какой интерфейс нужно передать
распакованный кадр.
Если вы читали предыдущий выпуск про L3VPN, то в вопросе передачи пользовательского трафика не увидите
ничего нового — пара MPLS-меток и передача по транспортному LSP. Ingress PE проверяет какие метки поставить
и в какой интерфейс отправить, P меняет транспортную метку, а Egress PE по метке VPN принимает решение, в
какой AC-интерфейс передать полученный кадр.
Транспортная метка может назначаться как LDP (см. выпуск про MPLS), так и RSVP-TE (ещё ждёт своего часа).
Для примера, возьмём LDP — по всей сети запускается этот протокол, который для каждого Loopback-адреса
каждого MPLS-маршрутизатора распространит по сети метки.
В нашем случае R1 после работы LDP будет, грубо говоря, знать 5 меток: как добраться до каждого из оставшихся
маршрутизаторов.
Нас интересует LSP R1→R6 и обратно. Заметьте, что для того, чтобы VC перешёл в состояние UP, должны быть оба
LSP — прямой и обратный.
Существует несколько разных способов реализации услуги VPWS. Об этом мы поговорим чуть ниже, а для
примера разберём ту, которая наиболее часто сейчас используется.
За распространение сервисных меток отвечает тот же LDP, только генно-модифицированный — Targeted LDP.
Теперь он может устанавливать соединение с удалёнными маршрутизаторами и обмениваться с ними метками.
В нашем примере к R1 и R6 подключены клиенты. R1 через LDP сообщит свою метку для этого клиента R6 и
наоборот.
На обоих концах вручную мы настраиваем удалённую LDP-сессию. Она никак не привязана к VPN. То есть одна и
та же сессия может использоваться для обмена метками любым количеством VPN.
Обычный LDP — это link-local протокол и ищет соседей среди непосредственно подключенных маршрутизаторов,
то есть TTL его пакетов — 1. Однако tLDP достаточна IP-связность.
Как только с обеих сторон появятся AC-интерфейсы с одинаковым VC-ID, LDP поможет им сообщить друг другу
метки.
Соответственно далее все команды по настройке MPLS L2VPN даны в нотации Cisco IOS-XE.
Внимание: для каждой ноды CSR1000V требуется 2,5 ГБ RAM. В противном случае образ либо не запустится,
либо будут различные проблемы, вроде того, что порты не поднимаются или наблюдаются потери.
Практика VPWS
Упростим топологию до четырёх магистральных узлов. По клику можете открыть её в новой вкладке, чтобы
смотреть на неё Alt+Tab'ом, а не ворочать страницу вверх-вниз.
Наша задача — прокинуть Ethernet от Linkmeup_R1 (порт Gi3) до Linkmeup_R4 (порт Gi3).
1. Настраиваем xconnect на обоих концах на AC-интерфейсах (PE-CE), обращаем внимание, что VC-ID должен
быть одинаковым.
2.
Linkmeup_R1(config)#interface Gi 3
Linkmeup_R4(config)#interface Gi 3
Команда xconect 4.4.4.4 127 encapsulation mpls заставляет LDP поднять удалённую сессию с узлом 4.4.4.4 и
создаёт MPLS PW с VC ID 127. Важно, чтобы VC ID совпадали на двух противоположных AC-интерфейсах — это
указатель того, что их нужно срастить.
3. Профит.
4.
5.
0) IGP сошёлся, LDP определил соседей, поднял сессию и раздал транспортные метки.
Как видите, Linkmeup_R4 выделил транспортную метку 19 для FEC 4.4.4.4.
--А. Сначала мы настроили его на Linkmeup_R1 и tLDP начал периодически отправлять свой Hello на адрес 4.4.4.4
Как видите, это юникастовый IP пакет, который отправляется с адреса Loopback-интерфейса 1.1.1.1 на адрес
такого же Loopback удалённого PE — 4.4.4.4.
Упакован в UDP и передаётся с одной меткой MPLS — транспортной — 19. Обратите внимание на приоритет —
поле EXP — 6 — один из наивысших, поскольку это пакет служебного протокола. Подробнее мы об этом
поговорим в выпуске о QoS.
--Б. После того, как настроили xconnect на стороне Linkmeup_R4 — сразу Hello и установление соединения по TCP.
В этот момент установлено LDP-соседство
Команды show mpls l2transport vc detail и show l2vpn atom vc detail в целом идентичны для наших примеров.
Почему-то Wireshark не разобрал внутренности MPLS, но я вам покажу, как прочитать вложение:
Два блока, выделенных, красным — это MAC-адреса. DMAC и SMAC соответственно. Жёлтый блок 0800 — поле
Ethertype заголовка Ethernet — значит внутри IP.
Далее чёрный блок 01 — поле Protocol заголовка IP — это номер протокола ICMP. И два зелёных блока — SIP и
DIP соответственно.
Теперь вы можете в Wireshark!
Соответственно ICMP-Reply возвращается только с меткой VPN, потому что на Linkmeup_R2 возымел место PHP и
транспортная метка была снята.
Если VPWS — это просто провод, то он должен спокойно передать и кадр с меткой VLAN?
Да, и нам для этого не придётся ничего перенастраивать.
Вот пример кадра с меткой VLAN:
Здесь вы видите Ethertype 8100 — 802.1q и метку VLAN 0x3F, или 63 в десятичной системе.
Виды VPWS
Рассмотренный пример — это EoMPLS (Ethernet over MPLS). Он является частью технологии PWE3, которая суть
развитие VLL Martini Mode. И всё это вместе и есть VPWS. Тут главное не запутаться в определениях. Позвольте
мне быть вашим проводником.
Итак, VPWS — общее название решений для L2VPN вида точка-точка.
PW — это виртуальный L2-канал, который лежит в основе любой технологии L2VPN и служит туннелем для
передачи данных.
VLL (Virtual Leased Line) — это уже технология, которая позволяет инкапсулировать кадры различных протоколов
канального уровня в MPLS и передавать их через сеть провайдера.
Выделяют следующие виды VLL:
VLL CCC — Circuit Cross Connect. В этом случает нет метки VPN, а транспортные назначаются вручную (статический
LSP) на каждом узле, включая правила swap. То есть в стеке будет всегда только одна метка, а каждый такой LSP
может нести трафик только одного VC. Ни разу не встречал его в жизни. Главное его достоинство — он может
обеспечить связность двух узлов, подключенных к одному PE.
VLL TCC — Translational Cross Connect. То же, что CCC, но позволяет с разных концов использовать разные
протоколы канального уровня.
Работает это только с IPv4. PE при получении удаляет заголовок канального уровня, а при передаче в AC-
интерфейс вставляет новый.
Интересно? Начните отсюда.
VLL SVC — Static Virtual Circuit. Транспортный LSP строится обычными механизмами (LDP или RSVP-TE), а
сервисная метка VPN назначается вручную. tLDP в этом случае не нужен. Не может обеспечить локальную
связность (если два узла подключены к одному PE).
Martini VLL — это примерно то, с чем мы имели дело выше. Транспортный LSP строится обычным образом, метки
VPN распределяются tLDP. Красота! Не поддерживает локальную связность.
Kompella VLL — Транспортный LSP обычным образом, для распределения меток VPN — BGP (как и полагается, с
RD/RT). Уау! Поддерживает локальную связность. Ну и ладно.
PWE3 — Pseudo Wire Emulation Edge to Edge. Строго говоря, область применения этой технология шире, чем
только MPLS. Однако в современном мире в 100% случаев они работают в связке. Поэтому PWE3 можно
рассматривать как аналог Martini VLL с расширенным функционалом — сигнализацией так же занимаются
LDP+tLDP.
Коротко его отличия от Martini VLL можно представить так:
• Сообщает статус PW, используя сообщение LDP Notification.
• Поддерживает Multi-Segment PW, когда end-to-end канал состоит из нескольких более мелких кусков. В
этом случае один и тот же PW может стать сегментов для нескольких каналов.
• Поддерживает TDM-интерфейсы.
• Предоставляет механизм согласования фрагментации.
• Другие...
Сейчас PWE3 — стандарт де факто и именно он был в примере выше.
Я тут везде говорю об Ethernet для того, чтобы показать наиболее наглядный пример. Всё, что касается других
канальных протоколов, это, пожалуйста, на самостоятельное изучение.
VPLS. Point-to-Multipoint
Мне очень нравится термин точка-многоточка. Есть в нём что-то детское, игривое. И это то, о чём мы поговорим
сейчас.
VPLS — Virtual Private LAN Service. По своей сути — это коммутатор. Провайдер подключает несколько точек
заказчика к своей сети в разных её концах и обеспечивает L2 связность. И теперь это задача транспортной сети
провайдера — заботиться о правильной коммутации кадров, то есть изучении MAC-адресов.
Терминология
VPLS-домен — изолированная виртуальная L2-сеть, то есть, грубо говоря, один отдельный L2VPN. Два разных
клиента — два разных VPLS-домена.
VSI — Virtual Switching Instance. Виртуальный коммутатор в пределах одного узла.
Для каждого клиента (или сервиса) он свой. То есть трафик разных VSI не может кочевать из одного в другой.
Аналог VRF/VPN-instance в L3VPN.
В терминах Cisco это VFI — Virtual Forwarding Instance. Я позволю себе вольно обращаться с терминами VPLS-
домен, VSI и VFI, иногда используя их как синонимы.
VE — VPLS Edge — узел PE, участник VPLS-домена.
В вопросе изучения MAC-адресов в VPLS есть один нюанс, который резко отличает его от L3VPN.
PE должен не просто знать физический порт, откуда пришёл кадр — важно определить соседа или, точнее PW
как виртуальный интерфейс. Дело в том, что клиентский кадр нужно отправить не просто в какой-то физический
порт, а именно в правильный PW, иными словами, правильному соседу.
Для этой цели каждому соседу выдаётся личная метка, с которой тот будет отправлять кадр этому PE в данном
VPLS-домене.
И в дальнейшем по VPN-метке, заглянув в LFIB, PE узнает, от какого соседа пришёл кадр.
Напомню, что L3VPN без разницы, откуда пришёл IP-пакет, поэтому для префикса в VRF всем соседям сообщается
одна и та же метка.
Схема доставки пользовательского трафика незамысловата. Но что же с пресловутым Control Plane'ом? Опять
придётся поломать мозги или малыми жертвами?
Извините, но дальше начинается трэш и содомия. Не сразу — попозже, но будет. Вы действуете на свой страх и
риск.
Поэтому один из главных вопросов в VPLS — обнаружение всех PE, куда подключены клиенты данного VSI.
Существует здесь два подхода: ручная настройка и автоматическое обнаружение. Первый путь изначально
предложила Cisco (драфт Мартини), отцом второго является Juniper (драфт Компелла).
11 выпусков СДСМ пропагандировал упрощение жизни инженера и автоматизацию всего и вся. И вот, настал тот
момент, когда нужно забыть всё, чему вас учили. Это первый случай (если не поднимать холивар вокруг VTP),
когда решение с ручной настройкой соседей оказывается более популярным.
Стало интересно?
Прежде чем приоткроем кулисы, хочу сделать замечание: независимо от того, что мы вытворяем с VPN-метками,
транспортные LSP строятся как обычно LDP или RSVP-TE. Поэтому далее касаться транспорта мы будем только
вскользь.
Точно также, независимо от используемого режима, VPLS при более детальном рассмотрении разваливается на
point-to-point PW. То есть мы имеем не некое централизованное облако коммутации, а просто набор
виртуальных линий между всем соседями. Решение о передаче кадра принимает Ingress PE или, проще говоря,
выбирает нужный PW.
Слово «драфт», прочно закрепившееся за этими двумя подходами, уже давно неправомерно и используется по
исторической инерции. Драфтом предложение может быть только шесть месяцев.
На данный момент draft-martini переродился в RFC 4447 — Интернет-стандарт про PWE3, а драфт-Компелла
устарел и умер.
Если же говорить именно о VPLS, то тут есть два стандарта:
“Virtual Private LAN Service (VPLS) Using BGP for Auto-discovery and Signaling”. RFC 4761.
“Virtual Private LAN Service (VPLS) Using Label Distribution Protocol (LDP) Signaling” RFC 4762.
Историческая справка по методам.
Именно это лаконичное решение и стало стандартом де факто в большинстве сетей по всему миру.
С тем, как работает Martini-mode мы уже познакомились в части про VPWS. Ровно то же самое и здесь, только
удалённые LDP сессии создаются для каждого VSI не с одним соседом, а с несколькими.
Практика VPLS
Разберём работу VPLS на практике по шагам вот по этой схеме. Это всё та же сеть, но теперь клиент решил, что
ему недостаточно двух точек, он хочет четыре и объединить их все в одну сеть.
Кликабельно.
Забыли о том, что у нас до этого был сервис VPWS — этой конфигурации больше нет.
Файл начальной конфигурации.
Итак на шаге 0 у нас готовы необходимые транспортные LSP, а соответственно, и маршрутизация итд.
1. Создаём VFI — Virtual Forwarding Instance
2.
Linkmeup_R1(config)#l2vpn vfi context Blue
Linkmeup_R1(config-vfi)#vpn id 63
Linkmeup_R1(config-if-srv)#description Blue-A
Linkmeup_R1(config-if-srv)#encapsulation default
Linkmeup_R1(config)#interface gigabitEthernet 4
Linkmeup_R1(config-if-srv)#description Blue-C
Linkmeup_R1(config-if-srv)#encapsulation default
В режиме конфигурации интерфейса мы создаём Service Instance — это привязка интерфейса к сервисам. Каким
именно — настроим позднее. Номер Service Instance произвольный — он локальнозначимый для интерфейса
(как и у классического сабинтерфейса).
encapsulation default означает, что мы хватаем все кадры без разбора (а могли бы выбирать по метке VLAN или
по факту наличия двух меток — QinQ, например), то есть весь физический интерфейс привязываем к VFI.
Хочу знать больше про Service Instance…
6. Теперь нам нужно связать сервисы на AC-интерфейсах (service instance) с VFI. Для этого нам понадобятся
bridge-domain.
7.
8.
Linkmeup_R1(config)#bridge-domain 255
Цифра 255 в общем-то произвольная (0-4096). Может выбираться в соответствии с клиентским VLAN, например.
Строго локальный для устройства и никуда не передаётся.
Что произошло?
1. Сразу после этого устанавливаются соединения LDP и происходит обмен метками. Технически LDP достаточно
привязки к bridge-domain — не обязательно, чтобы были AC-интерфейсы (это поведение зависит от
производителя.).
Заметьте, что разным соседям Linkmeup_R1 выдаёт разные метки — это для того, чтобы можно было корректно
изучить MAC-адреса потом.
2. Если запустить пинг с Blue-A, то в дампе (на интерфейсе Gi1 Linkmeup_R1) можно увидеть сначала ARP-запрос:
Поскольку он широковещательный, то следом за ним можно увидеть его точную копию с одной лишь разницей
— метки VPN и транспортная:
Один кадр был отправлен на Linkmeup_R3, другой — на Linkmeup_R4.
К сожалению, установить зависимость между Pseudoport и pseudowire мне так и не удалось. Как инженеру
определить, с какого PW изучается MAC-адрес?
Например show l2vpn vfi показывает очевидное соответствие, но эти имена никак не перекликаются.
Если кому-то удастся проследить связь между Pseudoport и pseudowire, эта статья станет чуточку полнее.
Естественно, это всё строго локально. Как и обычные коммутаторы — VPLS не сигнализирует MAC'и другим PE, а
занимается их изучением исключительно в рамках Data Plane.
Другое название VPLS Kompella-mode — VPLS Auto-Discovery, потому что именно это является его качественным
отличием от Martini. Также вы можете услышать VPLS BGP Signaling.
В секции BGP для VPLS есть своя Address Family: L2VPN AFI (25) и VPLS SAFI (65)
В ней настраивается соседство с абсолютно всеми PE, которые могут участвовать в каком-либо VPLS-домене.
Заметьте, здесь без привязки к конкретному VSI.
Если используются RR, то соседство поднимается только с ними.
Когда BGP хочет сообщить L2-префикс всем PE данного VSI, он высылает BGP Update всем настроенным здесь
соседям, опять же независимо от того, хотят они получать данный префикс или нет. Здесь всё так же, как в L3VPN
— там vpnv4-префиксы тоже рассылаются всем PE.
Когда удалённый PE получает этот BGP Update, он проверяет RT в поле NLRI и сравнивает с теми, которые
настроены в его VSI.
Если совпадение найдено, PE импортирует этот префикс в нужный VSI. Если нет — отбрасывает.
Вот так и реализован Auto-Discovery.
То есть это не какая-то отдельная фаза, чтобы выявить всех участников VPLS-домена и составить их список, а
просто механизм распознавания свой-чужой по отношению к анонсу.
Передача префиксов
В целом префикс L2VPN — вещь довольно искусственная — PE своим BGP Update, скорее, сообщает сам факт
своего участия в VPLS-домене и метку этого факта. Но это не играет большой роли.
Какого-то адреса, тем более MAC'а, в поле NLRI сообщения BGP Update VPLS не передаёт. Помните, что изучение
MAC-адресов — это полностью функция Data Plane.
Однако различать анонсы разных VSI всё равно нужно, поэтому знакомый нам Route Distinguisher тоже
присутствует. Обычно он составляет автоматически из номера AS и VPN ID.
Распределение меток
Помните фразу "Хочешь накормить человека один раз — дай ему рыбу. Хочешь накормить его на всю жизнь —
дай ему удочку"? Для выделения меток в VPLS Kompella mode используется механизм блоков меток. Один PE
другому не сообщает точное значение — он даёт ему информацию для её вычисления.
Я по себе я знаю, что пытаться понять что-то пока ты не знаешь, зачем оно нужно — путь к несварению и трата
лишнего времени. В конце этой главы я расскажу, зачем нужна такая странная схема, а пока вы разбираетесь,
просто поверьте мне и Кирити Компелле — нужна.
VE Block Size
Label Base
Напомню, что VE — VPLS Edge — граница сети VPLS — PE-маршрутизатор на котором запущен VPLS.
Прежде чем я ударюсь во все тяжкие про формулы и значения, я считаю себя обязанным объяснить на пальцах в
общем как это работает, потому что потратил кучу времени и нервов, чтобы разобраться.
Я искренне верю, что RFC является источником безусловной ясности, но порою в том же виде, в каком им
является формула эквивалентности массы и энергии для Ньютона.
Когда на PE приходит L2VPN кадр со стороны MPLS сети, нужно точно знать, от какого он соседа — это нужно,
чтобы изучить MAC-адрес, поэтому как и в случае с режимом Martini основная идея заключается в том, что PE
каждому соседу в конкретном VSI должен сообщить уникальную метку, чтобы видеть, от кого пришёл кадр.
Пусть R1 за главного.
0. В Kompella mode R1 не передаёт метку в явном виде своим соседям R2 и R3.
1. Вместо этого он им сообщает из какого диапазона нужно метки выбирать, чтобы идентифицировать данный
VC.
2. У каждого РЕ есть свой порядковый номер n в VPLS-домене. Зная свой номер и диапазон меток, соседи
вычисляют исходящую сервисную метку: отсчитывают n-ую по счёту с начала. То есть R2 взял вторую (2), а R3 —
третью (3).
3. R2 и R3 сообщают свои номера R1, и он тоже вычисляет, какая входящая сервисная метка будет от R2, какая от
R3, отсчитывая от начала диапазона 2 и 3.
4. Аналогично свои собственные диапазоны определяют R2 и R3 и сообщают их друг другу и R1. И цикл
вычислений повторяется.
5. В конце концов все будут знать и исходящие метки для данного VPLS и входящие.
Теперь вторая итерация: поглубже копнём, какой матан лежит под этой простой идеей.
VE ID настраивается вручную — это идентификатор PE-маршрутизатора в домене VPLS (его порядковый номер).
Должен быть уникален в пределах одного VSI.
LB — Label Base — это начало диапазона, первая метка, которая может быть использована.
VBS — VE Block Size — это длина блока меток — или проще, минимальное количество меток в этом VSI. Для Cisco
по умолчанию это 10. Для Juniper — 8 (может быть уменьшен до 2 или увеличен).
Вот как будет выглядеть набор меток: {LB, LB+1, .., LB+VBS-1}.
На этой анимации показан процесс распределения меток на PE1: Если PEX хочет отправлять трафик на PE1, он
должен использовать соответствующую метку X.
Однако если выделенного количества меток мало, то поможет параметр VBO — VE Block Offset — смещение
блока. Он позволяет создать несколько блоков. И тем соседям, кому не хватило, метки распределяются по тому
же принципу, но из нового блока, с новым LB.
Необходимый VBO вычисляется по формуле: VBO = ЦЕЛОЕ(VE-ID/VBS)*VBS.
Хочется заметить, что VBO — это не про смещение меток, это про диапазон, в который попадает порядковый
номер VE. Если попал в первый диапазон — берётся первый блок меток, если во второй — то второй итд.
Таким образом в случае использования нескольких блоков, набор меток будет выглядеть так же, как и прежде
{LB, LB+1,… LB+VBS-1}, но LB при этом зависит от VBO. То есть у нас связка <LB, VBO, VBS>
1. PE1 выбирает в качестве Label Base 1000 — то есть 1000-1009 — это блок меток, из которого его соседи смогут
взять себе по одной.
2. PE1 вычисляет VBO. VBO=ЦЕЛОЕ(101/10)*10=100.
3. PE1 передаёт собирает все данные в BGP Update всем своим соседям: LB: 1000, VBS:10, VBO:100, VE-ID:101. Ну и
всякие RD, RT, которые нам сейчас не интересны.
Сам PE1 пока никаких меток не считает — он ждёт Update от соседей.
4. BGP Update от PE1 достигает PE5. Его VE-ID: 105. И сейчас ему нужно вычислить исходящую метку для данного
VSI (чей RT указан так же в BGP Update)в сторону PE1.
5. Первое, что делает PE5 — проверяет, а умещается ли он в блок, анонсированный PE1. Вот здесь и понадобится
VBO. Должно выполниться неравенство VBO ≤ PE5 VE-ID ≤ VBO+VBS-1. И оно выполняется 100≤105≤109.
Поясню. PE1 вычислил, что его ID в диапазоне 100-109 (со смещением 100 и длиной 10) — соответственно все
узлы с VE ID из этого набора будут выбирать метку из первого блока.
6. Итак PE5 в пределах анонсируемого диапазона, поэтому он может идти дальше и вычислить свою исходящую
метку по формуле (PE1 LB + PE5 VE-ID — VBO) = (1000 + 105 — 100) = 1005.
Ещё раз вся эта арифметика, означает, что от LB нужно отсчитать столько меток, каким по счёту идёт VE-ID от VBO.
Значит, PE5, чтобы отправить L2 кадр данного VSI на PE1 вставит в MPLS-заголовок VPN-метку 1005.
PE1 пока не знает, про метку 1005 — ему предстоит её вычислить, как это сделал PE5. А для этого нужно узнать
его VE ID.
7. Теперь PE5 тоже должен отправить BGP Update всем соседям (технически, не надо дожидаться 7 шага — такую
последовательность я взял для примера. PE5 отправляет свой BGP Update как только всё было настроено).
• а. Выбрал LB, например, 5000.
• б. Вычислил VBO = RND(105/10)*10=100.
• в. Скомпоновал BGP Update. LB: 5000, VBS:10, VBO:100, VE-ID: 105.
• г. Отправил его всем PE.
8. Когда PE1 узнал VE-ID соседа (из BGP Update), он может посчитать входящую метку для данного соседа и VSI.
И он делает то же самое:
• а. Проверяет неравенство по полученным VBO И VBS: VBO ≤ PE1 VE-ID ≤ VBO+VBS. 100≤101≤109. Отлично.
• б. Вычисляет входящую метку: (PE1 LB + PE5 VE-ID — VBO) = (1000 + 105 — 100) = 1005 — то же самое
число, что посчитал и PE5 для исходящей метки. То есть когда PE1 получит кадр с меткой VPN 1005, он будет
знать сразу и то, какому VPN он предназначен и от какого соседа пришёл, то есть как изучить его MAC, если
необходимо.
9. Но это ещё не всё. PE1 должен теперь вычислить и исходящую метку к PE5. И все данные у него для этого
имеются.
(PE5 LB + PE1 VE-ID — VBO) = (5000 + 101 — 100) = 5001. То есть PE1 при отправке кадров в этот VSI к PE5 вставит в
них VPN-метку 5001.
10. PE5 вычисляет входящую: (PE5 LB + PE1 VE-ID — VBO) = (5000 + 101 — 100) = 5001.
К сожалению, довольно очевидный и в корне своём логичный механизм я могу описать только таким сложным
языком.
Если вы ещё не эволюционировали до понимания механизма Label Block, вернитесь к видео четырьмя экранами
выше.
Интересна судьба PE10, которая окажет своё влияние на жизни всех других PE.
Дело в том, что он не укладывается в блок 100-109 со своим VE ID 110. Его VBO будет 110=ЦЕЛОЕ(110/10)*10. А в
качестве LB он выбрал 10000.
Когда PE10 пришлёт результаты своих калькуляций PE5, неравенство не выполнится: 110 ≤ 105 ≤ 119.
В этом случае запускается процесс выделения нового блока.
1. PE5 выбирает новый LB 5030, VBS уже выбран PE10 — 10.
2. Имея уже данные от PE10,
• А. PE5 вычисляет исходящую метку к PE10: (PE10 LB + PE5 VE-ID — PE5 VBO) = (10000 + 105 — 100) = 10005.
Обратите внимание, что отнимается локальный VBO.
• Б. Вычисляет входящую метку от PE10: (PE5 New LB + PE10 VE-ID — PE10 VBO) = (5030 + 110 — 110) = 5030.
Используется новый LB и VBO PE10.
3. PE5 высылает PE10 новый BGP Update, анонсируя уже два префикса: первый — старый, а второй — LB: 5030, VE
ID: 105, VBS:10, VBO:110.
4. VE-ID PE10 в этот раз входит в новый диапазон 110-119,
• А. поэтому он может вычислить исходящую метку: (PE5 LB + PE10 VE-ID — PE10 VBO) = (5030 + 110 — 110)
= 5030. То есть PE10 при отправке кадра этого VSI на PE5 должен вставить VPN-метку 5030.
• Б. Может он вычислить и входящую от PE5: (PE10 LB + PE5 VE-ID — PE5 VBO) = (10000 + 105- 100) = 10005.
Здесь он использует тот VBO, в который входит PE5, а не PE10.
5. Каждый PE должен будет выделить по второму блоку меток, чтобы общаться с PE10. Вычисления
продолжаются.
Должны быть очень веские доводы, почему протокол реализован именно так, а не по аналогии с LDP или MBGP
для L3VPN.
Как это водится в СДСМ, дальше вы читаете эксклюзив. Причём на этот раз, вероятно, не только рунетовского
уровня, но и вообще во всём Интернете я не нашёл адекватного пояснения, зачем эта система блоков была
изобретена. Не смейтесь сильно, но я даже писал Компелле, когда ни один из окружающих меня CCIE не
ответил на этот вопрос.
Всё это из-за столь желанной функции Auto-discovery (про которую уже было выше) и специфики L2, а именно
изучения MAC-адресов. И всё будет понятнее в сравнении с L3VPN, где про назначения блока меток никто даже
не думал.
Итак, как работает Auto-Discovery в L3VPN? Некоторый PE страждет рассказать всему миру о двух вещах — во-
первых, о том, какие префиксы он знает, во-вторых о том, кому они предназначены. И он хочет рассказать об
этом всем сразу без разбора — все, кто являются его MBGP соседями получат его Update, а по RT поймут,
интересны ли им эти анонсы. На нет — и суда нет — отбросят. А если интересны, то в свою таблицу
маршрутизации VPN занесут полученный префикс и его VPN-метку.
Всё то же самое верно и для L2VPN. За исключением одного: изучения MAC-адресов. BGP в L3VPN сообщает
всем одну и ту же метку — ему совершенно без разницы, откуда потом придёт пакет с данными, главная его
забота — передать его в правильный клиентский интерфейс.
Но не таков VPLS. Чтобы в будущем отправлять данные конкретному соседу, нужно сначала изучить MAC-адреса
клиента, подключенного к этому соседу. И сделать это можно только, если от разных соседей приходят кадры с
разными метками.
И здесь-то и кроется дьявол. В BGP Auto-Discovery происходит в тот же момент, что и анонс префикса.
И, во-первых, совершенно не в духе BGP будет, если сначала отсылать пустой Update с целью поиска всех
участников VPLS-домена, а потом отдельно то же самое, но с конкретными метками каждому из них.
И даже, если вы приемлете «во-первых» (Фуфуфу), появляется, «во-вторых». Во-вторых, анонс конкретных меток
найденным соседям. Хорошо, когда нет RR, и один PE может отправить другому Update адресно. Тогда каждый
PE получит только своё сообщение и только свою метку. Но реальность такова, что RR стали её (реальности)
частью и, имея соседство только с RR, PE шлёт Update ему, а тот рассылает всем своим клиентам. А если PE шлёт
несколько Update'ов, то все они разлетятся по всем. Получается, что каждый его сосед получит не только свою
метку, но и все остальные, которые ему даром не сдались.
Просто представьте себе дамп в котором вы видите сотню Update'ов для левых устройств.
И вот тут механизм автоматического вычисления меток выходит на первый план, как весьма элегантное решение
этой проблемы.
Здесь стоит отдать должное гибкости мысли Кирити Компеллы.
И знаете, пока эта концепция блока меток не сформировалась в непротиворечивый набор синапсов в моём
мозге, я с пренебрежением относился к ней. Она казалась мне топорной и устаревшей. Примерно, как DVMRP.
Но теперь я проникся идеей и даже несколько удивлён тому, что внятного объяснения нигде нет.
Замечу также, что ситуацию с потерянными метками несколько пересмотрели с выпуском RFC 6624 (в котором,
кстати, Компелла тоже принял непосредственное участие):
Label blocks and label values are managed by the PEs. As sites get
added and removed, labels are allocated and released. The easiest
way to manage these is to use fixed-size label blocks rather than
variable-size blocks, although the signaling described here supports
either. If an implementation uses fixed-size blocks, then allocating
a label for a new site may requiring allocating a new block;
similarly, freeing a label may require freeing a block.
If the implementation requires fixed-size blocks, there is probably a
default block size, but the implementation SHOULD allow the
administrator to choose a size. Larger label block sizes mean more
potential «wasted» labels but less signaling overhead, a trade-off
that the administrator might want to control.
И более того, режим LDP-Signalling + BGP Auto-Discovery позволяет совместить достоинства обоих методов. Хотя и
появляется вот этот самый двухшаговый механизм — сначала изучаем соседей, потом рассылаем метки.
Linkmeup_R1(config-vfi)#vpn id 63
Linkmeup_R1(config-vfi-autodiscovery)#ve id 101
Этот способ позволяет настроить три типа VFI: ручной Martini с настройкой соседей. BGP Autodiscovery
+ BGP Signalling, либо BGP Autodiscovery + LDP Signalling.
В нашем случае мы выбрали оба — BGP.
Опционально мы можем задать количество членов VPLS-домена. В cisco по умолчанию — 10. Командой ve
range Х можно увеличить от 11 до 100 (но не уменьшить). Huawei — по умолчанию 10, можно изменять (1-16000).
Juniper — по умолчанию 8, можно изменять (2,4,8, 16...)
Route Distinguisher и Route Target мы можем не настраивать — они будут назначены автоматически. Разве что
вам хочется странного — объединить в один домен разные VFI.
Далее я даю команду mpls label range 1000 1999. Она глобально задаёт диапазон динамически используемых
меток. Вообще говоря этого делать не нужно, поскольку так всем приложениям MPLS (LDP, TE, BGP) мы
указываем, какие метки выбирать, а я не люблю кому-то что-то указывать. Но я делаю это для более наглядной
иллюстрации вычисления меток.
Предупреждение говорит как раз о том, что распределённые прежде транспортные метки не укладываются в
новый диапазон.
3. Привязываем интерфейсы к Service Instance:
4.
Linkmeup_R1(config)#interface gigabitEthernet 3
Linkmeup_R1(config-if-srv)#description Blue-A
Linkmeup_R1(config-if-srv)#encapsulation default
Linkmeup_R1(config)#interface gigabitEthernet 4
Linkmeup_R1(config-if-srv)#description Blue-C
Linkmeup_R1(config-if-srv)#encapsulation default
Потом создаём Address-Family L2VPN VPLS и указываем соседей, которые будут участвовать в L2VPN. Заметьте, не
в конкретном VFI Blue, а вообще.
Здесь вы должны помнить, что обычно мы используем Route Reflector'ы — не нужно настраивать всех соседей
вручную, иначе смысл Auto-Discovery теряется.
То есть если всего PE-устройств в сети MPLS — 100, в данном VPLS-домене — 20, а L2VPN RR — 2, то на каждом PE
нужно поднять соседство только с этими двумя RR.
Ну вы же не маленькие, чтобы я вам это рассказывал?
Что произошло?
Это Linkmeup_R1 сообщает Linkmeup_R3, как вычислить VPN-метку для трафика, предназначенного ему для VPLS
с RT 65400:63.
CE-ID (он же VE ID)=101, VBO=100, VBS=10, LB=1000.
Это уже Linkmeup_R3 сообщает Linkmeup_R1:
CE-ID=103, VBO=100,VBS=10, LB=3000
И вот Linkmeup_R4 сообщает Linkmeup_R1:
CE-ID=104, VBO=100,VBS=10, LB=4000
Давайте, не заглядывая в таблицы меток на PE, посчитаем, какие метки будут назначены?
Linkmeup_R3→Linkmeup_R1
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤103≤109.
Метка: LB + Local VE ID — VBO = 1000+103-100=1003.
Метку 1003 вставит Linkmeup_R3 в кадр, который хочет отправить на Linkmeup_R1 в этом VFI.
Linkmeup_R1→Linkmeup_R3
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤101≤109.
Метка: LB + Local VE ID — VBO = 3000+101-100=3001.
Метку 3001 вставит Linkmeup_R1 в кадр, который хочет отправить на Linkmeup_R3 в этом VFI.
Linkmeup_R1→Linkmeup_R4
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤101≤109.
Метка: LB + Local VE ID — VBO = 4000+101-100=4001.
Linkmeup_R4→Linkmeup_R1
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤104≤109.
Метка: LB + Local VE ID — VBO = 1000+104-100=1004.
Linkmeup_R3→Linkmeup_R4
Неравенство VBO ≤ Local VE ID ≤ VBO+VBS-1 выполняется: 100≤103≤109.
Метка: LB + Local VE ID — VBO = 4000+103-100=4003.
К сожалению, в реальной жизни таких красивых цифр не увидишь, там будут нагромождения тарабарщины. Но с
другой стороны, и вчитываться в них вам особо не придётся — обычно, если метка выделена, то уже не
принципиально, какая.
3. Соответственно, если сейчас мы отправим ping с Blue-A на Blue-D, то должны увидеть VPN-метку 3001 в ICMP-
Request и 1003 в ICMP-Reply:
Вы по-прежнему можете использовать команды show mpls l2transport vc detail и show l2vpan atom vc detail для
просмотра деталей:
Командой show bgp l2vpn vpls rd X ve-id Y block-offset Z вы можете вывести всю информацию о блоке меток от
данного соседа.
Сложность и количество команд настройки выглядит больше, чем для режима Martini, но нужно помнить, что
1) Это однократная настройка. При добавлении нового PE в VPLS-домен, настраивать нужно только его (в случае
использования RR). Для Martini придётся пройтись по всем существующим PE этого VPLS-домена.
2) Конфигурация по большей части одинаковая — меняется только VE ID. Секция BGP вообще берётся копипастом
(в случае использования RR).
Теория и практика VPLS Kompella mode на примере Juniper: русским для русских.
Конфигурация и примеры вычисления меток: Сама cisco.
Matini vs Kompella
В результате, какие преимущества даёт использование BGP Kompella mode перед Martini Mode?
• Auto-Discovery. Нет необходимости на каждом PE настраивать удалённые LDP-сессии со всем участниками
этого VPLS-домена. При использовании RR вопрос полной связности совсем отпадает.
• Вместе с Auto-Discovery BGP поддерживает и обмен префиксами/метками. Это обычно ставится в плюс
методу, хотя это необходимая функция.
• Здесь, вероятно, лучше заметить, что если у оператора уже есть инфраструктура BGP, то L2VPN
сигнализацией через BGP впишется в неё органично.
А вот если этот протокол до сих пор не использовался, то выглядеть он может, как пятая нога.
• У BGP всё схвачено на предмет Inter-AS VPN. Option C позволит организовать бесшовный (seamless) MPLS
между различными AS и протянуть через него тысячи PW.
Междоменные (Inter-AS) VPN не такая уж большая сложность для Martini при организации иерархического
VPLS — тогда нет нужды создавать полносвязную топологию PE-устройств в VPLS-домене. Про H-VPLS мы
ещё поговорим позже. Можем вычеркнуть это из его слабых сторон.
Что же касается столь активно эксплуатируемого Auto-Discovery в Kompella, то тут есть два замечания:
Во-первых, уже давно для внедрения конфигурации используются внешние средства. И эти внешние средства
могут, проводя анализ конфигурации, находить соседей и готовить скрипты для узлов без ручного труда чёрных
инженеров.
Многие проприетарные системы управления поддерживают этот функционал. А сети, в которых действительно
это требуется обычно моновендорные и управляются такими NMS.
Во-вторых, RFC 4762 вводит механизм Auto-Discovery в режим Martini. Реализован он может быть через RADIUS
или через тот же BGP.
Например, оборудование cisco позволяет настроить режим LDP + BGP Autodiscovery командой autodiscovery LDP
signaling BGP в секции l2vpn vfi. С одной стороны имеем простой и неизбыточный метод распределения меток, с
другой механизм автоматического поиска соседей (правда секцию BGP придётся оставить).
Как бы то ни было у Martini теперь есть решения для задачи обнаружения соседей и ещё одно очко
присуждается Гриффиндору.
Вместе с бережным отношением к меткам, простотой конфигурации и отладки, Martini Mode не только не
выглядит аутсайдером, но и, вообще-то давно сыскал любовь операторов. И сегодня он занимает подавляющую
долю рынка.
Ну и под занавес ещё одна оптимизация VPLS, которая делает жизнь чуточку легче.
Иерархический VPLS (H-VPLS)
Изначально VPLS — это плоская технология — все соседи одного ранга. И если в Kompella mode RR в очередной
раз эффективно решают проблему полносвязной топологии, то Martini Mode в операторских сетях может вызвать
кризис рабочей силы — все инженеры будут только настраивать удалённые LDP-сессии. Напомню сложность
задачи O(n^2): n*(n-1)/2 — где n — число узлов.
Такая топология скрывает и ещё одну проблему — широковещательные кадры Ethernet — каждый пакет будет
повторён столько раз, сколько соседей у данного PE.
А не можем ли мы здесь применить что-то вроде BGP-шных Route Reflector'ов?
Можем. Наш путь к спасению — H-VPLS (Hierarchical VPLS), который описан в RFC 4762.
MTU-s обычно имеют восходящие интерфейсы к двум PE-rs — для отказоустойчивости. Но может быть и один.
Механизмы подключения MTU-s к PE-rs: MPLS PW или QinQ. Поскольку мы тут про MPLS, то будем рассматривать
только первый способ.
PE-rs между собой взаимодействуют как обычные PE, образуя полносвязную топологию и используют правило
расщепления горизонта.
При взаимодействии PE-rs и MTU-s, PE-rs воспринимает PW от MTU-s как AC-интерфейс, то есть, как рядового
клиента.
А значит:
— Всё, что PE-rs получил от MTU-s он рассылает всем соседним PE-rs и всем подключенным MTU-s,
— То, что PE-rs получил от соседнего PE-rs он рассылает всем подключенным к нему MTU-s, но не отправляет
другим PE-rs.
Таким образом, каждому MTU-s нужно поддерживать связь только с двумя (или одним) соседом, а количество
PE-rs достаточно невелико, чтобы организовать между ними полносвязную топологию.
При добавлении нового узла нужно настроить только его и вышестоящий PE-rs.
Для организации Inter-AS VPN H-VPLS тоже может сослужить службу. Например, два подключенных друг к другу
ASBR могут быть PE-rs более высокого уровня иерархии.
Практика H-VPLS
Мы не будем усложнять себе жизнь резервированиями и Dual-Homing'ом. Вместо этого останемся в рамках
нашей же топологии, но Linkmeup_R1 станет MTU-s, а Linkmeup_R2 — PE-rs.
Linkmeup_R2(config-vfi)# vpn id 63
Первой командой входим в режим настройки xconnect, следующими двумя связываем AC-интерфейс и VC-канал.
ID 6310 произвольный, но должен совпадать с тем, который мы настроим на PE-rs. Здесь я выбрал 63 — как
индикатор VPN ID, а 11 — порядковый номер VC на данном MTU-s.
Linkmeup_R1(config-xconnect)#interface GigabitEthernet3
Linkmeup_R1(config-if-srv)#encapsulation default
Что произошло?
PW поднялись
Большой клиент, много трафика. И вот случается что-то страшное, и таблица MAC-адресов очищается. И сотни
дурнопахнущих мегабит устремляются во все концы VPLS-домена. И на линиях, где раньше проходил только
трафик данного филиала этого клиента, теперь летит всё-всё-всё.
Коварство этой ситуации заключается в том, что это кратковременные всплески, которые мгновенно забивают
очереди QoS, вызывая потери, невзирая на ширину канала. И вы даже не увидите эти всплески в статистике
интерфейса, потому что оборудование просто не успело их зафиксировать.
Случай Б
Вообще-то он уже был описан раньше, да и похож немного на Случай А. В этот раз просто дам больше деталей.
Вот такая сеть:
Как видите, тут филиал крупного клиента подключен через узкий арендованный канал с полосой пропускания
100 Мб/с. И как бы ему их за глаза.
Но, случается что-то страшное и таблица MAC-адресов очищается. И весь трафик этого VSI, для которого не
изучен в данный момент MAC-адрес назначения, будет широковещаться. И если, например, общий трафик этого
клиента составлял 400 Мб/с, то это 400 Мб/с флуда по всей сети, которая упрётся в 100 Мб/с арендованного
канала. После чего последуют кратковременные потери трафика на время переизучения MAC-ов. А для больших
сетей это может занять несколько минут.
Случай В
Расширим случай Б. Теперь у нас на доступе не один клиент, а кольцо коммутаторов. И одна линия между ними
выполнена в виде РРЛ-пролёта. Ситуация не такая редкая, учитывая масштабы расстояний в нашей необъятной,
а, скорее, даже типичная.
В целом, происходит всё то же, что и в случае Б, но при этом у нас здесь есть ещё какое-то решение по защите от
петель: STP или какой-то проприетарный протокол. Суть их одна — заблокировать лишний порт. А если что-то не
так со связностью, о которой они судят по наличию и отсутствию сообщений, разблокировать.
Теперь следующий шаг наших размышлений — флуд, который заваливает узкие линии и ведёт к потерям
пакетов. Если в этом трафике большое количество высокоприоритетных пакетов CS6/CS7, то теряться будут и
кадры протоколов. И тогда начинается цирк — протокол восстанавливает линк, потому что думает, что топологии
хана, и что происходит? В открытый порт устремляется 100 Мб/с трафика, который усугубляет ситуацию.
Это всё может дальше и по нарастающей пойти, цепляя за собой всё большие и большие участки сети.
Случай Г
Буква эта даже немного говорящая. Потому что такой случай не может произойти просто так.
Вот такая сеть.
Дизайн в данном случае предполагает, что между двумя PE прокинут дополнительный PW для сигнализации
протокола защиты от петель (как и в случае В). Точнее их два — один через прямой линк, другой окольный через
MPLS-сеть.
То есть мы получаем физическое кольцо коммутаторов, разделённое одним заблокированным портом.
Да, автор знает, что так сети не строят. Да, автор знает о последствиях. Нет, автор, не принимал участия в
разработке дизайна.
И ещё одна деталь — в разных кольцах есть точки подключения одного и того же клиента, соответственно, в них
направлен один и тот же VSI.
Теперь представьте себе ситуацию, что приехал огромный такой трактор и начал точечно погружать свой ковш в
землю пока не порвал оптику сразу в двух местах. На самом деле достаточно вспомнить про плоские кольца, и
ситуация уже не кажется такой невозможной.
Итак, когда обрывают сразу два конца одного кольца, PE оказывается изолированным, соответственно все его
PW переходят в состояние Down, в том числе и служебный для протокола защиты от петель. Протокол думает,
что кольца сейчас разомкнуты (а они действительно разомкнуты) и восстанавливает заблокированный
интерфейс в обоих кольцах. Чувствуете уже засаду? у нас есть две цепочки коммутаторов, которые кончаются на
двух PE и подключены к интерфейсам, привязанным к одному и тому же VSI. Два разомкнутых физических
кольца срастаются в одно замкнутое логическое кольцо. И если один PE изолирован и не может навредить
остальной части сети, то второй вполне себе в бою и начинает злостно рассылать широковещательный трафик.
Случай Д
Имеется сеть VPLS с двумя центральными PE. Например, это сеть DCI. ДЦ1 подключен к двум PE — так
называемый Dual-Homing — режиме Active/Active — то есть оба плеча могут принимать и передавать трафик.
При этом коммутация внутри не происходит — поэтому петля исключена.
Всё прекрасно, пока трафик в обоих направлениях ходит через одно и то же плечо. Интересное начинается в
случае ассиметричного пути. Например, трафик к ДЦ1 приходит по левому плечу, а уходит по правому.
В целом, нормальная ситуация. Но не для L2. PE1 будет изучать MAC-адреса других ДЦ — весь такой молодец, но
трафик от ДЦ1 будет приходить на PE2, который ни сном ни духом про MAC-адреса. Соответственно, он будет
полученный трафик широковещать и привет ситуации А-В.
Да, часть этих проблем — это непродуманный дизайн. Да, есть те или иные «решения», которые позволяют
уменьшить вероятность и серьёзность проблем, но Ethernet — как вода — просочится везде. И главная проблема
— в механизме широковещательных рассылок — это ахилесова пята по всём остальном прекрасного протокола,
который завоевал мир.
Сейчас, вероятно, вы думаете, что все беды на свете от L2, в том числе прошлогоднее землетрясение в Непале, и
надо от него уходить, предоставляя L3VPN. Что ж, где-то вы правы. Никто не мечтает избавиться от него так, как я,
который прошёл через все вышеперечисленные ситуации.
Однако это данность, от которой никуда не деться. И если мы не можем убрать корень проблемы в виде
механизма широковещательной рассылки в Ethernet, то можно придумать способ с ней бороться.
О нём мы и поговорим в следующий раз — EVPN. Революционное решение, которое переносит функцию
изучения MAC-адресов на Control Plane и привлекает для этого BGP.
Длина исходного кода этой статьи почти 190 000 символов. Возможно, это характеристика имени
«Марат».
============================================
Как вы помните из прошлого выпуска провайдер linkmeup встал на ступень Tier 2. Но просто предоставлять услуги
доступа в Интернет или L2/3VPN-ы (быть по сути трубой для трафика) Linkmeup не устраивает. Сейчас большим
спросом пользуются услуги облачного хранения данных, поэтому linkmeup обзавелся несколькими
собственными датацентрами, расположенные по экономическим соображениям в Рязани. В связи с этим перед
нами встала новая задача — как связать датацентры между собой и предоставить клиентам доступ к
корпоративным СХД, расположенные в наших автозалах? Ввиду того, что в core-network уже запущен MPLS, то
наш выбор пал на EVPN/MPLS. Его и рассмотрим.
Данная технология решает проблемы существующих на сегодняшний день методов объединения датацентров
через виртуальную L2 сеть. Конечно, эта технология не единственная в своем роде, но другие мы пока что
рассматривать не будем в силу их проприетарности. Всегда надо смотреть в будущее и хотя сегодня мы будем
строить сеть исключительно на Juniper MX, мы, как провайдер, не можем быть уверены в том, что завтра у нас не
появятся парочка ASR9K. Возможно, некоторые из решений, примененных в EVPN, вам покажутся слишком
сложными и непонятными. Но при этом не стоит забывать зачем эта технология была придумана, какие
проблемы она решает и возможно ли было реализовать это по-другому. Хотя в названии присутствует слово
микровыпуск, не стоит думать, что данная статья будет маленькой и простой. Наоборот, объем статьи более 115
000 знаков (порядка 60 страниц А4, написанных 11-м шрифтом) и многое из описанного не совсем очевидно и
понятно с первого раза.
Сразу хочу заострить внимание читателя на том, что в данной статье мы будем разворачивать и рассматривать на
практике EVPN поверх MPLS, а не VXLAN. Но, как вы понимаете, EVPN это control plane, поэтому принцип работы
что поверх MPLS, что поверх VXLAN будет примерно одинаков, но есть и существенные отличия. Поэтому, если вы
хотите поближе узнать EVPN/VXLAN, то можете почитать документацию, например, Brocade — у них эта тема
хорошо раскрыта, либо документацию Cisco на коммутаторы серии Nexus. Ну а мы приступим к изучению
EVPN/MPLS.
Содержание выпуска
Вспоминаем VPLS
Думаю, что все уже прочитали выпуск про L2VPN и представляют себе, что такое VPLS и с чем его едят. Немного
освежим в памяти какие виды VPLS существуют на сегодняшний день и чем же они существенно отличаются:
• VPLS LDP-signaling (Martini)
• VPLS LDP-signaling with BGP-Autodiscovery
• VPLS BGP-signaling (Kompella)
VPLS LDP-signaling (Martini) — наиболее простая технология, реализующая функционал VPLS, и в плане
конфигурирования и в плане траблшутинга, но сложна в администрировании, так как данная не наделена
функцией автоматического поиска РЕ-маршрутизаторов, входящих в один VPLS домен. Поэтому, все РЕ-
маршрутизаторы, участвующие в одном VPLS домене, явно прописываются на каждом РЕ-маршрутизаторе
вручную. В итоге, добавление нового сайта в существующий VPLS домен подразумевает изменение
конфигурации на всех РЕ-маршрутизаторах данного VPLS домена, что, на мой взгляд, не очень удобно, особенно
если у клиента 5-6 сайтов и более. К плюсам данной технологии можно отнести ее простоту и отсутствие
необходимости в добавлении нового семейства адресов в протокол BGP (для части старого оборудования в тот
момент, когда родилась технология, понадобилось бы обновить софт). Tак как вся сигнализация работает
исключительно по LDP, то работа данной технологии была понятна инженерами без необходимости что-то
заново изучать (всё-таки мы, люди, в основной своей массе существа ленивые). Но в современных реалиях,
думаю, что удобнее один раз добавить новое семейство адресов в BGP (пусть даже придется обновиться софт на
паре железок), а не бегать постоянно по всем PE-кам при добавлении нейбора в VPLS-домен.
VPLS LDP-signaling with BGP-Autodiscovery. В конечном счете разработчики технологии VPLS LDP-signaling все же
поняли свою ошибку — отсутствие автоматического поиска других РЕ-шек сильно ограничивало
масштабируемость данного решения в сравнении с VPLS BGP-signaling, поэтому было решено добавить в данную
технологию автоматический поиск РЕ-маршрутизаторов. Естественно, средствами LDP это реализовать у них не
получилось, поэтому был использован великий и могучий BGP, в который было добавлено еще одно семейство
адресов (причем отличное от семейства адресов, использующихся в VPLS Kompella), зарезервировано новое
расширенное комьюнити l2vpn-id и добавлен новый FEC — FEC129 (в VPLS LDP используется FEC128). В итоге, при
использовании данной технологии, поиск PE маршрутизаторов производится по протоколу BGP, а L2 каналы уже
сигнализируются по LDP. На мой взгляд, данными действиями разработчики перечеркнули все, чем они
гордились до этого и, если ваше оборудование поддерживает и Martini+BGP AD и Kompella, то лично я бы
предпочел второе.
VPLS BGP-signaling (Kompella). Данная технология сильно отличается от двух предыдущих — общая у них только
цель — организация виртуальной L2 сети поверх сети провайдера. Данный вид VPLS использует для
сигнализации протокол BGP, который обеспечивает и автоматический поиск соседей и сигнализирование
виртуальных L2 каналов. В итоге мы имеем хорошо масштабируемое решение, а меньшая распространенность
VPLS BGP-signaling в сетях провайдеров обусловлена скорее всего тем, что данная разработка продвигалась
Juniper и до определенного времени просто не поддерживалась другими вендорами, а также кажущаяся на
первый взгляд сложность самой технологии — чего стоит одна модель распределения меток.
Все перечисленные технологии обеспечивают один и тот же результат — организацию виртуальной L2 сети
поверх сети провайдера, разнятся только средства реализации и возможности данных технологий, о которых вы
можете почитать в предыдущем выпуске СДСМ. Но у данных технологий есть несколько общих проблем,
которые накладывают определенные неудобства при эксплуатации и не дают покоя разработчикам. Таких
проблем как минимум три:
1. Нет возможности для multihomed сайтов (сайтов, подключенных к 2-м и более PE маршрутизаторам
одновременно) использовать все линки для передачи трафика (работать в Active-Active mode);
2. Эти технологии не предоставляют расширенных функций L3, за исключением банального
добавления BVI/IRB (Bridge Virtual Interface/Integrated Routing and Bridging) интерфейса в VPLS домен для выхода
во внешнюю сеть;
3. MAC-адреса изучаются исключительно на уровне data plane, что приводит к увеличению
флуда BUM (roadcast, Unknown Unicast, Multicast) трафика в сети провайдера.
Бороться с этими недостатками в VPLS уже бесполезно — это сильно усложнит и так не простые технологии (к
примеру есть технология NG-VPLS (Next-Generation VPLS), которая используется P2MP LSP, но о ее реальном
использовании я не слышал). Поэтому была изобретена новая технология, в которой данные недостатки были
устранены. Сегодня мы поговорим об Ethernet VPN (EVPN). Бытует мнение, что данная технология является
развитием VPLS BGP-signaling, думаю, что для простоты восприятия, не будет лишним в данной статье сравнивать
EVPN c VPLS BGP-signaling (далее буду писать просто VPLS, что подразумевает именно VPLS BGP-signaling).
Лично мое мнение, что данная технология является гибридом L3VPN и VPLS BGP-signaling. А почему, думаю, вы
поймете, дочитав статью до конца. Итак, поехали…
Как вы уже поняли, EVPN использует MAC-адреса, как роутинговые адреса. Это можно сравнить с
распределением маршрутов внутри L3VPN.
Думаю все прочитавшие статью о L2VPN помнят, что в VPLS распределение меток с помощью BGP производится
блоками, так как получателю пакета (в смысле PE маршрутизатору) необходимо знать, с какого PE-
маршрутизатора прилетел данный пакет, и ассоциировать MAC-адрес с PW до этого PE маршрутизатора. В EVPN
такой необходимости уже нет. Это происходит из за того, что EVPN обрабатывает MAC-адреса, так же, как L3VPN
IPv4 префиксы — PE маршрутизатор, изучив новый MAC-адрес через data plane от подключенного CE
маршрутизатора, сразу анонсирует данный MAC по BGP. В BGP анонсе указывается MPLS метка и protocol next-
hop (как правило, это лупбек PE маршрутизатора). В итоге все остальные PE маршрутизаторы знают куда
отправлять пакет и с какой меткой.
Интересный факт: в VPLS (любом его виде), в описанном выше сценарии, PE3 узнала бы только MAC-адрес CE1,
так как от CE2 к CE1 пакет передается уже юникастом и не попадет на PE3. А при использовании EVPN PE3 изучает
оба MAC-адреса: и CE1 и CE2, первый узнает из анонса от PE1, второй из анонса от PE2.
Надеюсь, принцип работы технологии понятен, и теперь мы можем перейти от теории к практике и посмотреть
на работу EVPN на примере.
Juniper позволяет нам сконфигурировать routing-instance для EVPN двумя способами — первый это instance с
типом EVPN (VLAN Based Service) — самый простой, и второй, instance с типом virtual-switch (VLAN Aware Service).
Лично мне больше нравится второй вариант, так как он более гибок, но для наглядности в нашей лабе мы будем
использовать оба способа. Однако различия этих двух способов не только в конфигурации.
• VLAN Based Service — данный тип использования EVPN хорош тем, что bridge-домены полностью
изолированы друг от друга. Но на каждый влан придется делать новую routing instance. В таком сценарии трафик
между PE маршрутизаторами может идти как с влан тегом так и не тегированным. JunOS по умолчанию
отправляет тегированный трафик с оригинальным тегом (если, конечно, не настроены какие-либо правила
перезаписи тега на интерфейсе).
• Конфигурация routing instance с типом EVPN выглядит вот так:
•
bormoglotx@RZN-PE-3> show configuration routing-instances RZN-VPN-1
instance-type evpn;
vlan-id 777;
interface ge-0/0/2.200;
interface ge-0/0/2.777;
routing-interface irb.777;
route-distinguisher 62.0.0.3:1;
vrf-import VPN-1-IMPORT;
vrf-export VPN-1-EXPORT;
protocols {
evpn {
interface ge-0/0/2.777;
flexible-vlan-tagging;
encapsulation flexible-ethernet-services;
mac 50:01:00:03:00:04;
unit 777 {
encapsulation vlan-bridge;
vlan-id 777;
family bridge;
vlan-id 777;
Это значение определяет, какой тег используется для нормализации. То есть если к данному EVPN инстансу будет
подключен помимо влана 777 еще и влан 200 (как в показанном выше конфиге), то при получении пакета с тегом
200, PE маршрутизатор будет снимать данный тег (тег 200) и навешивать новый — 777. На прием PE-ка будет
действовать в обратной последовательности — сниматься тег 777 и навешивать тег 200 при отправке в интерфейс
в сторону CE-маршрутизатора, в нашем случае в интерфейс ge-0/0/2.200 (см конфигурацию выше, на схемах
данный CE маршрутизатор не показан).
Это минимальная конфигурация, которая позволит EVPN работать (не забываем про базовую настройку сети —
IGP, MPLS и т.д., которая тут не представлена). Как видите, мы указываем RD и RT, так как для сигнализации
используется BGP. Все как обычно — RD делает наш маршрут уникальным, а RT используются для фильтрации
маршрутов. Политики импорта и экспорта на всех PE-маршрутизаторах одинаковые, но для тех, кому интересна
их конфигурация, приведу ее под спойлером:
Конфингурация политик
• VLAN Aware Service — в этом случае мы делаем только одну routing instance с типом virtual switch и
добавляем в нее bridge-домены. Если у клиента будет 30 вланов, нам не надо городить конфиг на сотни строк,
делая instance на каждый влан — достаточно в созданный для клиента instance добавить 30 bridge-доменов. В
этом случае наличие vlan тега, согласно RFC, обязательно.
• Конфигурация instance с типом virtual-switch имеет примерно такой вид:
•
bormoglotx@RZN-PE-1> show configuration routing-instances RZN-VPN-1
instance-type virtual-switch;
interface ge-0/0/2.0;
route-distinguisher 62.0.0.1:1;
vrf-import VPN-1-IMPORT;
vrf-export VPN-1-EXPORT;
protocols {
evpn {
extended-vlan-list 777;
bridge-domains {
VLAN-777 {
vlan-id 777;
flexible-vlan-tagging;
encapsulation flexible-ethernet-services;
mac 50:01:00:01:00:04;
unit 0 {
family bridge {
interface-mode trunk;
vlan-id-list 777;
Никаких проблем при использовании с одной стороны EVPN, с другой virtual switch быть не должно (если вы все
делаете как положено), так как JunOS из инстанса EVPN отправляет тегированный трафик с оригинальным тегом.
Во всяком случае в ходе тестирования я проблем не обнаружил. Но есть один нюанс. Стоит учитывать, что
нормализация может сыграть с вами злую шутку, если вы начнете в одном и том же EVPN домене использовать
разные типа инстансов не разделяя вланы по bridge-доменам. К примеру на одном PE-маршрутизаторе в инстанс
с типом EVPN вы добавляете два влана: 777 и 1777, а для нормализации используете влан 777. С другого конца у
вас будет virtual switch с двумя bridge доменами — vlan 777 и vlan 1777. В итоге что получаем: пакет прилетает от
CE во влане 1777, происходит нормализация влана на 777 и в инстанс virtual switch пакет прилетает во влан 777.
А хост назначения то во влане 1777, то есть в другом bridge домене. В итоге — у вас нет связности между хостами
в одном влане. Либо другой вариант развития событий — в одном и том же bridge домене вы сконфигурировали
разные теги, предназначенные для нормализации. В таком сценарии у вас тоже не будет связности (вообще не
будет), так как с PE1 пакет будет улетать например с нормальным тегом 777, а на PE2 нормальный тег — 1777. В
итоге PE2 будет просто отбрасывать пакеты с не соответствующим номером влана.
Маршруты EVPN
В данный момент времени еще обмена пакетами между CE маршрутизаторами не производилось (естественно,
CDP и прочие радости отключены, дабы в сеть не улетало что то лишнее), поэтому ни один из PE
маршрутизаторов не изучил ни одного MAC-адреса. Это можно проверить:
RZN-VPN-1 1 1 0 0 2 0 0 0
Из данного вывода мы можем узнать, что всего в данном routing-instance 1 интерфейс и он в активном
состоянии, IRB интерфейсов у нас нет (о них позже). Мы видим двух соседей ( по нашей схеме это PE2 и PE3), а
также что нами еще не изучен ни один MAC-адрес ( local — это MAC-адреса, локальные для данного PE
маршрутизатора, а remote — это MAC-адреса, полученные от соседних PE маршрутизаторов).
Теперь посмотрим, какие маршруты у нас есть в таблице маршрутизации данной routing-instance:
3:62.0.0.1:1::777::62.0.0.1/304
*[EVPN/170] 01:33:42
Indirect
3:62.0.0.2:1::777::62.0.0.2/304
3:62.0.0.3:1::777::62.0.0.3/304
У нас всего три маршрута, причем первый локальный для PE1. Что же это за маршруты и зачем они нужны?
Давайте разбираться. В EVPN существует всего 5 типов маршрутов:
• 1 — Ethernet Auto-Discovery (A-D) route
• 2 — MAC/IP Advertisement route
• 3 — Inclusive Multicast Ethernet Tag route
• 4 — Ethernet Segment route
• 5 — IP Prefix Route*
Примечание: маршрут 5-го типа в настоящее время еще не утвержден в статуте RFC, и пока что описан только
в драфте и поэтому в данной статье мы его рассматривать не будем.
RD — думаю всем понятно, что это такое, в показанном ниже анонсе это :62.0.0.3:1:
Ethernet Tag ID — это номер влана, в нашем случае :777:
IP Address Length — длина IP-адреса, указанного в следующем поле (на оборудовании Juniper данное значение
не показывается)
Originating Router’s IP Address — IP-адрес оригинатора маршрута, как правило лупбек PE маршрутизатора. В
нашем случае это :62.0.0.3.
Примечание: /304 — длина префикса, Juniper автоматически добавляет ее ко всем EVPN маршрутам, смысловой
нагрузки по сути не несет. Как написано на сайте Juniper, данное значение означает максимальную длину
маршрута и позволяет использовать эту особенность при поиске маршрутов с помощью регулярных выражений.
Ну что ж, учтем на будущее.
Address: 0x95ca3d4
Source: 62.0.0.255
Task: BGP_6262.62.0.0.255+179
AS path: I (Originator)
Communities: target:6262:777
Import Accepted
Localpref: 100
PMSI расшифровывается как Provider Multicast Service Interface, и это не что иное, как Point-to-Multipoint LSPs. В
данной статье мы не будем рассматривать как работает p2mp LSP, так как это очень большая и сложная тема, но,
как видите, в EVPN используется функционал p2mp LSP для пересылки BUM трафика. PE3 сгенерировал метку
299904, которую могут использовать другие PE маршрутизаторы, чтобы отправить BUM трафик на PE3.
Маршрут типа 3 генерируется на каждый влан отдельно, о чем и говорят в его названии слова Ethernet Tag. Если
у вас будет два bridge-домена (например влан 777 и влан 1777), то PE маршрутизатор сгенерирует два маршрута
типа 3 — по одному на каждый влан (bridge-домен).
Мы выяснили, что в начальный момент времени в таблице маршрутизации EVPN есть только маршруты типа 3,
чтобы PE маршрутизаторы знали с какой меткой им отправлять широковещательные пакеты на удаленные PE
маршрутизаторы.
RZN-CE1-SW1#ping 10.0.0.2
.!!!!
Одни пакет потерялся, так как CE1 сделал ARP запрос на резолв адреса 10.0.0.2. Теперь посмотрим, появились ли
адреса в MAC-таблице:
RZN-VPN-1 1 1 0 0 2 0 1 1
Появились сразу два MAC-адреса: один локальный для PE1 (адрес CE1) и один MAC, полученный от PE2 (адрес
CE2):
2:62.0.0.1:1::777::aa:bb:cc:00:06:00/304
*[EVPN/170] 00:05:23
Indirect
2:62.0.0.2:1::777::aa:bb:cc:00:07:00/304
Теперь у нас в таблице два новых маршрута (всего в таблице маршрутов 5, маршруты типа 3 не показаны для
сокращения вывода). Маршруты имеют тип 2 — MAC/IP Advertisement route. Данный маршрут имеет следующий
вид:
Address: 0x95c9f90
Source: 62.0.0.255
Age: 26 Metric2: 1
Task: BGP_6262.62.0.0.255+179
AS path: I (Originator)
Communities: target:6262:777
Import Accepted
ESI: 00:00:00:00:00:00:00:00:00:00
Localpref: 100
Как я и написал ранее, EVPN использует MAC-адреса как роутинговые адреса. Из анонса от PE2, PE1 теперь знает,
что, чтобы добраться до MAC-адреса aa:bb:cc:00:07:00 во влане 777 (обращаю внимание, что именно в 777 влане,
так как один и тот же MAC-адрес может быть в разных вланах, и это будут разные маршруты), необходимо
навесить на пакет две метки: 300272 (VPN) и транспортную метку до 62.0.0.2.
Примечание: помимо всем известных полей Route Distinguisher, Protocol next hop и т д, мы видим поле ESI,
которое в данном анонсе выставлено в нули. Это поле очень важно при использовании multihomed сайтов, и к
нему мы вернемся чуть позже, в данном сценарии оно не играет роли.
Как и L3VPN, EVPN умеет генерировать метки per-mac, per-next-hop и per-instance:
• per-mac — на каждый мак адрес генерируется отдельная метка. Как вы понимаете данный вид
распределения меток слишком расточителен;
• per-next-hop — наверно точнее будет сказать per-CE или per-AC, то есть одна и та же метка генерируется
только для MAC-адресов, находящихся за одним и тем же Attachment Circuit (то есть если к одному PE
маршрутизатору в одном routing-instance подключено два CE маршрутизатора, то для MAC-адресов, изученных
от CE1, PE маршрутизатор будет генерировать одну метку, а для MAC-адресов, изученных от CE2 — другую)
• per-instance — одна метка генерируется на весь routing-instance, то есть у всех маршрутов будет одна и та
же метка. В JunOS вы можете увидеть данную метку при просмотре EVPN instance в режиме extensive.
Изучение MAC-адресов
Теперь посмотрим на MAC-таблицу на PE1:
MAC flags (S -static MAC, D -dynamic MAC, L -locally learned, C -Control MAC
aa:bb:cc:00:06:00 D ge-0/0/2.0
Колонка flag говорит нам о том, как был изучен данный адрес: MAC-адрес aa:bb:cc:00:06:00 имеет только флаг D,
что означает, что этот мак изучен динамически (стандартным способом через data plane) и, так как больше
никаких флагов мы не видим, то можем с уверенностью сказать, что данный MAC изучен от локально
подключенного CE маршрутизатора. А вот MAC-адрес aa:bb:cc:00:07:00 имеет два флага — DC. Что значит первый
флаг, мы уже знаем, а вот флаг С говорит о том, что данный адрес изучен через control plane.
Если мы посмотрим на таблицу MAC-адресов на PE3, то увидим, что все адреса изучены данным PE
маршрутизатором через control plane, и нет ни одного локального MAC-адреса:
MAC flags (S -static MAC, D -dynamic MAC, L -locally learned, C -Control MAC
Примечание: если вы заметили, в одном случае я использовал команду show bridge mac-table, а во втором show
evpn mac-table. Это обусловлено тем, что на разных PE маршрутизаторах routing instance сконфигурированы по-
разному — в первом случае virtual-swicth, во втором EVPN.
На PE3 нет ни одного изученного локально MAC-адреса, так как еще не было трафика от CE3. Давайте исправим
данную ситуацию, запустив пинг до CE3, и еще раз посмотрим данную таблицу:
RZN-CE1-SW1#ping 10.0.0.3
.!!!!
MAC flags (S -static MAC, D -dynamic MAC, L -locally learned, C -Control MAC
aa:bb:cc:00:05:00 D ge-0/0/2.777
Как видите, на PE3 теперь появился MAC-адрес CE3, изученный через data plane.
Как и у обычного свича, адреса в MAC-таблице EVPN имеют определенный “срок годности”, по умолчанию этот
срок равен 300-м секундам. Если в течении данного времени этот MAC был неактивен и не обновлялся, то
маршрут удаляется из таблицы. Вроде, все просто — таймер отработал — MAC удалили. Но все не так просто, как
кажется. Давайте рассмотрим, как это происходит.
Итак, PE3 изучил MAC-адрес CE3 и отправил его в BGP анонсе остальным PE маршрутизаторам. Предположим, что
в течении 300 секунд запись не обновлялась. Тогда PE3 должен удалить данный MAC-адрес из таблицы, что он и
делает. Но мы помним, что PE3 отправил всем своим соседям информацию о том, что данный MAC-адрес
находится за ним. А вдруг этот хост переехал или вообще уже выключен? Что тогда? Остальные PE
маршрутизаторы так и будут слать пакеты для CE3 на PE3, как в черную дыру? Конечно, нет. Дело в том, что если
PE маршрутизатор удаляет из таблицы локальный MAC-адрес, то он отправляет BGP Withdrawn сообщение,
которое заставляет другие PE маршрутизаторы удалить этот маршрут, а следовательно и MAC-адрес, из своих
таблиц. Давайте это проверим.
На первом скрине представлен BGP UPDATE Message, который объявляет MAC-адрес aa:bb:cc:00:07:00 (картинки
кликабельны):
Спустя 300 секунд, мы видим еще одно BGP UPDATE Message, которое является Withdrawn сообщением,
отменяющим маршрут до указанного ранее MAC-адреса:
Помимо MAC aging time, у EVPN есть механизм сигнализации о смене MAC-адреса. Когда от CE маршрутизатора
PE-ка получает Gratuitous ARP, то генерируется BGP Update, в котором содержится withdrawn сообщение с
указанием старого MAC-адреса и анонс нового MAC-адреса.
Но помимо MAC-адреса маршрут MAC/IP Advertisement route может опционально содержать в себе и IP-адрес
хоста. Добавим в наш EVPN роутинговый-интерфейс IRB и посмотрим какой маршрут появился:
family inet {
address 10.0.0.254/24;
mac 02:00:00:00:00:02;
bormoglotx@RZN-PE-1> *2:62.0.0.1:1::777::02*
2:62.0.0.1:1::777::02:00:00:00:00:02/304
*[EVPN/170] 14:17:31
Indirect
2:62.0.0.1:1::777::02:00:00:00:00:02::10.0.0.254/304
*[EVPN/170] 14:17:31
Indirect
Появились два новых маршрута, причем первый это только MAC-адрес irb.777, а вот второй MAC+IP. Mac+IP
анонс имеет вид ARP записи, все PE маршрутизаторы, участвующие в одном EVPN-домене, синхронизируют свои
ARP записи, что позволяет уменьшить количество флуда широковещательных ARP запросов по сети провайдера.
Address: 0x940d804
Task: RZN-VPN-1-evpn
AS path: I
Communities: evpn-default-gateway
ESI: 00:00:00:00:00:00:00:00:00:00
В данном маршруте появилось новое расширенное коммьюнити evpn-default-gateway. Именно так помечаются
маршруты, которые являются основным шлюзом для routing-instance. Данный маршрут будет генерироваться
для каждого влана отдельно.
Почему генерируются два маршрута? Дело в том, что первый маршрут, в котором указан только MAC-адрес,
используется исключительно для свитчинга в bringe-домене, а вот маршрут MAC+IP уже используется для
маршрутизации и является по своей сути arp записью. Забегу чуточку вперед и напишу, что точно так же будут
генерироваться маршруты до хостов при движении трафика в другие вланы или во внешнюю сеть (это мы
рассмотрим далее при добавлении в схему еще одного влана).
1:62.0.0.2:0::112233445566778899aa::0/304
Данный маршрут не несет информации о MAC-адресах, но имеет очень широкое применение, такое как:
• Автоматический поиск PE маршрутизаторов, к которым подключен один и тот же CE-маршрутизатор
• Анонс ESI метки
• Анонс массовой отмены изученных MAC-адресов
• Анонс Aliasing метки
Маршрут типа 1 может анонсироваться per-EVI или per-ESI. Первый анонс используется при анонсировании
Aliasing метки, второй — для возможности массовой отмены анонсированных MAC-адресов какого-либо ethernet
сегмента.
В представленном выше выводе магический набор букв и цифр :112233445566778899aa: есть не что иное, как
ESI, сконфигурированный администратором сети на физическом интерфейсе:
flexible-vlan-tagging;
encapsulation flexible-ethernet-services;
esi {
11:22:33:44:55:66:77:88:99:aa;
single-active;
mac 50:01:00:02:00:06;
unit 111 {
encapsulation vlan-bridge;
vlan-id 111;
family bridge;
Данный маршрут, помимо ESI несет в себе очень важное значение, которое представлено в виде расширенного
коммьюнити: esi-label. Выглядит оно следующим образом:
Address: 0x95c0f28
Source: 62.0.0.255
Task: BGP_6262.62.0.0.255+179
AS path: I (Originator)
Import Accepted
Localpref: 100
Так как данный маршрут имеет в своем составе нативное расширенное комьюнити, характерное для данного
EVPN-домена, то все PE маршрутизаторы в evpn-домене импортируют данный маршрут в таблицу
маршрутизации соответствующей EVPN instance:
bormoglotx@RZN-PE-3> show route table RZN-VPN-3.evpn.0 match-prefix *1:62* detail | match esi
У нас может быть два сценария: когда используется режим Single-Active и когда используется режим Active-Active
(All-Active).
Как нетрудно догадаться, в Single-Active режиме у нас работает только одно плечо, второе находится в резерве. В
случае падения основного плеча, трафик переходит на резервное. Возможно использовать одно плечо для
передачи трафика в одном влане, а второе во втором, но сразу по обоим плечам в одном влане трафик идти не
может (точнее не должен — если не так, то пишите в поддержку, видимо вы нашли баг, либо, что более
вероятно, у инженера, который собирал схему, кривые руки).
В Active-Active или All-Active режиме работают все линки от CE к PE, для чего собирается MC-LAG. Принцип
работы технологии MC-LAG в данной статье рассматриваться не будет: подразумевается, что читатель уже изучил
данную тему.
В первом случае все просто — выбирается DF, и весь трафик, включая и BUM трафик, форвардит только он. При
этом ESI label в анонсе отсутствует (во всяком случае на оборудовании Juniper ее нет), хотя согласно RFC даже при
Single-Active режиме рекомендуется использовать данную метку, чтобы в случае ошибки в работе механизма
выбора DF (когда оба PE маршрутизатора вдруг будут считать себя DF) не образовалась петля.
При нормальной работе механизма выбора DF одно плечо просто блокируется, а значит PE маршрутизатор не
изучает по заблокированному линку MAC-адреса, следовательно и не анонсирует ничего на другие PE
маршрутизаторы. Но, даже если каким то заковыристым путем на данный маршрутизатор прилетит BUM трафик,
то он будет просто отброшен.
Во втором случае немного сложнее. Тут так же выбирается DF, который имеет право отправлять BUM трафик в
сторону CE маршрутизатора — то есть проблемы с трафиком, идущим к CE маршрутизатору, нет. Проблемы могут
появиться при передаче BUM трафика от CE маршрутизатора. Так как CE маршрутизатору абсолютно без разницы
кто из PE маршрутизаторов DF (точнее сказать CE маршрутизатор думает, что просто подключен к другому
коммутатору агрегированным интерфейсом), то возможна следующая ситуация. Предположим, что
широковещательный пакет от CE1 прилетел на PE1, который не является DF. PE1 получает пакет и отправляет его
всем остальным PE маршрутизаторам, включая и PE2. PE2, являясь DF маршрутизатором для данного сегмента,
форвардит BUM трафик обратно на CE маршрутизатор. Да, получили петлю. Вот тут-то нам и пригодится ESI-label.
Дело в том, что при отправке пакета на PE2, PE1 навешивает две метки: ESI-label (дно меток) и Inclusive Multicast
label. PE2 получает пакет, снимает верхнюю метку и обнаруживает ESI-label, это говорит маршрутизатору о том,
что флудить пакет в сторону CE1 не надо, так как трафик из этого сегмента и прилетел. Но зачем же тогда этот
пакет вообще отправлять на PE2? Дело в том, что к PE2, помимо CE1, от которой и был получен данный трафик,
могут быть подключены другие CE маршрутизаторы, которые могут быть заинтересованы в данном трафике.
Сокращения на схеме:
IM — Inclusive Multicast label
ESI — ESI label
TL — Transport MPLS label
Примечание: PE1 и PE2 непосредственно соединены, поэтому транспортная метка при отправке трафика от PE1
на PE2 не навешивается. Если бы между ними было бы больше одного хопа, то мы бы получили стек из трех
меток.
Aliasing label
И снова данная функция касается multihoming CE. Трафик от CE маршрутизатора в All-Active режиме должен
балансироваться между всеми линками. Так как балансировка производится по какому-то алгоритму, известному
только самому CE маршрутизатору и его разработчику, то возможна ситуация, когда multihoming CE
маршрутизатор будет отправлять весь исходящий трафик только через один интерфейс. В результате, маршруты
типа 2 будут отправляться только с одного PE маршрутизатора, предположим что только с PE1:
Так как другие маршрутизаторы не будут знать, как добраться до указанного сегмента через PE2, то через него
трафик не пойдет, что вызовет простой одного из плеч между PE и CE маршрутизаторами. Для этого каждый PE
маршрутизатор анонсирует анонсирует Aliasing метку для своего ethernet сегмента. Так как остальные PE
маршрутизаторы получают маршруты типа 1, то они видят, что PE1 и PE2 имеют линки в одном и том же ES и
работают в All-Active режиме. Используя полученную Aliasing метку, другие PE маршрутизаторы могу отправлять
пакеты на CE маршрутизатор и через PE1 и через PE2, навещивая на пакет, который пойдет через PE2 вместо VPN
метки — Aliasing-метку, полученную в от PE2 в маршруте типа 1, сгенерированного per-EVI (EVPN instance).
Сокращения на схеме:
AL — Aliasing label
EVPN — EVPN label
TL — Transport MPLS label
В маршрутах типа 1 есть флаг, который отвечает за информирование других PE маршрутизаторов о том, в каком
режиме работает данный PE маршрутизатор в данном ethernet сегменте — Single-Active или All-Active. Данный
флаг находится находится в составе расширенного комьюнити, добавляемого к анонсу маршрута типа 1. Если
флаг поднят, то маршрутизатор работает в режиме Single-Active (флаг так и называется Single-Active flag), если
флаг не поднят — то маршрутизатор работает в All-Active режиме. Ниже пример маршрута, в котором поднят
флаг и отсутствует метка:
Nexthop: Self
Localpref: 100
AS path: [6262] I
Nexthop: Self
Localpref: 100
AS path: [6262] I
Примечательно, что данный маршрут не несет комьюнити, которое сконфигурено на экспорт из routing-instance:
Address: 0x95c1954
Source: 62.0.0.255
Task: BGP_6262.62.0.0.255+51796
AS path: I (Originator)
Communities: es-import-target:33-44-55-66-77-88
Import Accepted
Localpref: 100
Сгенерированное коммьюнити:
Communities: es-import-target:33-44-55-66-77-88
Если у другого PE маршрутизатора будет ESI, например aaaa334455667788aaaa, то, как не трудно догадаться, их
коммьюнити будет одинаково, а значит маршрут будет тоже импортирован. Но не стоит паниковать, все уже
украдено до нас: в теле самого маршрута указан полный идентификатор ESI и данный маршрут будет
импортирован, но проигнорирован. Как и RT, es-import-target предназначен только для фильтрации маршрутов.
Ниже представлен сам маршрут типа 4 и его комьюнити:
bormoglotx@RZN-PE-1> show route table bgp.evpn.0 match-prefix *4:62* detail | match "comm|\/304"
Communities: es-import-target:33-44-55-66-77-88
Думаю, вы уже догадались, что мы получаем в анонсе расширенное комьюнити, состоящее из всех нулей:
Nexthop: Self
Localpref: 100
AS path: [6262] I
Communities: es-import-target:0-0-0-0-0-0
Не стоит полагать, что из за этого все сломается. Даже с таким комьюнити все будет работать, но если у вас в сети
будут, например, ESI в диапазоне хх: хх:00:00:00:00:00:00:00:01-хх: хх:00:00:00:00:00:00:99:99, то у всех маршрутов
типа 4 будут одинаковые комьюнити, а значит PE маршрутизаторы будут принимать и устанавливать в таблицы
маршрутизации все маршруты типа 4, даже если они им не нужны. Но думаю, что об это не стоит париться,
плюс/минус 100 маршрутов погоды не сделают (почему не сделают — поймете, когда дочитаете статью до
конца).
Не знаю, заметил ли читатель, но в маршрутах типа 1 и 4 RD выглядит несколько странно. Например, маршрут
типа 2 от PE2:
2:62.0.0.2:1::777::aa:bb:cc:00:07:00/304
1:62.0.0.2:0::112233445566778899aa::0/304
От PE2 маршурт типа 1 имеет RD 62.0.0.2:0, хотя от этого же PE2 маршруты типа 2 или 3 прилетают с RD 62.0.0.2:1,
который и сконфигурен в routing instance. Что происходит с RD? Для проверки данного явления создадим два
routing instance с типом EVPN и назначим им совершенно разные RD:
route-distinguisher 62.0.0.1:3;
route-distinguisher 9999:99;
1:62.0.0.1:0::112233445566778899aa::0/304
1:62.0.0.1:0::aaaa334455667788aaaa::0/304
router-id 62.0.0.1;
И это значение берется как первая часть RD, а вторая выставляется в нашем случае в ноль. Давайте помянем
router id:
router-id 62.62.62.62;
1:62.62.62.62:0::aaaa334455667788aaaa::0/304
Как видите JunOS сам сгенерировал RD. Что будет если мы не укажем router-id? Давайте проверим. Но усложним
задачу, навесив на лупбек еще пару адресов:
unit 0 {
family inet {
address 10.1.1.1/32;
address 62.0.0.1/32;
address 62.62.62.62/32;
family iso {
address 49.0000.0620.0000.0001.00;
Смотрим теперь:
1:10.1.1.1:0::112233445566778899aa::0/304
1:10.1.1.1:0::aaaa334455667788aaaa::0/304
JunOS выбрал наименьший IP-адрес лупбека и использовал его как router-id. Это происходит потому, что данный
маршрут типа 1 сгенеирирован per-ESI. Если маршрут будет генерироваться per-EVI, то у него будет нативный RD
инстанса, из которого данный маршрут анонсируется. А вот маршрут типа 4 всегда будет иметь RD, уникальный
на маршрутизатор, так как он всегда генерируется per-ESI.
Генерация маршрута per-ESI имеет некоторую особенность. Так как идентификатор ESI конфигурируется на
физическом интерфейсе, то если у нас будет например 10 логических юнитов (можно сказать вланов) на данном
интерфейсе и все в разных EVPN-инстансах, то мы получим, что в разных инстансах будет сгенерирован один и
тот же маршрут типа 1. Зачем генерировать 10 одинаковых маршрутов (разница в них будет только в RT), если
можно сгенерировать только один и навесить на него RT-ки всех заинтересованных в данном маршруте
инстансов?
Давайте посмотрим как это работает на примере. Вот конфигурация ESI на физическом интерфейсе:
vrf-target target:62:1;
vrf-target target:62:2;
Nexthop: Self
Localpref: 100
AS path: [6262] I
Как видите, у маршрута две RT-ки: target:62:1, которая соответствует RZN-VPN-1 и target:62:2, соответствующая
eVPN-test. Эта функция уменьшает время сходимости. Если данный линк отвалится, то он отвалится у всех
инстансов, к которым он прикреплен. В нашем случае вместо 2-x BGP Withdrawn сообщений, улетит только одно,
но с двумя RT.
Примечание: маршруты типа 1 и 4, если будет желание у читателя будем рассматривать отдельно, в отдельной
статье, посвященной EVPN multihoming.
Механизм выбора DF
Механизм выбора DF позволяет выбрать разный DF для разных вланов, тем самым можно, например, добиться
балансировки трафика между различными bridge-доменами — трафик разных вланов будет идти по разным
линкам в сторону CE маршрутизатора внутри одного EVPN-instance.
Маршрутизатор отправляет анонс маршрута типа 4 с указанием ESI и соответствующим комьюнити и запускает
таймер выбора DF. По умолчанию данный таймер установлен в 3 секунды. Его можно изменить, но он должен
быть одинаков на всех PE маршрутизаторах сегмента — иначе алгоритм может отработать некорректно.
По истечению таймера все PE маршрутизаторы, участвующие в выборе DF, составляют полный список всех PE
маршрутизаторов сегмента начиная с самого маленького адреса. Каждому из PE маршрутизаторов в списке
присваивается номер (i), начиная с нуля.
После этого высчитывается номер DF по формуле V mod N = i, где V — номер влана, а N количество PE
маршрутизаторов в сегменте. Тот PE маршрутизатор, номер которого будет результатом вычисления и
становится DF данного сегмента в данном влане.
Попробуем высчитать DF для влана 777 если у нас будет только 2 PE маршрутизтора с адресами 62.0.0.1 и
62.0.0.2.
62.0.0.1 i=0
62.0.0.2 i=1
Так как влан у нас 777, то V=777, а N=2 (так как у нас всего два маршрутизатора в сегменте). Теперь считаем 777
mod 2 = 1. Значит DF у нас 62.0.0.2.
62.0.0.1 i=0
62.0.0.2 i=1
62.0.0.3 i=2
Как нетрудно догадаться, если у нас в сегменте будет два влана например 777 и 778 и два PE маршрутизатора, то
в 777 влане DF станет PE1, а в 778 PE2.
Для примера посмотрим, кто в указанной выше схеме будет DF при vlan-id 777:
L3-функционал в evpn
В данный момент мы разобрались, какие существуют маршруты в EVPN и как будет передаваться трафик внутри
одного bridge-домена. Это конечно хорошо, но ведь данная технология предназначена для соединения
датацентров, а в них, как правило, не один влан, как у обычного клиента, и логично, что между ними (вланами)
должен ходить трафик. Да и связь датацентра с внешним миром тоже необходима. Сейчас мы будем разбирать,
как же работает маршрутизация пакетов между разными вланами (bridge-доменами).
IRB synchronization
Но перед тем, как нырнуть с головой в странный но интересный мир интегрированной в EVPN маршрутизации,
осветим очень важный пункт — синхронизация дефолтных шлюзов. Мы ведь до сих пор не знаем, зачем же к
анонсам IRB-интерфейсов добавляется default-gateway community. Не для красоты же. Думаю, что исходя из
названия данного пункта, вы уже догадались что это необходимо для синхронизации дефолтных шлюзов. Что
такое синхронизация, как она происходит и зачем нужна? Давайте разбираться.
Для начала посмотрим все MAC-адреса на PE1,2 и 3, которые навешены на их IRB-интерфейсы. По порядку, PE1:
MAC: 02:00:00:00:07:77
MAC: 02:00:00:00:17:77
На PE1 mac адреса irb интрефейсов сконфигурированы вручную. Теперь перейдем к PE2:
MAC: 02:00:00:02:07:77
MAC: 02:00:00:02:17:77
Тут MAC пострашнее, так как его я оставил таким, каким он зашит в оборудование.
Все PE маршрутизаторы анонсируют MAC+IP маршрут до своего или своих дефолтных шлюзов (irb.777 и irb.1777).
Когда PE маршрутизатор получает маршрут MAC+IP, помеченный default-gateway community, то он начинает
воспринимать полученный MAC-адрес удаленного IRB-интерфейса, как свой собственный адрес. Ведь если есть
интерфейсы, на которых несколько IP-адресов и один MAC, то почему не может быть обратного — один IP и
несколько MAC-адресов? Синхронизация дефолтных шлюзов бывает двух видов: автоматическая и ручная.
Автоматическую синхронизацию мы сейчас рассмотрим, к ручной вернемся чуть позже.
Посмотреть какие адреса используются PE маршрутизатором можно следующей командой (проверим на PE1):
02:00:00:02:17:77
00:05:86:71:96:f0
02:00:00:02:07:77
На PE1 два bridge-домена, для каждого каждого из которых синхронизация дефолтных шлюзов производится
индивидуально. В отличии от PE1, на PE3 только один bridge-домен и один IRB-интерфейс. Соответственно
синхронизация производится только для bridge-домена VLAN-777:
02:00:00:00:07:77
02:00:00:02:07:77
В итоге получается следующая картина — irb.777 на PE1 должен отзываться на три MAC-адреса:
• 00:05:86:71:96:f0 (PE3)
• 02:00:00:02:07:77 (PE2)
• 02:00:00:00:07:77 (native PE1)
И, естественно, мы сейчас проверим, что IRB-интерфейс будет отвечать на пакеты, адресованные не на его
собственный MAC. Сделаем это по-деревенски — просто пропишем статическую arp запись на CE
маршрутизаторе на нужный нам MAC-адрес. Так как CE1-1 подключен к PE1 в bridge-домен VLAN-777, то при
резолве MAC-адреса irb.777 он получает нативный MAC-адрес irb.777- 02:00:00:00:07:77. Мы же создадим на CE1-
1 статическую arp запись, которая будет указывать, что MAC-адрес irb.777 на PE1 не 02:00:00:00:07:77, а
02:00:00:02:07:77 (который в действительности принадлежит irb.777 на PE2):
Логично предположить, что трафик пойдет на PE2, так как указанный на CE1-1 MAC-адрес соответствует irb.777 на
PE2. Для того, чтобы проверить куда же пойдет трафик, навесим на IRB-интерфейсы PE-шек такие фильтры:
[edit]
+ filter {
+ input irb777-counter;
+ }
+ filter {
+ input irb1777-counter;
+ }
[edit]
+ firewall {
+ family inet {
+ filter irb777-counter {
+ term 1 {
+ then {
+ count irb777;
+ accept;
+ }
+ }
+ }
+ filter irb1777-counter {
+ term 1 {
+ then {
+ count irb1777;
+ accept;
+ }
+ }
+ }
+ }
+ }
Как вы можете заметить, фильтры просто считают, что попало на IRB-интерфейс и пропускают весь трафик. В
данный момент времени и на PE1 и на PE2 счетчики по нулям.
На PE1:
Filter: irb777-counter
Counters:
irb777 0 0
На PE2:
Filter: irb777-counter
Counters:
irb777 0 0
Итак, запустим 33 icmp запроса до 10.0.0.254 с CE1-1 (почему 33? Чтобы никто не догадался!):
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Как вы помните, CE1-1 считает, что MAC-адрес шлюза по умолчанию не локальный мак irb.777 PE1, а MAC irb.777
PE2, это очень важно.
Filter: irb777-counter
Counters:
irb777 3300 33
Опа, все 33 пакета были приняты локальным IRB-интерфейсом. Давайте посмотрим, что у нас творится со
счетчиком на PE2:
Counters:
irb777 0 0
Все по нулям. Трафик туда просто не отправлялся и обрабатывался локальным IRB-интерфейсом PE1.
Как destination указан не MAC локального интерфейса irb.777 на PE1, а MAC-адрес irb.777 PE2. Но вот что
примечательно: посмотрим, с какого адреса прилетает ответ от PE1 на CE1-1:
Ответ все таки PE1 шлет с нативного MAC-адреса irb.777. То есть, как вы понимаете, irb.777 только принимает
пакеты, адресованные на MAC-адреса других интерфейсов irb.777 (PE2 и PE3), но как сорс адрес при отправке
какого-либо пакета чужие MAC-адреса PE1 не использует. Это очень важно, так как, например, при резолве
адреса дефолтного шлюза, IRB-интерфейс будет отвечать и указывать только свой нативный MAC-адрес.
Для чистоты эксперимента укажем CE1-1, что теперь MAC-адрес irb.777 равен MAC-адресу интерфейса irb.777 на
PE3:
Естественно, на irb.777 PE3 я также навесил данный фильтр. Запускаем пинг и проверяем:
!!!!!!!!!!!!!!!!!!!!!!!!!!!
Заглянем в WIreshark, чтобы удостовериться, что пакет с CE был отправлен с необходимым нам destination MAC-
адресом:
Filter: irb777-counter
Counters:
irb777 6000 60
irb.777 на PE1 обработал еще 27 пакетов, в то время, как на PE3 счетчик так и стоит на нуле:
Filter: irb777-couter
Counters:
irb777 0 0
Вообще ручная синхронизация — это просто отключение автоматической синхронизации, вследствие того, что
она просто не нужна. Почему? Мы сейчас конфигурили на всех PE-ках одинаковые IP-адреса на IRB-интерфейсах,
но разные MAC-и. Второй способ настройки IRB-интерфейсов в EVPN (он же и рекомендованный) — одинаковые
IP и MAC-адреса на всех IRB-интерфейсах одного и того же bridge-домена. При таком раскладе IRB-интерфейсы
уже синхронизированы, так как везде одинаковые MAC. Поэтому можно дать команду default-gateway do-not-
advertise и тем самым запретить генерацию маршрутов MAC+IP для IRB-интерфейсов.
Большим плюсом синхронизации дефолтных шлюзов является то, что это позволяет нам перемещать
виртуальные машины между датацентрами без перерыва сервиса (при выполнении определенных условий,
таких как, задержка менее 100мс между точками А (откуда перемещается машина) и Z (куда перемещается
машина) и т д). После перемещения виртуальной машины она может продолжать отправлять пакеты во
внешнюю сеть на адрес дефолтного шлюза, который находится в ее arp — то есть даже очищать arp кэш нам не
придется. Естественно, будет сгенерирован новый BGP Update о том, что теперь данный MAC в другом месте.
Вообще по теме VM Mobility в EVPN необходимо писать отдельную немаленькую статью и, поэтому, освещать её
сейчас мы не будем.
Надеюсь, что все вышесказанное отложилось в памяти, так как без этого не будет понятен механизм работы L3
интерфейсов в EVPN. Теперь перейдем непосредственно к передаче пакетов между bridge-доменами.
Для тестирования будем использовать ту же лабу, что и до этого, но добавим в неё роутинговые интерфейсы и
пару CE маршрутизаторов, как это указано на схеме:
Для простоты в статье я не буду указывать хостнеймы, как они указаны на схеме, а буду использовать
сокращения:
RZN-CE1-SW1 ⇒ CE1-1
RZN-CE1-SW2 ⇒ CE1-2
RZN-CE2-SW1 ⇒ CE2-1
RZN-CE2-SW2 ⇒ CE2-2
RZN-CE2-SW1 ⇒ CE3
Схема на первый взгляд имеет, мягко говоря, странный вид — на всех PE маршрутизаторах одинаковые IRB-
интерфейсы. Думаю, что у вас должны возникнуть как минимум два вопроса — как это работает и зачем это
нужно. Давайте попробуем ответить на эти вопросы.
Итак, поехали. Для начала вспомним как работает основной (или дефолтный, кому как нравится) шлюз в уже
нами изученном VPLS. У нас есть какой-то PE маршрутизатор, на котором мы создаем IRB-интерфейс. Этот же IRB-
интерфейс мы добавляем в какой-нибудь VRF или выпускаем в GRT, если есть такая необходимость. Возможно,
что у нас таких маршрутизаторов более одного, и мы используем vrrp для резервирования основного шлюза, но
мастером все равно будет кто-то один. То есть в VPLS у нас есть только один выход во внешнюю сеть,
расположенный на каком-то PE маршрутизаторе, входящем в VPLS-домен. Весь трафик, направленный наружу,
со всех остальных PE маршрутизаторов будет идти через данную PE-ку, так как она является единственным
выходом во внешнюю сеть (это, если не применять костыли в виде намеренно сломанного vrrp). Минусы данной
схемы очевидны — PE-ке, на которой будет находится дефолтный шлюз, придется переваривать весь исходящий
трафик VPLS-домена, направленный во внешнюю сеть и весь входящий в VPLS домен трафик из внешнего мира. А
уж, если эта PE-ка откажет, и у нас не собран VRRP, то мы вообще будем отрезаны от других сетей или внешнего
мира. Как ни странно, но у данной схемы есть и плюсы — это простота. Любому инженеру описанное выше
решение будет понятно и в плане конфигурирования и в плане траблшутинга, чего я не могу сказать про
решение, используемое в EVPN.
Помимо описанных выше недостатков, есть еще один важный нюанс — в описанной выше схеме мы никак не
можем оптимизировать L3 трафик, идущий внутрь VPLS-домена или выходящий из него.
EVPN предлагает нам совершенно иную схему использования L3 интерфейсов. Если CE маршрутизатор хочет
иметь выход во внешнюю сеть, другие вланы или интернет, то на PE-ке, к которой подключен данный CE
маршрутизатор, должен быть сконфигурирован дефолтный шлюз в виде L3 интерфейса. Естественно, на каждый
влан должен быть свой шлюз.
Примечательно то, что в RFC явно не написано, что каждый PE маршрутизатор должен иметь IRB-интерфейс для
возможности выхода во внешнюю сеть. А вот в документации Juniper по настройке EVPN есть вот такие строки:
Initially when EVPN and Layer 3 gateway functionality were conceived, some basic assumptions were made, and RFC
requirements were to be followed.
These were:
2. All PE’s should have the same IP address for the GW. From the RFC, if there is a discrepancy between the GW IP
addresses, an error is logged. Though it must be noted that different addresses can still be configured as both MAC/IP for
advertisement to remote provider edge (PE) devices and are installed on all participating PE devices.
Вернемся к нашей схеме. У нас два bridge-домена — это домен VLAN-777 и VLAN-1777. Во влане 1777 у нас два CE
маршрутизатора — это CE1-2 и CE2-2, во влане 777 три маршрутизатора: CE1-1, CE2-1 и CE3. Естественно, я хочу
иметь связность между всеми CE маршрутизаторами, указанными на схеме.
Но чтобы связать несколько bridge-доменов между собой одного добавления L3 интерфейса в routing-instance
EVPN недостаточно. Необходимо еще создать на каждом PE маршрутизаторе routing-instance с типом VRF
(которая используется для L3VPN), в которую необходимо поместить наши L3 интерфейсы. Таким образом мы
свяжем два инстанса: VRF и EVPN (или virtual-switch):
Примечание: можно выпустить наш EVPN и в GRT (global routing table), но, мне кажется, что это не очень хорошая
идея. Во всяком случае это поддерживается, а уж реализовывать этот функционал или нет — решает каждый сам.
Как было сказано выше, нам необходимо сконфигурировать routing instance с типом VRF и связать ее с EVPN.
Ниже представлена конфигурация с PE2 — virtual switch и связанный с ним VRF:
interface ge-0/0/2.0;
interface ge-0/0/3.0;
route-distinguisher 62.0.0.2:1;
vrf-import VPN-1-IMPORT;
vrf-export VPN-1-EXPORT;
protocols {
evpn {
bridge-domains {
VLAN-1777 {
vlan-id 1777;
routing-interface irb.1777;
VLAN-777 {
vlan-id 777;
routing-interface irb.777;
instance-type vrf;
interface irb.777;
interface irb.1777;
route-distinguisher 62.0.0.2:10002;
vrf-target {
import target:6262:10001;
export target:6262:10001;
vrf-table-label;
Такие же VRF поднимаются на остальных PE маршрутизаторах, за исключением того, что в VRF на PE3 нет
интерфейса irb.1777.
Мы уже знаем, что маршрут типа 2 может опционально содержать IP-адрес хоста. Сам маршрут MAC+IP мы уже
видели: если помните, то при добавлении в EVPN IRB-интерфейса у нас генерировались два маршрута: просто
MAC-адрес IRB-интерфейса, чтобы можно было до него добраться внутри bridge-домена не прибегая к
маршрутизации и MAC+IP, к которому прикреплялось комьюнити default gateway. Второй маршрут был
необходим для роутинга и является arp записью. Но MAC+IP маршрут генерируется не только для дефолтного
шлюза. Такой маршрут до какого либо хоста будет появляться в том случае, если это хост попытается выйти во
внешнюю сеть или другой влан.
Что надо хосту, чтобы выйти из влана? Верно — необходимо отправить пакет на шлюз по умолчанию. В нашем
случае роль шлюза для bridge-домена играет IRB-интерфейс PE маршрутизатора. А чтобы послать пакет на IRB-
интерфейс, хосту надо знать MAC-адрес этого IRB-интерфейса. Поэтому, для начала хост отправляет arp запрос на
резолв MAC-адреса IRB-интерфейса. В тот момент, когда IRB-интерфейс получает arp запрос от хоста (в нашем
случае CE маршрутизатора), который к данному PE маршрутизатору непосредственно подключен*, он и
генерирует два маршрута типа 2: только MAC-адрес и MAC+IP — и рассылает их по BGP в виде EVPN маршрутов.
Помимо этого, так как этот же маршрут в виде обычного IPv4 префикса с маской /32 появится еще и в связанном
с EVPN VRF-е как локальный маршрут, то по BGP отправляется еще и vpnv4 маршрут до данного хоста (зачем
нужно второе — поймете позже). Собственно, вышеописанное — это главный принцип работы EVPN при
маршрутизации между вланами, который и позволяет оптимизировать прохождение трафика между разными
bridge-доменами или между EVPN и внешними сетями.
Саму таблицу arp записей можно посмотреть на каждом PE маршрутизаторе. Для примера на PE2:
*10.0.1.22 и 10.0.1.222 — это secondary адреса CE2-2, навешенные в ходе тестирования для снятия дампов.
В выводе указывается, с какого интерфейса был сделан arp запрос, в каком bridge-домене и routing instance. Эта
информация будет полезна, так как один и тот же MAC-адрес может быть в разных вланах или, как в
представленном выше выводе — на одном физическом интерфейсе может быть несколько адресов, и,
естественно, у них будет один MAC-адрес. Ко всем этим хостам вы обязательно найдете маршрут в VRF:
Теперь перейдем от теории к практике: разберем, как трафик будет идти от CE3 к CE1-2. Первый находится во
влане 777 и имеет адрес 10.0.0.3, второй во влане 1777 и имеет адрес 10.0.1.1. Напоминаю, что на PE3 нет
локального интерфейса irb.1777.
Итак, CE3 хочет отправить пакет на CE1-2, который находится в другой сети. CE3 не знает мак адрес основного
шлюза, поэтому делает arp запрос на резолв адреса 10.0.0.254, который для данного CE маршрутизатора
является основным шлюзом в другие сети. Естественно, на CE3 (да и на всех остальных CE-маршрутизаторах
прописан дефолтный маршрут в сторону IRB-интерфейса). Так как PE3 получает arp запрос от CE3, адресованный
его локальному IRB-интерфейсу, то PE3 генерирует MAC+IP маршрут и отправляет его на остальные PE-ки.
Помимо этого, так как маршрут 10.0.0.3/32 появился в VRF в виде локального маршрута, то PE3 анонсирует еще и
BGP vpnv4 маршрут:
2:62.0.0.3:1::777::aa:bb:cc:00:05:00::10.0.0.3/304
Примечание: как правило, маршрут типа 2, содержащий только MAC-адрес, бывает уже сгенерирован раннее. В
таком случае данный маршрут повторно не генерируется, дабы избежать флапов. PE маршрутизатор просто
генерирует только MAC+IP анонс. Это не сложно увидеть на практике, посмотрев время жизни этих маршрутов —
оно, как правило, будет разным.
Двигаемся далее. CE3 теперь знает MAC-адрес дефолтного шлюза, а значит знает, куда надо слать пакет,
адресованный CE1-1 (имеется в виду MAC-адрес L2 заголовка). CE3 формирует пакет и в L3 заголовке адресом
назначения указывает адрес CE1-1 (10.0.1.1), исходящим адресом указывает собственный адрес CE3 (10.0.0.3). В
L2 заголовке адресом назначения указывает мак адрес irb.777, а исходящим адресом — собственный MAC-адрес
(адрес интерфейса в сторону PE маршрутизатора).
Пакет прилетает на PE3. Так как MAC-адрес назначения — локальный интерфейс irb.777, то PE3 снимает L2
заголовок и делает IP lookup в таблице маршрутизации VRF, которая связана с нашей EVPN-instance. В настоящий
момент в данной таблице четыре активных маршрута:
10.0.0.0/24 и 10.0.0.3/32 локальны для PE3 (второй как раз был сгенерирован при arp-запросе на irb.777), а вот
маршрут до сети 10.0.1.0/24 мы получаем по BGP от PE1 и PE2.
Так как на PE1 и PE2 создан такой же VRF, как и на PE3 (с одинаковыми RT), то PE3 принимает все анонсы от PE1 и
PE2. На них (PE1 и PE2), в свою очередь в данный VRF добавлен интерфейс irb.1777, а значит они будут
анонсировать маршут до сети 10.0.1.0/24 по BGP в виде обычного vpnv4 маршрута, который и будет
импортирован в таблицу маршрутизации VRF на PE3. В выводе выше показаны только активные маршруты,
поэтому мы видим только один анонс, всего их, естественно, два — один получен от PE1, второй — от PE2.
Лучшим выбран маршрут от PE1, так как он имеет меньший router-id, а все остальные параметры маршрутов,
полученных от обоих PE-шек полностью идентичны. Какой маршрут будет выбран лучшим — от PE1 или PE2 —
абсолютно неважно (к примеру если у нас будет 10 сайтов, то мы будем получать 9 маршрутов к одной сети, но
выберется все равно только один), так как все равно при получении BUM трафика из bridge-домена VLAN-777,
PE1 будет флудить его во все интерфейсы bridge-домена VLAN-1777. Почему — выясним далее.
В ходе IP lookup-а, PE3 поимает, что префикс 10.0.1.0/24 находится на PE1, поэтому PE3 отправляет пакет через
L3VPN на PE1:
Возможен вариант, когда на PE3 будет включена балансировка трафика по эквивалентным путям (ECMP) и в FIB
будет установлено два маршрута, а значит трафик может пойти и на PE2, но это, как я написал выше, не важно —
главное чтобы пакет попал на PE маршрутизатор, на котором есть локальный bridge-домен VLAN-1777 (по-
другому быть и не может, если, конечно, у вас не настроен какой-нибудь жесткий ликинг между VRF-ми). Если
такого bridge-домена на PE-ке не будет, то не будет и от нее анонса до сети 10.0.1.0/24.
PE1 принимает пакет от PE3 в VRF, делает IP lookup и понимает, что пакет предназначен bridge-домену VLAN-
1777:
16 *[VPN/0] 02:25:02
Так как PE1 не знает MAC-адреса хоста 10.0.1.1, то производится флуд arp запроса во все интерфейсы bridge-
домена VLAN-1777 на резолв данного адреса. Если быть точнее, одна копия пакета отправляется на CE1-2, а
вторая, с inclusive multicast меткой на PE2. А как же функция split horizon? Ведь пакет, полученный от PE
маршрутизатора, не должен отправляться на другие PE маршрутизаторы. А тут по факту мы его нарушаем без
зазрения совести. Дело в том, что данный пакет пришел, по L3VPN (то есть по сути из какой то внешней сети по
отношению к EVPN на PE1), поэтому правило split-horizon тут не работает. Но мы то знаем что пакет прилетел из
EVPN — не возникнет ли широковещательного шторма? Пакет хоть и прилетел из evpn, но из другого
широковещательного домена (CE3 находится во влане 777, а CE1-2 во влане 1777). Так как это разные bridge-
домены, то и широковещательного шторма между ними возникнуть не может — пакеты то между bridge-
доменами маршрутизируются.
Так как CE1-2 является хостом назначения и подключен к PE1, то он отвечает на данный arp запрос. Как мы
помним, после получения arp-а, адресованного IRB-интерфейсу от какого либо хоста, PE маршрутизатор должен
сгенерировать маршрут типа 2 MAC+IP. В связи с этим, PE1 генерирует MAC+IP и vpnv4 маршрут:
2:62.0.0.1:1::1777::aa:bb:cc:00:09:00::10.0.1.1/304
Теперь у PE1 есть маршрут MAC+IP до хоста 10.0.0.3 в таблице маршрутизации EVPN и 10.0.0.3/32 в таблице
маршрутизации VRF. Аналогично и со стороны PE3: маршрут до хоста 10.0.1.1/32 есть в таблице маршрутизации
epn и VRF. Выходит, что теперь обмену пакетами между CE3 и CE1-2 ничего не препятствует. Но есть один нюанс.
Давайте посмотрим таблицу маршрутизации в VRF на PE1:
В VRF появился какой то странный маршрут с пока что нам неизвестным протоколом EVPN, да еще и
преференсом 7, что его делает лучше BGP ( а также предпочтительнее маршрутов ISIS, OSPF и т д). Как то странно,
не правда ли. Что это за маршрут? Зачем он нам нужен, ведь и без него все будет работать. Дело в том, что
данный маршрут необходим для прямого обмена трафиком между EVPN, минуя L3VPN. Давайте его рассмотрим
внимательно:
*EVPN Preference: 7
Address: 0x97f5f90
Task: RZN-VPN-1-evpn
AS path: I
Это не что иное, как указание, какой надо добавить L2 заголовок, чтобы отправить пакет на CE3! Посмотрим, что
за MAC-адрес указан как источник: SMAC: 00:05:86:71:1a:f0. Логично, что если это источник пакета, то он должен
быть на PE1. Давайте прикинем, с какого MAC-адреса могут уходить пакеты во влан 777? Логично предположить,
что это будет интерфейс irb.777, а значит в L2 заголовке должен быть именно его MAC. Посмотрим, какой в
действительности MAC-адрес у irb.777:
MAC: 02:00:00:00:07:77
Все верно, в заголовке указан MAC-адрес локального интерфейса irb.777 на PE1, а значит наши рассуждения
были верны. Давайте теперь идентифицируем, кому же принадлежит MAC-адрес назначения: DMAC:
aa:bb:cc:00:05:00? Думаю, гадать не стоит — это должен быть MAC CE3. Давайте проверять:
2:62.0.0.3:1::777::aa:bb:cc:00:05:00::10.0.0.3/304
Данный MAC принадлежит хосту 10.0.0.3, куда и указывает маршрут. Для достоверности пойдем на CE3 и
посмотрим, как MAC на ее интерфейсе в сторону PE:
Принадлежность адресов мы установили. Теперь поглядим на вторую строку интересующей нас части вывода:
А это значения, которыми необходимо заполнить остальные поля ethernet кадра при отправке на CE3.
То есть данный маршрут нам явно указывает, что если надо отправить ethernet кадр с irb.777 на хост CE3, то надо
добавить указанные значения в L2 заголовок, навесить две метки: Push 300352, Push 299792(top) и отправить
пакет в интерфейс ge-0/0/0.0. Все просто.
Примечание: данное действие с пакетом подразумевает использование composite next hop. Именно поэтому
включение функционала chained-composite-next-hop обязательно на Juniper, при настройке EVPN.
chained-composite-next-hop {
ingress {
evpn;
Откуда же берется данный маршрут? Может быть нам его прислала PE3? Давайте проверим что анонсирует PE3
на рефлектор:
2:62.0.0.3:1::777::aa:bb:cc:00:05:00::10.0.0.3/304
Ничего криминального, только два маршрута имеют в своем составе адрес 10.0.0.3. Первый — vpnv4 маршрут,
второй — EVPN тип 2.
Значит этот маршрут локален для PE-маршрутизатора. Все верно. Данный маршрут генерируется локальным PE
маршрутизатором на основе EVPN MAC+IP маршрута. Но тогда почему его нет на PE3? Воспользовавшись
методом банальной эрудиции, можно прийти к выводу, что на PE3 нет bridge-домена влан 1777 с интерфейсом
irb.1777 (ведь с него должен уходить пакет на CE1-2) и интерфейса irb.1777 нет в связанном VRF. А так как нет
локального интерфейса, то какой MAC-адрес указать как source? Не поставишь же адрес другого интерфейса. Вот
поэтому данный маршрут и отсутствует на PE3. Давайте проверим эту теорию — деактивируем на PE1 в VRF
интерфейс irb.777, с которого должен будет улетать пакет на PE3.
[edit]
[edit]
[edit]
RZN-CE1-SW2#ping 10.0.0.3
!!!!!
Естественно, пинг прошел, но теперь трафик идет через L3VPN в обе стороны. Но хочется сказать, что даже в
таком сценарии маршрут трафика оптимизирован. Тоже самое произойдет, если вывести bridge-домен VLAN-777
из конфигурации (в этом случае irb.777 еще будет в VRF, но в состоянии down, так как для того, чтобы IRB-
интерфейс был в up, необходим хотя бы один физический интерфейс в состоянии up в bridge-домене, в котором
находится IRB-интерфейс).
Но мы остановились на том, что пакет от CE3 дошел до CE1-2.Теперь CE1-2 хочет ответить на данный пакет. Здесь
мы уже обойдемся без выводов из CLI.
Итак, CE1-2 отправляет пакет на адрес основного шлюза, адрес которого он уже знает. PE1 принимает пакет в
bridge-домене VLAN-1777. Так как в пакете в L2 заголовке адресом назначения указан irb.1777, то PE1 снимает L2
заголовок и делает IP lookup в таблице маршрутизации VRF. В таблице маршрутизации есть маршрут до хоста
10.0.0.3/32, причем, как показано выше, маршрутов два и лучший EVPN. PE1 просто меняет L2 заголовок,
навешивает метки и отправляет пакет на PE3.
PE3 получает пакет, видит метку, которая указывает на то, что необходимо сделать L2 lookup в MAC-таблице
bridge-домена VLAN-777, и, согласно информации в ней, переслать пакет на CE3.
Собственно, вот мы и рассмотрели весь процесс, происходящий с пакетом, при его движении от CE3 к CE1-2 и
обратно. Но мы рассмотрели процесс в момент, когда еще не было трафика между данными узлами и PE
маршрутизаторы не знали MAC-адресов CE1-2 и CE3. После того, как адреса стали известны и маршруты
разлетелись по всем PE-кам, трафик пойдет несколько иначе. Давайте вкратце рассмотрим, как конечном итоге
будет идти трафик:
От CE3 к CE1-2:
1. Пакет от CE3 попадает в bridge-домен влан 777 на PE3.
2. PE3 делает IP lookup в звязанном VRF и видит специфичный маршрут до хоста 10.0.1.1/32. Так как на PE3
нет локального bridge-домена влан 1777, то и нет и EVPN маршрута. Значит трафик идет через L3VPN на PE1.
3. PE1 принимает пакет в VRF, снимает с него метку и видит, что он предназначен bridge-домену влан 1777.
4. PE1 отправляет пакет на CE2-1 согласно MAC-таблице bridge-домена влан 1777.
Теперь пакет в обратном направлении От CE1-2 к CE3:
1. CE1-2 отправляет ответный пакет на PE1.
2. PE1 делает IP lookup в VRF и видит маршрут к хоста 10.0.0.3/32, причем лучший маршрут — это маршрут
EVPN.
3. PE1 навешивает новый L2 заголовок и добавляет стек из двух меток, согласно информации,
содержащейся в EVPN в маршруте в связанном VRF.
4. PE3 принимает пакет от PE1, снимает метку и видит, что необходимо сделать L2 lookup в MAC-таблице
bridge-домена VLAN-777.
5. Далее PE3 пересылает пакет на CE3.
Как видите, в обратную сторону пакет летит несколько иначе — это называется ассиметричным форвардингом.
Возникает резонный вопрос — почему асимметричным? Дело в том, что ingress PE делает IP lookup в VRF и
отправляет пакет на основании имеющегося в VRF EVPN маршрута, а вот egress PE уже принимает пакет не в VRF,
а в EVPN-инстанс. Если сравнить две последние схемы, то будет хорошо видна симметричность и
асимметричность трафика. Думаю, что все поняли как это работает.
Как вы знаете, ARP запрос отправляется на бродкастный адрес, а ответ на него форвардится назад по указанному
в заголовке MAC-адресу отправителя.
В рассмотренном выше случае CE1-2 был непосредственно подключен к PE1 и все работало штатно: PE1
отправлял arp запрос, и CE1-2 ему отвечал — собственно, никаких проблем. Но, если бы CE3 отправлял пакет на
CE2-2, то события развивались несколько иначе. Сначала все так же, как и описано ранее:
1. PE3 смотрит в таблицу маршрутизации VRF и видит маршрут к сети 10.0.1.0/24, полученный от PE1.
2. У PE3 нет других вариантов, кроме как отправить пакет через L3VPN на PE1.
3. PE1 принимает пакет, делает L3 lookup и переправляет его в bridge-домен VLAN-1777. Так как irb.1777 еще
не знает MAC-адрес CE2-2, то он инициирует arp запрос на резолв адреса CE2-2 (10.0.1.2), отправляя пакет на CE1-
2 и PE2.
4. CE1-2 дропает пакет, так как адрес 10.0.1.2 ему не принадлежит. PE2 пересылает полученный запрос на
CE2-2.
5. CE2-2 принимает arp запрос и отвечает на него юникастом на MAC-адрес, принадлежащий irb.1777 на
PE1.
Но получит ли irb.1777 на PE1 ответ от CE2-2? Вспоминаем про синхронизацию MAC-адресов между дефолтными
шлюзами. Вспомнили? Значит понимаете, что irb.1777 на PE2 примет пакет, направленный на MAC-адрес irb.1777
PE1. В итоге PE1 не получит ответа на свой запрос, сколько бы он их ни отправлял, а значит не разрезолвит IP-
адрес назначения и не сможет отправить пакет на CE2-2. Все было бы так, если бы это был бы не EVPN.
Так как irb.1777 на PE2 принял arp от CE2-2, то он генерирует маршрут типа 2 (MAC и MAC+IP), а также vpnv4
префикс. Как понимаете PE1 уже не нужен ответ на его arp запрос, так как теперь он получил MAC-адрес CE2-2 по
BGP и может переслать ему пакет, который находился в буфере. Получается, что трафик на CE2-2, который живет
на PE2 идет с PE3 петлей через PE1? Не совсем так. Петлей прилетел только пакет (или пакеты), который PE3 уже
успел отправить и которые находились в очереди на отправку на PE1. Но так как и на PE3 появился в VRF более
специфичый маршрут до CE2-2, то в дальнейшем трафик уже пойдет не через PE1 по маршруту 10.0.1.0/24, а
напрямую на PE2 (по маршруту 10.0.1.2/32, который появится в таблице маршрутизации VRF).
В рассмотренном нами случае у всех IRB-интерфейсов были разные MAC-адреса, что подразумевало
необходимость в синхронизации дефолтных шлюзов. Рекомендуемый вариант использования IRB-интерфейсов
— использовать одинаковые MAC и IP-адреса на всех PE маршрутизаторах одного bridge-домена. Как вы
понимаете, когда везде MAC-адреса будут одинаковы и все будет работать так, как я описал выше, только
синхронизации дефолтных шлюзов, по сути, не надо.
Давайте попробуем достучаться до например хоста 10.0.1.1/32 из VRF, который не связан ни с одной EVPN.
Делать новый VRF мне не хочется, поэтому я поступлю проще: на PE3 деактивируем instance evpn, а в VRF
деактивируем irb.777 и добавим новый интерфейс irb.0 (20.0.0.1/24):
[edit]
bormoglotx@RZN-PE-3# show routing-instances RZN-VPN-1
##
##
instance-type evpn;
vlan-id 777;
interface ge-0/0/2.777;
routing-interface irb.777;
route-distinguisher 62.0.0.3:1;
vrf-import VPN-1-IMPORT;
vrf-export VPN-1-EXPORT;
protocols {
evpn {
interface ge-0/0/2.777;
[edit]
instance-type vrf;
interface irb.0;
route-distinguisher 62.0.0.3:10003;
vrf-target {
import target:6262:10001;
export target:6262:10001;
vrf-table-label;
[edit]
family inet {
address 20.0.0.1/24;
Смотрим, что у нас в таблице маршрутизации:
Я специально деактивировал данный VRF, чтобы показать, что маршруты /32 сразу прилетят в виде vpnv4
префиксов и встанут в таблицу маршрутизации (как видите время жизни маршрута в таблице у всех префиксов
одинаково и равно трем секундам).
Теперь запустим пинг с нашего IRB-интерфейса (20.0.0.1) на CE1-2 (10.0.1.1), который живет за PE1:
!!!!!
!!!!!
Итак, до 10.0.1.1 транспортная метка 299776, а до 10.0.1.2 — 299792. Смотрим, что это за LSP:
Метка 299776 — транспортная метка до 62.0.0.1 (PE1):
Как видите, даже из VRF, абсолютно ничего не знающего про EVPN, трафик идет оптимальным путем. Обратный
трафик из EVPN в VRF до сети 20.0.0.0/24 идет по маршруту, полученному по BGP:
Логично, что трафик пойдет по этому маршруту. Запустим пинг и проверим, что все работает:
bormoglotx@RZN-PE-3> ping rapid routing-instance VRF-VPN-1 source source 20.0.0.1 10.0.0.2
!!!!!
Но почему нельзя было сделать так же как и в VPLS — один выход из всего домена? Давайте подумаем, какую
проблему решает описанное выше использование L3 интерфейсов. EVPN по своей сути предназначалась для
соединения датацентров. Из датацентра идет очень приличное количество трафика, в отличии от простого
клиентского VPLS. Поэтому рассмотрим вот такой случай:
У нас одна точка выхода из VPLS, расположенная на PE2, и предположим, что CE1 подключен к L3VPN, а CE2 к
VPLS домену. Важным тут является то, что обе эти сетки будут жить в одном и том же датацентре, но вот ходить
трафик между ними будет по такой петле:
Сначала трафик от Server 2 идет к выходу из VPLS домена, который находится на PE2, и с PE2, через L3VPN
возвращается обратно на PE1. Возможно, что даже эти два серверы будут включены в одни и тот же коммутатор
и/или стоят в одном и том же стативе в датацентре. Да, если это какой то малый объем трафика, то пусть он так и
идет — скорее всего, тут игра не стоит свеч. Но, если это потоковое видео, загрузка какого либо контента с FTP-
server-а и т д? Тогда весь этот объем трафика дважды пройдет по ядру сети, просто забивая полосу пропускания
по сути “паразитным” трафиком. Именно эту задачу решает L3 функционал EVPN. Генерируя /32 маршрут к хосту
и передавая его в VRF, EVPN оптимизирует прохождение трафика между разными сетями. Если в представленной
выше схеме использовать EVPN, то PE1 сгенерировал бы /32 маршрут к server1, и трафик пошел бы локально
через PE1, а не петлей через все ядро:
И это только один пример…
Заключение
Как видите, EVPN является не просто технологией 2-го уровня. В данную технологию глубоко интегрирован и
роутинг и свитчинг. Причем использовать вышеописанную схему с интеграцией в VRF не обязательно, если вы
прокидываете просто клиентский L2 сервис.
Но за всё в этом мире надо платить и EVPN не исключение. То что технология сложна и запутана — это не
проблема, надо просто в ней разобраться (ведь когда то и VPLS казался темным лесом — а сейчас кажется, что
вроде все логично и понятно (во всяком случаем мне)). Одной из проблем может стать большое количество /32 и
большое количество маршрутов типа 2, разобраться в которых порой будет нереально. Давайте прикинем, что у
нас например 4 сети, размером /24 — грубо говоря, это сети на 250 хостов. Если мы хотим, чтобы все хосты
общались друг с другом, то мы получим 1000 маршрутов /32 (по 250 маршрутов /32 и типа 2 на каждую сеть /24).
А если таких доменов будет 10? Тогда уже 10 000 маршрутов с маской /32 будут летать по нашей сети, нагружая
control plane. Причем эти цифры в реалиях современных датацентров с их системами виртуализации будут на 2-3
порядка выше описанных в статье. Мы знаем, что роутрефлектор отправляет своим нейборам все маршруты,
разрешенные групповой экспортной политикой. Если, для примера, в нашу топологию добавить маршрутизатор
PE4, который будет иметь vpnv4 сессию с рефлектором, то он будет получать от рефлектора все наши 10 000
маршрутов, которые ему то особо не нужны. Естественно, PE4 будет смотреть на RT и отбрасывать анонс, но эта
работа тоже будет нагружать процессор RE. В RFC нет никаких рекомендаций по этому поводу. Juniper же
рекомендует использовать семейство адресов route-target, дабы получать только нужные анонсы. Но в своей
практике от данного семейства адресов я получал пока что только проблемы.
Ко всему прочему ответим на простой вопрос: почему MAC-адреса не используются для роутинга? Ведь в
отличии от IPv4 адресов, MAC-адресов больше, они глобально уникальны, есть как бродкастные, так и
мультикастные адреса, есть даже приватные (точнее назначенные вручную администраторами вне зависимости
от производителя оборудования) MAC-адреса. Используй — не хочу! Но почему-то используется IP со всеми его
костылями типа NAT и т д. Одной из самых важных причин является то, что MAC-адреса, в отличии от IP-адресов,
не агрегируются в подсети, так как первая их часть отвечает не за географическое расположение адреса или
организацию, которой этот блок адресов выдан, а за принадлежность оборудования к тому или иному
производителю. В итоге получается что теоретически MAC-адреса поддаются агрегации, но практически на
живой сети это сделать нереально, так как например MAC-адрес 04:01:00:00:01:01 принадлежит железке,
расположенной где нибудь на побережье Флориды, а железка с MAC-адресом 04:01:00:00:01:02 например уже в
Рязани.
Сегодня FV насчитывает более 550 000 маршрутов, агрегированных до /8-/24. Представьте размер таблицы
маршрутизации, если бы для роутинга использовались исключительно /32 адреса. Зачем я об этом пишу? Дело в
том, что если у вас соединены 5-6 датацентров, в которых порядка 100к MAC-адресов, то представьте какая
нагрузка ляжет на control plane по распределению только EVPN маршрутов (о практически таком же количестве
/32 я молчу). У данной проблемы есть решения, например, использование PBB, но, как говорится, это уже совсем
другая история…
EVPN multihoming работает в двух режимах: Single-Active и Active-Active. Мы сегодня в основном остановимся на
более сложном и интересном варианте: Active-Active, так как Single-Active по сути очень упрощенная версия
Active-Active.
Данная статья рассчитана на тех, кто уже имеет общие знания о EVPN: основные принципы работы, отличия от
VPLS и т д. В противном случае понять содержание статьи будет сложно.
Примечание: Лабораторный стенд я собрал в EVE-NG с использованием vMX: как P-маршрутизатор и свичи
запущены vMX версии 14.1, как PE-маршрутизаторы vMX 16.1, как конечные хосту 5 Linux-машин. В отличии от
прошлой лабы, которую я собирал на ноутбуке, данная лаба слишком требовательна к ресурсам. Дело в том, что
vMX 16.1 работает на двух виртуальных машинах и требует в общей сложности 4 CPU и 8Гб RAM. В итоге для
представленной в статье лабы необходимо порядка 35Гб RAM на сервере, Но хочу заметить что в рабочем
состоянии вся лаба занимала чуть больше 23Gb RAM (это надо иметь ввиду, если вдруг захотите поднять данную
лабу дома).
Мы будем рассмотрим вот такую топологию:
В конфигурации я буду использовать vlan-aware метод, то есть через виртуальный свич, так как данный метод
наиболее гибок и интересен, во всяком случае для меня. На каждом PE-маршрутизаторе создано по три EVPN
инстанса (сокращенно EVI — EVPN Instance), конфигурация которых на всех трех РЕ-ках примерно одинакова —
различия лишь в RD, RT и номерах вланов. Два других инстанса добавлены только чтобы продемонстрировать
некоторые особенности EVPN Multihoming наглядно.
instance-type virtual-switch;
interface ae3.777;
route-distinguisher 62.0.0.1:1;
vrf-target target:42000:1;
protocols {
evpn {
extended-vlan-list 777;
}
bridge-domains {
BRIDGE-777 {
vlan-id 777;
Ничего сложного: инстанс с типом виртуальный свич, RT, RD и всего лишь один бридж-домен с vlan-id 777. Этот
же влан указан в расширенном списке вланов протокола evpn. Для тестирования нам ничего больше и не надо.
flexible-vlan-tagging;
encapsulation flexible-ethernet-services;
aggregated-ether-options {
lacp {
active;
periodic fast;
unit 777 {
description eVPN-1;
encapsulation vlan-bridge;
family bridge {
interface-mode trunk;
vlan-id-list 777;
Простой агрегат, работающий как транковый интерфейс, в котором разрешен только 777 влан.
А вот на PE1 и PE2 конфиг несколько отличается от PE3, так как данные PE-ки являются multihomed к RZN-SW-1:
flexible-vlan-tagging;
mtu 1600;
encapsulation flexible-ethernet-services;
esi {
00:00:00:00:00:00:00:00:00:01;
all-active;
aggregated-ether-options {
lacp {
active;
periodic fast;
system-id 02:00:00:00:00:01;
unit 777 {
description eVPN-1;
encapsulation vlan-bridge;
family bridge {
interface-mode trunk;
vlan-id-list 777;
Тут нам интересен появившийся идентификатор ESI. Напомню для тех кто забыл (или не знал) — данный
идентификатор необходимо назначить вручную (при использовании MC-LAG может генерироваться
автоматически), причем у всех интерфейсов, подключенных к одному и тому же сегменту этот идентификатор
должен быть одинаковым.
Примечание: для какой цели тут указан system-id будет описано в конце статьи
В нашем случае я выбрал простой идентификатор 00:00:00:00:00:00:00:00:00:01, так как его значение не играет
для нас большой роли, главное чтобы оно было отлично от зарезервированных значений (все нули и все
единицы) и не пересекалось со значением уже сконфигурированных значений ESI в других сегментах. То есть
грубо говоря ESI должен быть уникален для всей сети, где запускается EVPN. Для non-multihoming сегментов
данный идентификатор не играет вообще никакой роли и автоматически выставляется в 0-ль. Естественно, даже
для non-multihoming PE-маршрутизаторов можно ручкамии задать ненулевое значение ESI на линках, и это всего
навсего повлечет за собой генерацию лишних маршрутов — то есть по сути проблем как таковых и не будет. А
вот если это заданное ручками значение ESI совпадает со значением уже сконфигурированного ESI на другом или
других стыках то у вас начнутся проблемы.
В EVPN существует 5 типов маршрутов (тип 5 я прошлый раз не рассматривал, но я постараюсь затронуть эту тему
в статье о EVPN/VxLAN):
Тип 2 — это MAC/IP маршрут. Данный маршрут указывает PE-маршрутизатору куда и с какой меткой отправлять
юникастовые пакеты на конкретный мак-адрес, указанный в маршруте. По сути аналогичен анонсу vpnv4
префикса в L3VPN. Маршрут может также содержать и ip адрес хоста.
Тип 3 — это Inclusive Multicast маршрут. Данный маршрут указывает PE-маршрутизатору куда и с какой меткой
отправлять BUM трафик.
Итак, в 0-вой момент времени, как только мы запустили EVPN, маршрутизаторы начинают рассылать друг другу
маршруты типа 3, что бы можно было обмениваться BUM трафиком. Это справедливо для сценария без
multihoming-га. Так как в нашем сегменте два маршрутизатора смотрят в один и тот же сегмент, то у нас
появляются маршруты типа 1 и 4. Зачем нам маршрут типа 3 вы уже должны знать, поэтому далее мы заострим
внимание на маршрутах типа 1 и 4.
Как я написал выше — мы только что запустили EVPN и пока что никакого обмена трафиком между хостами не
было, о чем говорит нам отсутствие MAC-адресов в таблице форвардинга инстанса vSwitch-eVPN-1:
vSwitch-eVPN-1 1 1 0 0 2 1 0 0
В представленном выводе видно, что у нас есть multihomed сегмент. Чтобы узнать информацию об этом сегменте
мы рассмотрим extensive вывод предыдущей команды:
Instance: vSwitch-eVPN-1
MAC advertisements: 0 0
MAC+IP advertisements: 0 0
VLAN Domain ID Intfs / up IRB intf Mode MAC sync IM route label
Number of neighbors: 2
62.0.0.2
Received routes
Inclusive multicast: 1
Ethernet auto-discovery: 2
62.0.0.3
Received routes
Inclusive multicast: 1
Ethernet auto-discovery: 0
ESI: 00:00:00:00:00:00:00:00:00:01
Данный вывод дает нам полную информацию по нашему EVPN инстансу. Часть полей вам должна быть уже
понятна. Согласно данному выводу у нас есть ESI 00:00:00:00:00:00:00:00:00:01, который работает в режиме
Active-Active:
Number of neighbors: 2
62.0.0.2
Received routes
Inclusive multicast: 1
Ethernet auto-discovery: 2
Судя по информации выше от RZN-PE-2 мы получаем один маршрут типа 3 и два маршрута типа 1.Правда это не
совсем так. Помимо этих маршрутов, RZN-PE-2 отдает нам еще один маршрут типа 4, но почему он тут не показан,
увидим позже.
А вот от RZN-PE-3 на данный момент мы получаем только один маршрут типа 3 и все:
62.0.0.3
Received routes
Inclusive multicast: 1
Ethernet auto-discovery: 0
Это и логично, так как данный PE-маршрутизатор не является multihomed и пока все что нам от него надо знать —
это маршрут типа 3. Дальше по мере изучения маков данный маршрутизатор начнет рассылать анонсы типа 2, но
пока что никаких маков он не изучил. Если бы у нас были бы сконфигурены дефолтные шлюзы, то появились бы
еще маршруты типа 2 (в завизимости от количества irb интерфейсов, добавленных в инстанс).
Помимо описанной выше информации по нашему EVI в выводе указано, что для сегмента с ESI
00:00:00:00:00:00:00:00:00:01 выбран Designated forwarder и указана Aliasing label:
ESI: 00:00:00:00:00:00:00:00:00:01
В данный момент многое из выводов не понятно. Для понимания принципов работы EVPN Multihoming нам надо
разобраться как минимум со следующими вопросам:
1. Зачем Multihomed PE-маршрутизатор начинает анонсировать дополнительные маршруты типа 1 и 4, каково их
назначение;
2. Что такое DF и как происходят его выборы;
3. Почему маршрутов типа 1 аж два.
4. Что такое Aliasing label в выводе выше.
Борьба с петлями имеет целый комплекс мер. Первое естественно split horizon — кадр, полученный от других PE
маршрутизаторов (то есть из ядра) не отправляется снова в ядро. Но естественно этого недостаточно, так как
основное место сети, где может возникнуть петля — это подключение multihomed CE коммутатора к нескольким
PE-маршрутизаторам. Для устранения петель в этом сегменте используются Designated Forwarder и Split Horizon
Label, Но обо всем по порядку.
Что такое DF и зачем он нужен?
Первый сценарий возникновения петли: представим, что удаленный PE маршрутизатор получает от CE BUM
трафик (например банальный arp запрос) и рассылает его всем остальным PE-кам (предположим это PE3). Так как
два PE маршрутизатора (PE1 и PE2) смотрят в один и тот же сегмент и они оба получают BUM трафик от PE3, то
получится, что в этот сегмент прилетят две копии трафика, которые далее начнут петлять по все сети, включая и
ядро:
Для борьбы с данным явлением в EVPN для каждого multihomed-сегмента выбирается Designated Forwarder —
узел, который ответственный за форвардинг BUM трафика в сторону конкретного сегмента в конкретном влане.
Все остальные маршрутизаторы, сколько бы их не было в сегменте, не имею права отправлять BUM трафик в
сторону CE маршрутизатора/коммутатора (в данном ESI в данном влане).
1. Сначала все PE маршрутизаторы должны понять, сколько еще маршрутизаторов подключено к указанному
сегменту и какие у них адреса (лупбеки);
2. По истечении таймера (по умолчанию 3 секунды) формируется список всех PE маршрутизаторов, участвующих
в выборе DF, начиная с наименьшего адреса и заканчивая наибольшим. Список адресов нумеруется с 0-ля;
4. Маршрутизатор, выбранный DF-ом разблокриует передачу BUM трафика в сторону CE, а все остальные non-DF
маршрутизаторы продолжают блокировать BUM трафика в сторону CE маршрутизатора/коммутатора в данном
сегменте в данном влане.
Сначала ответим на вопрос, как маршрутизаторы понимают, кто еще имеет линк в этом же сегмент (и есть ли
такие маршрутизаторы вообще)? Для этого и существует маршрут типа 4. Посмотрим на данный маршрут:
bormoglotx@RZN-PE-1> show route table vSwitch-eVPN-1.evpn.0 match-prefix *4:6*
В таблице маршрутизации нашего EVPN инстанса таких маршрутов нет. Дело в том, что в данную таблицу
попадают только те маршруты, расширенное community которых соответствует импорту, сконфигурированному в
инстансе. Например для vSwitch-eVPN-1 равно:
target:42000:1;
Получается что у маршрута типа 4 какое то другое, отличное от сконфигурированного на импорт community. Это
происходит из-за того, что маршруты в evpn могут генерироваться двумя способами — per-EVI и per-ESI.
per-ESI — этот маршрут сгенерирован не каким-то определенным инстансом, а маршрутизатором для всех
инсатнсов имеющих линк в данном ESI. Один и тот же сегмент может быть включен в несколько evpn инстанций
(к примеру в инстанс EVPN1 добавлен интерфейс ae3.777, а в EVPN2 — ae3.778, хоть это и разные юниты, но ESI
конфигурится на весь интерфейс целиком, а значит у данных интерфейсов будет один и тот же ESI, хоть и
находятся они в разных EVI).
Маршруты, генерируемые per-EVI должны иметь нативные RT и RD инстанса, из которого эти маршруты
анонсируются (либо какие то ещё RT, если они дополнительно навешиваются экспортной политикой — то есть
добавляются вручную администраторами). Маршруты типа 2 и 3 всегда генерируются per-EVI, а значит всегда
имеют в составе маршрута нативную RD и RT инстанса, из которого данные маршруты анонсируются. А вот для
маршрутов, генерируемых per-ESI все несколько сложнее и зависит от типа маршрута.
Данный маршрут всегда генерируется per-ESI. RD у данного маршрута будет сгенерировано автоматически
маршрутизатором из router-id (если указан) или адреса лупбека (так как ни к одной из EVPN инстанций данный
маршрут собственно и не относится). RT также не указывается в ручную, а генерируется из ESI и только те
маршрутизаторы, имеющие один и тот же ESI импортируют данный маршрут. Именно поэтому в выводе,
рассмотренном раннее в начале статьи не мы не видим, что multihomed сосед анонсирует нам маршрут типа 4.
Примечание: вообще то не совсем так, так как для RT берется только часть битов ESI и импортировать данный
маршрут будут все PE-ки, имеющие одинаковые биты ESI, используемые для генерации RT.
Примечание: JunOS генерирует RD для маршрутов per-ESI используя нулевое значение во второй части RD:
62.0.0.1:0.
Так где же искать наш маршрут типа 4? В JunOS существуют несколько таблиц маршрутизации. Маршруты EVPN
сначала попадают в таблицу bgp.evpn.0 и из нее уже импортируются в какие то другие таблицы маршрутизации
(secondary tables). Поэтому данный маршрут можно найти в таблице bgp.evpn.0, из которой он экспортируется в
таблицу __default_evpn__.evpn.0:
4:62.0.0.1:0::01:62.0.0.1/304 ES
*[EVPN/170] 02:57:15
Indirect
4:62.0.0.2:0::01:62.0.0.2/304 ES
bormoglotx@RZN-PE-3>
4:62.0.0.1:0::01:62.0.0.1/304
4:62.0.0.2:0::01:62.0.0.2/304
Address: 0xb1e55f0
Source: 62.0.0.100
AS path: I (Originator)
Communities: es-import-target:0-0-0-0-0-0
Import Accepted
Localpref: 100
Особо ничего криминального — большая часть полей свойственна BGP маршруту. Но вот в строке community мы
обычно привыкли видеть например domain-id, origin или target community. Тут же совсем другие community.
Это специально зарезервированное для EVPN community. Как я и писал выше данный маршрут генерируется
исключительно per-ESI и получить его должны только те PE-маршрутизаторы, которым этот маршрут нужен. А
нужен он только тем PE-кам, которые имеют линк в том же ESI, что и отправитель маршрута. Поэтому community
данного маршрута генерируется на основании ESI и имеет вид es-import-target:0-0-0-0-0-0.
В нашем случае все нули, и я специально взял такое ESI, чтобы показать, что это community может содержать
только нули во второй своей части (первая часть зарезервирована и равна 0x06 (type) и 0х02 (sub type), кому
интересно читаем RFC) и это никак не скажется на работоспособность EVPN. В итоге в нашей лабораторной сети
только RZN-PE-1 и RZN-PE-2 импортируют данный маршрут.
А где же сам ESI спросите вы? Идентификатор указан непосредственно в самом маршруте:
4:62.0.0.2:0::01:62.0.0.2/304 ES, просто пустые октеты (нули) опускаются (подобно ipv6). И как не трудно
догадаться если два маршрутизатора будут иметь линки в в разных сегментах, но их идентификаторы будут
равны 00:00:00:00:00:00:00:00:00:01 у первого и 10:00:00:00:00:00:00:00:00:01 у второго, то маршруты будут
импортированы обоими маршрутизаторами. По community происходит только первоначальная фильтрация —
сам же маршрут будет использован только если ESI, указанный в маршруте совпадает с ESI на самом
маршрутизаторе, который этот маршрут получил, иначе — маршрут будет отброшен.
Как только маршрутизатор понимает, что он является multihomed (понимает он это по ненулевому значению ESI
в конфигурации интерфейсов), он начинает отправлять маршрут типа 4, чтобы все соседние маршрутизаторы
знали о его присутствии в сети.
После того, как маршруты разлетелись по сети, RZN-PE-1 и RZN-PE-2 узнают, что они подключены к одному и тому
же ESI. Оба маршрутизатора ждут в течении 3 секунд (по дефолту) маршрутов типа 4 от остальных PE-
маршрутизаторов, после чего, на основании полученных от соседей маршрутов типа 4 составляют список всех
подключенных к данному сегменту узлов, причем на всех узлах данный список будет одинаков, в нашем случае
такой:
62.0.0.1 i=0
62.0.0.2 i=1
После этого маршрутизаторы начинают высчитывать, кто будет DF по формуле V mod N = i, где V — номер влана,
а N количество PE маршрутизаторов в сегменте. Тот PE маршрутизатор, номер которого будет результатом
вычисления и становится DF данного сегмента в данном влане. Как вы понимаете, для каждого влана будет свой
DF — получается некая балансировка BUM трафика.
В лаборатории сконфигурено три EVPN инстанса, каждому инстансу соответствует один влан, я использовал
вланы 777, 778 и 779. Так как multihomed PE-ек у нас 2, то количество узлов равно 2. Получаем, что в данном
сегменте DF-ом для вланов 777 и 779 будет выбран RZN-PE-2, а для 778 — RZN-PE-1, что легко проверить:
Instance: vSwitch-eVPN-1
ESI: 00:00:00:00:00:00:00:00:00:01
Instance: vSwitch-eVPN-2
ESI: 00:00:00:00:00:00:00:00:00:01
Instance: vSwitch-eVPN-3
ESI: 00:00:00:00:00:00:00:00:00:01
Данная схема имеет свои плюсы и минусы. Самый очевидный минус — это сам механизм выбора DF. Как только
в сегменте появляется новый маршрутизатор, имеющий линк в сторону ESI X или происходит
падение/восстановление линка на маршрутизаторе в сторону ESI X, то для данного сегмента происходит пересчет
DF. Причем самой плохой ситуацией будет пропадание линка в сторону ESI X на DF маршрутизаторе. Так как
остальные маршрутизаторы блокируют передачу BUM трафика в сторону CE устройства, то на время
детектирования падения DF и высчитывание нового DF BUM трафик будет дропаться всеми PE-
маршрутизаторами сегмента, так как в данный момент времени они все будут non-DF. Но в сейчас есть
драфт RFC, который описывает новую процедуру выбора DF. Но пока что все работает так, как описано.
Стоит упомянуть, что выбор DF для vlan-aware и vlan-bundle методов немного различаются. Так как виртуальный
свич может терминировать несколько бридж-доменов, то выбор DF в этом случае происходит не для каждого
влана отдельно, а для всех вланов сразу, а в расчетах используется наименьший сконфигурированный номер
влана. Для примера добавим в виртульный свич вланы 30,778 и 779. Нетрудно подсчитать, что если взять за
основу наименьший номер влана — 30, то DF-ом для сего данного сегмента будет PE1 — 62.0.0.1:
VLAN Domain ID Intfs / up IRB intf Mode MAC sync IM route label
А теперь удалим 30-й влан. Теперь наименьший номер влана это 777, то есть теперь DF-ом должен стать PE2 —
62.0.0.2:
VLAN Domain ID Intfs / up IRB intf Mode MAC sync IM route label
Примечание: в выводах выше, да и в литературе встречается понятие Backup forwarder или Backup Designated
forwarder (BDF). BDF это просто еще одно название non-DF маршрутизатора. В EVPN нет бекапного форвардера
(как например в OSPF DR и BDR) — DF только один, все остальные non-DF или BDF. В случае появления в сегменте
еще одного маршрутизатора или при падении одного из маршрутизаторов сегмента происходят перевыборы DF.
Теперь мы выяснили зачем нужен маршрут типа 4 и как он выглядит.
Но выбрав DF мы победили только один тип петель. Но петля может все равно возникнуть если CE
маршрутизатор начнет отправлять трафик сторону non-DF маршрутизатора. Для примера, если RZN-PE-1, является
non-DF получит BUM трафик от RZN-SW-1 то мы получим петлю, так как: RZN-PE-1, получив BUM трафик от CE,
отправит этот трафик в сторону других PE-шек, включая RZN-PE-2. RZN-PE-2, являясь DF для данного сегмента, без
зазрения совести отправляет трафик обратно в сторону RZN-SW-1, откуда он и пришел. В итоге получилась петля:
И пока петлю не разорвать трафик так и будет летать туда-сюда.
Чтобы этого избежать нам понадобится маршрут типа 1, так же сгенерированный per-ESI.
Но в отличии от маршрутов типа 4, в маршрутах типа 1, сгенерированных хоть per-ESI, хоть per-EVI указывается
нативное community инстанса или нескольких инстансов, которым данный маршрут интересен (а почему, мы
узнаем чуть позже):
*[EVPN/170] 1d 00:09:01
Indirect
1:62.0.0.2:0::01::FFFF:FFFF/304 AD/ESI
1:62.0.0.2:1::01::0/304 AD/EVI
Сгенерированный per-ESI маршрут типа 1 несет в себе расширенное community в котором указана mpls метка,
называемая split horizon label:
Address: 0xb1e55f0
Source: 62.0.0.100
Task: BGP_42000.62.62.0.0.100
Announcement bits (1): 0-vSwitch-eVPN-1-evpn
AS path: I (Originator)
Import Accepted
Localpref: 100
Как это нам поможет победить описанную выше петлю? Теперь, non-DF маршрутизатор, отправляя BUM трафик в
сторону DF-маршрутизатора, будет добавлять в стек меток дополнительную метку, указанную в данном
community. То есть получается такая картина: PE маршрутизатор получил BUM трафик из сегмента с ESI X, для
которого он является non-DF маршрутизатором. Теперь он должен переслать этот трафик все остальным PE-кам в
EVPN домене, включая и другие PE-маршрутизаторы, имеющие линк в ESI X. Всем PE-маршрутизаторам трафик
отправляется как обычно — с использованием IM метки, а вот маршрутизатору, который является DF-ом для
сегмента ESI X, маршрутизатор сначала навешивает Split horizon метку и только потом IM метку. Это будет
указывать DF маршрутизатору на то, что данный пакет пришел из ESI X и обратно в этот сегмент его отправлять не
надо. Логично, что эту метку надо добавлять только в том случае, если пакет отправляется в сторону DF
маршрутизатора, так как non-DF маршрутизаторы и так этот трафик не отправят в сегмент ESI X.
Со стороны DF маршрутизатора это выглядит так:
Если маршрутизатор получил пакет с IM меткой и S=1 (то есть дно меток а занчит данная метка — последняя в
стеке), то маршрутизатор рассылает пакет всем подключенным к нему CE-коммутаторам/маршрутизаторам в
данном EVPN инстансе.
Если же маршрутизатор получил пакет с IM меткой и S=0 (то есть данная метка — не последняя в стеке), то
верхняя метка снимается и делается второй mpls lookup. Делая второй lookup маршрутизатор видит Split Horizon
метку с S=1. Исходя из этого маршрутизатор флудит пакет в сторону всех CE маршрутизаторов/коммутаторов, за
исключением того, который находится в том же сегменте, из которого трафик и получен.
Возникает вопрос, почему данный маршрут генерируется per-ESI, но в отличии от маршрута типа 4 имеет
нативное community инстанса (или как в нашем случае нескольких инстансов)? Дело в том, что данный маршрут
несет в себе не только split horizon label. Если вы обратите внимание на community esi-label:all-active (label
302656), то увидите, что указан тип сегмента all-active или single-active. Эта информация необходима другим PE-
кам, чтобы понимать — а можно ли балансировать трафик по PE-кам или нет (но об этом чуть позже) и как
использовать Aliasing label.
Еще одна важная функция данного маршрута — обеспечение быстрой сходимости. К примеру у нас отвалился
линк в сторону CE устройства, логично что все этот линк отвалился для всех инстансов, в которые он был
добавлен. А значит надо отменять все маршруты, которые которые анонсированы PE-кой для данного сегмента,
то есть маршрутизатор должен начать отправлять withdraw сообщения, отменяя анонсированные MAC/IP
маршруты из всех инстансов, которые имели имели линк в сторону данного ESI, так как теперь эти маршруты не
действительны. А если таких маршрутов несколько тысяч? Поэтому вместо отправки кучи withdraw сообщений
маршрутизатор отменяется маршрут типа 1, что заставляет все остальные PE маршрутизаторы понять, что через
данный PE маршрутизатор больше этот сегмент не доступен. Это называется MAC Mass Withdraw. Маршутизатору
проще быстро обработать одно сообщение вместо тысячи, что ествественно сокращает время сходимости,
особенно если MAC-адресов за отвалившимся интерфейсом несколько тысяц.
Теперь думаю понятно, почему у данного маршрута именно нативное(-ые) community — в нашем сценарии PE3
не имеет ESI 00:00:00:00:00:00:00:00:00:01 и если community генерировать, как для маршрута типа 4, то PE-3 этот
маршрут просто отбросит, проверив его community.
Примечание: если вы заметили в маршруте типа 1, сгенерированного per-ESI, указываются вместо тега все
единицы: 1:62.0.0.2:0::01::FFFF:FFFF/304 AD/ESI. Это не прихоть Juniper, тут все согласно RFC — в маршруте типа 1,
если он сгенерирован per-ESI в поле tag-id должно быть указано максимально возможное значение (под это поле
выделено 32-бита), а mpls метка выставляется в 0.
Таким образом EVPN позволяет избежать петель и обеспечили возможность быстрой сходимости. Но если вы
вспомните в начале в выводе мы видели, что соседний маршрутизатор анонсировал нам 2 маршрути типа 1. Что
за второй маршрут? Так получилось, что маршрут типа 1 может генерироваться еще и per-EVI.
Зачем нам маршрут типа 1, сгенерированный per-EVI?
1:62.0.0.1:1::01::0/304 AD/EVI
*[EVPN/170] 1d 00:20:59
Indirect
1:62.0.0.2:1::01::0/304 AD/EVI
Address: 0xb1e55f0
Source: 62.0.0.100
Task: BGP_42000.62.62.0.0.100
AS path: I (Originator)
Communities: target:42000:1
Import Accepted
Localpref: 100
Route Label: 300208 — это aliasing метка, которая наравне с сервичной меткой, указанной в маршруте типа 2
может использоваться для форвардинга трафика. Зачем же эта метка нам нужна, если у нас и так есть сервисная
метка из маршрута типа 2? Дело в том, что это все таки EVPN предоставляет сервис L2VPN — то есть
подключается к нам клиент к провадеркому оборудованию не как к маршрутизатору, а как к свичу. И если вы
вспомните, что PE-маршрутизатор от клиента изучает MAC-адреса через data plane. То есть теоретически
возможна ситуация, когда multihomed CE будет отправлять пакеты только в сторону одного из PE-
маршрутизаторов (причины могут быть разные — начиная от багов самого оборудования и заканчивая
алгоритмом балансировки). А значит только один маршрутизатор изучит MAC адрес от CE
маршрутизатора/коммутатора и отправит анонс MAC/IP:
Если посмотреть таблицы форвардинга, то видно, что часть MAC-ов на RZN-PE-2 (он является DF в данный момент
для 777 влана), изучены через data plane (обратите внимание на указанные стрелками адреса):
MAC flags (S -static MAC, D -dynamic MAC, L -locally learned, C -Control MAC
00:05:86:71:87:f0 D ae3.777
00:50:79:66:68:0e D ae3.777
MAC flags (S -static MAC, D -dynamic MAC, L -locally learned, C -Control MAC
00:05:86:71:87:f0 D ae3.777
00:50:79:66:68:0e D ae3.777
Что у нас получается? Получилась ситуация, когда только RZN-PE-2 изучил MAC адрес какого то хоста за RZN-SW-1
и отправил MAC/IP маршрут, содержащий данный мак ( в нашем случае даже два таких маршрута). Если мы
посмотрим таблицу форвардинга на RZN-PE-3, то увидим в ней все эти маки, изученные через control plane:
MAC flags (S -static MAC, D -dynamic MAC, L -locally learned, C -Control MAC
00:05:86:71:87:c0 D ae0.777
Но вот если посмотреть что мы получаем на RZN-PE-3, то будет ясно, что маршруты с RZN-PE-1 и RZN-PE-2
приходят ассиметрично. Вот маршруты, анонсированные с RZN-PE-1:
2:62.0.0.1:1::777::00:05:86:71:87:f0/304 MAC/IP
2:62.0.0.1:1::777::00:50:79:66:68:0e/304 MAC/IP
2:62.0.0.2:1::777::00:05:86:71:87:f0/304 MAC/IP
2:62.0.0.2:1::777::00:50:79:66:68:0e/304 MAC/IP
Как видите, два мака видны только через RZN-PE-2. Если для RZN-PE-3 тут нет ничего криминального, то вот RZN-
PE-1 тоже получает маршрут от RZN-PE-2 с этим MAC. Получается, что RZN-PE-1 должен отправлять трафик в
сторону этих хостов через RZN-PE-2. Но было бы глупо думать, что разработчики EVPN опустили бы такую простую
и банальную ошибку. В маршруте типа 2 (MAC/IP) содержится идентификатор ESI, к которому относится данный
MAC-адрес. RZN-PE-1, получает маршрут типа 2, видит, что MAC виден через сегмент, к которому он
непосредственно подключен. Поэтому RZN-PE-1 ставит next-hop-ом тоннель в сторону RZN-PE-2, а физический
линк в сторону ESI:
MAC flags (S -static MAC, D -dynamic MAC, L -locally learned, C -Control MAC
00:05:86:71:87:f0 D ae3.777
00:50:79:66:68:0e D ae3.777
В таблице форвардинга видно, что MAC адрес виден через логический интерфейс ae3.777, а флаг говорит, о том,
что мак изучен динамически через control plane от удаленной PE-ки. В итоге, хоть RZN-PE-1 и не изучил данный
MAC адрес через data plane, но отправлять трафик в сторону RZN-SW-1 он будет по прямому линку.
Но появляется другой вопрос — если на RZN-PE-3 данный MAC виден только через RZN-PE-2, так как RZN-PE-1 не
анонсировал маршрути MAC/IP с заданным MAC адресом, то почему вдруг RZN-PE-3 станет отправлять пакеты на
данный мак адрес через RZN-PE-1? Вот тут сцену выходит aliasing label.
RZN-PE-3 знает (из маршрута типа 1, сгенерированного per-ESI), что RZN-PE-1 и RZN-PE-2 подключены к одному и
тому же сегменту и работают в режиме Active-Active. В таком случае в целях балансировки, RZN-PE-3 может
использовать aliasing label, которая будет выполнять роль сервисной метки. В итоге RZN-PE-3 может отправлять
трафик, предназначенный для хоста за RZN- SW-1 через RZN-PE-2, используя метку, указанную в маршруте типа 2,
а также через RZN-PE-1, используя aliasing label вместо сервисной метки, которая указана в маршруте типа 1.
Aliacing label указывается для каждого multihomed соседа в каждом инстансе, что видно на RZN-PE-3:
ESI: 00:00:00:00:00:00:00:00:00:01
ESI: 00:00:00:00:00:00:00:00:00:01
ESI: 00:00:00:00:00:00:00:00:00:01
to table vSwitch-eVPN-3.evpn-mac.0
Хочу заметить, что оборудование Juniper генерирует метку для мак адреса в MAC/IP маршруте per-EVI (то есть
одна на весь инстанс). И самое интересное то, что aliasing label будет точно такой же как и mac-label. Это видно из
представленного ниже вывода:
ESI: 00:00:00:00:00:00:00:00:00:01
С RZN-PE-1 анонсируется четыре маршрута типа 2, и у всех одна и та же метка. Но тогда возникает вопрос, а зачем
нам вообще анонсировать aliasing label, если она равна mac label? Дело в том, что это свойственно оборудованию
Juniper, другие вендоры — Cisco, Brocade, Huawei или ALu — могут иметь другое видение на данный вопрос и
генерировать метки по другому.
Давайте прикинем, возможны ли какие нибудь проблемы при использовании aliasing метки? Рассмотрим такую
ситуацию. Маршрутизатор RZN-PE-3 получил маршруты типа 1 per-EVI от RZN-PE-1 и RZN-PE-2, и теперь знает
aliasing метку до обоих маршрутизаторов. А вот маршрутов типа 1 per-ESI на RZN-PE-3 еще нет. Получается, что
если RZN-PE-3 начнет балансировать трафик с использованием aliasing метки, то может получится ситуация, когда
например multihomed маршрутизаторы будут работать в режиме Single-Active и часть трафика, отправленная на
пассивный узел, будет просто дропаться. То есть теоретически RZN-PE-3 может начать балансировать трафик, а
фактически не знает можно ли это делать или нет. Как быть? Поведение маршрутизатора в такой ситуации четко
регламентировано RFC — пока маршрутизатор не получит маршрут типа 1, сгенерированный per-ESI с указанием
режима работы multihoming-а, он не должен отправлять трафик в данный сегмент с использованием aliasing
метки, полученной в маршруте типа 1 per-EVI.
Данная метка может анонсироваться и в Single-Active сценарии. В этом случае она используется не для
балансировки трафика по multihomed PE-кам, а для установки в таблицу форвардинга бекапного пути, который
автоматически станет активен при падении основного плеча.
А нужен ли нам MC-LAG в EVPN?
Мы рассматривали схему с подключением multihomed CE к PE-кам с использованием LAG. Причем для PE-
маршрутизаторов это просто один физический интерфейс, добавленный в бадл, а вот со стороны CE- один LAG, в
который добавлены интерфейсы в сторону обоих PE-шек, то есть получается некая эмуляция MC-LAG, во всяком
случае CE маршрутизатор/коммутатор будет думать, что подключен к одному и тому же узлу провайдера и
балансирует трафик по обоим членам бандла. С точки зрения конфигурации это выглядит так:
flexible-vlan-tagging;
mtu 1600;
encapsulation flexible-ethernet-services;
aggregated-ether-options {
lacp {
active;
periodic fast;
gigether-options {
802.3ad ae0;
gigether-options {
802.3ad ae0;
flexible-vlan-tagging;
mtu 1600;
encapsulation flexible-ethernet-services;
esi {
00:00:00:00:00:00:00:00:00:01;
all-active;
aggregated-ether-options {
lacp {
active;
periodic fast;
system-id 02:00:00:00:00:01;
mtu 1600;
encapsulation flexible-ethernet-services;
esi {
00:00:00:00:00:00:00:00:00:01;
all-active;
aggregated-ether-options {
lacp {
active;
periodic fast;
system-id 02:00:00:00:00:01;
Со стороны RZN-SW-1:
LACP state: Role Exp Def Dist Col Syn Aggr Timeout Activity
Со стороны PE маршрутизаторов:
LACP state: Role Exp Def Dist Col Syn Aggr Timeout Activity
LACP state: Role Exp Def Dist Col Syn Aggr Timeout Activity
Возможен вариант, когда со стороны PE-маршрутизаторов будут просто физические интерфейсы, а вот со
стороны CE — простой статический LAG (без LACP).
Ну и второй вариант подключения — через стандартный MC-LAG со всем вытекающими (ICCP, ICL). Сложно не
согласиться, что первый вариан на много проще второго. И применять EVPN/MPLS и MC-LAG лично я смысла не
вижу, особенно при условии, что MC-LAG в All-Active режиме еще и требует ICL, кроме случаев, когда MC-LAG
жизненно необходим или уже сконфигурен для других сервисов (не ломать же его теперь).
К плюсам EVPN с MC-LAG можно отнести то, что помимо EVPN на данном стыке можно реализовать и другие
сервисы с резервированием (ну к примеру VPLS с бекап сайтом или L2CKT с бекапным нейбором — ведь не все
железо поддерживает EVPN). А вот из минусов можно выделить то, что обычно MC-LAG ограничен 2-мя
нейборами (EVPN multihoming поддерживает больше 2-х PE-шек в режиме Active-Active); необходимость в линке
между PE-ками, проприетарность самой технологии (имеется в виду MC-LAG) ну и наверно можно добавить как
минус увеличение конфигурации.
В итоге получается, что в EVPN заложен полный функционал multihoming, который позволяет обойти
ограничения VPLS. Единственной проблемой все же в EVPN Active-Active multihoming будет проблема с
шейпингом трафика от клиента. Если клиент купил полосу в 100Mbps и вы выставите на интерфейсах по 50Mbos,
то при нормальной работе вы получите суммарно нужную полосу, а вот как только одно из плеч отвалится,
клиент уже будет в праве на вас жаловаться, так как вы ему зарезали скорость в два раза. Но хотя часто ли
клиенты просят L2VPN multihoming с Active-Active?
Наверно это все, что я хотел рассказать в данной статье, не раздув ее до гигантских размеров.
Однако сеть linkmeup выросла до размеров федерального оператора. Возможность управления трафиком и
быстрого восстановления сервисов стали очень важным требованием в MPLS-сети.
Пора внедрять Traffic Engineering.
Содержание выпуска:
Левое плечо — широкий оптический канал 10G. Правое — резерв через арендованную линию — 1G.
Общий объём трафика — 2,5 Гб/с, мобильного: 800 Мб/с.
В случае разрыва основного канала, нужно переключить на резервный только мобильный трафик и сделать это
за 50мс.
Базовые механизмы работы MPLS TE были рассмотрены в выпуске СДСМ 10, куда я вас и шлю за подробным
рассмотрением. А здесь приведу лишь короткую сводку.
Data Plane
С точки зрения передачи данных TE несколько отличается от LDP. Жирным выделены отличия:
1. В TE-туннель трафик нужно поместить насильно, тогда как в LDP он попадает автоматически
Juniper здесь — исключение.
2. Первый маршрутизатор навешивает внешнюю MPLS-метку (PUSH LABEL)
3. Транзитные маршрутизаторы смотрят на какой интерфейс поступил пакет и значение метки и, поменяв её
на новую согласно таблице меток, отправляют её в выходной интерфейс (SWAP LABEL)
4. Предпоследний маршрутизатор снимает транспортную метку (POP LABEL, PHP — зависит от реализации и
настроек)
5. В случае обрыва на пути трафик можно спасти путём перенаправления пакетов в заранее
подготовленный туннель.
Control Plane
А вот в плане управления отличия гораздо более значительные. C ними всю оставшуюся дорогу и будем
разбираться.
Терминология
LSP — Label Switched Path — вообще говоря, любой путь через сеть MPLS, но порой подразумевают LDP LSP.
Однако мы не будем столь категоричны — при необходимости я буду указывать, что имею в виду именно LDP
LSP.
RSVP LSP — соответственно LSP, построенный с помощью RSVP TE с учётом наложенных ограничений. Может
также иногда называться CR-LSP — ConstRaint-based LSP.
Туннелем мы будем называть один или несколько MPLS LSP, соединяющих два LSR-маршрутизатора. Метка MPLS
— это по сути туннельная инкапсуляция.
В случае LDP — каждый LSP — это отдельный туннель.
В случае RSVP туннель может состоять из одного или нескольких LSP: основной, резервный, best-
effort, временный.
Говоря TE-туннель, мы будем подразумевать уже конкретно MPLS Traffic Engineering туннель, построенный RSVP-
TE.
TEDB — Traffic Engineering Data Base — тот же LSDB протоколов IS-IS/OSPF, но с учётом ресурсов сети, которые
интересны модулю TE.
CSPF — Constrained Shortest Path First — расширение алгоритма SPF, которое ищет кратчайший путь с учётом
наложенных ограничений.
Итак, MPLS TE хочет строить LSP с учётом требуемых ресурсов и пожеланий оператора, поэтому столь простой LDP
с его лучшим маршрутом тут не у дел.
И его место занимает RSVP-TE — наследник отвергнутого стеком TCP/IP протокола RSVP.
TE работает в тесном симбиозе с IGP. Хотя правильнее это называть паразитизмом. Он вынуждает их (OSPF или
IS-IS) служить себе: переносить нужную ему информацию и тем самым наполнять TEDB.
Всё это подробно и в красках в статье СДСМ10. А ещё там же самый простой пример на практике.
Статический маршрут
Самый простой в понимании и самый сложный в обслуживании способ.
Linkmeup_R1(config)#interface Ethernet0/3
IGP Shortcut
Этот способ наиболее распространённый и поддерживается почти всеми производителями.
Маршрутизатор рассматривает туннель, как виртуальный интерфейс. И через этот интерфейс удалённые
маршрутизаторы словно бы непосредственно подключены к локальному, а не находятся в десятках хопов. Этакая
телекоммуникационная червоточина. Она и называется — shortcut — сокращённый путь.
Червоточина Фламма
Но протоколы IGP по умолчанию не хотят этого видеть и используют для отправки трафика физический
интерфейс.
Таким образом всё, чьей точкой назначения является этот маршрутизатор, или узлы за ним, будет отправлено в
туннель. В том числе и VPN-пакеты.
Таким образом туннель становится обычным интерфейсом, и, как у любого другого интерфейса у него должна
быть метрика.
Метрика туннеля
Во-первых, есть два типа метрик:
Метрика IGP — хорошо известная нам из курса базовой маршрутизации метрика интерфейсов.
Метрика TE — та метрика, которая будет использована при расчёте метрики TE-туннеля.
• По умолчанию, TE=IGP.
• По умолчанию, используется TE.
• По умолчанию, метрика туннеля равна сумме TE-метрик всех линий от Ingress до Egress по кратчайшему
IP-пути (а не по тому, по которому туннель идёт). То есть метрики обычных IP-маршрутов и маршрутов через
туннель будут одинаковыми, даже если туннель фактически намного длиннее.
• Почему выбирается по кратчайшему пути? Логично, чтобы метрика туннеля должна перебить метрику
лучшего IP-пути.
• При равенстве метрик маршрутизатор выберет именно туннель, поскольку IGP shortcut именно это и
подразумевает.
Если есть IP-пути, которые не имеют общих сегментов с туннельным LSP, и при этом их метрики равны, будет
иметь место балансировка.
Tunnel-policy*
*Этот способ зависит от производителя — у кого-то есть, у кого-то нет.
Tunnel-policy применяется для перенаправления исключительно трафика VPN в туннели.
То есть в режиме настройки VPN (не важно, L2 или L3) указывается какой туннель должен быть использован.
Существует две возможности:
1. Tunnel binding mode. В зависимости от Egress PE выбирать конкретный туннель. Применимо только к
RSVP LSP.
2. Select-Seq mode. Тунель будет выбираться в порядке, указанном в конфигурации. Это может быть TE-
туннель, LDP-туннель, с балансировкой или без.
Особенности Juniper
У джуна зачастую свой подход (ещё сегодня в этом убедитесь). Так у него существует несколько таблиц
маршрутизации:
1. IP routing table (inet.0)
2. MPLS routing table (inet.3)
3. MPLS forwarding table (mpls.0).
При помещении VPN-маршрутов в таблицу IP-маршрутизации BGP сверяется с таблицей MPLS inet.3. Если в ней
он находит LSP до Next Hop'а маршрутра VPN, то автоматически трафик загоняется в этот LSP. Никаких
дополнительных действий не требуется.
Это в некотором смысле похоже на микс Tunnel-Policy и IGP Shortcut, только автоматически.
Практика
Всё та же сеть, но с ограничениями по пропускной способности.
Нам нужно обеспечить L3VPN клиенту.
У клиента есть требования: 8 Мб/с. Вынь да положь.
Направляем трафик в туннель через Auto-Route.
В лаборатории ограничение интерфейса — 10000 кб/с. Поэтому при задании требований туннеля и доступных
полос, отталкиваемся исключительно от этой цифры.
Поехали!
Итак, начнём с того, что никакого LDP — только RSVP-TE. То есть LSP нет, пока мы не настроим туннель.
Хоть мы всё это уже и делали в прошлый раз, но начнём настройку сначала.
1. Базовая конфигурация уже имеется (IP+IGP)
2. Файл конфигурации.
3. Включаем возможности TE
4.
Linkmeup_R1(config)#mpls traffic-eng tunnels
Обратите внимание, что команда ip rsvp bandwidth указывает полосу только в одном направлении. То есть если
мы настроили её на интерфейсе E0/0 в сторону Linkmeup_R2, то это означает, что в 5Мб/с ограничена полоса
только для исходящего трафика.
Чтобы ограничить в другую сторону, нужно настроить интерфейс E0/1 со стороны Linkmeup_R2.
Команда metric-style wide — обязательна, напоминаю. Дело в том, что TE использует новые TLV с расширенными
метками, а по умолчанию ISIS генерирует только короткие.
Поскольку конфигурация полностью одинаковая, для других узлов не привожу.
8. Настраиваем TE-туннель.
9.
10.
Linkmeup_R1(config)#interface Tunnel4
Linkmeup_R1(config-if)#description To Linkmeup_R4
Здесь мы указали, что туннель строим до узла 4.4.4.4, требуется 8 Мб/с, а LSP строится динамически (без Explicit-
Path)
Сразу после этого видим, что туннель поднялся.
То есть CSPF рассчитал маршрут с учётом нашего ограничения, RSVP PATH успешно сигнализировал путь, а RSVP
RESV зарезервировал ресурсы на всём пути.
Трассировка показывает, что путь проложен ровно так, как мы этого хотели.
А в сообщении RSVP PATH можно увидеть, что он несёт информацию о требуемой полосе.
В дампе вы можете видеть начало объекта ERO с перечислением всех узлов по пути будущего RSVP LSP и запрос
резервирования полосы пропускания.
Здесь стоит 1000000 Байтов в секунду или ровно 8 Мегабит в секунду (если мы не путаем Мега с Меби). Величина
эта дискретная и меняется с некоторым шагом. В случае данной лабы — это 250 кб/с.
Linkmeup_R4(config)#interface Tunnel1
Linkmeup_R4(config-if)#description To Linkmeup_R1
Настройка на Linkmeup_R4
Linkmeup_R4(config)#interface Tunnel1
19.
Сейчас путь от R1 до R4 выглядит так: R1->R5->R2->R6->R3->R4 — всё из-за этих чёртовых ограничений.
LSP перестроился на R1->R5->R2->R6->R3->R7->R4 с потерей одного пакета. Это время может значительно
увеличиться, если физического падения линии не будет на маршрутизаторах.
Что при этом происходило?
1. Сначала R1 через сообщение RSVP PATH ERROR узнал о том, что линия испорчена.
2. R1 отправил RSVP PATH TEAR по направлению к 4.4.4.4, а обратно идущий RSVP RESV TEAR удалил LSP.
Если у нас не останется путей, удовлетворяющих заданным условиям — беда — LSP не будет.
Например, выключим линию R2-R5 и наблюдаем падения TE-туннеля на R1 без его дальнейшего восстановления.
Переоптимизация туннелей
Если линк R3->R4 восстановится, туннель перестроится обратно?
Да. Но не скоро. Пролетит много пакетов, прежде чем Ingress PE шевельнёт своим RSVP. (На самом деле зависит
от производителя)
Это называется переоптимизацией туннелей (Tunnel reoptimization). С некоторой периодичностью Ingress PE
заставляет CSPF проверить, а не появилось ли более оптимальных маршрутов.
1. CSPF находит новый путь, удовлетворяющий всем условиям. В нашем случае R1->R5->R2->R6->R3->R4.
2. Ingress PE сигнализирует новый RSVP LSP, отправляя RSVP PATH.
3. Получив RSVP RESV, он понимает, что новый LSP готов.
4. Отправляет RSVP PATH TEAR, чтобы сломать старый LSP.
5. Когда RSVP RESV TEAR возвращается — всё закончено.
То есть сначала он строит новый RSVP LSP, пускает туда трафик и только потом ломает старый. Этот механизм
называется Make-Before-Break, о котором в конце.
Конкретный туннель:
Но не беспокоит ли вас вот эта идея с Bandwidth? Не возвращаемся ли мы в каменный век, когда не было
переподписки. Да и как вообще определять величину этого ограничения? А что делать с тем, что она плавает в
течение суток на порядки?
Offline Bandwidth
Метод, когда мы настраиваем статическое значение требуемой полосы, называется Offline Bandwidth.
Идея в том, что есть некая программа стоимостью в трёшку на Патриарших прудах, которая по каким-то
алгоритмам вычисляет для вашего трафика одну цифру, которую вам и нужно настроить на туннеле.
Полосу можно настроить для всего туннеля, как мы делали это выше на практике:
Это значение может отличаться от того, что указано для туннеля и имеет более высокий приоритет.
При этом для другого LSP (path-option 2, например), значение может отличаться — мол, если уж не получается
зарезервировать 8 Мб/с, давай хотя бы 5 попробуем?
Auto-Bandwidth
А Autobandwidth молодец.
Этот механизм отслеживает загрузку туннеля в течение определённого периода и потом адаптирует
резервирование.
Терминология
Adjust Interval — время, в течение которого маршрутизатор наблюдает за трафиком и отслеживает пики.
Adjust Threshold — порог, после которого RSVP перезапрашивает резервирование.
Ближе к телу.
Например, Adjust Interval у нас 2 часа. Текущее значение зарезервированной полосы пропускания — 90 Мб/с.
Adjust Threshold — 20 Мб/с.
В первом интервале всплеск 119 Мб/с (до 119 Мб/с) — больше порога. Значит RSVP-TE пытается построить новый
туннель с новыми значениями для полосы пропускания.
Во втором — 23Мб/с (до 142) — опять больше порога. Обновляем резервирование по возможности.
В третьем максимальное значение падает до 137 Мб/с — разница только 5. Ничего не происходит.
В четвёртом всплеск падает до 116 (разница 21) — RSVP сигнализирует новый LSP с пониженными требованиями
по полосе.
Так, каждые два часа будет происходить проверка и, возможно, перестроение туннелей.
Чем короче Adjust Interval, тем, соответственно, чаще будет обновляться резервирование и более рационально
использоваться доступная полоса пропускания.
Примерно так при двухчасовом интервале будет выглядеть 24-часовое поведение auto-bandwidth.
Вот измерили мы в 8 утра всплеск — 200 Мб/с. И два часа держится это значение для туннеля. А за это время на
работу уже пришёл народ и запустил ютуб — средняя скорость уже 240, а всплески до 300. До 10 утра будет
происходить тихая деградация. Тихая, потому что ни туннель, ни Auto-Bandwidth о ней не знают. А вот
пользователи знают и их ИТшник тоже знает, уж поверьте.
Если же сильно уменьшать интервал юстировки, то на сети будут постоянно пересигналзироваться новые LSP.
Для решения этой и других проблем существуют механизмы Overflow и Underflow. Первый — для слежения за
ростом трафика, второй — за снижением.
Если разница между текущим резервированием и всплесками трафика превосходит порог Overflow несколько
раз подряд, RSVP TE будет пробовать построить новый LSP, не дожидаясь истечения Adjust Interval.
То же и для Underflow — RSVP-TE будет пересегнализировать LSP с более низкими требованиями, если заметил
тенденцию к уменьшению объёма трафика.
Далее для каждого туннеля отдельно нужно активировать AutoBandwidth. При этом можно задать другое
значение для Adjust Interval, а также установить минимально и максимально возможные значения для
резервируемой полосы.
Приоритеты туннелей
Это механизм, который приоритезирует туннели: какой из них важнее. Он применим, как для случая Auto-
Bandwidth в частности, так и для любого построения RSVP LSP вообще.
Если полосы пропускания не хватает на узле, и у нового туннеля приоритет установки выше, чем приоритет
удержания у старого, новый будет построен — старый сломан.
Данные о приоритетах замещения передаются в RSVP-TE PATH и учитываются при резервировании ресурсов на
промежуточных узлах.
Практика
Если вы обратили внимание, то после настройки tunnel mpls traffic-eng badnwidth на туннельном интерфейсе, в
конфигурации автоматически появляется строка tunnel mpls traffic-eng priority 7 7.
Дело в том, что без требований по полосе приоритеты не имеют никакого значения — через один узел можно
проложить сколько угодно туннелей — ведь полоса не резервируется — и команды нет.
Но, как только появилось требование, по полосе, приоритеты начинают играть роль.
7 — это значение по умолчанию — наименьшее.
Linkmeup_R1(config)#interface Tunnel42
Необходимая полоса всего 4Мб/с. Поэтому туннель должен пройти по пути R1->R2->R3->R4.
С Tunnel4 у них только один общий линк R3->R4, но его полоса пропускания только 10. А двум туннелям нужно
8+4=12.
Tunnel42 с приоритетом установки 4 выдавливает Tunnel4 с приоритетом удержания 7.
И тому приходится искать новый путь.
И он находится:
Сначала удаляется старый RSVP LSP Tunnel4 и сигнализируется новый по доступному пути
Получается, что
• без Autobandwidth мы либо настраиваем требования полосы вручную на всей сети, либо вообще не
делаем этого, пуская на самотёк,
• без Autobandwidth мы никогда не знаем, сколько реально трафика в туннеле,
• без Autobandwidth мы никак не можем его ограничить,
• без Tunnel priority мы не можем сказать наверняка, какие туннели пострадают.
Explicit-Path
Идея Explicit-Path более чем полно была раскрыта в 10-м выпуске СДСМ.
Как вы помните, CSPF вычисляет кратчайший путь с учётом ограничений. Далее этот путь трансформируется в
объект ERO (Explicit Route Object) сообщения RSVP-TE PATH, который явно сообщает, по какому пути этот PATH
нужно передать.
Так вот если, вы хотите, чтобы какие-то узлы обязательно присутствовали или наоборот отсутствовали в этом
пути, можно это явно указать в Explicit-Path, который станет одним из входных ограничений для CSPF.
Итак, мы вручную задаём, через какие узлы должен пролечь LSP, а через какие не должен.
RSVP-TE просит CSPF рассчитать маршрут с учётом Explicit-Path и других ограничений туннеля.
Если одно входит в противоречие с другим — беда, не будет LSP.
Explicit-Path — это строго локальное ограничение — только Ingress LSR о нём знает и не передаёт ни в анонсах
IGP, ни в сообщениях RSVP-TE.
Настройка Explicit-path выполняется в два этапа:
1) Создание самого explicit-path с ограничениями:
...
SRLG
SRLG — Shared Risk Link Group. Ещё один способ повлиять на LSP и отличная идея против плоских колец.
Задача этой функции предотвратить построение основного и резервного LSP через линии, которые могут
повредиться одновременно.
Например, два волокна, которые физически проходят в одном кабеле, наверняка порвутся одним и тем же
ковшом экскаватора.
Вручную (конечно, а как иначе маршрутизатор узнает, что это физически идентичные линии) настраиваются
интерфейсы, которые являются членами одной SRLG-группы.
Информация о SRLG распространяется по сети вместе с анонсами IGP, как и доступная полоса или значение
Attribute-Flag, и помещается потом в TEDB.
Далее CSPF должен учитывать эту информацию при расчёте кратчайших маршрутов.
Для добавления интерфейсов в одну группу риска на любых узлах вводится команда:
RFC3630 для OSPF, а для ISIS определяют TLV для Administrative Group, который передаётся IGP вместе с другими
характеристиками линиями.
Пока вы не согнулись под тяжестью знаний, расскажу вам такую историю.
Огромнейшая сеть linkmeup. Своя оптика, свои РРЛ пролёты, куски лапши, доставшиеся от купленных домонетов,
куча арендованных каналов у разных операторов. И через всё это хозяйство MPLS, хуже того — TE-туннели.
Каждый раз, настраивая туннель, учитывать в Explicit Path все эти детали — с ума можно сойти.
Но, новая связка — удивительное спасение, которое решит все наши проблемы, просто нажмите кнопку «сделать
хорошо».
Итак.
Administrative Group (у Juniper: admin-group, у Cisco: Attribute-Flag) — это атрибут физического интерфейса,
который может описать 32 его дискретных характеристики.
Какой бит из 32 за что отвечает решает оператор самостоятельно.
Раз уж примеры у нас в консоли Cisco, то далее буду использовать термин Attribute-Flag наравне с
Administrative group, что не совсем правильно.
Например,
считаем с наименее значимых битов (с конца):
первый бит в 1 означает, что это оптика
второй бит в 1 означает, что это РРЛ
третий бит в 0 означает, что это линия в сторону сети доступа, а 1 — магистральный интерфейс.
четвёртый бит в 1 означает, что это аренда
пятый бит в 1 означает, что это Балаган-Телеком
шестой бит в 1 означает, что это Филькин-Сертификат
седьмой бит в 1 означает, что это канал через интернет без гарантий.
…
десятый бит в 1 означает, что полоса пропускания меньше 500 Мб/с
итд. я так могу все 32 утилизировать.
Если это равенство выполняется, туннель можно строить через этот интерфейс.
Рассмотрим на примере.
У нас есть 32 бита и политика — за что отвечает каждый из них (возьмём пример выше).
В Mask мы указываем, какие характеристики канала нас интересуют. Например, для туннеля с трафиком 2G
важно
1. РРЛ это или нет
2. Магистральная линия или в сторону сегмента доступа
3. Канал через интернет или нет
Поэтому в маске выставляем 1 там, где важно, что стоит:
4.
5. Attribute-Flag 0000 0101 — Оптика, не РРЛ, магистральный и не через Интернет. Attribute-Flag && Mask =
0000 0100 = Affinity && Mask — сюда можно пускать трафик. Не важно, оптика или нет — результат тот же.
6.
То есть при построении LSP на каждом линке будет учитываться значение Attribute-Flag.
По умолчанию значение Attribute-Flag на интерфейсе — 0x0. И в некотором смысле — это прискорбно — ведь
результат операции «И» с маской будет отличаться от результата с Affinity, а значит мы должны настроить
Attribute-Flag на всех интерфейсах.
Соответственно, в пределах компании можно выработать политики, как помечать интерфейсы и как управлять
трафиком. Можно возложить эту задачу даже на систему управления, чтобы работа инженера сводилась к
расстановке галочек в графическом интерфейсе, а конфигурация затем применялась бы автоматически.
Но в любом случае это не умаляет человеческого фактора с одной стороны и просто непостижимой сложности
отладки и обслуживания с другой.
Однако случаи комплексного внедрения Administrative Group даже на сетях российиских операторов имеются.
Другим примеров использования могли бы быть коды регионов или стран. Тогда можно было бы задавать через
какую географию пропускать трафик.
В этом свете 32 бита оказывается очень мало, поэтому RFC 7308 определяет расширенные административные
группы, количество бит в которых ограничено естественым пределом LSA или вообще MTU.
Значение Attribute-Flag по умолчанию 0x0. Поэтому его и возьмём в качестве Affinity — то есть все интерфейсы у
нас подпадают под условие.
Кроме R3-R4, на котором мы настроим Attribute-Flag 0x1. Поскольку равенство не выполнится — CSPF не сможет
строить кратчайший путь через этот линк.
Linkmeup_R1(config)#interface Tunnel4
Linkmeup_R3(config)#interface e0/0
Linkmeup_R1(config)#interface Tunnel4
Надёжность и сходимость
На практике мы уже видели, что перестроение туннеля в случае поломки занимает несколько секунд. Что ж, не
так уж и плохо было во времена моего деда.
Вся история развития компьютерных сетей — это история борьбы с авариями, борьбы за скорость сходимости, за
уменьшение времени перерыва.
Что у нас есть на вооружении?
1. Защита на физическом уровне. Например, APS в SONET или LAG в Ethernet.
2. IP — решение всех проблем. IGP, BGP, VRRP итд.
3. Набор технологий в MPLS.
Если бы эволюция строила людей по этому принципу, мы бы умирали преимущественно от старости (вторая
причина по числу смертей была бы «погиб под собственным весом»).
Path Protection
При настройке туннеля мы можем указать, сколько и каких LSP мы хотим построить.
1. Primary — это основной LSP, который и будет использоваться для передачи трафика.
2. Secondary — запасной LSP. Если Ingress PE узнаёт от падении основного — он переводит трафик на
запасной.
3. Последний в свою очередь тоже может быть:
o Standby — всегда наготове: путь заранее вычислен и LSP сигнализиован. То есть он сразу готов
подхватить трафик. Может также называться Hot-standby.
o Non-standby — путь заранее вычислен, но LSP не сигнализирован. При падении основного LSP
Ingress LSP сначала с помощью RSVP-TE строит запасной, потом пускает в него трафик. Зато полоса не простаивает
зарезервированная. Может называться Ordinary.
4. Best Effort — если основной и запасной пути сломались или не могут быть удовлетворены условия, то
RSVP-TE построит хоть как-нибудь без резервирования ресурсов.
Protection — это не только и не столько про восстановление сервиса, сколько про скорость этого восстановления.
В этом ключе понятное дело, что non-standby совсем не дело. Опираясь на IGP, RSVP-TE сначала ждёт обновления
маршрутной информации, потом сам должен отработать — счёт на секунды. Сигналом является уведомление от
RSVP-TE или BFD, что LSP больше не живой, либо информация от IGP об изменении топологии.
Для случая Standby строится одновременно основной RSVP LSP и резервный. Соответственно, как только Ingress
LSR фиксирует разрыв шаблона основного LSP, трафик сразу переключается на запасной — нам грозит потеря
только тех пакетов, которые были посланы ровно до момента, как авария была зафиксирована.
FRR использует обходные пути и описан в RFC4090 Среднее время переключения после детектирования аварии
— 50мс.
Это вещь, которая просто включается, а дальше работает автоматически. То есть с точки зрения конфигурации
выглядит элементарно.
Как это обычно и бывает, вещи которые просто настраиваются, скрывают под пальто нечто интересное.
Когда PLR замечает, что линия, через которую лежит транзитный LSP, упала, он мгновенно перенаправляет
трафик. Заметьте, что не Ingress PE этим занимается, а именно тот узел, на котором произошёл обрыв. Падение
линка фиксируется по падению интерфейса или BFD-сессии.
Можно сравнить FRR со стрелкой на железнодорожных путях.
Чтобы так быстро перенаправить пакеты, Bypass LSP должен быть построен заранее. Так и происходит.
Каждый узел по ходу Primary LSP ищет, как обойти падение следующего линка и падение следующего хопа.
То есть он запускает полный механизм построения LSP:
1. CSPF до MP (NHOP для случая падения линка и NNHOP для случая падения узла)
2. Отправляет по просчитанному пути RSVP PATH с запросом резервирования.
3. Поулчает RSVP RESV, если резервирование удалось.
Идея auto-tunnel значительно глубже, чем только автоматические FRR-туннели. Читать об этом тут.
Всё очень просто — FRR LSP — это обычный туннель. То есть нам достаточно туннелировать наш предыдущий
туннель на участке от PLR до MP, а это значит, добавить ещё одну MPLS-метку в каждый пакет. Итого их будет 3:
VPN, Tunnel, FRR.
Итак, когда пакет приходит на PLR во время аварии, тот сначала делает обычный SWAP внешней метки, словно
бы он должен был выйти через старый (в данный момент сломанный интерфейс) и ещё он знает, что надо
передать его в FRR туннель — добавляет ещё одну метку.
Далее пакет коммутируется по Bypass LSP по стандартным правилам — меняется внешняя (FRR) метка, а две
внутренние остаются неизменными.
На предпоследнем узле внешняя метка снимается — PHP и до MP пакет идёт с изначальными двумя.
MP получает пакет, смотрит на транспортную метку и далее коммутирует пакет, словно бы ничего и не
происходило.
Важно, что всё это работает, только если используется глобальный пул меток, а не специфичный по интерфейсам.
Так MP не учитывает, с какого интерфейса пришёл пакет с данной меткой.
FRR Node Protection
Всё абсолютно то же самое за исключением транспортной метки — PLR должен знать какую метку ждёт NNHOP.
Туннель теперь строится не до следующего узла, а через один — NNHOP.
В этом помогает атрибут сообщения RSVP — LRO (Label Request Object). Будучи в RSVP PATH он просит узлы по
пути выделять метки.
А в RSVP RESV Label Object содержит эти самые выделенные метки.
Bandwidth Protection
При сигнализации Bypass LSP возникает вопрос: а резервировать ли ресурсы.
Если да, то это уже называется Bandwidth Protection.
При этом обычно нет смысла два раза резервировать ресурсы для одного и того же туннеля. Ну действительно —
от того, что мы увели трафик из Primary в Bypass ведь не следует, что ресурсы будут использоваться дважды на
PLR и MP? Тем более, что свободной полосы вообще может не хватить. Поэтому вводится понятие SE (Shared
Explicit). Если в изначальном RSVP PATH будет установлен этот атрибут, ресурсы не будут резервироваться
дважды — промежуточные узлы буду знать, что это не совсем независимый LSP — это старый задумал что-то.
5. PLR осуществляет переключение мгновенно после обнаружения аварии. Для каждого приходящего от
Ingress LSR пакета:
1. меняет оригинальную транспортную метку на ту, которую ждёт MP.
2. добавляет сверху новую Bypass метку.
Режимы FRR.
Единственный вопрос, который стоит ещё обсудить про FRR — какие LSP собственно перенаправлять? Он же не
один всё-таки, наверно, проходит через этот PLR?
Тут есть два варианта:
• Many-to-One (или Facility mode). Соответственно — все полетят через один туннель.
• One-to-One. То есть для каждого транзитного LSP будет построен свой личный обходной туннель.
Первый вариант предпочтителен, поскольку использует ресурсы более рационально. Всё, что было выше
именно про режим Facility.
One-to-One вводит пару новых терминов:
Detour LSP — запасной туннель. Тот же Backup LSP, но Detour защищает только один Primary LSP,
DMP — Detour Merge Point — Тот же MP.
Практика
Продолжаем всё с той же сетью и с того момента, на котором мы остановились (если не считать affinity).
Файл конфигурации.
Path-Protection
Добавим Standby LSP с более низкими требованиями полосы пропускания: 3 Мб/с.
Linkmeup_R1(config)#interface tunnel4
Обратите внимание, что Preference (1) должен быть таким же, как и у Primary LSP.
Путь защитного туннеля лёг следующим образом:
Во-первых, на линии R1-R2 4 Мб/с из 5 уже занял Tunnel42. Поэтому для запасного LSP Tunnel4 не осталось
полосы.
Во-вторых, основной и резервный LSP используют обычно метод резервирования полосы Shared Explicit (SE), что
означает, что для одного и того же туннеля не будет полоса резервироваться дважды. Поэтому через 10 Мб/с
линк R1-R5 удалось проложить и основной LSP (8 Мб/с) и резервный (3 Мб/с).
В-третьих, вы можете видеть, что резервный LSP на участке R6-R4 он выбрал тот же путь, что и основной. Поэтому
использование Explicit-path иногда вполне может быть оправдано.
Для удовольствия и удовлетворения можете дёрнуть линк R2-R5 и убедится, что трафик абонентов почти не
прерывался.
Если в текущей конфигурации у вас пинг прекратился и не восстанавливается, попробуйте понять почему.
Local-Protection (FRR)
Если вы всё ещё дёргаете линк R2-R5, пожалуйста, перестаньте и верните его в состояние Up.
Кроме того, для наглядности работы FRR, придётся убрать Path-Protection.
Файл конфигурации
Linkmeup_R1(config)#interface tunnel4
Linkmeup_R4(config)#interface tunnel1
2.
3. для защиты от падения узла R6: R2->R6->R3 (R2->R3).
4.
5. для защиты линка R2->R5 (R2->R6->R5)
6.
7. для защиты от падения узла R5: R2->R5->R1 (R2->R1).
8.
Обратите внимание на то, что защитные туннели строятся без какого-либо учёта полосы пропускания, пока об
этом отдельно не будет сказано.
Так, теперь я хочу разорвать линию R2->R6.
По идее для защиты этой линии у нас есть Tunnel65436 (R2->R5->R6). Но тогда полный путь будет выглядеть
немного странно: R1->R5->R2->R5->R6-R3->R4 — то есть по линии R5-R2 трафик пройдёт дважды — туда и
обратно. Поэтому R2 ненадолго включает интеллект и выбирает Tunnel65437, который напрямую ведёт к R3.
Тогда на участке R2-R3 мы должны увидеть две метки в стеке — VPN и туннельную. Метка bypass не будет
вставляться, потому что PHP.
Если хочется, увидев все три метки, убедиться, что FRR работает, введите на R2 команду
PUSH VPN — 16
PUSH Tunnel — 26
Метки на R3:
Прекрасно!
Ну и на последок пара лёгких тем без практики.
MPLS QoS
Теме QoS будет посвящён отдельный выпуск. Готовьтесь. Но не поговорить немного об этом сейчас было бы
непростительно.
MPLS TE IntServ
Итак, MPLS TE использует парадигму IntServ QoS — предварительное резервирование ресурсов по всему пути.
То есть мы изначально уверены, что необходимая полоса (и другие требования) будет предоставлена сервису.
При этом пакеты внутри туннеля (LSP) все равнозначны.
Однако, такое случается, что трафик у клиента растёт. Может, в какой-то момент его объём превосходит
статически настроенный порог, а свободной полосы больше нет, или Autobandwidth ещё не успел отработать
повышение скорости.
Так или иначе — пакеты начинают отбрасываться, причём безо всякого разбора — важные они или нет.
То есть идея IntServ в реализации MPLS TE сама по себе ещё не гарантирует, что на каждом отдельном узле
проблем не возникнет.
MPLS TE DiffServ
А кто у нас там отвечает за Per-Hop Behavior? Напомните? DiffServ? А не объединить ли нам эти две прекрасные
парадигмы?
Ведь в заголовке MPLS имеется поле EXP, которое планировалось Expериментальным, но уже
давно официально используется для задания приоритета пакетов и называется Traffic class. Вот только по старой
привычке его и сейчас продолжат называть EXP,
Это называется MPLS DiffServ-aware Traffic Engineering — MPLS DS-TE.
Идея, вообще говоря, заключается в том, чтобы MPLS-пакетам предоставить то качество сервиса, которое
ожидали оригинальные пакеты. То есть в идеале нужно сделать соответствие 1 к 1. Но EXP — это всего лишь 3
бита, то есть 8 значений приоритета, тогда как DSCP — 6 бит (64 значения) — как ни крути, но детализация при
такой архивации теряется.
Таким образом, существует два подхода:
E-LSP — EXP-Inferred LSP. Забить и радоваться тому, что имеем.
L-LSP — Label-Inferred LSP. Кодировать приоритет связкой EXP+метка.
E-LSP
Для случая, когда изначально имеем дело с полем DSCP — мы переносим в MPLS EXP только три наиболее
значимых (левых) бита DSCP.
И да, мы смиряемся с потерей деталей.
Когда PDU приходит на Ingress LSR, мы помещаем его в туннель и задаём приоритет в поле EXP.
Ну например, в одном туннеле у нас пойдут данные ШПД и фиксированной телефонии. Естественно, телефонии
мы дадим приоритет 5, а всему остальному 0.
Тогда даже если внутри одного туннеля случится затор, первыми будут умирать слабые.
L-LSP
В этом случае данные QoS кодируются в связку Метка+EXP. Предполагается, что метка задаёт механизм
обработки в очередях, а метка — приоритет отбрасывания пакета.
Информация о PHB должна быть сигнализирована в процессе установки LSP.
Каждый L-LSP несёт только один тип сервиса.
На сегодняшний день операторы в большинстве своём определяют четыре класса трафика: BE, AF, EF и CS. E-LSP
более чем достаточно для этого, поэтому L-LSP не только практически не используется, но и более того, не у всех
вендоров реализован. Поэтому останавливаться далее на сравнении методов я даже не буду.
Режимы QoS
А вот что интересно, так это какому всё-таки полю CoS доверять на каждом узле: IP DSCP, Tunnel EXP или VPN EXP?
Помните, уже сталкивались с такими понятиями при разборе TTL в MPLS L3VPN? Что-то похожее и тут.
Uniform Mode
Это плоская модель End-to-End.
На Ingress PE мы доверяем IP DSCP и копируем (строго говоря, отображаем, но для простоты будем говорить
«копируем») его значение в MPLS EXP (как туннельный, так и VPN заголовки). На выходе с Ingress PE пакет уже
обрабатывается в соответствии со значением поля EXP верхнего заголовка MPLS.
Каждый транзитный P тоже обрабатывает пакеты на основе верхнего EXP. Но при этом он может его поменять,
если того хочет оператор.
Предпоследний узел снимает транспортную метку (PHP) и копирует значение EXP в VPN-заголовок. Не важно, что
там стояло — в режиме Uniform, происходит копирование.
Egress PE снимая метку VPN, тоже копирует значение EXP в IP DSCP, даже если там записано другое.
То есть если где-то в середине значение метки EXP в туннельном заголовке изменилось, то это изменение будет
унаследовано IP-пакетом.
Pipe Mode
Если же на Ingress PE мы решили не доверять значению DSCP, то в заголовки MPLS вставляется то значение EXP,
которое пожелает оператор.
Но допустимо и копировать те, что были в DSCP. Например, можно переопределять значения — копировать всё,
вплоть до EF, а CS6 и CS7 маппировать в EF.
Каждый транзитный P смотрит только на EXP верхнего MPLS-заголовка.
Предпоследний узел снимает транспортную метку (PHP) и копирует значение EXP в заголовок VPN.
Egress PE сначала производит обработку пакета, опираясь на поле EXP в заголовке MPLS, и только потом его
снимает, при этом не копирует значение в DSCP.
То есть независимо от того, что происходило с полем EXP в заголовках MPLS, IP DSCP остаётся неизменным.
Такой сценарий можно применять, когда у оператора свой домен Diff-Serv, и он не хочет, чтобы клиентский
трафик как-то мог на него влиять.
Short-Pipe Mode
Этот режим вы можете рассматривать вариацией Pipe-mode. Разница лишь в том, что на выходе из MPLS-сети
пакет обрабатывается в соответствие с его полем IP DSCP, а не MPLS EXP.
Это означает, что приоритет пакета на выходе определяется клиентом, а не оператором.
Ingress PE не доверяет IP DSCP входящих пакетов
Транзитные P смотрят в поле EXP верхнего заголовка.
Предпоследний P снимает транспортную метку и копирует значение в VPN-метку.
Egress PE сначала снимает метку MPLS, потом обрабатывает пакет в очередях.
Объяснение от cisco.
Однако ситуация совсем иная, если на транспорте RSVP-TE. Если узлов PE много, то может стать головной болью
настроить туннели между всеми нужными парами маршрутизаторов.
LDP over TE
Этот подход не требует нового функционала. Вводят иерархию — в неком неизменном ядре сети поднимается
полносвязная система TE-туннелей между P-маршрутизаторами.
Делается это один раз и никогда уже не меняется.
А обычные PE маршрутизаторы друг к другу строят LDP LSP.
В стеке пакета MPLS, движущегося в ядре сети, получится три метки — VPN, LDP, RSVP-TE.
То есть LDP LSP, как бы туннелируются в RSVP LSP.
На, назовём это, сегменте доступа у нас удобный и уютный LDP, а в ядре сети (это может быть междугородней
магистралью) при этом есть возможность управлять трафиком.
RSVP Auto-Mesh/Auto-Tunnel
Это маленькая, но крайне полезная импрувизация, позволяющая автоматизировать настройку туннелей.
Как только в TEDB появляется новое PE-устройство, с ним моментально строятся прямые и обратные туннели.
Какая конфигурация применяется? Заранее создаётся шаблон настройки туннельного интерфейса.
Как узнать, что новый узел — это PE? В шаблоне указывается ACL, который определяет с кем можно строить.
Например, мы берём за правило, что у PE узлов интерфейс Loopback 127 будет 10.127.127.0/24, и анонсируем его
в IGP.
Заключение
Хотелось бы подвести краткий итог одной фразой: всё, что было описано в данной статье, в самом деле
встречается на белом свете и вовсе не замки на песке.
Поэтому кратко повторим:
MPLS TE использует RSVP-TE, как протокол распределения меток и резервирования ресурсов. А тот в свою
очередь опирается на LS IGP:
• OSPF с его Opaque LSA
• IS-IS с TLV
При расчёте кратчайших маршрутов CSPF берёт требования из конфигурации TE-Туннеля, а ограничения из TEDB.
Требования туннеля:
• Требуемая полоса и приоритет установки
• Affinity/Administrative Group
• Explicit-Path
Make-Before-Break:
Это широко используемая концепция в MPLS TE — сперва добейся! Прежде, чем сломать что-то, что уже
работает, построй новый LSP,
Применяется при:
• Переоптимизации туннелей
• FRR
• Важный туннель пытается вытеснить менее важный.
Защита туннелей:
• Когда ломается линия/узел, в первые 50 мс отрабатывает FastReRoute, спасая те пакеты, что уже идут в
LSP.
• Потом Ingress LSR узнаёт о проблемах с основным LSP и перенаправляет трафик в резервный LSP — так
уже спасаются все последующие пакеты.
• Далее Ingress LSR пытается восстановить основной LSP в обход проблемного участка, если это возможно.
Приоритет туннелей:
Каждый туннель имеет два значения:
• Setup Priority
• Hold Priority.
Обычно они равны.
0 — наивысший, 7 — низший.
Туннель с более высоким значением Setup Priority вытеснит установленный туннель с более низким Hold Priority.
Полезные ссылки
• Три документа от cisco на тему MPLS TE. Длинно и по делу:
1. MPLS Traffic Engineering
Одно из удивительнейших достижений современности — это то, как, сидя в Норильске, человек может чатиться
со своим другом в Таиланде, параллельно покупать билет на вечерний самолёт к нему, расплачиваясь
банковской картой, в то время, как где-то в Штатах на виртуалочке его бот совершает сделки на бирже со
скоростью, с которой его сын переключает вкладки, когда отец входит в комнату.
А через 10 минут он закажет такси через приложение на телефоне, и ему не придётся даже брать с собой в
дорогу наличку.
В аэропорту он купит кофе, расплатившись часами, сделает видеозвонок дочери в Берлин, а потом запустит
кинцо онлайн, чтобы скоротать час до посадки.
За это время тысячи MPLS-меток будут навешаны и сняты, миллионы обращений к различным таблицам
произойдут, базовые станции сотовых сетей передадут гигабайты данных, миллиарды пакетов больших и малых
в виде электронов и фотонов со скоростью света понесутся в ЦОДы по всему миру.
В своём вояже к QoS, теме обещанной многократно, мы сделаем ещё один съезд. На этот раз обратимся к жизни
пакета в оборудовании связи.
Вскроем этот синий ящик и распотрошим его.
Кликабельно и увеличабельно.
Сегодня:
1.
Коротко о судьбе и пути пакета
2.
Плоскости (они же плейны): Forwarding/Data, Control, Management
3.
Кто как и зачем обрабатывает трафик
4.
Типы чипов: от CPU до ASIC'ов
5.
Аппаратная архитектура сетевого устройства
6.
Путешествие длиною в жизнь
Мы в этой статье поговорим обо всех. Но преимущественно речь будет о транзитных — ведь именно на них
провайдер зарабатывает деньги.
Все рассуждения данной статьи, с поправками на заголовки, протоколы и конкретные действия с пакетом,
применимы к любым сетевым устройствам, будь то маршрутизатор, файрвол или коммутатор — их задача:
передать пакет следующему узлу ближе к назначению.
Дабы избежать кривотолков и неуместной критики: автор отдаёт себе отчёт в том, что реальная
ситуация зависит от конкретного устройства. Однако задача статьи — дать общее понимание принципов
работы сетевого оборудования.
Следующую схему мы выберем в качестве отправной точки.
Независимо от того, что за устройство, как реализована обработка трафика, пакету нужно пройти такой путь.
1. Путь делится на две части: входной и выходной тракты.
2. На входе происходит сначала декапсуляция — отделение заголовка от полезной нагрузки и прочие
присущие протоколу вещи (например, вычисление контрольной суммы)
3. Далее стадия входной обработки (Ingress Processing) — сам пакет без заголовка (нагрузка) томится в
буфере, а заголовок анализируется. Здесь могут к пакетам применяться политики, происходить поиск точки
назначения и выходного интерфейса, создаваться копии итд.
4. Когда анализ закончен, заголовок превращается в метаданные (временный заголовок), склеивается с
пакетом и они передаются на входную очередь. Она позволяет не слать на выходной тракт больше, чем тот
может обработать.
5. Далее пакет может ждать (или запрашивать) явное разрешение на перемещение в выходную очередь, а
может просто туда передаваться, а там, поди, разберутся.
6. Выходных трактов может быть несколько, поэтому пакет далее попадает на фабрику коммутации, цель
которой, доставить его на правильный.
7. На выходном тракте также есть очередь — выходная. В ней пакеты ожидают выходной обработки (Egress
Processing): политики, QoS, репликация, шейпинг. Здесь же формируются будущие заголовки пакета. Также
выходная очередь может быть полезной для того, чтобы на интерфейсы не передавать больше, чем они могут
пропустить.
8. И завершающая стадия — инкапсуляция пакета в приготовленные заголовки и передача его дальше.
Вот и вопрос — в железе или ПО. Он преследует мир IP-сетей с момента их основания и, как это водится,
развитие происходит циклически.
Есть вещи тривиальные, для которых элементная база существует… ммм… с 60-х. Например, АЦП, аппаратные
очереди или CPU.
А есть те, которые стали прорывом относительно недавно.
Часть функций всегда была и будет аппаратной, часть — всегда будет программной, а часть — мечется, как та
обезьяна.
В этой статье мы будем преимущественно говорить об аппаратных устройствах, лишь делая по ходу ремарки по
поводу виртуальных.
2. Уровни и плоскости
Мы столько раз прежде использовали эти понятия, что пора им уже дать определения.
В работе оборудования можно выделить три уровня/плоскости:
• Forwarding/Data Plane
• Control Plane
• Management Plane
Forwarding/Data Plane
Плоскость пересылки.
Главная задача сети — доставить трафик от одного приложения другому. И сделать это максимально быстро, как
в плане пропускной способности, так и задержек.
Соответственно главная задача узла — максимально быстро передать вошедший пакет на правильный выходной
интерфейс, успев поменять ему заголовки и применив политики.
Поэтому существуют заранее заполненные таблицы передачи пакетов — таблицы коммутации, таблицы
маршрутизации, таблицы меток, таблицы соседств итд.
Реализованы они могут быть на специальных чипах CAM, TCAM, работающих на скорости линии (интерфейса). А
могут быть и программными.
Примеры:
1. Принять Ethernet-кадр, посчитать контрольную сумму, проверить есть ли SMAC в таблице MAC-адресов.
Найти DMAC в таблице MAC-адресов, определить интерфейс, передать кадр.
2. Принять MPLS-пакет, определить входной интерфейс и входную метку. Выполнить поиск в таблице меток,
определить выходной интерфейс и выходную метку. Свопнуть. Передать.
3. Пришёл поток пакетов. Выходным интерфейсом оказался LAG. Решение, в какие из интерфейсов их
отправить, тоже принимается на Forwarding Plane.
Control Plane
Плоскость управления.
Всему голова. Она заранее заполняет таблицы, по которым затем будет передаваться трафик.
Здесь работают протоколы со сложными алгоритмами, которые дорого или невозможно выполнить аппаратно.
Например, алгоритм Дейкстры реализовать на чипе можно, но сложно. Так же сложно сделать выбор лучшего
маршрута BGP или определение FEC и рассылку меток. Кроме того, для всего этого пришлось бы делать
отдельный чип или часть чипа, которая практически не может быть переиспользована.
В такой ситуации лучше пожертвовать сабсекундной сходимостью в пользу удобства и цены.
Работа и реализация Control Plane универсальна: ЦПУ + оперативная память: работает одинаково хоть на
стоечных маршрутизаторах, хоть на виртуальных сетевых устройствах.
Эта система — не мысленный эксперимент, не различные функции одной программы, это действительно
физически разделённые тракты, которые взаимодействуют друг с другом.
Началось всё с разнесения плоскостей на разные платы. Далее появились стекируемые устройства, где одно
выполняло интеллектуальные операции, а другое было лишь интерфейсным придатком.
Вчерашний день — это системы вроде Cisco Nexus 5000 Switch + Nexus 2000 Fabric Extender, где 2000 выступает в
роли выносной интерфейсной платы для 5000.
Где-то в параллельной Вселенной тихо живёт SDN разлива 1.0 — с Openflow-like механизмами, где Control Plane
вынесли на внешние контроллеры, а таблицы пересылок заливаются в совершенно глупые коммутаторы.
Наша реальность и ближайшее будущее — это наложенные сети (Overlay), настраиваемые SDN-контроллерами,
где сервисы абстрагированы от физической топологии на более высоком уровне иерархии.
И несмотря на то, что с каждой статьёй мы всё глубже погружаемся в детали, мы учимся мыслить свободно и
глобально.
Разделение на Control и Forwarding Plane позволило отвязать передачу данных от работы протоколов и
построения сети, а это повлекло значительное повышение масштабируемости и отказоустойчивости.
Так один модуль плоскости управления может поддерживать несколько интерфейсных модулей.
В случае сбоя на плоскости управления механизмы GR, NSR, GRES и ISSU помогают плоскости пересылки
продолжать работать будто ничего и не было.
Management Plane
Плоскость или демон наблюдения. Не всегда его выделяют в самостоятельную плоскость, относя его задачи к
Control Plane, а иногда, выделяя, называют Monitoring.
Этот модуль отвечает за конфигурацию и жизнедеятельность узла. Он следит за такими параметрами, как:
• Температура
• Утилизация ресурсов
• Электропитание
• Скорость вращения вентиляторов
• Работоспособность плат и модулей.
Примеры:
1. Упал интерфейс — генерируется авария, лог и трап на систему мониторинга
2. Поднялась температура чипа — увеличивает скорость вращения вентиляторов
3. Обнаружил, что одна плата перестала отвечать на периодические запросы — выполняет рестарт плат —
вдруг поднимется.
4. Оператор подключился по SSH для снятия диагнонстической информации — CLI также обеспечивается
Control Plane'ом.
5. Приехала конфигурация по Netconf — Management Plane проверяет и применяет её. При необходимости
инструктирует Control Plane о произошедших изменениях и необходимых действиях.
Итак:
Forwarding Plane — передача трафика на основе таблиц пересылок — собственно то, из чего оператор извлекает
прибыль.
Control Plane — служебный уровень, необходимый для формирования условий для работы Forwarding Plane.
Management Plane — модуль, следящий за общим состоянием устройства.
В первую очередь это вопрос организации вышеописанных трактов: что делать с электрическим импульсом из
одного кабеля и как его передать в другой — правильный.
Для этого на сетевых устройствах есть букет разнообразных чипов.
Так, например, микросхемы (ASIC, FPGA) выполняют простые операции, вроде АЦП/ЦАП, подсчёта контрольных
сум, буферизации пакетов.
Ещё нужен модуль, который умеет парсить, анализировать и формировать заголовки пакетов.
И модуль, который будет определять, куда, в какой интерфейс, пакет надо передать. Делать это нужно для
каждого божьего пакета.
Кто-то должен также следить и за тем, можно ли этот пакет пропускать вообще. То есть проверить его на
предмет подпадания под ACL, контролировать скорость потока и отбросить, если она превышена.
Сюда же можно вписать и более комплексные функции трансляции адресов, файрвола, балансировки итд.
Исторически все сложные действия выполнялись на CPU. Поиск подходящего маршрута в таблице
маршрутизации был реализован как программный код, проверка на удовлетворение политикам — тоже.
Процессор с этим справлялся, но только он с этим и справлялся.
Чем это грозит понятно: производительность будет падать тем сильнее, чем больше трафика устройство должно
перемалывать и чем больше функций мы будем вешать на него. Поэтому одна за другой большинство функций
были делегированы на отдельные чипы.
И из обычного x86-сервера маршрутизаторы превратились в специализированные сетевые коробки, набитые
непонятными деталями и интерфейсами. А Ethernet-хабы переродились в интеллектуальные коммутаторы.
Функции по парсингу заголовков и их анализу, а также поиску выходного интерфейса взяли на себя ASIC, FPGA,
Network Processor.
Обработка в очередях, обеспечение QoS, управление перегрузками — тоже специализированные ASIC.
Такие вещи, как стейтфул файрвол, остались на ЦПУ, потому что количество сессий несъедобное.
Впрочем, вычисление хэша — алгоритм очень простой, и любой мало-мальски уважающий себя ASIC с этим
справится. Инженерам был адресован вопрос — а что дальше делать с хэшем?
Так появилась память CAM — Content Addressable Memory. Её адреса — это хэши значений. В своей ячейке CAM
содержит или ответное значение (номер порта, например) или чаще адрес ячейки в обычной RAM.
То есть пришёл Ethernet-кадр, ASIC'и его разорвали на заголовки, вытащили DMAC — прогнали его через CAM и
получили вожделенный исходящий интерфейс.
Подробнее о CAM дальше.
Долгое время решения этой проблемы не существовало. На заре сетей с пакетной коммутацией IP-пакеты
обрабатывались на CPU. И главная проблема этого — даже не коммутация на скорости линии (хотя и она тоже), а
влияние дополнительных настроек на производительность. Вы и сейчас можете это увидеть на каком-нибудь
домашнем микротике, если настроить на нём с десяток ACL — сразу заметите, как просядет пропускная
способность.
Интернет разрастался, политик становилось всё больше, а требования к пропускной способности подпрыгивали
скачкообразно, и CPU становился камнем преткновения. Тем более учитывая, что поиск маршрута подчас
приходилось делать не один раз, а рекурсивно погружаться всё глубже.
Так в лихие 90-е зародился MPLS. Какая блестящая идея — построить заранее путь на Control Plane. Адресацией в
MPLS будет метка фиксированной длины, и соответственно нужна единственная запись в таблице меток, что с
пакетом дальше делать. При этом мы не теряем гибкости IP, поскольку он лежит в основе, и можем использовать
CAM. Плюс заголовок MPLS — короток (4 байта против 20 в IP) и предельно прост.
Однако по иронии судьбы в то же время инженеры совершили прорыв, разработав TCAM — Ternary CAM. И с тех
пор ограничений уже почти не было (хотя не без оговорок).
Что же до MPLS, который ввиду данного события должен был скоропостижно скончаться, едва родившись, то он
прорубил себе дверь в другой дом. Но об этом мы уже наговорились.
Поэтому большая часть сетевой инфраструктуры ЦОДов сейчас виртуализируется. А это предполагает переход от
аппаратной архитектуры к гибридной. CAM, TCAM, NP, ASIC сейчас заменяются на связку DPDK с более умными
сетевыми картами, которые тоже поддерживают виртуалиацию — SR-IOV — и забирают на свои чипы некоторую
часть рутинной работы.
Кроме того, с развитием алгоритмических методов поиска, сегодня сокращается необходимость в CAM/TCAM на
традиционных коммутаторах и маршрутизаторах.
Таким образом мы снова становимся свидетелями сдвига парадигмы в вопросе реализации Forwarding Plane.
Но мы пока остаёмся в сфере аппаратной пересылки и теперь давайте подробнее обо всех чипах.
4. Типов-чипов
Я не ставлю целью данной статьи описать все существующие чипы — только те, что используются в
сетевом оборудовании.
Кроме того на чипах RAM (DRAM) реализованы очереди: входные, выходные, интерфейсные.
На входе каждой ячейки хранения в CAM стоят сравнивающие элементы (мне очень нравится термин
компараторы), которые могут выдавать 0 (разомкнуто) или 1 (замкнуто) в зависимости от того, что на них
поступило и что записано.
В сравнивающих элементах записаны как раз искомые значения.
Когда нужно найти запись в таблице, соответствующую определённому значению, это значение прогоняется
одновременно через ВСЕ сравнивающие элементы. Буквально, электрический импульс, несущий значения,
попадает на все элементы, благодаря тому, что они подключены параллельно. Каждый из них выполняет очень
простое действие, выдавая для каждого бита 1, если биты совпали, и 0, если нет, то есть замыкая и размыкая
контакт. Таким образом та ячейка, адресом которой является искомое значение, замыкает всю цепь,
электрический сигнал проходит и запитывает её.
Источник картинки.
Источник картинки.
Это чем-то похоже на пару ключ-замок. Только ключ с правильной геометрией может поставить штифты замка в
правильные положения и провернуть цилиндр.
Вот только у нас много копий одного ключа и много разных конфигураций замков. И мы вставляем их все
одновременно и пытаемся провернуть, а нужное значение лежит за той дверью, замок которой ключ откроет.
Для гибкого использования CAM мы берём не непосредственно значения из полей заголовков, а вычисляем их
хэш.
Хэш-функция используется для следующих целей:
1. Длина результата значительно меньше, чем у входных значений. Так пространство MAC-адресов длиной
48 бит можно отобразить в 16-ибитовое значение, тем самым в 2^32 раза уменьшив длину значений, которые
нужно сравнивать, и соответственно, размер CAM.
2. Основная идея хэш-функции в том, что результат её выполнения для одинаковых входных данных всегда
будет одинаков (например, как остаток от деления одного числа на другое — это пример элементарной хэш
функции).
3. Результат её выполнения на всём пространстве входных значений — это ± плоскость — все значения
равновероятны. Это важно для снижения вероятности конфликта хэшей, когда два значения дают одинаковый
результат.
4. Конфликт хэшей, кстати, весьма любопытная проблема, которая описана в парадоксе дней рождения.
Рекомендую почитать Hardware Defined Networking Брайна Петерсена, где помимо всего прочего он описывает
механизмы избежания конфликта хэшей.
5. Независимо от длины исходных аргументов, результат будет всегда одной длины. То есть на вход можно
подать сложное сочетание аргументов, например, DMAC+EtherType, и для хранения не потребуется выделять
более сложную структуру памяти.
Именно хэш закодирован в сравнивающие элементы. Именно хэш искомого значения будет сравниваться с
ними.
По принципу CAM схож с хэш-таблицами в программировании, только реализованными на чипах.
В этот принцип отлично укладывается также MPLS-коммутация, почему MPLS и сватали в своё время на IP.
Например:
1. Пришёл самый первый Ethernet-кадр на порт коммутатора.
2. Коммутатор извлёк SMAC, вычислил его хэш.
3. Данный хэш он записал в сравнивающие элементы CAM, номер интерфейса откуда пришёл кадр в RAM, а
в саму ячейку CAM адрес ячейки в RAM.
4. Выполнил рассылку изначального кадра во все порты.
5. Повторил пп. 1-5 ....
6. Заполнена вся таблица MAC-адресов.
7. Приходит Ethernet-кадр. Коммутатор сначала проверяет, известен ли ему данный SMAC (сравнивает хэш
адреса с записанными хэшами в CAM) и, если нет, сохраняет.
8. Извлекает DMAC, считает его хэш.
9. Данный хэш он прогоняет через все сравнивающие элементы CAM и находит единственное совпадение.
10. Узнаёт номер порта, отправляет туда изначальный кадр.
Резюме:
• Ячейки CAM адресуются хэшами.
• Ячейки CAM содержат (обычно) адрес ячейки в обычной памяти (RAM), потому что хранить конечную
информацию — дорого.
• Каждая ячейка CAM имеет на входе сравнивающий элемент, который сравнивает искомое значение с
хэш-адресом. От этого размер и стоимость CAM значительно больше, чем RAM.
• Проверка совпадения происходит одновременно во всех записях, отчего CAM дюже греется, зато выдаёт
результат за константное время.
• CAM+RAM хранят Hard Tables (аппаратные таблицы), к которым обращается чип коммутации.
0.0.0.0/0
10.10.10.8/29
10.10.0.0/16
10.8.0.0/13
Другие.
В сравнивающие элементы TCAM записываются биты маршрута, если в маске стоит 1, и «не важно», если 0.
При поиске нужной записи TCAM, как и CAM, прогоняет искомое значение одновременно по всем ячейкам.
Результатом будет последовательность 0, 1 и «не важно».
Только те записи, которые вернули последовательность единиц, за которыми следуют «не важно» участвуют в
следующем этапе селекции.
Далее из всех результатов выбирается тот, где самая длинная последовательность единиц — так реализуется
правило Longest prefix match.
Очевидно, что мы-то своим зорким взглядом, сразу увидели, что это будет маршрут 10.10.10.8/29.
Источник картинки.
Решение на грани гениальности, за которое пришлось заплатить большую цену. Из-за очень высокой плотности
транзисторов (у каждой ячейки их свой набор, а ячеек должны быть миллионы) они греются не меньше любого
CPU — нужно решать вопрос отвода тепла.
Кроме того, их производство стоит очень дорого, и не будет лукавством сказать, что стоимость сетевого
оборудования и раньше и сейчас определяется именно наличием и объёмом TCAM.
Внимательный читатель обратил внимание на вопрос хэш-функций — ведь она преобразует изначальный
аргумент во что-то совершенно непохожее на исходник, как же мы будем сравнивать 0, 1 и длины? Ответ: хэш
функция здесь не используется. Описанный выше алгоритм — это сильное упрощения реальной процедуры, за
деталями этого любознательного читателя отправлю к той же книге Hardware Defined Networking.
Однако память — это память — всего лишь хранит. Сама она трафик не передаёт — кто-то с ней должен
взаимодействовать.
Автору не удалось найти общепринятые термины для обозначения тех или иных компонентов, поэтому он взял
на себя смелость пользоваться собственным терминологическим аппаратом. Однако он готов в любой момент
прислушаться к рекомендациям и адаптировать статью к универсальным определениям.
Тот компонент, который занимается передачей пакетов, называется чипом коммутации — FE — Forwarding
Engine. Именно он парсит заголовки, запрашивает информацию в TCAM и перенаправляет пакеты к выходному
интерфейсу.
Работа с пакетом декомпозируется на множество мелких шагов, каждый из которых должен выполняться на
скорости линии, и совокупное время отработки тракта должно быть адекватным требованиям сети.
Реализован FE может быть на Сетевых Процессорах (NP), FPGA и элементарных ASIC или их последовательности.
Процесс разработки и отладки ASIC достаточно трудоёмок, поскольку в финальном чипе нет места ошибкам, зато
когда он завершён, их можно отгружать камазами.
ASIC стоит дёшево, потому что производство простое, массовое, вероятность ошибки низкая, а рынок сбыта
огромный.
Согласно документации Juniper, на части устройств их PFE (Packet Forwarding Engine) основан на
последовательности ASIC'ов и не использует более сложных микросхем.
Хорошим примером использования ASIC'ов сегодня могут служить фермы по майнингу криптовалют. Эволюция
привела этот процесс от CPU через кластеры GPU к ASIC'ам, специализированным исключительно на майнинге,
что позволило, уменьшить размер, энергопотребление и тепловыделение, сделав процесс значительно дешевле
и невероятно масштабируемым, напрочь сметя доморощенных крипто-бизнесменов с карты конкурентов.
Programmable ASIC
В последние годы наблюдается тенденция к реализации большинства функций на ASIC. Однако хочется оставить
возможность программировать поведение. Поэтому появились так называемые Программируемые ASIC,
которые обладают низкой стоимостью, высокой производительность и некоторой грибкостью.
Опять же, если обнаружена неисправность, то можно написать патч для ПО, который сможет её починить, и при
этом обновить только конкретно данный чип, без влияния на всю остальную систему.
FPGA значительно дороже в разработке и производстве, главным образом из-за заранее заложенной гибкости.
Из-за гибкости возможностей FPGA иногда используются для обкатки какой-либо новой технологии, когда с
помощью прошивки можно менять поведение компонента. И когда логика обкатана, можно запускать в
производство ASIC, реализующий её.
NP — Network Processor
В оборудовании операторского класса, где требования как к пропускной способности, так и к протоколам,
запущенным на устройстве, довольно высоки, часто используются специализированные чипы — сетевые
процессоры — NP. В некотором смысле можно считать их мощными FPGA, направленными именно на обработку
и передачу пакетов.
Крупные телеком-вендоры разрабатывают свои собственные процессоры (Cisco, Juniper, Huawei, Nokia), для
производителей помельче существуют предложения от нескольких гигантов, вроде Marvell, Mellanox.
Вот например презентация нового NP-чипа Cisco 400Gb/s Full-duplex: тыц.
А это описание работы чипсета Juniper Trio, который однако позиционируется, как NISP (Network Instruction Set
Processor), а не NP: тыц.
Немного маркетинга и суперэффектное видео о Nokia FP4: тыц
Задачи и возможности примерно те же, что и у FPGA. Дьявол кроется в деталях, куда мы уже не полезем.
Для этой модели возьмём модульное шасси, состоящее из интерфейсных и управляющих модулей и фабрики
коммутации.
Вроде такого
Общая шина
Общая шина (она же Back Plane, она же Midplane) устройства, связывающая друг с другом все модули.
Обычно, это просто батарея медных контактов без каких-либо микросхем.
Так выглядит задняя часть платы, которая вставляется в шину
Управляющий модуль
На нём расположены CPU, оперативная память, постоянная память для хранения ПО, конфигурации и логов,
интерфейсы для управления.
Он отвечает за Management Plane и за Control Plane.
С ним мы работаем, когда подключаемся к устройству по telnet/ssh.
Он загружает ПО в оперативную память и запускает все другие модули при подаче питания.
Он следит за Heart beat других модулей — специальными пакетами, получение которых говорит о том, что
модуль жив и работоспособен.
Он же может перезагрузить модуль, если Heart beat не получил (как программно, так и выключить питание на
плате).
Протокольные пакеты доставляются на CPU и тот, обрабатывав их, совершает какое-то действие, как то: записать
обновления в таблицы коммутации, сформировать ответный пакет, запросить информацию о каком-либо
компоненте итд.
Управляющий модуль занимается расчётом SPF, LSP, установлением соседств по разным протоколам. Он
записывает таблицы коммутации в Soft Tables оперативной памяти.
Так выглядят управляющие платы разных устройств
Модуль состоит из многих компонентов, которые могут быть реализованы как в одном чипе (System-on-Chip), так
и на множестве отдельных в зависимости от класса устройства и архитектуры.
PIC — Physical Interface Card
На PIC находятся интерфейсы и чип, который выполняет базовые операции с трафиком:
1. Восстанавливает битовый поток из электрических импульсов
2. Восстанавливает пакет из набора битов.
3. Удаляет служебную информацию (как то: преамбула, IFG).
4. Вычисляет контрольную сумму и
o а) если она бьётся со значением в пакете, пропускает его, удалив лишние заголовки,
например FCS.
o пиковые значения
o утилизация порта
o количество Unicast/Broadcast/Multicast
6. PIC также может восстановить сигнал SynchroEthernet, если необходимо.
В случае, если линейная плата модульная, то интерфейсная карта будет извлекаемой и заменяемой.
Так выглядит Juniper MIC (Modular Interface Card), совмещённый с чипом PIC
Во-первых, FE делится на Ingress FE и Egress FE. Первый обрабатывает соответственно пакеты на входном тракте,
второй — на выходном.
С одной стороны это разделение терминологическое — пакет пришёл на Ingress FE и далее должен быть
отправлен на Egress FE, возможно, другой платы.
С другой, разделение — зачастую вполне физическое: внутри одного FE чипа живут эти две сущности: Ingress и
Egress. Это и логично — ведь плата может быть как точкой входа, так и точкой выхода.
Во-вторых, именно входной FE определяет всю дальнейшую судьбу пакета в пределах узла:
• Вид будущих заголовков
• Приоритет внутри узла и при передаче вовне
• Выходной FE и интерфейс
• Какой именно из физических членов LAG или ECMP
* с небольшой оговоркой, что выходной тракт всё-таки может ещё произвести репликацию пакета или
зарезать его из-за переполненного буфера.
В-третьих, FE должен идентифицировать протокольные пакеты в транзитном трафике и передавать их на CPU.
Соответственно и получать пакеты (или инструкции) от CPU — тоже его работа.
Рядом с FE находятся CAM, TCAM и RAM, куда FE обращается в поиске выходного интерфейса и проверки ACL.
Они хранят Hard Tables.
Кроме того Ingress FE производит репликацию BUM трафика — он рассылает по одной копии пакета на каждый
Egress FE. А Egress FE уже делает столько копий, во сколько интерфейсов нужно отправить
QoS или TM — Traffic Management
Иногда в самом FE, иногда как отдельный чип, дальше идёт чип QoS, совмещённый с очередью, вместе обычно
носящие название Traffic Management.
Входная очередь (очередь на входном тракте) нужна для того, чтобы не переполнить выходную (очередь на
выходном тракте).
Выходная очередь предназначена для избежания явления, известного, как Back Pressure — когда на чип FE
пакеты поступают быстрее, чем он в состоянии обработать. Такая ситуация невозможна с Ingress FE, потому что к
нему подключено такое количество интерфейсов, что трафик от них он в состоянии переварить, либо Ethernet
через Flow Control возьмёт ситуацию под свой Control.
А вот на Egress FE трафик может сливаться со многих разных плат (читай Ingress FE) — и ему захлебнуться — это
как два байта переслать.
Задача очереди не только сгладить всплески трафика, но и управляемо дропать пакеты, когда это становится
неизбежным. А именно — выкидывать из очереди низкоприоритетные пакеты с бо́ льшей вероятностью, чем
высокоприоритетные. Причём отслеживать перегрузку желательно на уровне интерфейсов — ведь если через
дестятигигабитный интерфейс нужно отправить 13 Гб/с трафика, то 3 из них однозначно будет отброшено, а
четырёхсот-гигабитный FE при этом даже близок к перегрузке не будет.
Схема достаточно усложняется — две очереди, а значит, двойная буферизация, более того как-то надо по
интерфейсам их подробить, встаёт ещё вопрос такой: а если один интерфейс перегружен, то вся входная очередь
встанет?
Эти сложности никак не разрешались ранее, однако сегодня они адресованы механизму VOQ — Virtual Output
Queue. VOQ прекрасно описан вот в этой заметке.
В двух словах — это виртуализация всех очередей между различными FE. Имеется один физический чип памяти
DRAM на входном тракте, который внутри разбит на виртуальные очереди. Количество входных очередей — по
общему числу выходных. Выходная очередь больше не распологается реально на выходном модуле — она в том
же самом DRAM — только виртуальная.
Таким образом (возьмём пример Juniper), если есть 72 выходных интерфейса по 8 очередей на каждом, итого
получается 576 входных очередей на каждом интерфейсном модуле (читай TM). Если на устройстве 6 модулей,
то оно должно поддерживать 3456 VOQ.
Это элегантно снимает вопрос двойной буферизации и проблем Head of Line Blocking, когда одна выходная
очередь в момент перегрузки блокирует всю физическую входную — теперь с VOQ только ту виртуальную,
которая с ней связана.
Кроме того пакет теперь отбрасывается при необходимости на входной очереди, и не нужно его отправлять на
фабрику и забивать выходные очереди.
Что ещё важно знать про очереди, так это то, что даже те пакеты, которые предназначены на другой интерфейс
этого же FE, должны пройти через входную и выходную очереди.
Это нужно для той же самой борьбы с Back Pressure. Только очереди могут защитить FE от перегрузок и
отбрасывать лишний трафик согласно приоритетам, поэтому никакого прямого мостика для транзитного трафика
между Ingress FE и Egress FE не предусмотрено.
На фабрику однако такой «локальный» трафик попадать не должен.
Но про QoS мы ещё поговорим в следующей части.
Фабрика коммутации
Если мы возьмём Hi-End маршрутизатор операторского класса, то обычно в нём может насчитываться до двух
десятков интерфейсных плат, в каждой из которых установлен как минимум один чип коммутации FE. Каждый
чип коммутации смотрит частью своих ног в сторону интерфейсов, а частью в сторону задней шины. И ног там
предостаточно, потому что медная среда имеет свой предел по пропускной способности — нам не хватит
одного-двух выходов.
Как связать 8?
Уверены? Ничего не смущает?
Пропускная способность системы из 8 чипов остаётся той же, что и у пары — ведь каждый раз мы уменьшаем
количество ног для связи.
Второй момент, как нам вообще создать полносвязную топологию, если чипов, допустим, 16, и каждый из них
имеет по 32 контакта? 16*15/2 пучков кабелей по 32 жилы в каждом?
Эта проблема была адресована неблокирующимся сетям Клоза или сетям без переподписки.
У нас есть входные коммутационные элементы (Ingress FE), выходные (Egress FE) и транзитные. Задача
транзитных — связать входные с выходными. Любой входной связан с любым выходным через транзитный.
Входные и выходные не связаны друг с другом напрямую, транзитные также не имеют связи.
Нужно больше входных и выходных коммутационных элементов — добавляем транзитных. Нужно ещё больше?
Добавляем новый каскад транзитных:
Вот этим и напичканы платы коммутации в современных маршрутизаторах — очень тупые ASIC, которые только и
умеют, что быстро перекладывать пакеты со входа на выход.
Плата коммутации подключается к задней шине и имеет связность со всеми другими платами.
Обычно они работают в режиме N+1 — то есть все разделяют нагрузку, но при выходе из строя одной платы,
оставшиеся берут всё на себя.
Кстати, сами платы можно вполне назвать верхним каскадом иерархии фабрики Клоза.
Остался только вопрос по ячейкам. Ну и перекладывали бы эти ASICи пакеты сразу, зачем их ещё нарезать?
Здесь можно провести аналогию с ECMP. Если кто-то когда-либо настраивал попакетную балансировку между
различными путями, то он, наверняка, помнит, сколько боли это доставляло. Неупорядоченная доставка пакетов,
с которой с горем пополам справляется TCP, может основательно поломать IP-телефонию или видео, например.
Проблема в попакетной балансировке в том, что два пакета одного потока спокойно могут пойти разными
путями. При этом один из них маленький и очень быстро долетит до получателя, а другой акселерат-переросток
— застрянет в узком буфере. Вот они и разупорядочились.
То же происходит и на фабрике.
Неплохой метод борьбы с этим — попоточная балансировка — вычисляется хэш по кортежу значений (SMAC,
DMAC, SIP, DIP, Protocol, SPort, DPort, MPLS-метка итд.) и все пакеты одного потока начинают передаваться одним
путём.
Но это работает неидеально. Зачастую один очень жирный поток может нагрузить один линк в то время, как
другие будут простаивать. И с этим можно смириться на сети оператора, но нельзя в пределах этого синего
ящика.
Транзитные пакеты
Пусть мы имеем дело со стандартным Ethernet/IP-пакетом.
Узел — IP-маршрутизатор.
Пакет следует транзитом из L3-порта А в L3-порт Б.
1. Оптический сигнал приходит в порт. Здесь он преобразуется в электрические импульсы.
2. Импульсы попадают на PIC, где АЦП восстанавливает из них поток битов.
3. Поток битов модуль Ethernet разбивает на отдельные Ethernet-кадры. В этом ему помогает преамбула,
которая тут же за ненадобностью отбрасывается.
4. По ходу дела Ethernet вычисляет контрольную сумму кадра. А потом сравнивает с хвостовым заголовком
FCS.
5. Если совпало, пакет без FCS передаётся дальше.
6. Если нет — тут же отбрасывается, а счётчик ошибок на интерфейсе увеличивается на 1.
7. Здесь же на PIC вычисляется статистика трафика: количество, объём, скорость с разбивкой на Unicast,
Broadcast, Multicast.
8. Далее этот Ethernet кадр ещё со всем заголовками отправляется на FE.
9. FE извлекает DMAC из заголовка, обращается в CAM и ищет, есть ли там такая запись.
10. Она находится и CAM сообщает адрес в RAM.
11. Поскольку Ethernet терминируется на маршрутизаторе, данный DMAC — это MAC-адрес самого узла.
Поэтому запись в RAM сообщает, что порт назначения — сам этот маршрутизатор и нужно передать Payload
модулю IP (об этом говорит анализ поля EtherType в заголовке).
12.
13. Далее FE отделяет заголовок IP от нагрузки (Payload). Нагрузка будет томиться в буфере, а заголовок
разорвут и растащут по полям для анализа.
14. Какие же данные из заголовка понадобятся?
o Адрес назначения (IP в нашем случае, но может быть MAC, MPLS-метка итд.)
o Приоритет (DSCP, IEEE802.1p, EXP итд.)
o Значение TTL.
o Возможно понадобятся и другие поля, такие как адрес источника, информация о вложенных
данных (протокол, порт, приложение).
Далее, пока пакет греется во внутричиповом буфере, происходит обработка изученных данных.
o Уменьшение TTL на 1 и проверка, не равен ли он 0. Если равен — то запрос на CPU для
генерации ICMP TTL Expired in Transit.
o Проверка по ACL — можно ли вообще передавать этот трафик.
o Приняните решение о назначении пакета на основе DIP.
o Ingress FE здесь обращается к TCAM с просьбой найти маршрут, соответствующий данному IP-
адресу. Тот находит и передаёт адрес ячейки в RAM.
o FE от RAM получает Egress FE, выходной интерфейс и NextHop.
o В большинстве случаев Ingress FE выясняет на этом шаге MAC-адрес Next-Hop'а из таблицы
соседей (Adjacenies Tables).
o Тут же FE узнаёт необходима ли репликация пакетов и в какие порты (BUM-трафик в случае,
например сценариев L2VPN), считает хэш для определения в какой из интерфейсов LAG или ECMP послать этот
пакет.
Если адрес назначения локальный то или парсится следующий заголовок (как это и было выше с Ethernet), или
принимаются какие-то меры аппаратные (BFD, например) или пакет передаётся на CPU (BGP, OSFP итд.)
o Преобразование приоритета из заголовков пакета во внутреннюю CoS-метку, в соответствии с
которой пакет будет обрабатываться в пределах данного узла. Может навешиваться приоритет обработки в
очередях и приоритет отбрасывания пакета.
Всё это станет метаданными и будет помещено во временный заголовок, сопровождающий пакет до Egress FE:
o Egress FE
o Выходной интерфейс
o Приоритет
o TTL
o Next Hop (MAC-адрес)
Egress FE нужен для того, чтобы доставить пакет до нужного чипа коммутации; выходной интерфейс — чтобы
сообщить ему, куда пакет передать; приоритет — говорит, как с трафиком поступать в пределах устройства и,
возможно, что записать в заголовок пакета (DSCP); TTL — тоже понадобится для того, чтобы потом его вписать в
заголовок; а Next Hop MAC позволит затем определить, что писать в поле DMAC Ethernet-заголовка.
15. Данный метазаголовок приклеивается обратно к пакету перед помещением его во входную очередь. К
этому моменту уже создано нужное количество копий пакета и они направляются к нужным Egress FE.
16. В зависимости от реализации далее входная очередь может запрашивать разрешение у выходной на
передачу пакета, ожидать явное подтверждение или вовсе передавать безусловно.
17. Непосредственно перед передачей на общую шину, пакет разрезается чипом SerDes на ячейки.
18. Далее ячейки попадают на общую шину.
19. Оттуда на плату коммутации, если она есть.
20. Если чипов коммутации не много (2-4), то фабрики могут быть встроены в интерфейсные карты. Если
больше, то это или отдельностоящиме платы или составная часть управляющих.
21. Для нас всё это не принципиально — важно знать, что ячейки передаются через эти фабрики.
22. С общей шины ячейки приходят на чип SerDes выходной платы, где благодаря их номерам они обратно
собираются в пакет.
23. Пакет помещается в выходную очередь.
24. Выходная очередь служит защитой FE от чрезмерного потока трафика (Back Pressure). Очередь позволяет
отбрасываться пакеты контролируемо и прогнозируемо. Как раз в ней будет иметь значение приоритет CoS,
указанный в метазаголовке. Чем ниже приоритет, тем выше вероятность отбрасывания при перегрузках.
25. Таким образом на чип коммутации никогда не придёт больше трафика, чем он способен обработать.
26.
27. Здесь уже вступают в дело механизмы QoS: обработка пакетов в очередях, предотвращение перегрузок,
управление перегрузками, шейпинг.
28.
29. Возвращаясь к VOQ (Virtual Output Queue), можно заметить, что данная очередь часто совмещается с
очередями на интерфейсы: чтобы в порт 10 Гб/с не пытаться просунуть 13.
30. Однако интерфейсные очереди могут быть выполнены и на отдельных чипах ближе к интерфейсам или
даже на PIC.
31. После выходной очереди пакет с метазаголовком попадает на Egress FE.
32. Здесь теперь разбирается метазаголовок и Egress FE готовит уже окончательный вид настоящих
заголовков:
33. Заполняет поля приоритета, записывает правильный TTL, передаёт пакет уровню Ethernet, где
формируется полностью новый заголовок с SMAC данного устройства, а DMAC из временного заголовка (однако,
если MAC не был разрезолвлен на Ingress FE, это происходит здесь).
34. Здесь же может выполняться полисинг, настроенный на выходном интерфейсе (ограничение скорости,
например).
35. Далее пакет попадает на чип PIC, где вычисляется контрольная сумма, которая записывается в FCS,
добавляются преамбула и IFG, и вычисляется статистика отправленных пакетов.
36. Ну и потом, наконец, пакет отправляется в свой последний путь, реинкарнировав снова в импульс.
Локальные пакеты
Бо́ льшая часть локальных пакетов обрабатываются на ЦПУ.
Напомню, что локальные — это те, которые были созданы на данном узле, которые предназначены именно ему
(юникастовые), которые предназначены всем/многим (броадкастовые или мультикастовые) или которые
намеренно требуют обработки на ЦПУ (TTL Expired, Router Alert).
Входящие
Вплоть до FE с ними происходит всё то же самое, что и с транзитными. Далее чип коммутации, обратившись в
CAM, видит, что DMAC — это MAC-адрес локального устройства, заглядывает в EtherType. Если это какой-нибудь
BPDU или ISIS PDU, то пакет сразу передаётся нужному протоколу.
Если IP — передаёт его модулю IP, который, заглядывая в TCAM, видит, что и DIP тоже локальный — значит
нужно посмотреть в поле Protocol заголовка IPv4 (или Next Header IPv6).
Определяется протокол, принимается решение о том, какому модулю дальше передать пакет — BFD, OSPF, TCP,
UDP итд. И так пакет разворачивается до конца, пока не будет найдено приложение назначения.
Когда Ingress FE с этим справился, содержимое пакета передаётся на CPU через специальный канал связи.
На этом шаге достаточно интеллектуальные устройства применяют политику по ограничению скорости
протокольных пакетов, передаваемых на ЦПУ, чтобы одними только telnet'ами не заDoSить процессор.
Если данный пакет принёс информацию об изменении топологии (например, новый OSPF, LSA), Control Plane
долежен обновить Soft Tables (RAM), а затем изменения спускаются в Hard Tables (CAM/TCAM+RAM).
Если пакет требует ответа, то устройство должно его сформировать и отправить назад изначальному источнику
(например, TCP Ack на пришедший BGP Update) или передать куда-то дальше (например, OSPF LSA или RSVP
Resv).
Исходящие протокольные пакеты формируются на ЦПУ — он заполняет все поля всех заголовков на основе Soft
Tables и далее, в зависимости от реализации, спускает его на Ingress или Egress FE.
Из-за того, что пакет сформирован на процессоре, зачастую он не попадает под интерфейсные политики.
Архитектурно многие операции, выполняющиеся на FE, требуют того, чтобы FE прозизводил Lookup и
формировал заголовки.
Отсюда могут быть любопытные и неочевидные следствия, например, их не получится отловить ACL, вы можете
не увидеть их в зазеркалированном трафике, они не будут учитываться при ограничении скорости. Но это не
точно, зависит от вендора и оборудования.
Однако политики, работающие с очередями на CPU их, конечно, увидят.
Есть некоторые протоколы Control Plane, которые всё-таки обрабатываются в железе. Ярким примером может
служить BFD. Его таймеры выкручиваются вплоть до 1 мс. CPU, как мы помним, штука гибкая, но неповоротливая,
и пока BFD-пакет пройдёт по всему тракту и развернётся до заголовка BFD, пока до процессора дойдёт
прерывание, пока тот на него переключится, прочитает пакет, сгенерирует новый, вышлет его, пройдут десятки и
сотни миллисекунд — глядь, а BFD-то уже развалился.
Поэтому пакеты BFD в большинстве случаев разбираются на чипе, на нём же и готовится ответ. И только сама
сессия устанавливается через CPU.
Большие в этом вопросе пошли ещё дальше, перенеся на железо наиболее рутинные операции.
История выше отсылает нас к длинным пингам. Иногда инженер проверяет RTT своей сети путём пинга с одного
маршрутизатора на другой. Видит вариацию в десятки и сотни мс и, начиная переживать, открывает запросы
вендору. Пугаться тут нечего. Обычно ICMP обрабатывается на CPU. И именно занятостью процессора
определяется время ответа. При этом корреляция с реальным RTT сети практически нулевая, потому что
транзитный трафик на CPU не обрабатывается.
Некоторые современные сетевые устройства могут обрабатывать ICMP-запросы и формировать ICMP-ответы на
чипе (NP, ASIC, FPGA), минуя долгий путь до CPU. И вот в этом случае циферки в ping будут адекватны реальности.
Кроме того, есть технологии мониторинга качества сети (OAM), работающие аппаратно, например CFM.
Заключение
Как вы уже, вероятно, поняли из безумного количества if'ов выше, описать аппаратную коммутацию на
вендоронезависимом универсальном языке невозможно. Хуже того, даже если брать одного вендора, разные
его линейки оборудования и даже разные платы используют совершенно разную архитектуру.
Так, например, у Cisco есть платформы с программной маршрутизацией, а есть с аппаратной.
Или на Huawei интерфейсная очередь может быть реализована на чипе ТМ, а может на PIC.
Или там, где Cisco использует сетевые процессоры, Juniper обходится ASIC'ами.
Для коробочного устройства нужно убрать фабрики коммутации и поиск выходного чипа.
В маршрутизаторах сегмента SOHO, наверняка, будут отсутствовать CAM/TCAM.
Хореография вокруг очередей, которые могут быть сделаны тысячей различных способов, заслуживает
отдельных 600 страниц в книге «Соседняя очередь движется быстрее. История потерянного RFC».
Что уж говорить о современном мире виртуализации, где свергают старых правителей и возводят на трон новых.
Почти в каждом параграфе опытный и въедливый читатель найдёт, что следует уточнить, где дать более
развёрнутые объяснение. И будет прав… и не прав в то же время. У меня были долгие сомнения, ставить ли в
заголовок «маленьких» или «матёрых». И я поставил «маленьких», потому что это только введение в
безграничный мир аппаратной коммутации, которое не требует глубоких знаний протоколов или
электротехники, а если я начну погружаться в тонкости реализаций различных вендоров, то рискую никогда уже
не выбраться из стремительного водоворота деталей.
3. Механизмы DiffServ
4. Классификация и маркировка
• Behavior Aggregate
• Multi-Field
• Interface-Based
5. Очереди
8. Ограничение скорости
• Shaping
• Policing
• Механизмы Leaky Bucket и Token Bucket
До того как читатель нырнёт в эту нору, я заложу в него три установки:
— Не все проблемы можно решить расширением полосы.
— QoS не расширяет полосу.
— QoS про управление ограниченными ресурсами.
Потери
Эта метрика говорит о том, сколько из отправленных источником пакетов дошло до адресата.
Причиной потерь может быть проблема в интерфейсе/кабеле, перегрузка сети, битовые ошибки, блокирующие
правила ACL.
Что делать в случае потерь решает приложение. Оно может проигнорировать их, как в случае с телефонным
разговором, где запоздавший пакет уже не нужен, или перезапросить его отправку — так делает TCP, чтобы
гарантировать точную доставку исходных данных.
Задержки
Это время, которое необходимо данным, чтобы добраться от источника до получателя.
Задержки не так страшны приложениям, где не требуется спешка: обмен файлами, сёрфинг, VoD, интернет-
радиостанции итд. И напротив, они критичны для интерактивных: 200мс уже неприятны на слух при телефонном
разговоре.
Связанный с задержкой термин, но не являющийся синонимом — RTT (Round Trip Time) — это путь туда-обратно.
При пинге и трассировке вы видите именно RTT, а не одностороннюю задержку, хотя величины и имеют
корреляцию.
Джиттер
Разница в задержках между доставкой последовательных пакетов называется джиттером.
Как и задержка, джиттер для многих приложений не имеет значения. И даже, казалось бы, какая разница —
пакет доставлен, чего же боле?
Однако для интерактивных сервисов он важен.
Возьмём в качестве примера ту же телефонию. По сути она является оцифровкой аналоговых сигналов с
разбиением на отдельные чанки данных. На выходе получается достаточно равномерный поток пакетов. На
принимающей стороне есть небольшой буфер фиксированного размера, в который укладываются
последовательно поступающие пакеты. Для восстановление аналогового сигнала необходимо определённое их
количество. В условиях плавающих задержек следующий чанк данных может не прийти вовремя, что
равносильно потере, и сигнал не удаётся восстановить.
Наибольший вклад в вариативность задержки вносит как раз QoS. Об этом тоже много и нудно в тех же
главах Управление перегрузками и Ограничение скорости.
Это три основные характеристики качества сети, но есть две другие, которые тоже играют не последнюю роль.
Неупорядоченная доставка
Ряд приложений, таких как телефония, NAS, CES экстремально чувствительны к неупорядоченной доставке
пакетов, когда они приходят к получателю не в том порядке, в котором были отправлены. Это может приводить к
потере связности, ошибкам, повреждению файловой системы.
И хотя неупорядоченная доставка не является формально характеристикой QoS, но определённо относится к
качеству сети.
Даже в случае TCP, толерантного к этому виду проблем, происходят дублирующиеся ACK'и и ретрансмиты.
Полоса пропускания
Её не выделяют, как метрику качества сети, поскольку фактически её недостаток выливается в три указанные
выше. Однако в наших реалиях, когда некоторым приложениям она должна быть гарантирована или, наоборот,
по договору должна быть ограничена, а например MPLS TE её резервирует на всём протяжении LSP, упомянуть
её, хотя бы как слабую метрику, стоит.
Механизмы управления скоростью рассмотрим в главах Управление перегрузками и Ограничение скорости.
Тогда все пакеты пролетают насквозь в том же порядке, в котором они пришли и не испытывают никаких
дополнительных задержек — негде задерживаться.
Но на самом деле каждый маршрутизатор восстанавливает из сигнала биты и пакеты, что-то с ними делает (об
этом пока не думаем) и потом обратно преобразует пакеты в сигнал.
Появляется задержка сериализации. Но в целом это не страшно поскольку она постоянна. Не страшно до тех пор,
пока ширина выходного интерфейса больше, чем входного.
Например, на входе в устройство гигабитный порт, а на выходе радио-релейная линия 620 Мб/с, подключенная в
такой же гигабитный порт?
Никто не запретит пулять через формально гигабитный линк гигабит трафика.
Ничего тут не поделаешь — 380 Мб/с будут проливаться на пол.
Но при этом очень бы хотелось, чтобы проливалась худшая его часть — видео с youtube, а телефонный разговор
исполнительного директора с директором завода не прерывался и даже не квакал.
Хотелось бы, чтобы у голоса была выделенная линия.
Или входных интерфейсов пять, а выходной один, и одновременно пять узлов начали пытаться влить трафик
одному получателю.
Добавим щепотку теории VoIP (статью, про который никто так и не написал) — он весьма чувствителен к
задержкам и их вариации.
Если для TCP-потока видео с youtube (на момент написания статьи QUIC — ещё остаётся экспериментом)
задержки даже в секунды ровным счётом ничего не стоят благодаря буферизации, то директор после первого же
такого разговора с камчаткой призовёт к себе руководителя тех.отдела.
В более старые времена, когда автор цикла ещё делал уроки по вечерам, проблема стояла особенно остро.
Модемные соединения имели скорость 56к.
И когда в такое соединение приходил полуторакилобайтный пакет, он оккупировал всю линию на 200 мс. Никто
другой в этот момент пройти не мог. Голос? Не, не слышал.
Поэтому таким важным является вопрос MTU — пакет не должен слишком надолго оккупировать интерфейс. Чем
менее он скоростной, тем меньший MTU необходим.
Вот они — задержки.
Сейчас канал свободен и задержка низкая, через секунду кто-то начал качать большой файл и задержки выросли.
Вот он — джиттер.
Таким образом нужно, чтобы голосовые пакеты пролетали через трубу с минимальными задержками, а youtube
подождёт.
Имеющиеся 620 Мб/с нужно использовать и для голоса, и для видео, и для B2B клиентов, покупающих VPN.
Хотелось бы, чтобы один трафик не притеснял другой, значит нужна гарантия полосы.
Все вышеуказанные характеристики универсальны относительно природы сети. Однако существует три разных
подхода к их обеспечению.
Самый простой подход к реализации QoS, с которого начинались IP-сети и который практикуется и по сей день —
иногда потому что его достаточно, но чаще из-за того, что никто и не думал о QoS.
Кстати, когда вы отправляете трафик в Интернет, то он там будет обрабатываться как BestEffort. Поэтому через
VPN, прокинутые поверх Интернета (в противовес VPN, предоставляемому провайдером), может не очень
уверенно ходить важный трафик, вроде телефонного разговора.
В случае BE — все категории трафика равны, никакому не отдаётся предпочтение. Соответственно, нет гарантий
ни задержки/джиттера, ни полосы.
Этот подход носит несколько контринтуитивное название — Best Effort, которое новичка вводит в заблуждение
словом «лучший».
Однако фраза «I will do my best» означает, что говорящий постарается сделать всё, что может, но не гарантирует
ничего.
Для реализации BE не требуется ничего — это поведение по умолчанию. Это дёшево в производстве, персоналу
не нужны глубокие специфические знания, QoS в этом случае не поддаётся никакой настройке.
Однако эта простота и статичность не приводят к тому, что подход Best Effort нигде не используется. Он находит
применение в сетях с высокой пропускной способностью и отсутствием перегрузок и всплесков.
Например, на трансконтинентальных линиях или в сетях некоторых ЦОДов, где нет переподписки.
Иными словами в сетях без перегрузок и где нет необходимости особенным образом относиться к какому-либо
трафик (например, телефонии), BE вполне уместен.
IntServ
Заблаговременное резервирование ресурсов для потока на всём протяжении от источника до получателя.
В растущий бессистемно Интернет отцы сетей MIT, Xerox, ISI решили добавить элемент предсказуемости,
сохранив его работоспособность и гибкость.
Так в 1994 году родилась идея IntServ в ответ на стремительный рост реал-тайм трафика и развитие мультикаста.
Сокращалась она тогда до IS.
Название отражает стремление в одной сети одновременно предоставлять услуги для реал-тайм и не-реал-тайм
типов трафика, предоставив, при этом первым приоритетное право использования ресурсов через
резервирование полосы. Возможность переиспользования полосы, на которой все и зарабатывают, и благодаря
чему IP выстрелил, при этом сохранялась.
Миссию по резервированию возложили на протокол RSVP, который для каждого потока резервирует полосу
на каждом сетевом устройстве.
Грубо говоря, до установки сессии или начала обменом данными, конечные хосты отправляют RSVP Path с
указанием требуемой полосы. И если обоим вернулся RSVP Resv — они могут начать коммуницировать. При
этом, если доступных ресурсов нет, то RSVP возвращает ошибку и хосты не могут общаться или пойдут по BE.
Пусть теперь храбрейшие из читателей представят, что для любого потока в интернете сегодня будет
сигнализироваться канал заранее. Учтём, что это требует ненулевых затрат CPU и памяти на каждом транзитном
узле, откладывает фактическое взаимодействие на некоторое время, становится понятно, почему IntServ
оказался фактически мертворожденной идеей — нулевая масштабируемость.
В некотором смысле современная инкарнация IntServ — это MPLS TE с адаптированной под передачу меток
версией RSVP — RSVP TE. Хотя здесь, конечно же не End-to-End и не per-flow.
DiffServ
DiffServ сложный.
Когда в конце 90-х стало понятно, что End-to-End подход IntServ в IP провалился, в IETF созвали в 1997 рабочую
группу «Differentiated Services», которая выработала следующие требования к новой модели QoS:
• Никакой сигнализации (Адьёс, RSVP!).
• Основан на агрегированной классификации трафика, вместо акцента на потоках, клиентах итд.
• Имеет ограниченный и детерминированный набор действий по обработке трафика данных классов.
В результате в 1998 родились эпохальные RFC 2474 (Definition of the Differentiated Services Field (DS Field) in the
IPv4 and IPv6 Headers) и RFC 2475 (An Architecture for Differentiated Services).
3. Механизмы DiffServ
Что же собой являет DiffServ и почему он выигрывает у IntServ?
Если очень просто, то трафик делится на классы. Пакет на входе в каждый узел классифицируется и к нему
применяется набор инструментов, который по-разному обрабатывает пакеты разных классов, таким образом
обеспечивая им разный уровень сервиса.
Но просто не будет.
В основе DiffServ лежит идеологически выдержанная в традициях IP концепция PHB — Per-Hop Behavior. Каждый
узел по пути трафика самостоятельно принимает решение о том, как вести себя относительно пришедшего
пакета, на основе его заголовков.
Действия маршрутизатора с пакетом назовём моделью поведения (Behavior). Количество таких моделей
детерминировано и ограничено. На разных устройствах модели поведения по отношению к одному и тому же
трафику могут отличаться, поэтому они и per-hop.
Понятия Behavior и PHB я буду использовать в статье как синонимы.
Тут есть лёгкая путаница. PHB — это с одной стороны общая концепция независимого поведения каждого узла, с
другой — конкретная модель на конкретном узле. С этим мы ещё разберёмся.
Модель поведения определяется набором инструментов и их параметров: Policing, Dropping, Queuing, Scheduling,
Shaping.
Используя имеющиеся модели поведения, сеть может предоставлять различные классы сервиса (Class of
Service).
То есть разные категории трафика могут получить разный уровень сервиса в сети путём применения к ним
разных PHB.
Соответственно прежде всего нужно определить к какому классу сервиса относится трафик — классификация
(Classification).
Каждый узел самостоятельно классифицирует поступающие пакеты.
После классификации происходит измерение (Metering) — сколько битов/байтов трафика данного класса
пришло на маршрутизатор.
На основе результатов пакеты могут окрашиваться (Coloring): зелёный (в рамках установленного лимита), жёлтый
(вне лимита), красный (совсем берега попутал).
Если необходимо, далее происходит полисинг (Policing) (уж простите за такую кальку, есть вариант лучше —
пишите, я поменяю). Полисер на основе цвета пакета назначает действие по отношению к пакету — передать,
отбросить или перемаркировать.
После этого пакет должен попасть в одну из очередей (Queuing). Для каждого класса сервиса выделена
отдельная очередь, что и позволяет их дифференцировать, применяя разные PHB.
Но ещё до того, как пакет попадёт в очередь, он может быть отброшен (Dropper), если очередь заполнена.
Если он зелёный, то он пройдёт, если жёлтый, то его вполне вероятно, отбросят, если очередь полна, а если
красный — это верный смертник. Условно, вероятность отбрасывания зависит от цвета пакета и наполненности
очереди, куда он собирается попасть.
На выходе из очереди работает шейпер (Shaper), задача которого очень похожа на задачу полисера —
ограничить трафик до заданного значения.
Можно настроить произвольные шейперы для отдельных очередей или даже внутри очередей.
Об отличии шейпера от полисера в главе Ограничение скорости.
В DiffServ поведение каждого узла независимо от остальных, нет протоколов сигнализации, которые бы
сообщили, какая на сети политика QoS. При этом в пределах сети хотелось бы, чтобы трафик обрабатывался
одинаково. Если всего лишь один узел будет вести себя иначе, вся политика QoS псу под хвост.
Для этого, во-первых, на всех маршрутизаторах, настраиваются одинаковые классы и PHB для них, а во-вторых,
используется маркировка (Marking) пакета — его принадлежность определённому классу записывается в
заголовок (IP, MPLS, 802.1q).
И красота DiffServ в том, что следующий узел может довериться этой маркировке при классификации.
Такая зона доверия, в которой действуют одинаковые правила классификации трафика и одни модели
поведения, называется домен DiffServ (DiffServ-Domain).
Таким образом на входе в домен DiffServ мы можем классифицировать пакет на основе 5-Tuple или интерфейса,
промаркировать (Remark/Rewrite) его согласно правилам домена, и дальнейшие узлы будут доверять этой
маркировке и не делать сложную классификацию.
То есть явной сигнализации в DiffServ нет, но узел может сообщить всем следующим, какой класс нужно
обеспечить этому пакету, ожидая, что тот доверится.
Далее по приезду в аэропорт все заходят через одни двери. Тех, кто попытался провезти с собой оружие или не
имеет билета, не пускают (Drop). Бизнес и эконом попадают в разные залы ожидания и разный транспорт
(Queuing). Сначала на борт пускают Первый класс, потом бизнес, потом эконом (Scheduling), однако потом они в
пункт назначения все летят одним самолётом (интерфейс).
В этом же примере перелёт на самолёте — это задержка передачи (Propagation), посадка — задержка
сериализации (Serialization), ожидание самолёта в залах — Queuing, а паспортный контроль — Processing.
Заметьте, что и тут Processing Delay обычно пренебрежимо мал в масштабах общего времени.
Следующий аэропорт может обойтись с пассажирами совсем иначе — его PHB отличается. Но при этом если
пассажир не меняет авиакомпанию, то, скорее всего, отношение к нему не поменяется, потому что одна
компания — один DiffServ-domain.
Как вы могли уже заметить, DiffServ предельно (или беспредельно) сложен. Но всё описанное выше, мы
разберём. При этом в статье я не буду вдаваться в нюансы физической реализации (они могут различаться даже
на двух платах одного маршрутизатора), не буду рассказывать про HQoS и MPLS DS-TE.
Порог входа в круг инженеров, понимающих технологию, для QoS значительно выше, чем для протоколов
маршрутизации, MPLS, или, прости меня Радья, STP.
И несмотря на это DiffServ заслужил признание и внедрение на сетях по всему миру, потому что, как говорится,
хайли скэлэбл.
Всю дальнейшую часть статьи я буду разбирать только DiffServ.
4. Классификация и маркировка
Внутри своей сети администратор определяет классы сервиса, которые он может предоставлять трафику.
Поэтому первое, что делает каждый узел при получении пакета, проводит его классификацию.
Администратор определяет набор классов сервиса, которые сеть может предоставлять, и сопоставляет им
некоторое цифровое значение.
На входе в DS-домен мы никому не доверяем, поэтому проводится классификация вторым или третьим
способом: на основе адресов, протоколов или интерфейсов определяется класс сервиса и соответствующее
цифровое значение.
На выходе из первого узла эта цифра кодируется в поле DSCP заголовка IP (или другое поле Traffic Class: MPLS
Traffic Class, IPv6 Traffic Class, Ethernet 802.1p) — происходит ремаркировка.
Внутри DS-домена принято доверять этой маркировке, поэтому транзитные узлы используют первый способ
классификации (BA) — наиболее простой. Никакого сложного анализа заголовков, смотрим только записанную
цифру.
На стыке двух доменов можно классифицировать на основе интерфейса или MF, как я описал выше, а можно
довериться маркировке BA с оговорками.
Например, доверять всем значениям, кроме 6 и 7, а 6 и 7 перемаркировывать в 5.
Такая ситуация возможна в случае, когда провайдер подключает юрлицо, у которого есть своя политика
маркировки. Провайдер не возражает сохранить её, но при этом не хочет, чтобы трафик попадал в класс, в
котором у него передаются пакеты сетевых протоколов.
Behavior Aggregate
В BA используется очень простая классификация — вижу цифру — понимаю класс.
Так что же за цифра? И в какое поле она записывается?
• IPv4 TOS/IPv6 Traffic Class
• MPLS Traffic Class
• Ethernet 802.1p
IPv4 TOS
Поле QoS сопутствует нам ровно столько же, сколько и IP. Восьмибитовое поле TOS — Type Of Service — по
задумке должно было нести приоритет пакета.
Ещё до появления DiffServ RFC 791 (INTERNET PROTOCOL) описывал поле так:
IP Precedence (IPP) + DTR + 00.
То есть идёт приоритет пакета, далее биты требовательности к Delay, Throughput, Reliability (0 — без требований,
1 — с требованиями).
Последние два бита должны быть нулём.
Приоритет определял следующие значения…
Чуть позже в RFC 1349 (Type of Service in the Internet Protocol Suite) поле TOS немного переопределили:
Левые три бита остались IP Precedence, четыре следующих превратились в TOS после добавления бита Cost.
Вот как следовало читать единицы в этих битах TOS:
• D — «minimize delay»,
• T — «maximize throughput»,
• R — «maximize reliability»,
• C — «minimize cost».
Системный подход к QoS на всём протяжении пути отсутствовал, чётких рекомендаций, как использовать поле
приоритета тоже не было, описание битов Delay, Throughput и Reliability было крайне туманным.
Поэтому в контексте DiffServ поле TOS ещё раз переопределили в RFC 2474 (Definition of the Differentiated Services
Field (DS Field) in the IPv4 and IPv6 Headers):
Вместо битов IPP и DTRC ввели шестибитовое поле DSCP — Differentiated Services Code Point, два правых бита не
были использованы.
С этого момента именно поле DSCP должно было стать главной маркировкой DiffServ: в него записывается
определённое значение (код), которое в пределах данного DS-домена характеризует конкретный класс сервиса,
необходимый пакету и его приоритет отбрасывания. Это та самая цифра.
Все 6 бит DSCP администратор может использовать, как ему заблагорассудится, разделяя максимум до 64
классов сервиса.
Однако в угоду совместимости с IP Precedence за первыми тремя битами сохранили роль Class Selector.
То есть, как и в IPP, 3 бита Class Selector позволяют определить 8 классов.
Однако это всё же не более, чем договорённость, которую в пределах своего DS-домена, администратор может
легко игнорировать и использовать все 6 бит по усмотрению.
Далее также замечу, что согласно рекомендациям IETF, чем выше значение, записанное в CS, тем требовательнее
этот трафик к сервису.
Но и это не стоит воспринимать как неоспоримую истину.
Если первые три бита определяют класс трафика, то следующие три используются для указания приоритета
отбрасывания пакета (Drop Precedence или Packet Loss Priority — PLP).
Восемь классов — это много или мало? На первый взгляд мало — ведь так много разного трафика ходит в сети,
что так и хочется каждому протоколу выделить по классу. Однако оказывается, что восьми достаточно для всех
возможных сценариев.
Для каждого класса нужно определять PHB, который будет обрабатывать его как-то отлично от других классов.
Да и при увеличении делителя, делимое (ресурс) не увеличивается.
Я намеренно не говорю о том, какие значения какой именно класс трафика описывают, поскольку здесь нет
стандартов и формально их можно использовать по своему усмотрению. Ниже я расскажу, какие классы и
соответствующие им значения рекомендованы.
Биты ECN…
!!!!!
Linkmeup_R1. E0/0.
pcapng
!!!!!
Значение 184 — это десятичное представление двоичного 10111000. Из них первые 6 бит — это 101110, то есть
десятичные 46, а это класс EF.
Таблица стандартных значений TOS для удобных попингушек…
Linkmeup_R2. E0/0
pcapng
Любопытное замечание: адресат попингушек в ICMP Echo reply устанавливает такое же значение класса, как
было в Echo Request. Это логично — если отправитель послал пакет с определённым уровнем важности, то,
очевидно, он хочет получить его гарантировано назад.
Linkmeup_R2. E0/0
По счастливой случайности в MPLS заложили трёхбитовое поле EXP на всякий экспериментальный случай. И
несмотря на то, что уже давным-давно в RFC 5462 («EXP» Field Renamed to «Traffic Class» Field) официально стало
полем Traffic Class, по инерции его называют ИЭксПи.
С ним есть одна проблема — его длина три бита, что ограничивает число возможных значений до 9. Это не
просто мало, это на 3 двоичных порядка меньше, чем у DSCP.
Учитывая, что часто MPLS Traffic Class наследуется из DSCP IP-пакета, имеем архивацию с потерей. Или же… Нет,
вы не хотите этого знать… L-LSP. Использует комбинацию Traffic Class + значение метки.
Вообще согласитесь, ситуация странная — MPLS разрабатывался как помощь IP для быстрого принятия решения
— метка MPLS мгновенно обнаруживается в CAM по Full Match, вместо традиционного Longest Prefix Match. То
есть и про IP знали, и в коммутации участие принимает, а нормальное поле приоритета не предусмотрели.
На самом деле выше мы уже увидели, что для определения класса трафика используется только первые три бита
DSCP, а три другие — Drop Precedence (или PLP — Packet Loss Priority).
Поэтому в плане классов сервиса всё же имеем соответствие 1:1, теряя только информацию о Drop Precedence.
В случае MPLS классификация так же как и в IP может быть на основе интерфейса, MF, значения DSCP IP или
Traffic Class MPLS.
Маркировка означает запись значения в поле Traffic Class заголовка MPLS.
Пакет может содержать несколько заголовков MPLS. Для целей DiffServ используется только верхний.
Существуют три разных сценария перемаркировки при продвижении пакета из одного чистого IP-сегмента в
другой через MPLS-домен:
(это просто выдержка из статьи).
1. Uniform Mode
2. Pipe Mode
3. Short-Pipe Mode
Режимы работы…
Linkmeup_R2. E0/0.
pcapng
Итак, мы видим, что изначальная метка EF в IP DSCP трансформировалась в значение 5 поля EXP MPLS (оно же
Traffic Class, помним это) как VPN-заголовка, так и транспортного.
Тут мы являемся свидетелями режима работы Uniform.
Ethernet 802.1p
Отсутствие поля приоритета в 802.3 (Ethernet) находит своё объяснение в том, что Ethernet изначально
планировался исключительно как решение для LAN-сегмента. За скромные деньги можно получить избыточную
пропускную способность, и узким местом всегда будет аплинк — не за чем беспокоиться о приоритизации.
Однако очень скоро стало ясно, что финансовая привлекательность Ethernet+IP выводит эту связку на уровень
магистрали и WAN. Да и сожительство в одном LAN-сегменте торрентов и телефонии нужно разруливать.
По счастью к этому моменту подоспел 802.1q (VLAN), в котором выделили 3-битовое (опять) поле под
приоритеты.
В плане DiffServ это поле позволяет определить те же 8 классов трафика.
При получении пакета сетевое устройство DS-домена в большинстве случаев берёт в рассмотрение тот заголовок,
который оно использует для коммутации:
• Ethernet-коммутатор — 802.1p
• MPLS-узел — MPLS Traffic Class
• IP-маршрутизатор — IP DSCP
Хотя это поведение можно и изменить: Interface-Based и Multi-Field классификация. А можно иногда даже явно
сказать, в поле CoS какого заголовка смотреть.
Interface-based
Это наиболее простой способ классифицировать пакеты в лоб. Всё, что насыпалось в указанный интерфейс,
помечается определённым классом.
В некоторых случаях такой гранулярности хватает, поэтому Interface-based находит применение в жизни.
Практика по Interface-based классификации
Схема та же:
Настройка политик QoS в оборудовании большинства вендоров делится на этапы.
1. Сначала определяется классификатор:
2.
class-map match-all TRISOLARANS_INTERFACE_CM
class TRISOLARANS_INTERFACE_CM
Если пакет удовлетворяет классификатору TRISOLARANS_INTERFACE_CM, записать в поле DSCP значение CS7.
Здесь я забегаю вперёд, используя непонятные CS7, а далее EF, AF. Ниже можно прочитать про эти аббревиатуры
и принятые договорённости. Пока же достаточно знать, что это разные классы с разным уровнем сервиса.
5. И последним шагом применить политику на интерфейс:
6.
interface Ethernet0/2
Здесь немного избыточен классификатор, который проверят что пакет пришёл на интерфейс e0/2, куда мы потом
и применяем политику. Можно было бы написать match any:
match any
Однако политика на самом деле может быть применена на vlanif или на выходной интерфейс, поэтому можно.
Multi-Field
Наиболее часто встречающийся тип классификации на входе в DS-домен. Не доверяем имеющейся маркировке, а
на основе заголовков пакета присваиваем класс.
Зачастую это способ вообще «включить» QoS, в случае, когда отправители не проставляют маркировку.
Достаточно гибкий инструмент, но в то же время громоздкий — нужно создавать непростые правила для
каждого класса. Поэтому внутри DS-домена актуальнее BA.
Практика по MF классификации
Схема та же:
Из практических примеров выше видно, что устройства сети по умолчанию доверяют маркировке приходящих
пакетов.
Это прекрасно внутри DS-домена, но неприемлемо в точке входа.
А давайте теперь не будем слепо доверять? На Linkmeup_R2 ICMP будем метить как EF (исключительно для
примера), TCP как AF12, а всё остальное CS0.
Это будет MF (Multi-Field) классификация.
1. Процедура та же, но теперь матчить будем по ACL, которые выцепляют нужные категории трафика,
поэтому сначала создаём их.
2. На Linkmeup_R2:
3.
ip access-list extended TRISOLARANS_ICMP_ACL
permit icmp any any
class TRISOLARANS_ICMP_CM
set ip dscp ef
class TRISOLARANS_TCP_CM
class TRISOLARANS_OTHER_CM
8. И вешаем политику на интерфейс. На input, соответственно, потому что решение нужно принять на входе
в сеть.
9.
interface Ethernet0/1
Linkmeup_R1. E0/0.
pcapng
Linkmeup_R2. E0/0.
pcapng
Видно, что после классификаторов и перемаркировки на Linkmeup_R2 на ICMP-пакетах не только DSCP поменялся
на EF, но и MPLS Traffic Class стал равным 5.
Linkmeup_R1. E0/0.
pcapng
Linkmeup_R2. E0/0.
pcapng
Следующим тестом проверим UDP, который должен попасть в CS0 согласно нашим классификаторам. Для этого
воспользуемся iperf (привезти его в Linux Tiny Core изи через Apps). На удалённой стороне iperf3 -s — запускаем
сервер, на локальной iperf3 -c -u -t1 — клиент (-c), протокол UDP (-u), тест в течение 1 секунды (-t1).
Linkmeup_R1. E0/0.
pcapng
Linkmeup_R2. E0/0
pcapng
С этого момента всё, что приходит в этот интерфейс, будет классифицировано согласно настроенным правилам.
Независимо от способа классификации после неё пакету присваивается внутренний класс в пределах устройства,
в соответствии с которым он и обрабатывается. Заголовок при этом снимается, и голый (нет) пакет путешествует к
выходу.
А на выходе внутренний класс преобразуется в поле CoS нового заголовка.
В некоторых случаях нужно отобразить поле заголовка одного протокола в поле заголовка другого, например,
DSCP в Traffic Class.
Происходит это как раз через промежуточную внутреннюю маркировку.
Например, Заголовок DSCP ⇒ Классификация ⇒ Внутренний класс сервиса ⇒ Заголовок Traffic Class.
Формально, внутренние классы могут называться как угодно или просто нумероваться, а им в соответствие
только ставится определённая очередь.
На глубине, до которой мы погружаемся в этой статье, не важно, как они называются, важно, что конкретным
значениям полей QoS ставится в соответствие определённая модель поведения.
Если мы говорим о конкретных реализациях QoS, то количество классов сервиса, которое устройство может
обеспечить, не больше, чем количество доступных очередей. Зачастую их восемь (не то под влиянием IPP, не то
по неписанной договорённости). Однако в зависимости от вендора, устройства, платы, их может быть как
больше, так и меньше.
То есть если очередей 4, то классов сервиса просто нет смысла делать больше четырёх.
В плане PHB нет абсолютно никакой разницы что используется для классификации — DSCP, Traffic Class, 802.1p.
Внутри устройства они превращаются в классы трафика, определённые администратором сети.
То есть все эти маркировки — это способ сообщить соседям, какой класс сервиса им следует назначить этому
пакету. Это примерно, как BGP Community, которые не значат ничего сами по себе, пока на сети не определена
политика их интерпретации.
Рекомендации IETF (категории трафика, классы сервиса и
модели поведения)
Стандарты вообще не нормируют, какие именно классы сервиса должны существовать, как их классифицировать
и маркировать, какие PHB к ним применять.
Это отдано на откуп вендорам и администраторам сетей.
Имеем только 3 бита — используем, как хотим.
Это хорошо:
— Каждая железка (вендор) самостоятельно выбирает, какие механизмы использовать для PHB — нет
сигнализации, нет проблем совместимости.
— Администратор каждой сети может гибко распределять трафик по разным классам, выбирать сами классы и
соответствующий им PHB.
Это плохо:
— На границах DS-доменов возникают вопросы преобразования.
— В условиях полной свободой действий — кто в лес, кто бес.
Поэтому IETF в 2006 выпустила методичку, как следует подходить к дифференциации сервисов: RFC
4594 (Configuration Guidelines for DiffServ Service Classes).
Далее коротко суть этого RFC.
Модели поведения (PHB)
DF — Default Forwarding
Стандартная пересылка.
Если классу трафика не назначена модель поведения специально, он будет обрабатываться именно по Default
Forwarding.
Это Best Effort — устройство сделает всё возможное, но ничего не гарантирует. Возможны отбрасывания,
разупорядочивание, непредсказуемые задержки и плавающий джиттер, но это не точно.
Такая модель подходит для нетребовательных приложений, вроде почты или загрузки файлов.
Есть, кстати, PHB и ещё менее определённый — A Lower Effort.
AF — Assured Forwarding
Гарантированная пересылка.
Это улучшенный BE. Здесь появляются некоторые гарантии, например, полосы. Отбрасывания и плавающие
задержки всё ещё возможны, но уже в гораздо меньшей степени.
Модель подходит для мультимедии: Streaming, видео-конференц-связь, онлайн-игры.
RFC 2597 (Assured Forwarding PHB Group).
EF — Expedited Forwarding
Экстренная пересылка.
Все ресурсы и приоритеты бросаются сюда. Это модель для приложений, которым нужны отсутствие потерь,
короткие задержки, стабильный джиттер, но они не жадные до полосы. Как, например, телефония или сервис
эмуляции провода (CES — Circuit Emulation Service).
Потери, разупорядочивание и плавающие задержки в EF крайне маловероятны.
RFC 3246 (An Expedited Forwarding PHB).
CS — Class Selector
Это модели поведения, призванные сохранить обратную совместимость с IP-Precedence в сетях, умеющих в DS.
В IPP существуют следующие классы CS0, CS1, CS2, CS3, CS4, CS5, CS6, CS7.
Не всегда для всех них существует отдельный PHB, обычно их два-три, а остальные просто транслируются в
ближайший DSCP класс и получают соответствующий ему PHB.
Так например, пакет, помеченный CS 011000, может классифицироваться как 011010.
Из CS наверняка в оборудовании сохранились только CS6, CS7, которые рекомендованы для NCP — Network
Control Protocol и требуют отдельного PHB.
Как и EF, PHB CS6,7 предназначены для тех классов, что имеют очень высокие требования к задержкам и
потерям, однако до некоторой степени толерантны к дискриминации по полосе.
Задача PHB для CS6,7 обеспечить уровень сервиса, который исключит дропы и задержки даже в случае
экстремальной перегрузки интерфейса, чипа и очередей.
Важно понимать, что PHB — это абстрактное понятие — и на самом деле реализуются они через механизмы,
доступные на реальном оборудовании.
Таким образом один и тот же PHB, определённый в DS-домене, может различаться на Juniper и Huawei.
Более того, один PHB — это не статический набор действий, PHB AF, например, может состоять из нескольких
вариантов, которые различаются уровнем гарантий (полосой, допустимыми задержками).
Классы сервиса
В IETF позаботились об администраторах и определили основные категории приложений и агрегирующие их
классы сервиса.
Я здесь не буду многословен, просто вставлю пару табличек из этого Guideline RFC.
Категории приложений:
PHB AF обслуживает классы AF1, AF2, AF3, AF4. Им всем нужно обеспечить полосу, в ущерб задержкам и потерям.
Потери управляются битами Drop Precedence, поэтому они и называются AFxy, где x — класс сервиса, а y — Drop
Precedence.
EF нужна некая минимальная гарантия полосы, но что важнее — гарантия задержек, джиттера и отсутствия
потерь.
CS6, CS7 требуют ещё меньше полосы, потому что это ручеёк служебных пакетов, в котором всё же возможны
всплески (BGP Update, например), но в ней недопустимы потери и задержки — какая польза от BFD с таймером в
10 мс, если Hello вялится в очереди по 100 мс?
В незагруженной сети QoS не нужен, говорили они. Любые вопросы QoS решаются расширением линков,
говорили они. С Ethernet и DWDM нам никогда не грозят перегрузки линий, говорили они.
Они — те, кто не понимает, что такое QoS.
Но реальность бьёт VPN-ом по РКНу.
1) Не везде есть оптика. РРЛ — наша реальность. Иногда в момент аварии (да и не только) в узкий радио-линк
хочет пролезть весь трафик сети.
2) Всплески трафика — наша реальность. Кратковременные всплески трафика легко забивают очереди, заставляя
отбрасывать очень нужные пакеты.
3) Телефония, ВКС, онлайн-игры — наша реальность. Если очередь хоть на сколько-то занята, задержки начинают
плясать.
В моей практике были примеры, когда телефония превращалась в азбуку морзе на сети, загруженной не более
чем на 40%. Всего лишь перемаркировка её в EF решила проблема сиюминутно.
Пришло время разобраться с инструментами, которые позволяют обеспечить разный сервис разным классам.
Инструменты PHB
Существует на самом деле всего лишь три группы инструментов обеспечения QoS, которые активно
манипулируют пакетами:
• Предотвращение перегрузок (Congestion Avoidance) — что делать, чтобы не было плохо.
• Управление перегрузками (Congestion Management) — что делать, когда уже плохо.
• Ограничение скорости (Rate Limiting) — как не пустить в сеть больше, чем положено, и не выпустить
столько, сколько не смогут принять.
5. Очереди
В парке аттракционов нельзя отдать кому-то приоритет, если не организовать отдельную очередь для тех, кто
заплатил больше.
Такая же ситуация в сетях.
Если весь трафик в одной очереди, не получится выдёргивать из её середины важные пакеты, чтобы дать им
приоритет.
Именно поэтому после классификации пакеты помещаются в соответствующую данному классу очередь.
А далее одна очередь (с голосовыми данными) будет двигаться быстро, но с ограниченной полосой, другая
помедленнее (потоковое вещание), зато с широкой полосой, а какой-то ресурсы достанутся по остаточному
принципу.
Но в пределах каждой отдельной очереди действует то же правило — нельзя выдернуть пакет из середины —
только из его изголовья.
Каждая очередь обладает определённой ограниченной длиной. С одной стороны это диктуется аппаратными
ограничениями, а с другой тем, что нет смысла держать пакеты в очереди слишком долго. VoIP пакет не нужен,
если он задержался на 200мс. TCP запросит переотправку, условно, после истечения RTT (настраивается в sysctl).
Поэтому отбрасывание — не всегда плохо.
Разработчикам и дизайнерам сетевого оборудования приходится находить компромисс между попытками
сохранить пакет как можно дольше и напротив не допустить бесполезной траты полосы, пытаясь доставить уже
никому не нужный пакет.
В нормальной ситуации, когда интерфейс/чип не перегружен, утилизация буферов около нуля. Они
амортизируют кратковременные всплески, но это не вызывает их продолжительного заполнения.
Если же трафика приходит больше, чем может обработать чип коммутации или выходной интерфейс, очереди
начинают заполняться. И хроническая утилизация выше 20-30% — это уже ситуация, к которой нужно принимать
меры.
У Head Drop есть и ещё одно неочевидное преимущество — если пакет отбросить в начале очереди, то
получатель быстрее узнает о перегрузке на сети и сообщит отправителю. В случае Tail Drop информация об
отброшенном пакете дойдёт, возможно, на сотни миллисекунд позже — пока будет добираться с хвоста очереди
до её головы.
Оба механизма работают с дифференциацией по очередям. То есть на самом деле не обязательно, чтобы весь
буфер переполнился. Если 2-ая очередь пустая, а нулевая под завязку, то отбрасываться буду только пакеты из
нулевой.
Если для достижения цели не нужно ничего делать, значит где-то есть нюанс.
И этот нюанс — TCP.
Вспомним (поглубже и экстремально глубоко), как работает TCP — речь про современные реализации.
Есть Скользящее окно(Sliding Window или rwnd — Reciever's Advertised Window), которым управляет получатель,
сообщая отправителю, сколько можно посылать.
А есть окно перегрузки (CWND — Congestion Window), которое реагирует на проблемы в сети и управляется
отправителем.
Процесс передачи данных начинается с медленного старта (Slow Start) с экспоненциальным ростом CWND. С
каждым подтверждённым сегментом к CWND прибавляется 1 размер MSS, то есть фактически оно удваивается за
время, равное RTT (туда данные, обратно ACK) (Речь про Reno/NewReno).
Например,
Экспоненциальный рост продолжается до значения, называемого ssthreshold (Slow Start Threshold), которое
указывается в конфигурации TCP на хосте.
Далее начинается линейный рост по 1/CWND на каждый подтверждённый сегмент до тех пор, пока либо не
упрётся в RWND, либо не начнутся потери (о потерях свидетельсв повторное подтверждение (Duplicated ACK) или
вообще отсутствие подтверждения).
Как только зафиксирована потеря сегмента, происходит TCP Backoff — TCP резко уменьшает окно, фактически
снижая скорость отправки, — и запускается механизм Fast Recovery:
1. отправляются потерянные сегменты (Fast Retransmission),
2. окно скукоживается в два раза,
3. значение ssthreshold тоже становится равным половине достигнутого окна,
4. снова начинается линейный рост до первой потери,
5. Повторить.
Потеря может означать либо полный развал какого-то сегмента сети и тогда считай, что пропало, либо
перегрузку на линии (читай переполнение буфера и отбрасывание сегмента данной сессии).
Таков у TCP метод максимальной утилизации доступной полосы и борьбы с перегрузками. И он достаточно
эффективен.
Ничего плохого в этой ситуации не было бы, если бы она не вызывала неоптимальное использование полосы —
промежутки между зубцами пилы — потраченные зря деньги.
Вторая проблема — это TCP Starvation — истощение TCP. В то время, как TCP сбавляет свою скорость для
снижения нагрузки (не будем лукавить — в первую очередь, чтобы наверняка передать свои данные), UDP эти
все моральные страдания вообще по датаграмме — шлёт сколько может.
Итак, количество трафика TCP снижается, а UDP растёт (возможно), следующий цикл Потеря — Fast Recovery
случается на более низком пороге. UDP занимает освободившееся место. Общее количество TCP-трафика падает.
Чем решать проблему, лучше её избежать. Давайте попробуем снизить нагрузку до того, как она заполнит
очередь, воспользовавшись Fast Recovery/Slow Start, который только что был против нас.
Побочным эффектом RED является и то, что агрессивные TCP-сессии скорее начнут притормаживать, просто
потому что их пакетов много и они с бо́ льшей вероятностью будут отброшены.
Неэффективность использования полосы RED решает тем, что притупляет гораздо меньшую часть сессий, не
вызывая такую серьёзную просадку между зубьями.
Ровно по этой же причине UDP не может оккупировать всё.
И в пределах одной очереди у пакетов с разным приоритетом отбрасывания будут разные кривые. Чем ниже
приоритет, тем больше вероятность того, что его прихлопнут.
Очень важно здесь то, что это работает с TCP и это абсолютно неприменимо к UDP.
Либо приложение использующее UDP игнорирует потери, как в случае телефонии или потокового видео, и это
отрицательно сказывается на том, что видит пользователь.
Либо приложение само осуществляет контроль доставки и попросит повторно отправить тот же самый пакет. При
этом оно совсем не обязано просить источник снизить скорость передачи. И вместо уменьшения нагрузки
получается увеличение из-за ретрансмитов.
Именно поэтому для EF применяется только Tail Drop.
Для CS6, CS7 тоже применяется Tail Drop, поскольку там не предполагается больших скоростей и WRED ничего не
решит.
Для AF применяется WRED. AFxy, где x — класс сервиса, то есть очередь, в которую он попадает, а y — приоритет
отбрасывания — тот самый цвет.
Для BE решение принимается на основе преобладающего в этой очереди трафика.
В пределах одного маршрутизатора используются специальная внутренняя маркировка пакетов, отличная от той,
что несут заголовки. Поэтому MPLS и 802.1q, где нет возможности кодировать Drop Precedence, в очередях могут
обрабатываться с различными приоритетами отбрасывания.
Например, MPLS пакет пришёл на узел, он не несёт маркировки Drop Precedence, однако по результатам
полисинга оказался жёлтым и перед помещением в очередь (которая может определяться полем Traffic Class),
может быть отброшен.
При этом стоит помнить, что вся эта радуга существует только внутри узла. В линии между соседями нет понятия
цвета.
Хотя закодировать цвет в Drop Precedence-часть DSCP, конечно, возможно.
Отбрасывания могут появиться и в незагруженной сети, где казалось бы никакого переполнения очередей быть
не должно. Как?
Причиной этому могут быть кратковременные всплески — бёрсты — трафика. Самый простой пример — 5
приложений одновременно решили передать трафик на один конечный хост.
Пример посложнее — отправитель подключен через интерфейс 10 Гб/с, а получатель — 1 Гб/с. Сама среда
позволяет крафтить пакеты быстрее на отправителе. Ethernet Flow Control получателя просит ближайший узел
притормозить, и пакеты начинают скапливаться в буферах.
FIFO стало недостаточно, поэтому создали несколько очередей и начали плодить схемы диспетчеризации
трафика.
Однако FIFO никогда не уходит из нашей жизни: внутри каждой из очередей пакеты всегда обрабатываются по
принципу FIFO.
PQ — Priority Queuing
Второй по сложности механизм и попытка разделить сервис по классам — приоритетная очередь.
Трафик теперь раскладывается в несколько очередей согласно своему классу — приоритету (например, хотя не
обязательно, те же BE, AF1-4, EF, CS6-7). Диспетчер перебирает одну очередь за другой.
Сначала он пропускает все пакеты из самой приоритетной очереди, потом из менее, потом из менее. И так по
кругу.
Диспетчер не начинает изымать пакеты низкого приоритета, пока не пуста высокоприоритетная очередь.
Если в момент обработки низкоприоритетных пакетов приходит пакет в более высокоприоритетную очередь,
диспетчер переключаются на неё и только опустошив её, возвращается к другим.
PQ работает почти так же в лоб, как FIFO.
Он отлично подходит для таких видов трафика, как протокольные пакеты и голос, где задержки имеют
критическое значение, а общий объём не очень большой.
Ну, согласитесь, не стоит придерживать BFD Hello из-за того, что пришли несколько больших видео-чанков с
ютуба?
Но тут и кроется недостаток PQ — если приоритетная очередь нагружена трафиком, диспетчер вообще никогда
не переключится на другие.
И если какой-то Доктор ЗЛО в поисках методов завоевания мира решит помечать весь свой злодейский трафик
наивысшей чёрной меткой, все другие будут покорно ждать, а потом отбрасываться.
О гарантированной полосе для каждой очереди говорить тоже не приходится.
Высокоприоритетные очереди можно прирезать по скорости обрабатываемого в них трафика. Тогда другие не
будут голодать. Однако контролировать это непросто.
Следующие механизмы ходят по всем очередям по очереди, забирая из них некое количество данных, тем
самым предоставляя более честные условия. Но делают они это по-разному.
FQ-Fair Queuing
Следующий претендент на роль идеального диспетчера — механизмы честных очередей.
FQ — Fair Queuing
История его началась в 1985, когда Джон Нейгл предложил создавать очередь на каждый поток данных. По духу
это близко к подходу IntServ и это легко объяснимо тем, что идеи классов сервиса, как и DiffServ тогда ещё не
было.
FQ извлекал одинаковый объём данных из каждой очереди по порядку.
Честность заключается в том, что диспетчер оперирует числом не пакетов, а числом битов, которые можно
передать из каждой очереди.
Так агрессивный TCP-поток не может затопить интерфейс, и все получают равные возможности.
В теории. FQ так и не был реализован на практике как механизм диспетчеризации очередей в сетевом
оборудовании.
Здесь вы можете видеть, что из-за большого размера пакета в 3-ей очереди, в первые два цикла обработали по
одному пакету из первых двух.
Описание механизмов bit-by-bit Round Robin и GPS уже за пределами этой статьи, и я отсылаю читателя
к самостоятельному изучению.
WFQ — Weighted Fair Queuing
Второй и отчасти третий недостатки FQ попытался закрыть WFQ, обнародованный в 1989 году.
Каждая очередь наделялась весом и соответственно правом за один цикл отдавать трафика кратно весу.
Вес высчитывался на основе двух параметров: ещё актуальном тогда IP Precedence и длине пакета.
В контексте WFQ чем больше вес, тем хуже.
Поэтому чем выше IP Precedence, тем меньше вес пакета.
Чем меньше размер пакета, тем меньше и его вес.
Таким образом высокоприоритетные пакеты небольшого размера получают больше всего ресурсов, тогда как,
низкоприоритетные гиганты ждут.
На иллюстрации ниже пакеты получили такие веса, что сначала пропускается один пакет из первой очереди,
потом два из второй, снова из первой и только потом обрабатывается третья. Так, например, могло сложиться,
если размер пакетов во второй очереди сравнительно маленький.
Про суровую машинерию WFQ, с её packet finish time, виртуальным временем и Теоремой Парика можно
почитать в любопытном цветном документе.
Впрочем первую и третью проблемы это никак не решало. Flow Based подход был так же неудобен, а потоки,
нуждающиеся в коротких задержках и стабильных джиттерах, их не получали.
Это, впрочем, не помешало WFQ найти применение в некоторых (преимущественно старых) устройствах Cisco.
Там имелось до 256 очередей, в которые потоки помещались на основе хэша от своих заголовков. Этакий
компромисс между Flow-Based парадигмой и ограниченными ресурсами.
То есть DSCP определял в какую очередь помещать, а настроенный вес — сколько полосы доступно данной
очереди.
Самое главное, что это косвенно немного облегчило жизнь и low-latency потокам, которые теперь были
агрегированы в одну (две-три-…) очереди и получали свой звёздный час заметно чаще. Жить стало лучше, но ещё
не хорошо — гарантий никаких так и нет — в целом в WFQ все по-прежнему равны в плане задержек.
Да и необходимость постоянного слежения за размером пакетов, их фрагментации и дефрагментации, никуда не
делась.
RR — Round-Robin
Рука об руку с FQ шёл и RR.
Один был честен, но не прост. Другой совсем наоборот.
RR перебирал очереди, извлекая из них равное число пакетов. Подход более примитивный, чем FQ, и оттого
нечестный по отношению к различным потокам. Агрессивные источники легко могли затопить полосу пакетами
размером в 1500 байтов.
Однако он очень просто реализовывался — не нужно знать размер пакета в очереди, фрагментировать его и
собирать потом обратно.
Однако его несправедливость в распределении полосы перекрыла ему путь в мир — в мире сетей чистый Round-
Robin не был реализован.
Таким образом все очереди получают гарантированную полосу, независимо от размера пакетов в ней.
С DWRR всё же остаётся вопрос с гарантией задержек и джиттера — вес его никак не решает.
Теоретически, здесь можно поступить как и с CB-WFQ, добавив LLQ.
Однако это лишь один из возможных сценариев набирающего сегодня популярность
Это тот же старый злой DWRR, в который добавлена ещё одна очередь — приоритетная, пакеты в которой
обрабатываются с более высоким приоритетом. Это не значит, что ей отдаётся бóльшая полоса, но то, что оттуда
пакеты будут забираться чаще.
Существует несколько подходов к реализации PB-DWRR. В одних из них, как в PQ, любой пришедший в
приоритетную очередь пакет изымается сразу. В других, обращение к ней происходит каждый раз при переходе
диспетчера между очередями. В третьих и для неё вводится кредит и квант, чтобы приоритетная очередь не
могла отжать всю полосу.
Разбирать мы их, конечно, не будем.
Короткий итог про механизмы диспетчеризации
Десятилетиями человечество пыталось решить сложнейшую проблему обеспечения нужного уровня сервиса и
честного распределения полосы. Основным инструментом являлись очереди, вопрос был только в том, как из
очередей забирать пакеты, пытаясь их запихнуть в один интерфейс.
Начиная с FIFO, оно изобрело PQ — голос смог сосуществовать с сёрфингом, но не было речи про гарантию
полосы.
Появились несколько монструозные FQ, WFQ, работавшие если не per-flow, то почти так. CB-WFQ пришёл к
классовому обществу, но не стал от этого проще.
Как альтернатива ему развивался RR. Он превратился в WRR, а затем и в DWRR.
И в глубине каждого из диспетчеров живёт FIFO.
Однако, как видите, нет некоего универсального диспетчера, который все классы обрабатывал так, как они того
требуют. Это всегда комбинация диспетчеров, один из которых решает задачу обеспечения задержек, джиттера
и отсутствия потерь, а другой распределения полосы.
CBWFQ+LLQ или PB-WDRR или WDRR+PQ.
На реальном оборудовании можно указать какие именно очереди каким диспетчером обрабатывать.
CBWFQ, WDRR и их производные — это сегодняшние фавориты.
PQ, FQ, WFQ, RR, WRR — не скорбим и не помним (если, конечно, не готовимся к CCIE © Клиппер).
8. Ограничение скорости
Необходимость ограничения скорости трафика на первый взгляд очевидна — не выпустить клиента за пределы
его полосы согласно договору.
Да. Но не только. Допустим имеется РРЛ-пролёт шириной в 620 Мб/с, подключенный через порт 1Гб/с. Если
пулять в него весь гигабит, то где-то на РРЛ, которая, вполне вероятно, не имеет представления об очередях и
QoS, начнутся чудовищные отбрасывания случайного характера, не привязанные к реальным приоритетам
трафика.
Однако, если на маршрутизаторе включить шейпинг до 600 Мб/с, то EF, CS6, CS7 не будут отбрасываться совсем,
а в BE, AFх полоса и дропы распределятся согласно их весам. До РРЛ будет доходить 600 Мб/с и мы получим
предсказуемую картину.
Другой пример — входной контроль (Admission Control). Например, два оператора договорились доверять всей
маркировке друг друга, кроме CS7 — если что-то пришло в CS7 — отбрасывать. Для CS6 и EF — давать отдельную
очередь с гарантией задержки и отсутствия потерь.
Но, что если хитроумный партнёр начал лить в эти очереди торренты? Прощай телефония. Да и протоколы
начнут, скорее всего, разваливаться.
Логично в этом случае договориться с партнёром о полосе. Всё, что укладывается в договор — пропускаем. Что
не укладывается — отбрасываем или переводим в другую очередь — BE, например. Таким образом защищаем
свою сеть и свои сервисы.
Существует два принципиально разных подхода к ограничению скорости: полисинг и шейпинг. Решают они одну
задачу, но по-разному.
Рассмотрим разницу на примере такого профиля трафика:
Traffic Policing
Полисинг ограничивает скорость путём отбрасывания лишнего трафика.
Всё, что превышает установленное значение, полисер срезает и выбрасывает.
Что срезано, то забыто. На картинке видно, что красный пакет отсутствует в трафике после полисера.
Название «Policing» диктуется довольно строгим отношением инструмента к лишнему трафику — отбрасывание
или разжалование в более низкий класс.
Traffic Shaping
Шейпинг ограничивает скорость путём буферизации лишнего трафика.
Весь приходящий трафик проходит через буфер. Шейпер из этого буфера с постоянной скоростью изымает
пакеты.
Если скорость поступления пакетов в буфер ниже выходной, они в буфере не задерживаются — пролетают
насквозь.
А если скорость поступления выше выходной, они начинают скапливаться.
Выходная скорость при этом всегда одинакова.
Таким образом всплески трафика складываются в буфер и будут отправлены, когда до них дойдёт очередь.
Поэтому наряду с диспетчеризацией в очередях, шейпинг — второй инструмент, делающий вклад в совокупную
задержку.
На иллюстрации хорошо видно, как пакет, пришедший буфер в момент времени t2, на выходе оказывается в
момент t3. t3-t2 — это задержка, вносимая шейпером.
Главное достоинство такого подхода — оптимальное использование имеющейся полосы — вместо дропа
чрезмерного трафика, мы его откладываем.
Главный недостаток — непредсказуемая задержка — при заполнении буфера, пакеты будут томиться в нём
долго. Поэтому не для всех типов трафика шейпинг хорошо подходит.
Shaping использует механизм Leaky Bucket.
Шейпер никак не влияет на заголовки пакетов и их судьбу за пределами узла, в то время как после полисинга
устройство может перемарикровать класс в заголовке. Наример, на входе пакет имел класс AF11, метеринг
покрасил его в жёлтый цвет внутри устройства, на выходе оно перемаркировало его класс на AF12 — на
следующем узле у него будет более высокая вероятность отбрасывания.
match any
Шейпим до 20Мб/с:
policy-map TRISOLARANS_SHAPING
class TRISOLARANS_ALL_CM
interface Ethernet0/2
service-policy output TRISOLARANS_SHAPING
И вот результат:
Получается достаточно ровная линия общей пропускной способности и рваные графики по каждому отдельному
потоку.
Дело в том, что ограничиваем мы шейпером именно общую полосу. Однако в зависимости от платформы
отдельные потоки тоже могут шейпиться индивидуально, таким образом получая равные возможности.
policy-map TRISOLARANS_ADMISSION_CONTROL
class TRISOLARANS_TCP_CM
interface Ethernet0/1
Здесь указываем среднюю разрешённую скорость CIR (10Mб/с) и разрешённый всплеск Bc (1 875 000 байтов
около 14,6 МБ).
Позже, объясняя, как работает полисер, я расскажу, что за CIR да Bc и как эти величины определять.
Такая картина наблюдается при полисинге. Сразу видно резкие изменения уровня скорости:
А вот такая любопытная картина получается, если мы сделаем слишком маленьким допустимый размер
всплеска, например, 10 000 байтов.
Таблица тестов.
Имеем ведро с отверстием заданного размера внизу. В это ведро сверху сыпятся/льются пакеты. А снизу они
вытекают с постоянной битовой скоростью.
Когда ведро заполняется, новые пакеты начинают отбрасываться.
Размер отверстия определяется заданным ограничением скорости, которая для Leaky Bucket измеряется в битах
в секунду.
Объём ведра, его наполненность и выходная скорость определяют задержку, вносимую шейпером.
Для удобства объём ведра обычно измеряется в мс или мкс.
Чипы коммутации не очень-то хорошо понимают, что такое время, ещё хуже они считают сколько битов они за
единицу времени передали. Их работа — молотить.
Вот этот приближающийся бит — это ещё 400 000 000 бит в секунду или уже 400 000 001?
Алгоритм, решающий вторую задачу называется Token Bucket. Его идея изящна и проста (нет).
Рядом проходят две ленты конвейера: одна подвозит пакеты, вторая — увозит.
Чтобы попасть на отвозящий конвейер, пакет должен заплатить.
Монетки для этого он берёт из ведра в соответствии со своим размером. Грубо говоря — сколько битов —
столько и монеток.
Если ведро опустело и монет пакету не хватило, он окрашивается в красный сигнальный цвет и отбрасывается.
Увы-селявы. При этом монеты из ведра не вынимаются.
Следующему пакету монет уже может хватить — во-первых, пакет может быть поменьше, а, во-вторых, ещё
монет за это время нападает.
• Есть ведро ёмкостью 2500 байтов. На начальный момент времени в нём лежит 550 токенов.
• На конвейере три пакета по 1000 байтов, которые хотят быть отправлены в интерфейс.
• В каждый квант времени в ведро падает 500 байтов (500*8 = 4 000 бит/квант времени — ограничение
полисера).
• На исходе первого кванта времени в ведро падает 500 токенов. И в это время подходит первый пакет. Его
размер 1000 байтов, а в ведре 1050 токенов — хватает. Пакет красится в зелёный цвет и пропускается. 1000
токенов вынимается из ведра.
• В ведре остаётся 50 токенов.
• На исходе второго кванта времени в ведро падает ещё 500 токенов — итого 550. А размер пришедшего
пакета — 1000 — не хватает.
• Пакет красится красным и отбрасывается, токены не вынимаются.
• На исходе третьего кванта в ведро падает ещё 500 токенов — снова 1050. Размер пришедшего пакета —
1000 — хватает.
• Пакет красится в зелёный и пропускается, токены вынимаются из ведра.
Объём ведра в 2500 байтов фактически означает, что через такой полисер ни при каких условиях не пройдёт
пакет больше 2500 байтов — ему никогда не будет хватать токенов. Поэтому его объём должен быть не меньше
MTU и вообще рекомендуется объём, равный количеству трафика на максимальной скорости, разрешённой
полисером, за 1,5-2 секунды.
То есть формула следующая:
Если вернуться к практическому примеру по полисингу, где мы настраивали всплески (Bc), то станет понятно, что
при большом значении (1 875 000 байтов) все всплески амортизируются хорошо. А при маленьком (10 000
байтов), несмотря на то, что оно заметно больше MTU, полисер упирается в постоянное заполнение ведра и
отбрасывает большое количество пакетов.
Зачем ведру объём? Битовый поток не всегда равномерен, это очевидно. Ограничение в 400 Мб/с — это не
асимптота — трафик может её пересекать. Объём хранящихся монет позволяет небольшим всплескам пролетать,
не будучи отброшенными, однако среднюю скорость сохранить на уровне 400Мб/с.
Например, стабильный поток 399 Мб/с за 600 секунд позволит ведру наполниться до краёв.
Далее трафик может подняться до 1000Мб/с и держаться на этом уровне 1 секунду — 600 Мм (Мегамонет)
запаса и 400 Мм/с гарантированной полосы.
Или же трафик может подняться до 410 Мб/с и держаться таким на протяжении 60 секунд.
То есть запас монет позволяет слегка выйти за ограничение на продолжительное время или выплеснуть
короткий но высокий всплеск.
Теперь к терминологии.
Скорость поступления монет в ведро — CIR — Committed Information Rate (Гарантированная средняя скорость).
Измеряется в битах в секунду.
Количество монет, которые могут храниться в ведре — CBS — Committed Burst Size. Разрешённый максимальный
размер всплесков. Измеряется в байтах. Иногда, как вы уже могли заметить, называется Bc.
Tc — Количество монет (Token) в ведре C (CBS) в данный момент.
В статье я использую термин "Tc", так же, как он использован в RFC 2697 (A Single Rate Three Color Marker).
Однако есть и другой Tc, который описывает интервал времени, когда в ведро ссыпается новая порция монет.
Здесь следует сделать отступление.
Невозможно подстроить скорость интерфейса, чтобы удовлетворить условиям полисера, поэтому и вводится
система Token Bucket, реализующая по сути TDM (Time-Division Multiplexing) — она разрешает отправку трафика
только в определённые моменты времени.
То есть монеты не льются в ведро непрерывным потоком — современный мир, увы, дискретен.
В первом приближении предлагается один раз в секунду насыпать CIR монет. Потом через секунду итд.
Это работает плохо, потому что всплеск — и секунда молчания, всплеск — и секунда молчания, всплеск — и
секунда молчания.
Поэтому во втором приближении секунда делится на интервалы времени, в которые спускается определённое
число монет.
Такой интервал времени тоже называется (как минимум в литературе Cisco) Tc, а количество падающих монет —
Bc. При этом Bc = CIR*Tc.
То есть в начале каждого интервала Tc в ведро опускается Bc монет.
К CIR и CBS добавляется EBS — Excess Burst Size — Разрешённый размер всплесков во время пиков. Te —
количество монет в ведре E.
4.
5. Если и в ведре E не хватает монет, то пакет красится в красный, монеты не вынимаются ниоткуда.
6.
7.
Обратите внимание, что для конкретного пакета Tc и Te не суммируются.
То есть пакет размером 8000 байтов не пройдёт, даже если в ведре C будет 3000 монет, а в E — 7000. В C не
хватает, в E не хватает — ставим красное клеймо — шуруй отсюда.
Это очень изящная схема. Весь трафик, который укладывается в среднее ограничение CIR+CBS (автор знает, что
нельзя так напрямую складывать биты/с и байты) — проходит зелёным. В пиковые моменты, когда клиент
исчерпал монеты в ведре C, у него есть ещё накопленный за время простоя запас Te в ведре E.
То есть можно пропустить чуть больше, но в случае заторов такие с большей вероятностью будут отброшены.
sr-TCM описан в RFC 2697.
Используется для полисинга в PHB AF.
Ну и последняя система — самая гибкая и потому сложная — Two Rate — Three Color.
Two Rate — Three Color Marking
Модель Tr-TCM родилась из идеи, что не в ущерб другим пользователям и типам трафика, почему бы клиенту не
дать чуть больше приятных возможностей, а ещё лучше продать.
Скажем ему, что ему гарантировано 400 Мб/с, а если есть свободные ресурсы, то 500. Готовы заплатить на 30
рублей больше?
Добавляется ещё одно ведро P.
Таким образом:
CIR — гарантированная средняя скорость.
CBS — тот же разрешённый размер всплеска (объём ведра C).
PIR — Peak Information Rate — максимальная средняя скорость.
EBS — разрешённый размер всплесков во время пиков (Объём ведра P).
В отличие от sr-TCM, в tr-TCM в оба ведра теперь независимо поступают монеты. В C — со скоростью CIR, в P —
PIR.
Какие правила?
Приходит пакет размером B байтов.
1. Если монет в ведре P не хватает — пакет помечается красным. Монеты не вынимаются. Иначе:
2. Если монет в ведре C не хватает — пакет помечается жёлтым, и из ведра P вынимаются B монет. Иначе:
3. Пакет помечается зелёным и из обоих вёдер вынимаются B монет.
То есть правила в tr-TCM другие.
Пока трафик укладывается в гарантированную скорость, монеты вынимаются из обоих вёдер. Благодаря этому,
когда в ведре C монеты кончатся, останутся в P, но ровно столько, чтобы не превысить PIR (если бы вынимались
только из C, то P наполнялось бы больше и давало гораздо бо́ льшую скорость).
Соответственно, если он выше гарантированной, но ниже пиковой, монеты вынимаются только из P, потому что
в C уже нет ничего.
Для, возможно, лучшего понимания, рекомендую обратиться к оригинальным RFC или почитать тут.
Механизм Token Bucket вполне применим и в быту. Например, если я иду с друзьями в бар, в то время, как жена
проводит время с двумя детьми, то каждую минуту из ведра вынимается токен.
Если я вычерпаю всё ведро, то на выходных не могу пойти на пробежку — жду, пока накапает. Если токенов
мало, то часок побегать можно, а вот уехать на выходной на работу, чтобы заняться статьёй — уже нет.
Правда рейт наполнения ведра не постоянный, токены выделяются за добрые дела. На самом деле здесь
система из двух связанных ведёр — моего и жены. Но так можно и на целую статью материала написать.
Выше я описал все основные механизмы QoS, если не углубляться в иерархический QoS. Сложнейшая система с
многочисленными движущимися частями.
Всё хорошо (правда ведь?) звучало до сих пор, но что же творится под ванильной внешней панелью
маршрутизатора?
Годами вендоры добавляли всё новые и новые конутры, разрабатывали сложнейшие чипы, расширяли буферы,
чтобы с одной стороны поспевать за растущим объёмом трафика и новыми его категориями, а с другой, решать
нарастающий проблемы, вызываемые первым пунктом.
Непрекращающаяся гонка. Нельзя терять пакеты, если конкурент их не теряет. Нельзя отказаться от
функционала, если соперник стоит с ним под дверями заказчика.
Айда в логово проприетарщины!
Что управляет поведением узла и запускает соответствующие механизмы по отношению к пакету? Приоритет,
который он несёт в одном из заголовков? И да, и нет.
Как уже говорилось выше, внутри сетевого устройства обычно перестаёт существовать стандартный
коммутирующий заголовок.
Как только пакет попал на чип коммутации, заголовки с него снимаются и отправляются на анализ, а полезная
нагрузка томится в каком-то временном буфере.
На основе заголовков происходит классификация (BA или MF) и принимается решение о пересылке.
Через мгновение на пакет навешивается внутренний заголовок с метаданными о пакете.
Эти метаданные несут много важной информации — адреса отправителя и получателя, выходной чип,
порядковый номер ячейки, если была фрагментация пакета и обязательно маркировку класса (CoS) и приоритет
отбрасывания (Drop Precedence). Только маркировку во внутреннем формате — он может совпадать с DSCP, а
может и нет.
В принципе, внутри коробки можно задать произвольную длину маркировки, не привязываясь к стандартам, и
определять очень гибко действия с пакетом.
У Cisco внутренняя маркировка зовётся QoS Group, у Juniper — Forwarding Class, Huawei не определился: где-то
называет internal priorities, где-то local priorities, где-то Service-Class, а где-то просто CoS. Добавляйте в
комментарии названия для других вендоров — я дополню.
Вот эта внутренняя маркировка назначается на основе классификации, которую выполнил узел.
Важно, что если не сказано иного, то внутренняя маркировка работает только внутри узла, но никак потом не
отображается на маркировку в заголовках пакета, который будет отправлен с узла — она останется прежней.
Однако, на входе в DS-домен после классификации обычно происходит перемаркировка в определённый класс
сервиса, принятый в данной сети. Тогда внутренняя маркировка преобразуется в значение, принятое для
данного класса на сети, и записывается в заголовок отправляемого пакета.
Внутренняя маркировка CoS и Drop Precedence определяет поведение только внутри данного узла и никак явным
образом не передаётся соседям, кроме перемаркировки заголовков.
CoS и Drop Precedence определяют PHB, его механизмы и параметры: предотвращение перегрузок, управление
перегрузками, диспетчеризация, перемаркировка.
Через какие круги проходят пакеты между входным и выходным интерфейсами я рассмотрел в предыдущей
статье. Собственно она и оказалась внеплановой, поскольку в какой-то момент стало очевидно, что без
понимания архитектуры говорить о QoS преждевременно.
Однако, давайте повторимся.
1. Сигнал попадает на физический входной интерфейс и его чип (PIC). Из него вналивается битовый поток и
потом пакет со всеми заголовками.
2. Далее на входной чип коммутации (FE), где заголовки отделяются от тела пакета. Происходит
классификация и определяется, куда пакет нужно отправить дальше.
3. Далее во входную очередь (TM/VOQ). Уже здесь пакеты раскладываются в разные очереди на основе
своего класса.
4. Далее на фабрику коммутации (если она есть).
5. Далее в выходную очередь (TM).
6. Далее в выходной чип коммутации (FE), где навешиваются новые заголовки.
7. Далее в выходной интерфейс (возможно, через ещё одну очередь) (PIC).
На самом деле есть всего два места, где работают механизмы QoS — это чип коммутации и чип Traffic
Management/очереди.
При этом на чипе коммутации происходят операции, которые требуют анализа или действий с заголовками.
• Классификация
• Полисинг
• Перемаркировка
Остальное берёт на себя TM. В основном это рутинные операции с предопределённым алгоритмом и
настраиваемыми параметрами:
• Предотвращение перегрузок
• Управление перегрузками
• Шейпинг
К слову реально в очереди помещаются, по ним продвигаются, из них изымаются итд не сами пакеты, а только
записи о них. Нет смысла делать такое количество телодвижений с большими массивами битов. Пока над
записями измывается QoS, пакеты прекрасно себе лежат в памяти и извлекаются оттуда по адресу.
VOQ — это программная очередь (английский термин Software Queue более точен). После него сразу перед
интерфейсом находится ещё аппаратная очередь, которая всегда, строго работает по FIFO. Управлять какими-
либо её параметры практически невозможно (для примера, Cisco позволяет настроить только глубину командой
tx-ring-limit).
Как раз между программной и аппаратной очередью можно запускать произвольные диспетчеры. Именно в
программной очереди работают Head/Tail-drop и AQM, полисинг и шейпинг.
Размер аппаратной очереди очень небольшой (единицы пакетов), потому что всю работу по укладыванию в line-
rate делает диспетчер.
К сожалению, здесь можно сделать много оговорок, да и вообще всё перечеркнуть красной ручкой и сказать «у
вендора Х всё не так».
Хочется сделать ещё одно замечание о служебных пакетах. Они обрабатываются иначе, чем транзитные
пользовательские пакеты.
Будучи сгенерированными локально, они не проверяются на подпадание под правила ACL, и ограничения
скорости.
Пакеты же извне, предназначенные на CPU, с выходного чипа коммутации попадают в другие очереди — к CPU
— на основе типа протокола.
Например, BFD имеет наивысший приоритет, OSPF может подождать подольше, а ICMP и вообще не страшно
отбросить. То есть, чем важнее пакет для работоспособности сети, тем выше его класс сервиса при посылке на
CPU. Именно поэтому видеть в пинге или трассировке варьирующиеся задержки на транзитных хопах — это
нормально — ICMP — не приоритетный для CPU трафик.
Кроме того, на протокольные пакеты применяется CoPP — Control Plane Protection (или Policing) — ограничение
скорости во избежание высокой загрузки CPU — опять же, лучше предсказуемые отбрасывания в
низкоприоритетных очередях до того, как начались проблемы.
CoPP поможет и от целенаправленного DoS и от аномального поведения сети (например, петли), когда на
устройство начинает приходить много широковещательного трафика.
Полезные ссылки
• Лучшая книга по теории и философии QoS: QOS-Enabled Networks: Tools and Foundations.
• Некоторые отрывки из неё можно почитать тут, однако я бы рекомендовал читать её от и до, не
размениваясь.
• На удивление обстоятельная и хорошо написанная книга про QoS от Huawei: Special Edition QoS(v6.0).
Очень плотно разбирается архитектура оборудования и работа PHB на разных платах.
• Очень подробное сравнение sr-TCM и tr-TCM от Айни: Understanding Single-Rate and Dual-Rate Traffic
Policing.
• Про VOQ: What is VOQ and why you should care?
• Про QoS в MPLS: MPLS and Quality of Service.
• Относительно краткий бриф по QoS на примере Juniper: Juniper CoS notes.
• Практически весь QoS так или иначе ориентирован на специфику TCP и UDP. Не лишним будет
досконально разобраться в них: The TCP/IP Guide
• Ну а для тех, кто не чувствует в себе силы одолеть весь этот труд, Лохматый Мамонт для вас написал
отдельную заметку: В поисках утерянного гигабита или немного про окна в TCP.
• На этой странице сложно, но подробно описано как работают механизмы группы FQ: Queuing and
Scheduling.
• А если подняться на уровень выше, то откроется масштабный открытый документ, называющийся An
Introduction to Computer Networks, вгоняющий краску, потому что настолько мощный Introduction, что я там
половину не знаю. Даже самому захотелось почитать.
• Про WFQ очень научно, но при должно интеллекте, коим, очевидно, я не обладаю, понятно и в
цветах: Weighted Fair Queueing: a packetized approximation for FFS/GP.
• Есть ещё механизм LFI, который я затрагивать не стал, потому что сложно и в наших реалиях
стогигиабитных интерфейсов не очень актуально, однако ознакомиться может быть интересно: Link
Fragmentation and Interleaving.
Заключение
У этого выпуска было много рецензентов.
Спасибо.
Александру Фатину (@LoxmatiyMamont) за вводное слово и ценные советы по выразительности и доходчивости
текста.
Александру Клипперу (@metallicat20) за экспертную оценку.
Александру Клименко (@v00lk) за суровую критику и самые массивные изменения.
Андрею Глазкову (@glazgoo) за замечания по структуре, терминологии и за запятые.
Артёму Чернобаю за КДПВ.
Антону Клочкову (@NAT_GTX) за контакты с Миран.
Миран (miran.ru) за организацию сервера с Евой и трансляцией.
Традиционно моей семье, которая впрочем в этот раз наименее всего пострадала ввиду её отсутствия рядом в
самые тяжёлые моменты.
https://linkmeup.ru/sdsm/