Содержание

Errata_0003: Снятие и вставка VLAN тега при активном бите FRESH

Для понимания изложенного ниже рекомендуется предварительно ознакомиться с заметками "VLAN - Коммутация фреймов" и с таблицами МАС и VLAN из "Спецификация - Описание принципа работы".

Каждая запись в МАС таблице имеет бит Fresh. Этот бит Fresh логичнее воспринимать как NoFresh, т.к. наличие бита означает, что запись довольно старая и будет удалена при следующем запуске обработчика старения. Запуск проверки устаревания запускается раз в несколько минут.

Если запись в таблице МАС имеет активный бит Fresh, то фрейм, помимо ретрансляции на порт назначения, посылается на хост с признаком PUNT_SA_IS_ACTIVE. Программное обеспечение (ПО) хоста должно снять бит Fresh - это означает что запись свежая, т.к. пришел свежий фрейм от абонента. Когда абонент долго не посылает фрейм, то ПО, отрабатывающее старение, сначала выставляет бит Fresh, а при следующем проходе удаляет запись из МАС таблицы если бит Fresh не был сброшен пришедшим фреймом.

Оказалось, что когда фрейм отсылается на хост из-за активного бита Fresh и одновременно рассылается по таблицам маршрутизации, то при его выдаче в порты не происходит изменение содержимого фрейма, т.е. не работает вставка / удаление тега VLAN в теле фрейма. Фрейм передается в исходном состоянии, даже если VLAN модификация назначена для порта выдачи.

Проверку ошибки удобно провести с использованием отладочной платы для 1986ВЕ3Т. Микроконтроллер 1986ВЕ3Т, как плата под него, имеет два Ethernet контроллера и можно в программе одним контроллером послать фрейм в коммутатор 1923КХ028, а вторым контроллером принять пересланный фрейм из коммутатора.

Программа микроконтроллера должна уметь:

Правильность формирования VLAN фреймов желательно проверить, например сниффером Wireshark:

Для подключения к плате 1986ВЕ3Т настраиваем два порта коммутатора с расными тегами:

Здесь ETH_A, это контроллер ETHERNET_1 на плате 1989ВЕ3Т. Название ETH_A более удобно для отслеживания в логах, т.к. МАС адрес этого контроллера начинается 00:AA:33:44:55:66 (так мы назначили в тестовом ПО). Название ETH_В, это контроллер ETHERNET_2, с МАС адресом 00:BB:56:78:9A:BC.

Для каждого контроллера, кнопками на плате мы выбираем формат посылаемого фрейма:

По кнопкам осуществляется и передача фрейма ETH_A → ETH_B, или ETH_B → ETH_A. Данные по настройкам, длине и содержимом фрейма выводятся в логи показанные ниже.

Записи в МАС таблице будут появляться автоматически при получении фреймов коммутатором, т.е. алгоритм обучения будет работать почти штатно, с тем отличием, что

(В прошивке под коммутатор принудительное выставление Fresh при обучении включается битом ERR03_CHECK__FRESH_FORCED в файле MDR_1923KX028_Config.h.)

Функционал старения записей выключен, чтобы записи в МАС таблице не исчезали. Кроме этого необходимо настроить VLAN таблицу так, чтобы любые фреймы пересылались между обоими портами коммутатора, хотя они и имеют разные VLAN_ID. Оба порта должны быть в списке ForwardList, для обоих записей VLAN_ID (0x100, 0x200). Для проверки режима снятия тега, необходимо оба порта прописать в список UntagList и выставить для них бит UntagFromBTable в настройках портов.

Ниже, на принтскринах, наглядно отображены:

Вставка тега

Вставка тега необходима, когда нетегированный фрейм, полученный ACCESS портом VLAN сети, передается в TRUNK порт для передачи в соседний коммутатор. Наличие тега в фрейме показывает соседнему коммутатору к какой VLAN сети принадлежит фрейм.

Если запись в МАС таблице для принятого фрейма имеет активный бит FRESH, то вставка тега не происходит - это ошибочное поведение.

Правильное поведение

Нетегировнный фрейм приходит на порт 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, то снятие тега не происходит - это ошибочное поведение.

Правильное поведение

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

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, посылающий порт НЕ удаляет в выходном фрейме тег, совпадающий с тегом порта отправления. Фрейм передается без изменений.