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

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

Настраиваем 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)

→ Ведущий инженер группы аналитики и комплексного тестирования

Инженер-программист, пишущий на С++

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-интерфейс.

Не будем усложнять схему. Знайте, что VLAN «прячется» перед ingress-блоком
Не будем усложнять схему. Знайте, что VLAN «прячется» перед ingress-блоком

Дальше создадим 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:

  1. Destination меняется на source.

  2. Вместо изначального destination подставляется next-hope.

  3. При необходимости добавляется 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 на схеме заблокирован, поскольку мы говорим только про уровень L3
Блок FDB на схеме заблокирован, поскольку мы говорим только про уровень L3

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: 

  1. Создать соседа.

  2. Создать внутри 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-записи, мы смогли быстро ее выявить.

На практике часто за какой-то одной проблемой может прятаться несколько подпроблем. Очень важно сперва их выявить, а затем решать по отдельности. 

Заключение

Закончу небольшим списком советов. Что делать, если вы столкнулись с проблемами в работе коммутатора:

  1. Проверьте логи на предмет ошибок.

  2. «Занулите» конфигурацию и введите команды по одной, убеждаясь, что она правильно применилась и в CPU, и в ASIC.

  3. Рассматривая проблемы с маршрутизацией, проверьте L3-интерфейс, доступность next-hop и маршрутов, правили ACL, политики Control Plane.

Я надеюсь, что эта и предыдущая статьи приоткрыли для вас завесу тайны вокруг внутреннего устройства коммутаторов. И это поможет вам в повседневной работе или, быть может, вызовет интерес к более глубокому изучению сетевых устройств и их разработке.   

Если вам больше по душе видеоформат, c этой темой я выступал на Linkmeetup. Вот ссылка на YouTubeRutube).

Комментарии (5)


  1. Brak0del
    17.12.2024 13:16

    FIB — это так называемые CAM- или TCAM-таблицы

    Если не секрет, почему выбрали TCAM для реализации FIB?


    1. MikhailShpak
      17.12.2024 13:16

      tcam - еще с древних времен стандарт, в той же Cisco

      atcam - смотрится тоже интересно

      но у коллег по цеху - может быть своя логика для Sonic по выбору реализации)


      1. Brak0del
        17.12.2024 13:16

        Ясно, спасибо.


    1. yadro_team
      17.12.2024 13:16

      Заметили верно. «Чистый» FIB не подразумевает TCAM. Но TCAM позволяет добавить в строку с MAC-адресом дополнительные поля.


      1. andrewz13
        17.12.2024 13:16

        в разных ASIC по разному реализуется. SAI это надстройка над vendor SDK.