Содержание

VLAN - Коммутация фреймов

Для общего понимания, что такое VLAN и зачем нужен, желательно ознакомиться заранее по источникам в сети. Например по данной статье - MOXA - ТЕХНОЛОГИЯ VLAN. Здесь рассмотрим лишь аспекты реализации связанные с 1923КХ028.

Самое основное:

  1. Разбиение абонентов одной сети на принадлежность к различным VLAN сетям необходима чтобы Широковещательные фреймы ходили только в пределах своей VLAN сети. Абоненты из разных сетей VLAN изолированы друг от друга, потому что коммутатор пересылает сообщения от порта с заданным VLAN_ID, только портам с таким же VLAN_ID.
  2. В случае НЕ широковещательных фреймов, коммутация осуществляется по МАС источника и МАС назначения, что само по себе дает локализацию такого трафика между двумя абонентами. Но если МАС таблицы еще не обучены, и не знают в каком порту находится МАС назначения, то трафик рассылается всем портам у которых VLAN_ID такой же, как у порта принявшего фрейм.
  3. тегированный VLAN трафик обычно ходит лишь между коммутаторами. Устройства подключенные к коммутаторам ничего про VLAN не знают, они общаются обычным не тегированным трафиком. Т.е. сегментирование сети на виртуальные подсети (Virtual Local Area Network) происходит за счет настройки портов коммутаторов.

Коммутация пакетов в коммутаторе 1923КХ028 является VLAN-Based (Бывает еще Port-Based). Т.е. для маршрутизации фрейма ему присваивается VLAN таг, даже если фрейм пришел нетегированый. Для этого, когда какой-либо из портов микросхемы принимает нетегированный фрейм, то этому фрейму присваивается тег данного порта. Тег не вставляется непосредственно в тело пакета, а хранится где-то в заголовке принятого фрейма.

Далее пакет с тегом маршрутизируется согласно таблицам МАС и VLAN и рассылается на необходимые порты. Если порт назначения подключен к РС, принтеру или другому обычному абоненту, то фрейм уходит без тега. Если же порт назначения является TRUNC портом, т.е. портом подключенным к другому VLAN коммутатору, то необходимо передать тег в теле пакета. Это необходимо, т.к. абонент назначения подсети VLAN может находится на портах этого соседнего коммутатора.

Настройки портов 1923КХ028

Настроки для каждого из 16-ти портов 1923КХ029 хранятся в паре регистров классификатора PORT0_STRUC1/PORT0_STRUC2, PORT1_STRUC1/PORT1_STRUC2, и т.д. Последняя пара PORT16_STRUC1/PORT16_STRUC2 относится к порту Хоста, т.е. для классификатора Хост является 17-м портом. Биты настройки портов в данных регистрах следующие:

PORTх_STRUC1:

PORTх_STRUC2:

Жирным шрифтом выделены основные параметры, необходимые для настройки портов для реализации сетей VLAN.

Прохождение пакетов с настройками по умолчанию

Рассмотрим настройку коммутатора, когда он не разделяет общую сеть на подсети. Т.е. абоненты на всех портах находятся в одной VLAN сети. Из-за того, что VLAN_ID на всех портах одинаков, то коммутатор будет работать как будто никаких VLAN нет. Следовательно и настройка будет максимально простой, все порты настраиваются одинаково.

Поскольку коммутатор является VLAN-based, то какой-то общий VLAN_ID всем портам задать необходимо. Таким значением VLAN_ID по умолчанию является 1. (Cisco использует VLAN 1 как default VLAN, и management протоколы (STP, CDP, DTP, etc) используют VLAN 1.)

Рассмотрим этапы прохождения фрейма между двумя портами в настройках по умолчанию:

Пояснения:

  1. Компьютер А с МАС адресом МАС_А посылает фрейм, допустим компьютеру В с МАС адресом МАС_В.
  2. Фрейм от компьютера нетегированый, поэтому Port_1 при приеме фрейма присваивает ему свой VLAN_ID. Внутри коммутатора фрейм маршрутизируется с тегом VLAN_ID = 1.
  3. Поиск по таблице МАС показывает, что МАС_А еще не известен коммутатору. Т.е. это первый пакет пришедший с данного порта, поэтому требуется обучение МАС таблицы.
  4. Фрейм отправляется в порт, бит которого указан в регистрах классификатора CLASS_NPU_CTRL[7..0]/CLASS_NPU_CTRL1[11..0], это маска PUNT_PORT. Только один бит может быть установлен! Если хостом является РС, подключенный через PCI-Express, то для посылки в него фрейма используется Port16 и PUNT_PORT необходимо выставить в 0x10000.
  5. Далее драйвер в Linux обработает запрос и добавит запись в таблицу МАС, где укажет на каком порте коммутатора находится адрес МАС_А и к какой сети VLAN он принадлежит.
  6. В итоге, фрейм коммутатором никуда не пересылается. Он "тратится" на обучение таблицы МАС. Но хост при обучении может самостоятельно переслать фрейм по необходимым портам, тогда фрейм не потеряется.

Стоит отметить, что при попытке поменять PUNT_PORT на другое значение, ничего не меняется. Скорее всего 16-й порт задан по умолчанию, и в любом случае посылка фрейма на хост назначается на этот порт. Перенаправить фрейм на любой другой Ethernet порт можно настройкой блока TMU. Например, если в регистр TMU_PHY16_INQ_ADDR прописать (AXI_EGPI4_BASE_ADDR | AXI_GPI_INQ_PKTPTR) то все, что микросхема посылает в 16-й порт, будет уходить в 3-й порт (нумерация с 0). Абонент на 3-м порту получит фрейм на обучение с некоторым служебным заголовком. Но важно чтобы этот абонент был подключен к 1923КХ028 так-же и по SPI. Тогда он сможет обучить таблицу МАС через доступ по SPI. Для этого коммутатор должен работать в режиме MODE 2 (Slave SPI).

Пояснения:

  1. Компьютер А не получил ответа от компьютера B, и через некоторое время снова посылает пакет. При приеме фрейму присваивается тег порта VLANID 1.
  2. Классификатор коммутатора находит запись что MAC_A (Source MAC) находится в VLAN сети 1. Но не находит записей об MAC_B (Destination MAC). Поэтому он обращается в таблицу VLAN.
  3. В таблице VLAN указано, что фреймы с тегом VLANID = 1 должны пересылаться в порты заданные маской ForwList = 0xFFFF. Т.е. это все порты ethernet коммутатора. Далее из таблицы извлекается действие из поля UnicastMiss, оно показывает что делать с Unicast фреймом, если для него не нашлось записи в таблице МАС. (Остальные поля таблицы VLAN и возможные действия описаны тут - VLAN Table.) По умолчанию все действия в таблице прописываются драйвером как ACT_FORWARD. Т.е. фрейм будет переслан на все порты в маске ForwList для VLAN_ID 1.
  4. Фрейм пересылается на все порты, кроме того, откуда пришел данный фрейм. Тег снимается, потому что тег фрейма равен фрейму порта.
  5. Теперь компьютер В получает фрейм от компьютера А и сможет послать ответ.

Но первый ответ от РС_В снова будет истрачен на обучение, т.к. MAC_B нет в таблице МАС коммутатора! Поэтому, если ПО хотса не сделает пересылку фрейма, то он пропадет. Короче, поведение будет точно такое-же как при обучении пакета от РС_А.

Когда все МАС адреса и порты известны, то общение между PC_A и PC_B идет напрямую:

Пояснения:

  1. РС_В посылает фрейм, он при приеме тегируется VLAN_ID 1.
  2. В МАС таблице есть записи для МАС адресов источника и назначения.
  3. Оба абонента находятся в одной VLAN_ID 1, поэтому фрейм пересылается в Port0 для РС_А. Тег при выдаче снимается, т.к. тег фрейма равен фрейму порта.

Важно отметить, что при выдаче из порта, если тег фрейма не равен тегу порта, то фрейм уходит с тегом фрейма! Именно по этой причине настройка по умолчанию AFT (AcceptFrameType) выставлена в AnyTagged. Т.е. во всех рисунках выше, если бы входной фрейм был тегированый, то он так бы и был передан на остальные порты тегированым. Это важно, если порты коммутатора подключены не к компьютерам, а к TRUNK портам коммутаторов. Поскольку требуется переслать тегированный трафик так, как он есть. В итоге, VLAN_ID в таблицу МАС маршрутизации заносятся:

Но для того, чтобы коммутатор был прозрачным для VLAN тегированного трафика, необходимо либо при обучении МАС обновлять и таблицу VLAN, либо разрешить глобальную настройку пересылки тегированных фреймов в регистрах CLASS_GLOBAL_CFG и CLASS_GLOBAL_CFG1. Эти регистры содержат все необходимые поля, что есть в таблице VLAN, кроме самого поля VLAN_ID. Поскольку настройки этих регистров относится для VLAN_ID, для которых нет записей в таблице VLAN.

Пояснения:

Разделение сети на несколько VLAN

В расмотренных выше случаях, все порты коммутатора имели одинаковые настройки, т.е. находились в одной сети. Давайте теперь выделим два порта в отдельную сеть с помощью VLAN. Пусть это будут Port0 и Port1, идентификатор сети VLAN_ID зададим 100. Эти порты будут работать в режиме ACCESS, т.е. должны общаться со всеми другими портами, у который такой-же VLAN_ID 100. В итоге в свиче у нас получилось две сети:

  1. сеть с VLAN_ID 100 на портах 0 и 1.
  2. сеть с VLAN_ID по умолчанию 1 на всех остальных портах.

Допустим далее, что сеть у нас состоит не из одного свича, а из двух. И два абонента на втором свиче так-же должны быть в сети с VLAN_ID 100. Поэтому необходим TRUNK порт, который мог бы связать две сети в двух свичах между собой. В отличие от ACCESS порта, TRUNK порт пропускает сквозь себя покеты с любым VLAN_ID. Пусть TRUNK портами будут:

Необходимая настройка:

  1. В таблицы VLAN свичей добавляем запись:
    • VID (VLAN_ID) = 100, для обоих свичей
    • Switch1.ForwList = 0x8003, маска портов входящих в сеть VLAN 100 и Trunk портов.
      • 0x8000 - Маска Trunk порта Port15. Сюда пересылаются пакеты для отправки в switch1, если МАС адрес фрейма назначения не находится в данном свиче.
      • 0x1, 0x2 - Маска Port0 и Port1, только между этими портами и Trunk портом могут проходить пакеты VLAN_ID 100.
    • Switch1.UntagList = 0x0003. Маска портов для которых принудительно снимать тег при посылке фреймов абонету. Для Trunk порта снимать тег не нужно, бит остается нулевым!
    • Switch2.ForwList = 0x8003
      • 0х0001 - Маска Trunk порта Port0
      • 0х8002 - маска портов входящих в сеть VLAN 100
    • Switch2.UntagList = 0x8002. Маска портов входящих в сеть VLAN 100 (без TRUNK портов)
  2. Настройка Access портов на обоих коммутаторах: Switch1 Ports [0,1], Switch2 Ports [1,15]
    • VID = 100, теперь абонент на порте входит в состав подсети VLAN 100
    • AFT = UntaggedOnly. Access порты обмениваются только нетегированым трафиком. Если придет тегированый фрейм, то он будет отброшен.
    • UntagFromBTable (UNT_TBL) - принудительное снятие тега в исходящем фрейме согласно флагу порта в маске UntagList в VLAN таблице (для VLAN 100). Как уже было описано выше, по умолчанию при UNT_TBL = 0, в исходящем фрейме будет удален тег только если тег в фрейме совпадает с тегом порта. И если вдруг случится что на выход из порта придет фрейм с тегом, отличным от тега порта, то такой фрейм выйдет тегированным. Чего на Access порте быть не должно! Флаг UNT_TBL = 1 и маска в VLAN_Table.UntagList гарантируют что тег в исходящем фрейме будет удален в любом случае.
  3. В VLAN таблицах коммутаторов для дефолтного VLAN_ID 1 необходимо исключить из маски ForwardList биты портов, которые мы выделили в отдельную сеть VLAN_ID 100. Иначе фреймы с данных портов будут рассылаться на порты VLAN 100, причем тегированные, т.к. тег фрейма 1 не снимется выходя из порта 100, а UntagList для VLAN_ID 1 у нас настроен в 0. (см предыдущую главу)

Тегированый трафик через VLAN Trunk порт

Итак, рассмотрим ситуацию когда абонент нашей новой сети посылает широковещательный фрейм:

Пояснения:

Таким образом, настройки коммутаторов позволяют разделить абонентов одной сети на подсети с помощью тегов VLAN. В общем и целом, поскольку абоненты не получают тегированый трафик, то они даже не знают что разделены на какие-то подсети. Точнее сказать, абоненты не знают, что есть кто-то еще за пределами их подсети. Разделение позволяет локализовать широковещательный трафик и не позволяет ему "расползаться" по всей сети.

Нетегированый трафик через VLAN Trunk порт

Согласно ссылки на производителя MOXA в начале статьи, TRUNK порты могут обмениваться и нетегированым трафиком. Представим, что в рассмотренном только что примере, абонент на PORT4, который остался в дефолтной подсети 1, посылает свой фрейм. Посмотрим как это происходит:

Пояснения:

Только тегированый трафик через VLAN Trunk порт

Если есть необходимость организовать только тегированый трафик через TRUNK порты, то это можно реализовать следующей настройкой (выделено красным):

Пояснения:

Вот и все отличия от предыдущего режима с нетегировнным трафиком между TRUNK портами.

Приватный VLAN (PVLAN)

Признаться, у меня пока не сложилось ясного представления о преимуществах PVLAN и как их использовать. На мой взгляд, PVLAN позволяет выделить отдельный порт в коммутаторе, который будет выступать как провайдер или выделенная точка доступа к внешнему роутеру/серверу для остальных портов коммутатора разбитых на группы. Т.е. абоненты этих групп портов взаимодействуют с внешним миром через выделенный порт - точку доступа.

В общем случае, таких выделенных портов может быть несколько, чтобы их разделить использутся VLAN теги, которые называются Primary. В качестве примера можно представить что один порт коммутатора подключен к провайдеру интернета и трафик через этот порт тегируется тегом 10, а второй порт подключен к другому провайдеру и его трафик тегируется тегом 20. Остальные порты нужно распределить по провайдерам. Получаем, что Primary VLAN поделил порты коммутатора на первичные подсети.

Как мы уже знаем, трафик в отдельных VLAN не смешивается, поэтому за тарификацию провайдеры могут не беспокоится. :)

Выделенный порт, который коммутирует трафик от провайдера на остальные порты в своей Primary подсети, называется Promiscuous. Promiscuous переводят как неразборчивый или смешанный. Это связано с тем, что Promiscuous порт может обмениваться трафиком с любым из портов в своей подсети, не зависимо от режима работы этих портов.

Далее, порты каждого их первичных VLAN можно разбить на отдельные подсети, ограничив их взаимодействие друг с другом. Такие подсети организуются так-же за счет присвоения VLAN тегов портам, и называются они Secondary. Получаем как-бы, Secondary VLAN сети внутри Primary VLAN сети:

Для упрощения, на картинке показано только разбиение Primary VLAN 10. Primary VLAN 20 разбивается аналогично любым способом.

Порты входящие в secondary сети могут быть настроены в трех режимах :

Стоит отметить, что в спецификации достаточно хорошо изложена глава 13 - "Приватный VLAN". Рассказано зачем это надо и как настроить, поэтому перейдем сразу к поясняющим прохождение трафика картинкам.

Isolated Broadcast PVLAN трафик

Необходимо подчеркнуть, что каждый порт, входящий в Secondary VLAN иденти идентифицируется двумя VLAN_ID:

  1. Primary VLAN_ID - это VID Primary сети к которой принадлежит Secondary сеть. Данный параметр сохраняется в управляющем ПО и используется при обучении таблиц маршрутизации.
  2. Secondary VLAN_ID - это VID Secondary сети, к которой принадлежит порт. Это значение прописывается в регистры настройки порта в поле VID. И так-же используется в ПО при обучении.

Согласно спецификации, когда новый фрейм поступает на обучение, то ПО записывает в таблицу маршрутизации следующие записи:

Если порт Isolated:

MAC VID ForwList Action
МАС абонента Secondary[port] Маска порта Отбросить
МАС абонента Primary Маска порта Переслать

Secondary[port] - это VID порта принявшего пакет. Для изолированного порта запрещаются пересылки в порт фреймов с VID порта, поэтому прописано действие - Отбросить (ACT_DISCARD). Это нужно на тот случай, если соседний абонент, с таким же VID, каким-то образом узнал МАС адрес нашего порта и послал фрейм с нашим МАС адресом. По умочанию, МАС таблица по совпадению МАС адреса назначения и VID послала бы фрейм в изолированый порт, чего допустить нельзя. Поэтому такие фреймы отбрасываются.

Вторая запись, это разрешение пересылать в изолированный порт фреймы от провайдера.

Если порт Community:

MAC VID ForwList Action
МАС абонента Secondary[port] Маска порта Переслать
МАС абонента Primary Маска порта Переслать

Здесь в отличие от изолированного порта разрешается перенаправлять абоненту фреймы от соседей с таким же VLAN_ID.

Если порт Promiscuous:

MAC VID ForwList Action
МАС абонента Primary Маска порта Переслать
МАС абонента Secondary[0] Маска порта Переслать
МАС абонента Secondary[n] Маска порта Переслать

Тут, первая запись разрешает перенаправлять провайдеру фреймы от соседей с таким же Primary VLAN_ID. Которые могут быть в соседнем коммутаторе, см картинки ниже. А остальные записи разрешают перенаправление абоненту фреймов от всех Secondary подсетей данного Primary VLAN. n - это количество Secondary VLAN в Primary VLAN.

Для прохождения широковещательного трафика необходимо прописать маски ForwardList и UntagList в таблицу VLAN. Маски UntagList нужны чтобы теги, присваиваемые на входе и с которым фрейм коммутируется внутри свича, снимались при выходе фрейма в порт назначения.

Рассмотрим широковещательный трафик, исходящий из изолированного порта. Предположим что таблицы у нас уже обучены ранее. Т.е. рассмотрим почему и как фрейм проходит коммутатор:

Пояснения по посылке запроса:

Пояснения по получению ответа:

Путь ответа явялется уже Unicast потому что идет по двум известным адресам. Если смотреть Broadcast от севера, то он пройдет во все порты, потому что в ForwardList порта Promiscuous как раз указаны все порты для Primary VLAN_ID.

Isolated Unicast PVLAN трафик

Для наглядности разрисуем Unicast трафик от РС_А. Здесь все стандартно идет через таблицы МАС. На картинке лишь уточнено какая запись в МАС таблице за что отвечает.