LACP под лупой Wireshark
Привет Habr, всем максимально доброго дня!!!
После первой статьи прошло... чуть больше времени, чем рассчитывал, и вот решил продолжить тему медленных протоколов: сегодня LACP (Link Aggregation Control Protocol - протокол управления агрегацией каналов).
С самого начала, давайте вспомним самую важную картинку из прошлой статьи, а точнее - схему работы агрегированного канала.
Когда мы создаем LAG статически, то мы просто вручную присваиваем каждому физическому порту номер коллектора и номер дистрибьютора и отпускаем в свободное плавание: у портов нет возможности убедиться, а реально ли на другом конце кабеля порт также назначен в правильный канал? Или он там свободен как птица в полете, и у нас на горизонте реально маячит перспектива петли? Вот как раз для такого и был придуман протокол LACP, который и автоматизирует "вот это всё".
Понятно, что для координации коммутаторы должны обмениваться какими-то данными. И вот это нечто назвали - ту без особой фантазии - LACPDU. Отправляющий информацию называется «актором» (actor), а получающий – партнером (partner). Каждый коммутатор сам для себя актор, а для другого – партнер.
Актор может быть активным или пассивным. Пассивный не инициирует обмен протокольными блоками LACP (LACPDU), а только отвечает на входящие LACPDU, а вот активный отправляет LACPDU независимо от факта получения информации от соседа. Простите, партнера.
Согласно стандарту 802.3ad, количество активных коммутаторов LACP на одном канале должно быть не менее одного.
Соответственно, если два коммутатора являются активными, то проблем никаких – кто-нибудь да достучится. Если один активный, а другой пассивный – тоже хорошо: активный отправит LACPDU, пассивный его получит и ответит. А вот если пассивных два – тут беда: каждый ждет признания от второго и в итоге два одиночества не встречаются. В общем, все как у людей.
Ну что, давайте посмотрим как происходит установление канала, так сказать, in vivo. Для этого возьмем два коммутатора Eltex – больше под руками ничего не было – и соберем простенький стендик:
LACPDU с обоих коммутаторов будем собирать на порту Gi0/10 (для педантов Gi1/0/10). Для этого настроим SPAN-зеркалирование:
MES2308P(config)#interface Gi0/10
MES2308P(config-if)#port monitor gigabitethernet 0/1
MES2308P(config-if)#port monitor gigabitethernet 0/2
MES2308P(config-if)#exit
MES2308P(config)#
Ну и чтобы два раза не вставать, настроим сразу же и протокол LACP на двух наблюдаемых портах:
MES2308P(config)#default interface range Gi1/02
MES2308P(config)#interface range Gi0/1-2
MES2308P(config-if-range)#channel-group 1 mode auto
Первая команда нужна для того, чтобы сбросить оба нужных нам порта в настройки по умолчанию, то есть привести их к единообразному виду, необходимому для успешного агрегирования.
А вот увидев команду auto, апологеты протокола PAgP сейчас должны были бы несколько напрячься, но это излишне – auto у Eltex обозначает режим active во всех коммутаторах 23й серии. Ну а для комплекта еще и в 33й, 35й, 53й, то есть везде где вторая цифра в номере модели «3» или «5». Ну и до кучи - в маршрутизаторах.
Давайте теперь посмотрим, что нам покажет Wireshark. А покажет он, собственно, сами LACPDU, которые высылаются теперь с портов нашего подопечного коммутатора.
Сразу обращаем внимание на адрес назначения: это групповой адрес для так называемых «медленных протоколов» (slow protocols). Они называются так потому, что кадры, отправленные на эти адреса, не рассылаются получившим их коммутатором из всех портов, как это произошло бы, например, с мультикаст-адресами с OUI 01:00:5E. К медленным протоколам, к примеру, относятся еще и LLDP и вся семейка STP.
Для чего в LACP понадобился мультикаст? Во-первых, актор еще не знает мак-адреса партнера, а потому отправляет кадр «на деревню дедушке». А во-вторых, необходимо чтобы отправленный кадр обрабатывали не все устройства, а только «те кто понимает», то есть такие же коммутаторы как он сам.
Еще одна особенность работы протокола LACP, которая роднит его с семейством STP – протокол работает от порта до порта. То есть, кадры LACPDU отправляются не от всего коммутатора, а от имени каждого порта с указанием его, порта, MAC-адреса. В нашем примере MAC-адрес коммутатора MES2308P заканчивается на d0, а адреса портов Gi0/1 и Gi0/2 – на d1 и d2 соответственно. То же самое верно и для второго коммутатора. Зафиксируем данный момент, чтобы потом легче было ориентироваться в происходящем.
Попробуем рассмотреть более подробно структуру LACPDU:
Видим, что сообщение состоит из заголовка протокола, а точнее его версии, и четырех TLV:
TLV 1 – Информация об акторе (Actor information)
TLV 2 – Информация о партнере (Partner Information)
TLV 3 – Информация о коллекторе (Collector Information)
TLV 0 – Конец пакета. (Terminator)
Первые два TLV совершенно идентичны по структуре, разнятся только данные по актору и партнеру.
И первым идет приоритет системы SystemPriority и идентификатор системы SystemID. Эти два параметра в сочетании используются для того чтобы определить ведущий коммутатор, то есть тот, кто будет определять какие из портов активны в канале. Как мы знаем, активных (используемых для передачи и приема данных) может быть только 8, а всего в канале может быть и больше, все за ради резервирования и избыточности. Так вот, главным в паре становится тот коммутатор, у которого сочетание SysPriority+SysID – меньше. Все как в STP.
Согласно стандарту, приоритет системы по умолчанию равен 32768 (еще один «вьетнамский флешбек»), но разработчики серии MES x3xx и x5xx – те же, что включают активный режим командой auto – решили, что в их коммутаторах приоритет по умолчанию будет 1. Видимо, чтобы всегда выигрывать выборы.
Далее у нас поле Actor(Partner) Key. Это идентификатор группы каналов, к которой принадлежит данный порт. Значения этого поля могут не совпадать для каждого конкретного канала, но должны совпадать для группы, об этом мы еще поговорим чуть позже.
Следующие два поля – Actor(Partner) PortPriority и Actor(Partner) Port. Сочетание этих полей определяет, будет ли данный порт активным в логическом канале, то есть, будет ли он использоваться для приема и передачи информации, или будет запасным. PortPriority – снова как и в STP – по умолчанию равно 128 или х80 в шестнадцатеричном представлении (но в этой серии снова 1). Port – это порядковый номер порта. В коммутаторах Eltex нумерация физических портов начинается с 49 (или 0x31 в шестнадцатеричном представлении).
Ну и самое загадочное поле – Actor (Partner) State, состояние актора/партнера. Здесь какие-то буквы со звездочками, очень похожие на мат. Но нет, всему есть совершенно цензурное объяснение. Посмотрим в развернутом виде.
Звездочками всего лишь обозначены нули. А буквами – поля-флаги со значением равным единице.
Активность LACP (LACP Activity) – режим работы порта: 1 – active, 0 – passive.
Период ожидания (LACP Timeout): по умолчанию 0 - Long (30 секунд). 1 – Short (1 секунда).
Агрегация (Aggregation) – 1 – является членом группы портов, 0 – не является членом группы портов.
Синхронизация (Synchronization): 0 – не синхронизирован, 1 – синхронизирован.
Коллектор (Collecting): 0 – не подключен, 1 – подключен
Дистрибьютор (Distributing): 0 – не подключен, 1 – подключен.
По умолчанию (Defaulted): 0 – значение изменено в ходе работы протокола, 1 – значение заданное при настройке порта
Срок годности (Expired): 0 – кадр получен до истечения периода ожидания, 1 – кадр получен после истечения периода ожидания.
В нашем примере порт находится в активном режиме, он является членом группы портов (мы сами это настроили, тут не поспоришь) и все значения флагов не менялись с момента конфигурации.
Можем предположить, что в случае успешной сборки портов в логический канал, порт будет синхронизирован (флаг 4 равен 1), к нему будут подключены коллектор и дистрибьютор (флаги 5 и 6 равны 1). Если же порт будет включен в канал в качестве запасного, то конфигурация будет другой: флаг 4 будет равен 1, а флаги 5 и 6 будут равны 0, то есть, не будут использованы для приема и передачи данных. Это мы и проверим в нашей конфигурации далее.
Всё, замучил, понимаю – неукоснительно и неудержимо включаем LACP на портах Gi0/1 и Gi0/2 коммутатора MES2424. Переведем их сразу в пассивный режим, чтобы избежать путаницы в WireShark. В жизни, конечно же, лучше использовать режим активный (в этой серии коммутаторов Eltex - вторая цифра номера модели 4 или 7 - он называется active).
MES2424#configure
MES2424(config)default interface range gi0/1-2
MES2424(config)#interface range gi0/1-2
MES2424(config-if-range)#channel-group 1 mode passive
В WireShark сразу видим появление ответных кадров LACPDU от MAC-адресов :41 и :42, то есть от портов Gi0/1 и Gi0/2 коммутатора MES2424.
Как говорил один бывший руководитель одной бывшей страны: «Процесс пошел».
Теперь давайте разбираться, что там внутри процесса происходит. Для этого сравним соответствующие TLV Actor Information у портов :d1 и :41.
Первый обмен – оба рассинхронизированы (Out of Sync). Чувствуется взаимная холодность и недоверие.
Но это понятно, это всего лишь первый ответ, который получил :d1 после долгой серии безуспешных попыток добиться взаимности. Второй обмен – по секрету скажу – тоже будет безуспешным, и порты не синхронизиуются.
А вот трееееееееетий – тут уже все гораздо интереснее. Давайте посмотрим, что там у портов.
Наконец-то они синхронизировались (у обоих появился флаг в поле Synchronization). Такая же картинка и у другой пары портов :d2-:42. А значит, у нас «сошелся» канал и теперь порты будут передавать и принимать данные.
Ага, щазз.
Чтобы что-то передавать и принимать, нужно чтобы порт был подключен к коллектору и дистрибьютору – а у наших подопечных в этих полях пока что нули. Продолжаем наблюдения.
Сразу после синхронизации :41 отправляет сообщение с флагом Collecting, то есть подключается к коллектору, и теперь может использоваться для приема данных (точнее, он теперь знает какому коллектору будет отдавать полученные кадры). В ответ :d1 отправляет сообщение с флагами Collecting и Distributing, и :41 отвечает сообщением тоже с двумя упомянутыми флагами. Выглядит это как-то вот так.
Вот теперь канал сошелся и все порты в рабочем состоянии, потому что другая пара повторила то же самое. Итоговое состояние всех портов следующее.
Обращаем внимание на поля ActorKey. Они должны быть одинаковыми на всех портах каждой стороны канала (одинаковы на всех портах коммутатора :d0 и на всех портах коммутатора :40). Это придает коммутаторам уверенности в том, что если дистрибьютор отправит пакет в какой-то физический порт, на другой стороне он будет принят и отправлен в нужный коллектор, а значит не возникнет петель. Если же среди портов партнера возникает порт с другим значением поля Key, значит у соседа порт отнесен к другой канальной группе (другой PortChannel) и он должен быть удален из канала – ведущий коммутатор отключает в LACPDU на своем порту флаги Synchronization, Collecting и Distributing и прием/передача данных прекращается.
Но давайте прервем идиллическое сосуществование наших портов в LACP и отключим протокол на порту :42. Не, ну а чо он?!ТМ
MES2424(config)#interface gi0/2
MES2424(config-if)#no channel-group
Практически незамедлительно начинаем наблюдать такую картину в Wireshark: порт :42 сначала отвечает на LACPDDU порта :d2 полным набором флагов, а затем высылает серию из трех сообщений: в первом он сообщает от отключении дистрибьютора, во втором об отключении коллектора, а в третьем – об отключении синхронизации. Выглядит это примерно вот так:
После этого :d2, как сознательный активный порт продолжает высылать LACPDU, но не получает на них никакого ответа. При этом порты :d1 и :41 обмениваются LACPDU без каких-либо помех.
В итоге, насмотревшись на мучения :d2, автор решил снова включить LACP на порту Gi/0/2 коммутатора MES2424 (:42).
MES2424(config-if)#channel-group 1 mode passive
Кстати, а что будет, если на одном коммутаторе в одной канальной группе сконфигурировать порты с разными ролями LACP, например один порт active, а другой passive? Вроде же, ничего не мешает? Оставляю вас с этим вопросом, ответ дам в конце статьи.
После получения LACPDU от соседа, порт :42 ответил на LACPDU сообщением без единого флага кроме флага Aggregation.
А потом сразу же выслал три сообщения: сначала о синхронизации, затем о подключении коллектора, а затем о подключении дистрибьютора, таким образом подключив порт Gi0/2 к общему логическому каналу.
На этом я, пожалуй, закончу наше сегодняшнее повествование про LACP, которое получилось возможно даже излишне подробным. Но надеюсь, такой разбор полетов будет полезен, особенно при конфигурации разных там MLAGов и прочих вещей, требующих LACP.
P.S. Ну а теперь ответ на вопрос про разные режимы портов в одной канальной группе: не знаю как там у кого еще, у Eltex такое произойти не может, коммутатор предупредит, что в существующей канальной группе порты уже в определенном режиме и отклоняться от генеральной линии партии не рекомендуется.