Привет, Хабр! Возвращаюсь с продолжением нашей детективной истории про Петра, у которого не загружались картинки с котиками. В прошлом тексте, ссылку на который вы найдете в статье, мы выяснили, что проблема скрывается в коммутаторе. Теперь мы с вами погрузимся в глубь его программного устройства и будем по одному отметать версии о подозреваемых источниках проблем.
Когда введен десяток команд, сложно сказать, какая из них повлияла на прохождение трафика. Поэтому мы начнем вводить команды по одной и проверять правильность конфигурации. Так и поступим: «занулим» конфигурацию и будем контролировать выполнение команды на разных уровнях коммутатора.
Настраиваем L3-интерфейс
Для каждого действия я буду указывать уровень погружения внутрь коммутатора. Напомню их сверху вниз: CLI, Linux, SAI, SDK. И картинка из первой части — для освежения памяти.
Уровень CLI
Введем команду на создание L3-интерфейса:
switch1# configure terminal
switch1(config)# interface Ethernet 1
switch1(conf-if-Ethernet1)# ip address 10.1.1.1/24
И проверим direct-connected маршрут:
switch1# show ip route
Destination Gateway Interface Dist/Metric Uptime
------------------------------------------------------------------------------------------------------------
C>* 10.1.1.0/24 Direct Ethernet1 0/0 00:07
Посмотрим, как конфигурация зашла на Linux.
Уровень Linux
У нас есть интерфейс с IP- и MAC-адресами.
# ip a show Ethernet1
Ethernet1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9100 qdisc fq_codel state UP group default qlen 1000
link/ether 98:19:2c:9b:58:49 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.1/24 brd 10.1.1.255 scope global Ethernet1
Еще у интерфейса есть direct-connected маршрут.
# ip route list
10.1.1.0/24 dev Ethernet1 proto kernel scope link src 10.1.1.1
...
Как вы помните, конфигурация Linux и ASIC должна быть синхронизирована. Поэтому то же самое мы должны отправить через SAI в ASIC.
Если мир сетевого оборудования вам «абсолютно понятен», присоединяйтесь к нашей команде разработки коммутатора KORNFELD. Возможно, вас заинтересуют эти вакансии:
→ Сетевой инженер по автоматизации (Python)
→ Ведущий инженер группы аналитики и комплексного тестирования
Уровень SAI
Мы говорим коммутатору: «Создай, пожалуйста, в Virtual router интерфейс и добавь ему два маршрута. Если это маршрут с 32-й маской, то есть коммутатору, подними его на CPU-порт. А если это маршрут в «первую» сеть, отправь сразу на физический порт, не нужно поднимать его на CPU».
Уровень ASIC
Чтобы следующая часть была понятнее , нужно немного прояснить внутреннее устройство портов коммутатора. У каждого физического порта в ASIC есть два конвейера (пайплайна):
Ingress — на прием пакетов.
Egress — на передачу пакетов.
Пакет попадает на порт, проходит через ingress-пайплайн, откуда попадает в routing или в switching. На выходе пакет проходит через egress-пайплайн:
Теперь вернемся к нашей конфигурации. Она состоит из нескольких частей, в числе которых:
L3-интерфейс, принадлежащий определенному VRF.
ingress-интерфейс, принадлежащий L3-интерфейсу.
egress-интерфейс, принадлежащий L3-интерфейсу.
Маршруты, доступные через определенные egress-интерфейсы. Маршруты также принадлежат определенному VRF.
По команде, которую мы передали через SAI, в ASIC был создан L3-интерфейс с номером 4097, в VRF по умолчанию. Важным параметром L3-интерфейса является src MAC-адрес, который будет выставлен пакету при отправке. L3 ingress-интерфейс использует этот MAC-адрес для проверки, что пакет предназначен именно этому устройству.
drivshell>l3 intf show
Unit Intf VRF Group VLAN Source MAC MTU TTL InnerVlan NATRealm
---------------------------------------------------------------------------------------------------------------------------
0 4096 -3 0 1 98:19:2c:9b:58:49 9100 0 0 0
0 4097 0 0 4095 98:19:2c:9b:58:49 9100 0 0 0
Внимательный читатель наверняка обратил внимание на служебный VLAN 4095, в который помещен интерфейс. Выделение в служебный предотвратит «переливание» маршрутизируемого трафика во VLAN, созданный на коммутаторе.
С L3-интерфейсом 4097 связан ingress-интерфейс с номером 16383, который в свою очередь привязан к физическому порту. Пакеты, поступающие на физический порт, будут попадать на ingress-интерфейс 16383, а через него — на L3-интерфейс.
Дальше создадим egress-интерфейс для CPU с номером 132769. Egress-интерфейс тоже привязан к физическому порту, и все, что уходит через него, обязательно будет передано через физический порт. Функции, выполняемые выходным конвейером, иногда называют «последним приготовлением пакета перед отправкой».
Поскольку мы говорим о маршрутизации, то при переходе в следующий сегмент Ethernet должны подмениться src и dst MAC-адреса. Dst MAC-адрес является параметром именно egress-интерфейса, изменение этого поля заголовка происходит в выходном конвейере. В листинге ниже, 98:19:2c:9b:58:49 является MAC-адресом Control Plane
drivshell>l3 egress show
Entry Mac Vlan INTF PORT MOD MPLS_LABEL ToCpu Drop Ref Count
132768 98:19:2c:9b:58:49 1 4096 0 0 -1 no yes 2 no
132769 98:19:2c:9b:58:49 0 16383 0 0 -1 no no 4 no
Далее, согласно нашей конфигурации, создаются два маршрута: с 32-й и 24-й масками.
Отмечу, что таблица маршрутизации поделена на две части:
fast routing — это все с 32-й маской.
routing — все с остальными масками, включая 24-ую.
Fast routing содержит маршруты с 32-й маской, фактически хосты, и их можно посмотреть с помощью SDK-команды l3table, представленной в листинге ниже. Можно привести аналогию с таблицей neighbors в Linux. В соответствии с механизмом longest prefix match, dst IP-адрес в пакете ищется сперва в fast routing. Если подходящая запись не найдена, поиск переходит в routing.
Таблица routing содержит адреса подсетей, их можно посмотреть SDK-командой defip, представленной в листинге ниже.
drivshell>l3 defip show
# VRF Net addr Next Hop Mac INTF MODID PORT PRIO CLASS HIT
8 0 10.1.1.0/24 00:00:00:00:00:00 132769 0 0 0 2 n
1 0 0.0.0.0/0 00:00:00:00:00:00 132768 0 0 0 0 n
drivshell>l3 l3table show
Entry VRF IP address Mac Address INTF MOD PORT CLASS HIT H/W Index
1 0 10.1.1.1 00:00:00:00:00:00 132769 0 0 1 n 3224
Оба маршрута смотрят на egress-интерфейс 132769, который связан с CPU-портом.
Это может показаться странным. Адрес 10.1.1.1 принадлежит самому коммутатору, и пакеты, которые содержат этот dst IP-адрес, должны передаваться через CPU-порт. Однако, так как у нас еще нет ни одного next-hop в сети 10.1.1.0/24, то весь трафик для этой сети мы поднимаем на CPU. Чтобы процессор разобрался, что делать с трафиком.
Конфигурация целиком. Посмотрим, как выглядит наша текущая конфигурация на схеме. Для удобства восприятия я нарисовал CPU-порт и слева, и справа, но это один и тот же порт. Трафик заходит в порт, проходит через ingress pipeline, заходит в routing и выходит через egress pipeline. Сейчас у нас сконфигурирован только CPU, поэтому все маршруты указывают на CPU-порт и весь трафик оказывается в пространстве ядра.
Интерфейс настроен, можем поставить первую галочку в списке необходимых для работы L3 вещей:
Интерфейс✅CoPP
Доступный next-hop
Маршрут
Отладка проблемы: настраиваем Control Place policing
Вроде бы пользовательский трафик Петра с фотографиями котиков должен начать ходить. Запустим ping от router1 до switch1:
switch1# ping 10.1.1.1
PING 10.1.1.1 (10.2.1.1) 56(84) bytes of data.
From 10.1.1.2 icmp_seq=1 Destination Host Unreachable
From 10.1.1.2 icmp_seq=2 Destination Host Unreachable
From 10.1.1.2 icmp_seq=3 Destination Host Unreachable
К сожалению, трафик по-прежнему не идет. Попробуем разобрать коммутатор еще глубже.
Как коммутатор обрабатывает пакеты
Посмотрим верхнеуровнево на архитектуру обработки пакетов в коммутаторе:
Сначала пакет попадает в ingress pipeline. Этот конвейер обрабатывает входящие пакеты. На этом этапе пакет может быть отброшен. Например, если адрес, указанный в заголовке пакета, попадает под запрещающие ACL-правила, то пакет дропается (на схеме это отмечено серым). Если все нормально, то при прохождении ingress pipeline к пакету добавляется метаинформация. Она содержит сведения про:
физический порт, с которого был принят пакет,
распарсенные заголовки,
VLAN, который будет обрабатывать пакет,
другую информацию, в зависимости от найстройки.
После входного контейнера пакеты попадают в Memory Management Unit (MMU). Эта память хранит все пакеты и по очереди отправляет их на egress pipeline.
В egress pipeline происходит маршрутизация и последние приготовления перед отправкой. На выходе пакету нужно переехать в другой сегмент Ethernet, то есть должен измениться его MAC-адрес. При прохождении пакетом egress pipeline:
Destination меняется на source.
Вместо изначального destination подставляется next-hope.
При необходимости добавляется VLAN tag и другие изменения в заголовках.
После этих изменений пакет покидает коммутатор.
Как устроен MMU
Memory Management Unit (MMU) — это память, распределенная на ячейки фиксированного размера в 256B. Попадая в MMU, пакет делится на ячейки и записывается туда, где есть свободные места. Адрес первой ячейки, куда попал пакет, — это указатель, с которым мы работаем дальше.
Указатели помещаются в очереди и, в зависимости от алгоритма, будут обработаны. Пакет может направляется в несколько портов — например, при мультикастном трафике или зеркалировании. После передачи пакета его указатель удаляется из очереди. Когда указатель удален из всех очередей, пакет считается переданным — память можно использовать для других пакетов.
Как устроен ingress pipeline
Ingress pipeline парсит, аккуратно складывает и обрабатывает все заголовки входящего пакета. Каждый пакет проходит внутри пайплайна через несколько блоков, которые мы активируем при конфигурации порта:
FDB — forwarding database, активен только на уровне L2.
Field processor.
FIB — forwarding information base.
ACL и другие дополнительные блоки.
Данные пакета обрабатываются отдельно — они сразу попадают в ASIC:
FDB, Field processor и FIB — это так называемые CAM- или TCAM-таблицы. Они представляют собой соединенные друг с другом логические элементы. Чтобы понять, как таблицы работают, представим, что у нас есть IP-адрес на входе. За один такт он загружается в регистр, значения проходят через логические элементы, и за тот же один такт мы получаем результат. В данном случае результат — это hash, по которому мы можем пройти в RAM память и получить все значения, которые нужны для передачи пакета.
Получаем ARP
Теперь мы знаем чуть больше об обработке пакетов и можем вернуться к нашей конфигурации.
Уровень ASIC. Мы хотим запустить ping. Ping состоит из ARP-пакета, за которым идет ICMP-пакет. Наша задача — перехватить из трафика ARP-пакет и отправить его на обработку в Control Plane. С ней поможет Field processor. Он работает с полями заголовков и смещениями, для этого ему можно задать значение или маску. ARP-пакет можно однозначно определить по значению поля EtherType 0x0806:
// ARP- (RARP-) запись в Field processor
EID 0x00000011: gid=0x1,
DstMac
Part:0 Offset0: 64 Width0: 16
Part:0 Offset1: 36 Width1: 4
Part:0 Offset2: 40 Width2: 4
...
DATA=0x00009819 2c9b5849
InPorts
...
EtherType
Part:1 Offset0: 64 Width0: 16
DATA=0x00000806
IpType
Part:0 Offset0: 154 Width0: 2
Part:0 Offset1: 156 Width1: 2
Part:1 Offset2: 158 Width2: 1
DATA=0x00000008
action={act=CopyToCpu, ...}
Field processor можно представить в виде таблицы, в которой описаны значения полей заголовков и поле действие (action). Если пакет совпадает с указанными значениями (в примере ниже это dst MAC-адрес, порт, EtherType, IpType), то к нему применяется заданный action, в нашем случае это CopyToCpu:
CopyToCpu означает, что ARP будет поднят на ControlPlane и обработан конвейерами — отправлен на все порты в пределах VLAN, кроме того, что его принял. Также в качестве action часто используются MoveToCpu (пакет изымается из конвейера и направляется на ControlPlane), Drop (для отбрасывания пакета) и другие действия.
Field processor — это группа правил. Предположим, мы зашли в него и увидели, что наш ARP подпадает под какое-то правило, которое находится выше. В этом и заключается проблема, но как от нее избавиться? Давайте попробуем подняться на уровень SAI и посмотреть, какая команда приходит на конфигурирование Field processor.
Уровень SAI
Когда мы хотим перехватить ARP- или RARP-трафик, то создаем Trap group. Этой Trap group мы говорим, с каким приоритетом тот или иной трафик будет подниматься на CPU.
Trap срабатывает до того, как пакет попадает в уровень L3:
Возможно, вы уже узнали в Trap group функционал policer. Производители называют его по-разному, мы привыкли к названию CoPP — Control Plane Policing. Администраторы могут трогать его по соображениям безопасности, для оптимизации трафика или работы коммутатора.
В CoPP указывается протокол, приоритет и очередь, в которую его нужно передать. Давайте сконфигурируем.
Уровень CLI
// Конфигурация через CoPP
switch1# show running-configuration
!
copp-action queue4_group2
set trap-action copy
set trap-queue 4
set trap-priority 4
...
!
class arp priority 0
set copp-action queue4_group2
...
Предположим, проблема, с которой столкнулся Пётр, была именно в конфигурации CoPP. Ее случайно удалил его коллега в целях оптимизации или по иным причинам. Мы нашли и исправили проблему — к нам пришел ARP. Можем поставить вторую галочку в списке необходимых для работы L3 вещей:
Интерфейс✅CoPP✅Доступный next-hop
Маршрут
Но трафик все же не проходит, котики все еще не загружаются. Давайте рассмотрим оставшуюся часть конфигурации.
Добавляем neighbour в Data Plane
Уровень Linux
Внутри Linux пакет тоже проходит через пайплайн, который состоит из трех блоков:
маршруты,
таблица neighbors, которая заканчивается интерфейсом и MAC-адресом,
интерфейс, в который нужно отдать пакет.
После наших действий в Linux появилась ARP-запись, она же запись о соседях, мы ее видим:
// Запись о соседе
# ip neighbor
10.1.1.2 dev Ethernet1 lladdr 00:e0:4b:6d:97:cb REACHABLE
В ASIC аналогичной записи о neighbor изначально нет, ее добавляет исполнительная подсистема. Давайте проследим процесс ее добавления до Data Plane.
Уровень SAI
Исполнительная подсистема отслеживает изменения в сетевой подсистеме Linux через netlink. После появления neighbor будет выработана команда для SAI:
Создать соседа.
Создать внутри Virtual router next-hope, который привязан к интерфейсу, за которым находится сосед.
В принципе очень похоже на то, что мы видели в Linux:
Уровень SDK
В ASIC добавился egress-интерфейс 132770 с MAC-адресом neighbour, то есть мы создали выходную точку.
drivshell>l3 egress show
Entry Mac Vlan INTF PORT MOD MPLS_LABEL ToCpu Drop RefCount
132768 98:19:2c:9b:58:49 1 4096 0 0 -1 no yes 2
132769 98:19:2c:9b:58:49 0 16383 0 0 -1 no no 4
132770 00:e0:4b:6d:97:cb 4095 4097 3 0 -1 no no 1
Далее будет создан маршрут с 32-й маской, который смотрит в egress-интерфейс 132770.
drivshell>l3 l3table show
Entry VRF IP address Mac Address INTF MOD PORT CLASS HIT H/W Index
1 0 10.1.1.1 00:00:00:00:00:00 132769 0 0 1 y 3224
2 0 10.1.1.2 00:00:00:00:00:00 132770 0 0 0 y 5272
Посмотрим на картину отправки APR reply в целом. Трафик уходит вниз, попадает в CPU-порт, проходит через запись 10.1.1.2, которая только что добавилась в таблицу fast routes, и уходит через egress-интерфейс 132770.
Трафик ушел, а значит, должен появиться пинг. Проверяем:
//От router1 до switch1
switch1# ping 10.1.1.1
PING 10.1.1.1 (10.2.1.1) 56(84) bytes of data.
64 bytes from 10.2.1.1: icmp_seq=1 ttl=102 time=2.32 ms
64 bytes from 10.2.1.1: icmp_seq=2 ttl=102 time=2.13 ms
64 bytes from 10.2.1.1: icmp_seq=3 ttl=102 time=2.39 ms
Ping ходит, все отлично. Ставим галочку, что у нас есть доступный next-hope:
Интерфейс✅CoPP✅Доступный next-hop✅Маршрут
Остался лишь один пункт в нашем списке.
Создаем маршрут
Уровень CLI
Через новый доступный next-hop в командной строке нужно создать маршрут в сеть 10.2.2.0 через маршрутизатор 10.1.1.2:
switch1(config)# ip route 10.2.2.0/24 10.1.1.2 interface Ethernet 1
Проверяем в show-команде, что все получилось:
switch1# show ip route
Destination Gateway Interface Dist/Metric Uptime
------------------------------------------------------------------------------------------
S>* 10.2.2.0/24 via 10.1.1.2 Ethernet1 1/0 00:00:08
C>* 10.1.1.0/24 Direct Ethernet1 0/0 03:25:31
Успех! Посмотрим, все ли получилось в подсистемах коммутатора.
Уровень Linux
В Linux появился маршрут в сеть 10.2.2.0/24 с next-hop 10.1.1.2.
//Neighbor уже известен
# ip neighbor
10.1.1.2 dev Ethernet1 lladdr 00:e0:4b:6d:97:cb REACHABLE
//Добавлен маршрут через neighbor
# ip route
10.2.2.0/24 nhid 12 via 10.1.1.2 dev Ethernet1 proto 196 metric 20
10.1.1.0/24 dev Ethernet1 proto kernel scope link src 10.1.1.1
Ранее на коммутатор приходили ARP-ответы от 10.1.1.2, по этим ответам были созданы записи в таблице neighbors, и эти записи еще не протухли. Если бы на момент создания маршрута в таблице neighbors отсутствовала запись об 10.1.1.2, то ядро Linux само бы сгенерировало ARP-запрос и по ответу создало этот neighbour.
Уровень SAI
Команда SAI говорит о том, что такая-то подсеть доступна через такой-то next-hope и через такой-то RIF.
Уровень SDK
Появилась запись с 10.2.2.0/24 в таблице маршрутов через egress-интерфейс 132770, который был создан раньше.
drivshell>l3 defip show
Unit 0, Total Number of DEFIP entries: 98256
# VRF Net addr Next Hop Mac INTF MODID PORT PRIO CLASS HIT
8 0 10.2.2.0/24 00:00:00:00:00:00 132770 0 0 0 0 y
8 0 10.1.1.0/24 00:00:00:00:00:00 132769 0 0 0 2 n
1 0 0.0.0.0/0 00:00:00:00:00:00 132768 0 0 0 0 n
Проверяем, что количество ссылок на egress-интерфейс равно двум и все необходимые маршруты смотрят в egress-интерфейс.
drivshell>l3 egress show
Entry Mac Vlan INTF PORT MOD MPLS_LABEL ToCpu Drop RefCount
132770 00:e0:4b:6d:97:cb 4095 4097 3 0 -1 no no 2
Теперь у нас есть все, чтобы передавать трафик:
Интерфейс✅CoPP✅Доступный next-hop✅Маршрут✅
Посмотрим на картину в целом. Визуально убеждаемся, что конфигурация в Linux и ASIC синхронизированы:
Маршрут в сеть 10.2.2.0/24 (за маршрутизатором) через 10.1.1.2 (маршрутизатор).
Присутствует neighbor 10.1.1.2, известен его MAC-адрес и порт, через который он доступен. В ASIC он выглядит как маршрут 10.1.1.2 в таблице fast routes через egress-интерфейс.
Адрес 10.1.1.1 настроен на интерфейсе в Linux, а в ASIC присутствует маршрут 10.1.1.1 через CPU-порт.
Проверяем пинг:
//От pc1 до сети 10.2.2.0/24
switch1# ping 10.2.2.1
PING 10.2.2.1 (10.2.2.1) 56(84) bytes of data.
64 bytes from 10.2.2.1: icmp_seq=1 ttl=102 time=2.56 ms
64 bytes from 10.2.2.1: icmp_seq=2 ttl=102 time=2.02 ms
64 bytes from 10.2.2.1: icmp_seq=3 ttl=102 time=2.15 ms
Котики загружаются! Пётр доволен — все хорошо.
Отладка проблемы: поддерживаем neighbour активным
Но не будем расслабляться. Если мы немного подождем, то заметим следующую картину: раньше трафика не было, потом он опять появился. Есть какой-то провал:
//От pc1 до сети 10.2.2.0/24
switch1# ping 10.2.2.1
PING 10.2.2.1 (10.2.2.1) 56(84) bytes of data.
From 10.10.10.11 icmp_seq=1 Destination Host Unreachable
From 10.10.10.11 icmp_seq=1 Destination Host Unreachable
From 10.10.10.11 icmp_seq=1 Destination Host Unreachable
64 bytes from 10.2.2.1: icmp_seq=1 ttl=102 time=2.56 ms
64 bytes from 10.2.2.1: icmp_seq=2 ttl=102 time=2.02 ms
Провал вызван тем, что какое-то количество входящих пакетов было потеряно. Потом операционная система сгенерировала ARP-запрос, он прошел весь путь, и трафик снова пошел. Это проблема. Но в чем дело?
Дело в том, что, пока трафика не было, neighbor не использовался. Он был помечен как неактивный и был удален — специалисты еще говорят, что он «протух». Обычно в Linux это происходит за 300 секунд:
//Было REACHABLE стало STALE
# ip neighbor
10.1.1.2 dev Ethernet1 lladdr 00:e0:4b:6d:97:cb STALE
Чтобы избежать подобных проблем, нужны механизмы, которые будут поддерживать активное состояние нашего neighbour. Существует три распространенных механизма проверки его доступности при долгом отсутствии трафика:
ARP до next-hop при «протухании».
ARP до next-hop по таймеру.
Привязка Bidirectional Forwarding Detection-сессии к маршруту.
ARP до next-hop при «протухании». Самый простой механизм — это сделать триггер. Как только у нас протухла запись, мы генерируем запрос, проверяем у neighbour, жив ли он. Он нам ARP reply отвечает: «Да, я жив». Мы помечаем, что запись жива и все нормально. Но если вдруг neighbour перестал быть доступным, а запись еще какое-то время будет активной, то и в таблице маршрутов запись будет активной — трафик будет теряться. Поэтому я не рекомендую использовать такой механизм.
ARP до next-hop по таймеру. Интуитивно понятный вариант — завести таймер и периодически отсылать ARP-запрос, чтобы убеждаться в доступности соседнего узла. Но у этого подхода есть некоторые недостатки. Если делать интервал слишком длинным, то недоступность узла можно заметить не сразу — и вот, мы возвращаемся к вышеописанной проблеме с триггером. Если интервал будет коротким, то мы нагружаем сеть лишним служебным трафиком.
Привязка BFD-сессии к маршруту. BFD-протокол — это обмен hello-сообщениями между соседями по заданному интервалу, обычно задается от 300 мс до 3000 мс. BFD-сессию можно привязать к маршруту, к статическому тоже — об этом надо помнить. После дополнительных настроек недоступных neighbour больше нет.
Проблема с котиками окончательно решена!
Саммари: в чем была проблема
Чтобы собрать в кучку все, что я описал выше, выделю проблемы, «спрятанные» в рассматриваемой ситуации:
→ Трафик не проходил — следствием стало отсутствие ARP-записи.
→ ARP-запись, в свою очередь, отсутствовала из-за удаленного правила CoPP, человеческий фактор. Чтобы докопаться до этой проблемы, мы проделали небольшой сюжетный «крюк» по подсистемам.
→ Когда всплыла вторая проблема с «протуханием» ARP-записи, мы смогли быстро ее выявить.
На практике часто за какой-то одной проблемой может прятаться несколько подпроблем. Очень важно сперва их выявить, а затем решать по отдельности.
Заключение
Закончу небольшим списком советов. Что делать, если вы столкнулись с проблемами в работе коммутатора:
Проверьте логи на предмет ошибок.
«Занулите» конфигурацию и введите команды по одной, убеждаясь, что она правильно применилась и в CPU, и в ASIC.
Рассматривая проблемы с маршрутизацией, проверьте L3-интерфейс, доступность next-hop и маршрутов, правили ACL, политики Control Plane.
Я надеюсь, что эта и предыдущая статьи приоткрыли для вас завесу тайны вокруг внутреннего устройства коммутаторов. И это поможет вам в повседневной работе или, быть может, вызовет интерес к более глубокому изучению сетевых устройств и их разработке.
Если вам больше по душе видеоформат, c этой темой я выступал на Linkmeetup. Вот ссылка на YouTube (и Rutube).
Brak0del
Если не секрет, почему выбрали TCAM для реализации FIB?
MikhailShpak
tcam - еще с древних времен стандарт, в той же Cisco
atcam - смотрится тоже интересно
но у коллег по цеху - может быть своя логика для Sonic по выбору реализации)
Brak0del
Ясно, спасибо.
yadro_team
Заметили верно. «Чистый» FIB не подразумевает TCAM. Но TCAM позволяет добавить в строку с MAC-адресом дополнительные поля.
andrewz13
в разных ASIC по разному реализуется. SAI это надстройка над vendor SDK.