Привет, Хабр! Меня зовут Светлана Каткова, я старший инженер по разработке ПО для коммутатора KORNFELD в YADRO. Знакома ли вам ситуация: L2-связность работает, L3-маршруты есть, но большие файлы не копируются, VPN-туннель «рвет» соединение, а базы данных падают при попытке репликации? Диагностика показывает, что мелкие пакеты проходят идеально, а крупные — исчезают бесследно. С высокой вероятностью проблема упирается в Maximum Transmission Unit (MTU).

Тема MTU кажется простой только на первый взгляд. На практике мы сталкиваемся с разницей между L2 и L3 MTU, Jumbo Frames, настройкой Link Aggregation Group (LAG) и «сюрпризами» вендорских ОС при обновлении. Одна из ключевых проблем — непонимание, как из значения mtu получается реальный Ethernet-кадр, который уходит в кабель.

В этой статье рассмотрим правила настройки на примере Kornfeld OS, так как система аналогична многим вендорам.

Перед началом работы разберем основные определения:

  • MTU (Maximum Transmission Unit, L3) — максимальный размер IP-пакета, который может быть передан без фрагментации. Ethernet-заголовки здесь не учитываются. Классический размер: 1500 байт.

  • Frame Size (L2) — максимальный размер Ethernet-кадра целиком, учитывая заголовки, MTU и FCS.

  • Ethernet-заголовок (L2) — это служебная 14-байтовая структура, которая добавляется к данным на канальном уровне (Dest MAC, Src MAC, EtherType). Если используется VLAN (802.1Q), добавляется 4 байта (тег). Для Q-in-Q (802.1AD) — добавляется 8 байт.

Анатомия Ethernet-кадра

Ethernet-кадр (фрейм) — это то, что физически передается по проводу. Он включает в себя:

  • заголовок L2 Header, 

  • полезную нагрузку, например IP-пакет,

  • контрольную сумму FCS.

Формат Ethernet II — самый распространенный:

Размеры полей L2-заголовка без учета Preamble и FCS:

  • DA (Destination Address) — 6 байт,

  • SA (Source Address) — 6 байт,

  • EtherType — 2 байта (определяет протокол L3: 0x0800 для IPv4, 0x86DD для IPv6, 0x8100 для VLAN).

Итого: базовый L2-заголовок равен 14 байтам.

Что добавляет VLAN (802.1Q)

Если порт работает в режиме trunk, к заголовку добавляется тег VLAN (4 байта) между SA и E-Type:

Для Q-in-Q (802.1AD): добавляется 8 байт (два тега), L2-заголовок равен 22 байтам.

Ключевое правило, которое нужно запомнить: при передаче L3-пакета через L2-среду итоговый L2-кадр всегда больше, чем значение MTU.

Формула для расчета размера итогового L2 frame:

L2 Frame Size = MAC-заголовок (14 байт) + VLAN-теги (0, 4 или 8 байт) + другие заголовки (MPLS) + L3 MTU

Формула содержит:

  • MAC-заголовок размером 14 байт, содержащий адрес получателя, адрес отправителя и тип протокола.

  • VLAN-теги, которые добавляются на trunk-портах:

    • 0 байт на access-портах,

    • 4 байта на 802.1Q (один тег),

    • 8 байт на Q-in-Q (два тега 802.1AD).

  • MPLS-метки по 4 байта на каждую метку.

Шпаргалка по размеру метрик:

Сценарий

L2 Header

L3 MTU

Итоговый L2 Frame

Access port, без VLAN

14 байт

1500

1514 байт

Trunk port (802.1Q)

18 байт

1500

1518 байт

Q-in-Q (802.1AD)

22 байта

1500

1522 байта

В команду разработки коммутатора KORNFELD ищем старшего сетевого инженера и разработчика на C++. Если вы хорошо разбираетесь в материале, описанном в этой статье, откликайтесь на первую вакансию. А если давно пишете на С++ и знаете 20-й стандарт — отправляйте резюме на вторую вакансию.

Разделение понятий в Kornfeld OS

В Kornfeld OS используются два параметра MTU (Maximum Transmission Unit), которые работают на разных уровнях сетевой модели OSI:

frame-size (L2 MTU):

  • определяет максимальный размер Ethernet-кадра;

  • учитывает L2-заголовки: MAC-адреса, EtherType, VLAN-теги;

  • срабатывает на приеме и на передаче;

  • по умолчанию равен 9122 байтам.

mtu (L3 MTU):

  • определяет максимальный размер IP-пакета без L2-заголовка;

  • срабатывает только на исходящем порту;

  • по умолчанию равен 9100 байтам.

Почему разница 22 байта? Потому что 14 байт — базовый L2-заголовок, а 8 байт — запас  (возможное расширение заголовка) под VLAN-теги, MPLS-метки или другие заголовки. Производитель оставляет пространство для инкапсуляции, чтобы кадр с MTU 9100 гарантированно проходил даже при добавлении тегов. 

Обратите внимание: разница между frame-size (9122) и mtu (9100) как раз составляет 14 байт L2-заголовка + 8 байт служебного пространства.

Базовые правила работы с L2 и L3

Для L3-интерфейса (порты с IP-адресом: routed port, SVI, subinterface):

  • ограничение mtu срабатывает только на исходящем порту;

  • сравнивается IP-пакет (L3) со значением mtu;

  • при превышении возможна фрагментация, если разрешена, или отказ.

Для L2-интерфейса (порты без IP-адреса: access и trunk):

  • ограничение frame-size срабатывает и на входящем, и на исходящем портах;

  • сравнивается Ethernet-кадр целиком (L2) со значением frame-size;

  • при превышении на входе — увеличивается счетчик Oversize;

  • при превышении на выходе — увеличивается счетчик Discarded.

Jumbo Frames: когда нужны, а когда вредны

Jumbo Frame — это Ethernet-кадр, превышающий стандартные 1500 байт. В сетях коммутатора KORNFELD поддерживаются кадры до 9216 байт (значение L2 frame-size), что дает L3 MTU до 9194 байт.

Главная задача Jumbo — снизить накладные расходы на обработку пакетов (overhead). За счет чего это происходит:

  • Уменьшается количество пакетов для передачи одного объема данных.

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

  • Снижается нагрузка на CPU серверов для сети с Jumbo Frame. Каждый приходящий пакет на сетевой карте сервера генерирует прерывание, заставляя CPU останавливать текущую работу для его обработки. При переходе с MTU 1500 на Jumbo Frame 9000 количество пакетов для передачи того же объема данных уменьшается в 6 раз.

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

Эффект от Jumbo максимален в следующих случаях:

  • Storage networks (iSCSI, NFS, Ceph). В системах хранения данные передаются блоками, при стандартном MTU один такой блок разбивается на несколько пакетов — и процессор тратит время на их сборку и обработку. С Jumbo Frame блок уменьшается в один–два кадра, нагрузка на сервер заметно снижается.

  • Когда backup-трафик идет между серверами в изолированной среде. Резервное копирование — это непрерывный поток данных. Чем крупнее кадры, тем меньше сервер отвлекается на прерывания.

  • Когда происходит High Performance Computing (HPC) в MPI-приложениях. Jumbo Frame сокращает число пакетов и снижает задержки на их обработку.

Подводные камни: где лучше не использовать Jumbo Frame

В таблице собрала возможные проблемы, с которыми сталкиваются пользователи Jumbo Frame:

Проблема

Описание

Фрагментация 

Пакет с Jumbo Frame, попавший в сеть со стандартным MTU, будет фрагментирован (что нагрузит устройства) или отброшен (если установлен флаг DF – Don't Fragment).

Буферизация

Крупные кадры быстрее заполняют буферы портов, что может привести к дропам при micro-bursts.

Совместимость

Устройства должны поддерживать Jumbo Frames на каждом участке сети.

Обзор интерфейсов, на которых настраиваем L2/L3 MTU 

Мы рассмотрели, зачем нужны Jumbo Frame, а теперь разберемся, где они настраиваются. Не все интерфейсы одинаковые — у каждого типа свои значения по умолчанию и свои ограничения. Вот полная картина:

Интерфейс

L2 MTU (frame-size)

L3 MTU (mtu)

Примечание

Ethernet

9122 (default)

9100 (default)

Может быть переключен в L3-режим командой ip address

PortChannel (LAG)

9122 (default)

9100 (default)

Члены LAG наследуют эти значения от LAG-интерфейса

SVI (VLAN interface)

Не применимо

9100 (default)

L3-интерфейс поверх VLAN

Subinterface

Не применимо

9100 (default)

Не может превышать MTU родительского интерфейса

Management

Не применимо

1500 (default)

Отдельный out-of-band порт

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

L2-интерфейс 

(frame-size)

L3-интерфейс 

(mtu)

VLAN-теги

L2 Payload

MAX Frame Size (в кабель)

Расчет

frame-size 1500 (access)

не участвует

нет

нет

1500

1500 (frame-size) — порт работает только на L2, L3 MTU не участвует.

frame-size 1500 (trunk)

не участвует

802.1Q (4 байта)

нет

1500

1500 (frame-size) —  добавился тег, но ограничение считается по кадру целиком

не участвует

mtu 1500 (routed port)

нет

1500

1514

14 (L2-заголовок) + 1500 (L3 MTU) = 1514

frame-size 1500 (access)

mtu 1486 (SVI на этом VLAN)

нет

1486

1500

1500 (frame-size) - 14   (L2-заголовок) = 1486 (L3 MTU)

frame-size 1500 (trunk)

mtu 1482 (SVI на этом VLAN)

802.1Q

1482

1500

1500 - 14 (L2-заголовок) - 4 (VLAN) = 1482 (L3 MTU)

frame-size 1500 (parent port)

mtu 1482 (subinterface)

802.1Q

1482

1500

1500 - 14 (L2-заголовок) - 4 (VLAN)= 1482 (L3 MTU) — те же правила, что и у trunk-порта

Эта таблица показывает, как из настроенных значений MTU получить реальный максимальный размер кадра в байтах, который уйдет в физическую среду. Что означают столбцы:

  • L2-интерфейс (frame-size) — значение, настроенное на L2-порту (или унаследованное).

  • L3-интерфейс (mtu) — значение, настроенное на routed-интерфейсе (SVI, routed port, subinterface).

  • L2 Payload — размер полезной нагрузки, которая остается после вычитания заголовков (фактически — объем данных, который видит L3).

  • MAX Frame Size — итоговый размер Ethernet-кадра (без Preamble и FCS).

Как это выглядит в работе Kornfeld OS

Рассмотрим выводы tcpdump для разных интерфейсов. 

L2-интерфейс с frame-size 1500 (access port):

13:16:02.330108 98:19:2c:9b:4a:49 > 6c:b3:11:60:dc:1c, ethertype IPv4 (0x0800), length 1500:

(tos 0x0, ttl 64, id 4444, offset 0, flags [DF], proto UDP (17), length 1486) 10.107.11.3.50001 > 10.107.11.2.50002: UDP, length 1458

Сделаем проверку:

  • length 1500 — это L2 Frame Size.

  • Вычитаем 14 байт L2-заголовка → получаем 1486 байт (UDP-пакет).

  • Вычитаем 8 байт UDP-заголовка → получаем 1478? Нет, смотрим дальше.

  • Вычитаем IP-заголовок → получаем length 1458. Это нужные нам данные.

Проверяем: 14 (L2) + 20 (IP header) + 8 (UDP header) + 1458 (UDP data) = 1500. Все сходится.

L3-интерфейс с mtu 1500 (routed port):

12:18:53.306427 b4:7d:76:10:33:60 > 52:a5:00:00:47:01, ethertype IPv4 (0x0800), length 1514:

(tos 0x0, ttl 63, id 8890, offset 0, flags [DF], proto UDP (17), length 1500)  10.107.11.2.50001 > 10.107.3.3.50002: UDP, length 1472

Сделаем проверку:

  • length 1514 — итоговый L2 Frame Size.

  • Вычитаем 14 байт L2-заголовка → 1500 байт (это и есть наш mtu).

  • 1500 − 20 (IP) − 8 (UDP) = 1472 байта полезных данных.

Делаем вывод: при mtu 1500 на L3-порту сниффер показывает кадры размером 1514 байт. 

Статистика: как понять, что проблема в MTU

Когда кадр не проходит из-за превышения frame-size, это отражается в счетчиках интерфейса.

На входящем интерфейсе (превышение при приеме):

kornfeld# show interface Ethernet 5
...
Input statistics:
    60 packets, 52686 octets
    3 error, 0 discarded, 3 Oversize   # ← Oversize на входе

Это означает, что пришел кадр, который больше frame-size. Коммутатор его отбросил.

На исходящем интерфейсе (превышение при передаче): 

kornfeld# show interface Ethernet 21
...
Output statistics:
    69 packets, 50153 octets
    0 error, 3 discarded, 0 Oversize   # ← discarded на выходе

Это означает, что коммутатор хотел отправить кадр, но он не влезал в frame-size исходящего порта.

Проведем диагностику по счетчикам:

  • Oversize на входе → проблема на соседнем устройстве (оно шлет слишком большие кадры).

  • Discarded на выходе → проблема на вашем устройстве (вы пытаетесь отправить слишком большой кадр дальше).

Настройка на физическом порту

По умолчанию frame-size = 9122. Изменим его на 1518 (стандарт + тег 802.1Q):

kornfeld# configure terminal
kornfeld(config)# interface Ethernet 21
kornfeld(conf-if-Ethernet21)# frame-size 1518
kornfeld(conf-if-Ethernet21)# end

Проверка:

kornfeld# show interface Ethernet 21
...
Frame-size 1518 bytes
IP MTU 9100 bytes
...

Сброс к значению по умолчанию:

kornfeld(conf-if-Ethernet21)# no frame-size

После сброса параметр исчезает из running-config, но фактическое значение становится дефолтным (9122).

Диагностика через ping

Проверяем, проходит ли кадр определенного размера. Используем ключи:

  • -M do (Linux) — не фрагментировать на IP-уровне (DF флаг);

  • -f (Windows) — то же самое;

  • -s — размер полезной нагрузки ICMP.

Пример для L2-порта с frame-size 1518:

# L3 MTU при этом должен быть 1504 (1518 - 14)
# ICMP-пакет: 1504 - 20 (IP) - 8 (ICMP) = 1476
kf32# ping -M do -s 1476 -c 2 10.116.0.1
PING 10.116.0.1 (10.116.0.1) 1476(1504) bytes of data.
1484 bytes from 10.116.0.1: icmp_seq=1 ttl=64 time=0.227 ms
1484 bytes from 10.116.0.1: icmp_seq=2 ttl=64 time=0.177 ms
--- 10.116.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss

Если размер превышает limit:

kf32# ping -M do -s 1480 -c 2 10.116.0.1
From 10.116.1.1 icmp_seq=1 Frag needed and DF set (mtu = 1504)
ping: local error: message too long, mtu=1504

Настройка L3 MTU (mtu)

Разберем, что делать, если L3 MTU настраивается на routed-интерфейсах: L3 port, SVI, subinterface.

Настройка на SVI выглядит так:

kornfeld# configure terminal
kornfeld(config)# interface Vlan 707
kornfeld(conf-if-Vlan707)# mtu 1500
kornfeld(conf-if-Vlan707)# ip address 10.107.3.3/24
kornfeld(conf-if-Vlan707)# end

Проверка:

kornfeld# show interface Vlan 707
...
IP MTU 1500 bytes

Важное правило для Subinterfaces: L3 MTU на subinterface не может превышать L3 MTU родительского интерфейса. Это ограничение на уровне ядра Linux.

kornfeld(conf-subif-Ethernet10.100)# mtu 9100
Error: Invalid MTU parameter: the value must be equal or less
than MTU parameter on the parent interface.

Если на родительском интерфейсе mtu 9000, то на subinterface можно установить не более 9000.

Особенности L2/L3 MTU в LAG (PortChannel)

Агрегация каналов (LACP/Static) добавляет нюансов. В качественных реализациях Kornfeld OS принята концепция «общих» и «приватных» параметров:

Тип параметра

Что это

Примеры

Поведение

Общие (shared)

Должны быть одинаковыми на всех членах LAG

frame-size, mtu, speed

Наследуются от LAG-интерфейса

Приватные (private)

Могут отличаться

description, shutdown, storm-control

Настраиваются индивидуально

Принцип наследования:

  • При добавлении порта в LAG, его индивидуальные настройки frame-size или mtu игнорируются.

  • Порт наследует эти параметры от LAG-интерфейса.

  • В выводе show interface это явно указывается.

Пример настройки LAG:

kornfeld(config)# interface PortChannel 20
kornfeld(conf-if-po20)# frame-size 9000
kornfeld(conf-if-po20)# mtu 8900

Смотрим на физический порт-участник:

kornfeld# show interface Ethernet 6
...
Frame-size 9000 bytes (cause: member of PortChannel20)
IP MTU 8900 bytes (cause: member of PortChannel20)

Фраза (cause: member of PortChannel20) критически важна — она показывает, что значение не настраивалось вручную, а унаследовано. При удалении порта из LAG его настройки сбрасываются в default:

kornfeld(conf-if-Ethernet6)# no channel-group
%Notice: the interface configuration has been reset to it's default.

Теперь у порта следующие значения:

  • frame-size = 9122;

  • mtu = 9100, если он в L3-режиме.

Это предотвращает ситуацию, когда порт с «экзотическими» настройками MTU возвращается в общий пул и «ломает» соседей.

Отображение параметров MTU в конфигурации

Современные NOS скрывают параметры по умолчанию, чтобы не захламлять конфиг.

Правила отображения:

  • По умолчанию mtu (L3) и frame-size (L2) не отображаются в show running-configuration.

  • После ручной настройки параметр отображается всегда (даже если значение совпадает с дефолтным).

  • Фактические значения всегда можно посмотреть через show interface <if-name>.

Интерфейс с дефолтными настройками:

kornfeld# show running-configuration interface Ethernet 1
!
interface Ethernet1
 no shutdow

Но в show interface видим реальные значения:

kornfeld# show interface Ethernet 1
Ethernet1 is up, line protocol is up
Hardware is Eth, address is B4:7D:76:10:8A:00
Mode of IPV4 address assignment: not-set
Mode of IPV6 address assignment: not-set
Interface IPv6 oper status: Disabled
Frame-size 9122 bytes
LineSpeed 25Gb/s, Auto-negotiation  off
…

После ручной настройки (даже на дефолтное значение):

kornfeld# show running-configuration interface Ethernet 1
!
interface Ethernet1
 frame-size 9122   # ← отображается, хотя это default
 no shutdown

Для L3 MTU:

kornfeld# show running-configuration interface Ethernet 21
!
interface Ethernet21
 mtu 1500          # ← отображается, так как настроено вручную
 no shutdown
 ip address 192.168.0.1/30

Миграция с R1.5 на R1.6: важное предупреждение

Если вы обновляете коммутатор с версии 1.5 и ниже до 1.6+, будьте внимательны: максимальный размер кадра уменьшится на 22 байта.

В R1.5 существовал только параметр mtu, который фактически был L3 MTU, но под L2-заголовок всегда резервировалось 22 байта.

kornfeld(conf-if-Ethernet1)# mtu 9216   # L3 MTU = 9216
# Реальный L2 Frame = 9216 + 22 = 9238 байт

В R1.6+ появилось разделение: frame-size (L2 MTU) и mtu (L3 MTU). Максимальное значение frame-size = 9216.

kornfeld(conf-if-Ethernet1)# frame-size 9216   # L2 MTU = 9216
# Реальный L2 Frame = 9216 байт

Что это означает на практике:

Сценарий

R1.5

R1.6+

Разница

Настроено максимальное значение

mtu 9216 → L2 Frame = 9238

frame-size 9216 → L2 Frame = 9216

-22 байта

Сервер с Jumbo Frame 9216 (L3)

Работает

Кадры 9238 не проходят → Oversize

Несовместимость

Решение:

  • При проектировании новой сети закладывайте frame-size 9216 на коммутаторах и соответствующий L3 MTU на серверах (9216).

  • Обновляя существующую сеть, проверяйте настройки серверов и при необходимости меняйте их на mtu 9194 (9216 - 22).

В этой таблице собрала практические рекомендации, чтобы вы понимали, когда что менять:

Сценарий

Что делать

Команда

Обычный access-порт для пользователей

Оставить по умолчанию

Ничего

Trunk между коммутаторами с Jumbo

Увеличить L2 MTU

frame-size 9216

Storage VLAN (iSCSI, NFS) 

Включить Jumbo везде по сети

frame-size 9216 + mtu 9000

Проблемы с VPN (пакеты не проходят)

Уменьшить MTU на клиенте

mtu 1400 (пример)

LAG для storage

Настроить MTU на LAG-интерфейсе

frame-size 9216 (наследуется)

Диагностическая шпаргалка:

Что проверяем

Команда

Ожидаемый результат

Текущий MTU на интерфейсе

show interface Ethernet X

Значения Frame-size и IP MTU

Проходит ли кадр размером X

ping -M do -s <размер> <IP>

0% потерь

Есть ли Oversize на входе 

show interface Ethernet X

Счетчик Oversize = 0

Есть ли Discarded на выходе

show interface Ethernet X

Счетчик Discarded = 0

MTU на всех членах LAG

show interface Ethernet X

Все показывают (cause: member of ...)

Что важно помнить в работе с MTU

Собрала основные мысли статьи:

  • Не трогайте MTU без необходимости.

  • Помните про формулу: L2 Frame Size = MAC-заголовок (14 байт) + VLAN-теги (0, 4 или 8 байт) + другие заголовки (MPLS) + L3 MTU.

  • Размер кадра, который отправляется в кабель, всегда больше настроенного MTU.

  • При mtu 1500 на L3-интерфейсе в кабель уйдет 1514 байт, так как добавляется L2-заголовок. Это не ошибка.

  • Jumbo Frame хорошо работает для storage, бэкапов и HPC-кластеров. Поэтому его рекомендуют использовать в изолированных сегментах, например на транспортных сетях и в крупных ЦОД. Многие провайдеры сейчас используют 9000 байт как стандарт на магистральных линках. 

  • В LAG настраивайте MTU на самом LAG-интерфейсе. Участники LAG наследуют настройки автоматически.

  • При обновлении ПО проверяйте наличие разделения на L2/L3 MTU. При переходе на Kornfeld R1.6 максимальный размер кадра уменьшается на 22 байта.

Читайте другие материалы о работе KORNFELD. Узнайте, как настроить EVPN/VXLAN на коммутаторе и как связать VXLAN-сегменты.