======Errata_0003: Снятие и вставка VLAN тега при активном бите FRESH====== Для понимания изложенного ниже рекомендуется предварительно ознакомиться с заметками [[DOC:MK:1923KX028:vlan|"VLAN - Коммутация фреймов"]] и с таблицами МАС и VLAN из [[DOC:MK:1923KX028:manual|"Спецификация - Описание принципа работы"]]. Каждая запись в МАС таблице имеет бит Fresh. Этот бит Fresh логичнее воспринимать как NoFresh, т.к. наличие бита означает, что запись довольно старая и будет удалена при следующем запуске обработчика старения. Запуск проверки устаревания запускается раз в несколько минут. Если запись в таблице МАС имеет активный бит Fresh, то фрейм, помимо ретрансляции на порт назначения, посылается на хост с признаком PUNT_SA_IS_ACTIVE. Программное обеспечение (ПО) хоста должно снять бит Fresh - это означает что запись свежая, т.к. пришел свежий фрейм от абонента. Когда абонент долго не посылает фрейм, то ПО, отрабатывающее старение, сначала выставляет бит Fresh, а при следующем проходе удаляет запись из МАС таблицы если бит Fresh не был сброшен пришедшим фреймом. Оказалось, что когда фрейм отсылается на хост из-за активного бита Fresh и одновременно рассылается по таблицам маршрутизации, то при его выдаче в порты не происходит изменение содержимого фрейма, т.е. не работает вставка / удаление тега VLAN в теле фрейма. Фрейм передается в исходном состоянии, даже если VLAN модификация назначена для порта выдачи. Проверку ошибки удобно провести с использованием отладочной платы для 1986ВЕ3Т. Микроконтроллер 1986ВЕ3Т, как плата под него, имеет два Ethernet контроллера и можно в программе одним контроллером послать фрейм в коммутатор 1923КХ028, а вторым контроллером принять пересланный фрейм из коммутатора. Программа микроконтроллера должна уметь: * посылать нетегированные фреймы, для того чтобы коммутатор вставлял туда тег при пересылке. * тегированные фреймы, чтобы коммутатор удалял из них фреймы при пересылке. Правильность формирования VLAN фреймов желательно проверить, например сниффером Wireshark: {{doc:mk:1923kx028:wiresharkvlan.png}} Для подключения к плате 1986ВЕ3Т настраиваем два порта коммутатора с расными тегами: * KX028.Port_2 имеет VLAN тег 0x100 и подключен кабелем к ETH_A порту отладочной платы 1989ВЕ3Т * KX028.Port_3 имеет VLAN тег 0x200 и подключен кабелем к ETH_B порту отладочной платы 1989ВЕ3Т Здесь ETH_A, это контроллер ETHERNET_1 на плате 1989ВЕ3Т. Название ETH_A более удобно для отслеживания в логах, т.к. МАС адрес этого контроллера начинается 00:AA:33:44:55:66 (так мы назначили в тестовом ПО). Название ETH_В, это контроллер ETHERNET_2, с МАС адресом 00:BB:56:78:9A:BC. Для каждого контроллера, кнопками на плате мы выбираем формат посылаемого фрейма: * без тега * VLAN_ID 0x100 (256) * VLAN_ID 0x200 (512) По кнопкам осуществляется и передача фрейма ETH_A -> ETH_B, или ETH_B -> ETH_A. Данные по настройкам, длине и содержимом фрейма выводятся в логи показанные ниже. Записи в МАС таблице будут появляться автоматически при получении фреймов коммутатором, т.е. алгоритм обучения будет работать почти штатно, с тем отличием, что * при проверке ошибочного поведения, записи будут добавляться сразу с активным битом Fresh. * при проверке правильного поведения алгоритм обучения работает штатно - бит Fresh принудительно не выставляется. //(В прошивке под коммутатор принудительное выставление Fresh при обучении включается битом ERR03_CHECK__FRESH_FORCED в файле MDR_1923KX028_Config.h.)// Функционал старения записей выключен, чтобы записи в МАС таблице не исчезали. Кроме этого необходимо настроить VLAN таблицу так, чтобы любые фреймы пересылались между обоими портами коммутатора, хотя они и имеют разные VLAN_ID. Оба порта должны быть в списке ForwardList, для обоих записей VLAN_ID (0x100, 0x200). Для проверки режима снятия тега, необходимо оба порта прописать в список UntagList и выставить для них бит UntagFromBTable в настройках портов. Ниже, на принтскринах, наглядно отображены: * настройки таблиц коммутации коммутатора 1923КХ028 для случаев с активным битом Fresh * Логи из программы 1986ВЕ3Т, которая посылает и принимает фреймы. По этим логам можно видеть, как VLAN тег вставляется / удаляется из фрейма проходящего через коммутатор. =====Вставка тега ===== Вставка тега необходима, когда нетегированный фрейм, полученный ACCESS портом VLAN сети, передается в TRUNK порт для передачи в соседний коммутатор. Наличие тега в фрейме показывает соседнему коммутатору к какой VLAN сети принадлежит фрейм. Если запись в МАС таблице для принятого фрейма имеет активный бит FRESH, то вставка тега не происходит - это ошибочное поведение. {{doc:mk:1923kx028:kx028_errata003_tag.png}} ====Правильное поведение==== Нетегировнный фрейм приходит на порт EMAC2 или EMAC3, при этом тегируется тегом порта_RX. При пересылке в порт назначения, тег фрейма (порта_RX) не совпадает с тегом порта_TX и поэтому при выдаче в фрейм вставляется тег порта_RX. ETH_A: NO TAG // Оба Ethernet контроллера 1986ВЕ3Т посылают фреймы без тега! ETH_B: NO TAG Send ETH_A -> ETH_B // Обучается запись МАС_А Send ETH_B -> ETH_A // Обучается запись МАС_В Send ETH_A -> ETH_B // Пересылается нетегированный фрейм из МАС_А в МАС_В >! FAULT: Frames Len Mismuch, TX: 64 RX: 68 // Длина посланного и принятого фрейма отличается на VLAN Tag >! FAULT: Frame Data Comparison! // В пакет вставлен VLAN_ID порта A(0x100) > TX[64]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 > RX[68]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x81 0x00 0x01 0x00 - VLAN_ID (0x100) 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 Send ETH_B -> ETH_A // Пересылается нетегированный фрейм из МАС_А в МАС_В >! FAULT: Frames Len Mismuch, TX: 64 RX: 68 // Длина посланного и принятого фрейма отличается на VLAN Tag >! FAULT: Frame Data Comparison! // В пакет вставлен VLAN_ID порта B(0x200) > TX[64]: 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 > RX[68]: 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x81 0x00 0x02 0x00 - VLAN_ID (0x200) 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 Как видно, коммутатор работает правильно. При выключенном бите FRESH, посылающий порт вставляет в выходной фрейм тег порта, который принял данный фрейм. ====Неправильное поведение==== **ERRATA_0003: При установленном бите Fresh в таблице для МАС адреса источника, в пересылаемый фрейм не вставляется VLAN тег и фрейм транслируется в исходном состоянии.** ETH_A: NO TAG // Оба Ethernet контроллера 1986ВЕ3Т посылают фреймы без тега! ETH_B: NO TAG Send ETH_A -> ETH_B // Обучается запись МАС_А Send ETH_B -> ETH_A // Обучается запись МАС_В Send ETH_A -> ETH_B // Пересылается нетегированный фрейм из МАС_А в МАС_В > OK: Frames Length! // Длина фреймов совпала > OK: Frame Data Comparison! // Данные совпадают - VLAN тег не вставился! > TX[64]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 > RX[64]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 Send ETH_B -> ETH_A > OK: Frames Length! > OK: Frame Data Comparison! > TX[64]: 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 > RX[64]: 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 Как видно, коммутатор работает неправильно. При включенном бите FRESH, посылающий порт НЕ вставляет в выходной фрейм тег порта, который принял данный фрейм. Фрейм передается без изменений. =====Снятие тега ===== Снятие тега необходимо, когда тегированный фрейм от TRUNK порта соседнего коммутатора был принят и передается на ACCESS порт. Ведь абонент коммутатора должен получать нетегированный трафик, т.к. VLAN разбиение на подсети происходит только за счет настроек коммутаторов. Если запись в МАС таблице для принятого фрейма имеет активный бит FRESH, то снятие тега не происходит - это ошибочное поведение. {{doc:mk:1923kx028:kx028_errata003_untag.png}} ====Правильное поведение==== Тегированный фрейм обрабатывается со своим тегом, а не с тегом прининявшего его порта. При пересылке в порт назначения, если тег фрейма совпадает с фреймом порта, то тег удаляется из фрейма и фрейм уходит нетегированный. ETH_A: TAG_200 // ETH_A будет посылать фреймы с тегом порта, подключенного к ETH_B (KX028.Port_3) ETH_B: TAG_100 // ETH_B будет посылать фреймы с тегом порта, подключенного к ETH_А (KX028.Port_2) Send ETH_A -> ETH_B // Обучается запись МАС_А Send ETH_B -> ETH_A // Обучается запись МАС_В Send ETH_A -> ETH_B // Пересылается тегированный фрейм из МАС_А в МАС_В >! FAULT: Frames Len Mismuch, TX: 68 RX: 64 // Принятый фрейм короче исходного на длину VLAN Tag >! FAULT: Frame Data Comparison! // 1923КХ028 удалил VLAN Tag из фрейма при пересылке > TX[68]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x81 0x00 0x02 0x00 - VLAN_ID (0x200) 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 > RX[64]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 Как видно по логу, коммутатор работает правильно. При выключенном бите FRESH, посылающий порт удаляет в выходном фрейме тег, совпадающий с тегом порта отправления. ====Неправильное поведение==== **ERRATA_0003: При установленном бите Fresh в таблице для МАС адреса источника, в пересылаемом фрейме не удаляется VLAN тег и фрейм транслируется в исходном состоянии.** ETH_A: TAG_200 // ETH_A будет посылать фреймы с тегом порта, подключенного к ETH_B (KX028.Port_3) ETH_B: TAG_100 // ETH_B будет посылать фреймы с тегом порта, подключенного к ETH_А (KX028.Port_2) Send ETH_A -> ETH_B // Обучается запись МАС_А Send ETH_B -> ETH_A // Обучается запись МАС_В Send ETH_A -> ETH_B // Пересылается тегированный фрейм из МАС_А в МАС_В > OK: Frames Length! // Длина фреймов совпала > OK: Frame Data Comparison! // Данные совпадают - VLAN тег НЕ УДАЛЕН! > TX[68]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x81 0x00 0x02 0x00 - VLAN_ID (0x200) 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 > RX[68]: 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x00 0xAA 0x33 0x44 0x55 0x66 0x81 0x00 0x02 0x00 - VLAN_ID (0x200) 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 Send ETH_B -> ETH_A // Пересылается тегированный фрейм из МАС_В в МАС_А > OK: Frames Length! // Длина фреймов совпала > OK: Frame Data Comparison! // Данные совпадают - VLAN тег НЕ УДАЛЕН! > TX[68]: 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x81 0x00 0x01 0x00 - VLAN_ID (0x100) 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 > RX[68]: 0x00 0xAA 0x33 0x44 0x55 0x66 0x00 0xBB 0x56 0x78 0x9A 0xBC 0x81 0x00 0x01 0x00 - VLAN_ID (0x100) 0x00 0x32 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 Как видно по логу, коммутатор работает неправильно. При выключенном бите FRESH, посылающий порт НЕ удаляет в выходном фрейме тег, совпадающий с тегом порта отправления. Фрейм передается без изменений.