Умный на лестнице разглагольствует о MTU в OSPFv2

564a92c9cb05f995b2eb6cc792ded77d

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

Я, конечно, ничего этого на тот момент не знал. Я был как подросток возраста полового созревания, который тыкался своим стручком в любую дырку. И теперь передо мной был недовольный инженер, который решил поскорей разобраться с CCNAшником и вернуться к своим делам. Он задал вопрос — почему соседство OSPF зависает на стадии Exstart/Exchange. Я не смог ответить, и собеседование закончилось. Перед тем как выдворить меня за дверь, он снисходительно подсказал, что дело в MTU, но тогда это слово было для меня чем-то из области запуска космических кораблей — неким параметром, обращение с которым требует глубоких вычислений и недюженных умственных способностей. Иными словами, я на минуту оказался в одном модуле с космонавтом, но тут же был из него выброшен. Волей судьбы мне удалось устроиться в эту же контору в другом городе, и, по сути, начать заниматься тем же самым — переводом сервисов. Тогда-то я понял откуда взялся этот вопрос про MTU в OSPF…

Мы редко задаём вопросы. Вопросы требуют ответов. Вопрос возлагает на нас ответственность, или, и того хуже, рождает другие вопросы. И стоит вопросу проникнуть в нашу голову, как мы сидим сгорбившись среди ночи за экраном, или книгой, вместо того, чтобы обнимать нежную жену в тёплой постели. Инженерно-технические решения* создаются для того, чтобы вопросов не задавали — просто следуй инструкции и уходи с работы вовремя. К сожалению, даже если такой документ составлен скрупулёзно, исполнитель не спешит его читать, предпочитая краткий инструктаж от старшего коллеги. К чему сводятся все эти решения и инструкции? Как правило, они содержат только типовые конфигурации, порядок действий, который необходимо выполнить, причём безо всяких объяснений что и зачем выполняется. Даже официальные руководства крупных производителей сетевого оборудования грешат этим — что же говорить о провайдерах с их внутренними документами. Только редкие энтузиасты создают действительно детальные руководства, гении, увлечённые делом. Попробуй найди такого.

ИТР, с которыми мне пришлось работать, не имели упоминаний про MTU в OSPF. На железках согласование MTU было включено по умолчанию, поэтому типовые конфигурации не имели ни строки кода про MTU. Большинство арий, с которыми нам приходилось работать были тупиковыми: со стороны ABR отдавался маршрут по умолчанию, со стороны тупикового роутера** только несколько клиентских сетей. Самое маленькое сконфигурированное MTU, которое мне встречалось было не меньше 1200 байт. Для LSA в тупиковой арии это огромный размер, всё равно что Гибралтар для маленькой лодочки. Создавалось подозрение, что настраивать тупиковые роутеры с проверкой MTU было всё равно что прописывать в договор условие, о котором придётся долго спорить, но которое никогда не произойдет в жизни. Траблшутинг OSPF по причине MTU mismatch — пустая трата времени.

Из книги господина John T.Moy «OSPF: Анатомия протокола интернет маршрутизации» на странице 60 можно прочитать [2], что когда разрабатывался OSPF, Интернет тоже находился в стадии формирования и в нём использовалось множество развивающихся технологий канального уровня. Все они имели свои особенности: разнились скорости передачи, частота ошибок, MTU. Несмотря на то что OSPF изначально разрабатывался для ARPANET [2] (размер MTU- 1006 байт [3]), с течением времени OSPF начал притязать стать стандартом. Для этой цели ему требовалось стать совместимым со всеми этими технологиями. OSPF должен был работать одинаково хорошо поверх них всех, или покрайней мере, свести к минимуму влияние разных спецификаций на работоспособность протокола. Действительно, в RFC1583 (1994 г.) есть только одно упоминание о MTU [4]. Его суть сводится к тому, что OSPF не способен самостоятельно фрагментировать пакеты, и полагается в этом на IP протокол (при этом рекомендуется по возможности избегать фрагментации). Это всё. Изучать историю развития интернета по RFC то ещё удовольствие. К счастью, в 1998 году вышла в свет уже упомянутая книга John T.Moy, автора того же RFC1583. Из неё ясно [2], что в то время только несколько технологий канального уровня работали под управлением IP: Ethernet и point-to-point serial lines (MTU 1500 байт); PPP и FDDI (4352), которые только-только разрабатывались; 802.5 Token Ring (4464 [8]) и Frame Relay, имевшие нечётко определённый IP MTU. Поверх этих линков была вероятность, что пиры будут иметь несогласованность в отношении максимального размера пакета, который они могут отправить через линк, что вызовет проблемы при пересылке: как только один роутер отправит пакет большего размера, чем другой может принять, то этот пакет будет отброшен принимающей стороной. IP фрагментация может прийти на помощь. Но чтобы фрагментация случилась, все роутеры должны предварительно согласовать MTU. OSPF для согласования MTU был доработан. Доработку внесли в Database Description [5] два байта (Interface MTU) сразу после заголовка.

Мне пришлось собрать лабу из пары L3 коммутаторов***, чтобы проверить это. Я установил MTU в 160 байт***** на интерфейсе тупикового роутера, а на стороне ABR оставил без изменений 1500 байт. Включил дебаг. Статус был Full, соседство установилось сразу без единого замечания. Проверил то самое Interface MTU в Database Description, а оно равно 0. Оказалось, вендор отключил по умолчанию согласование MTU на всех своих продуктах, объяснив это тем, что не хочет создавать проблем [6]. Согласование MTU — это опция, а не требование.

Далее на ABR я отключил аннонс суммарных LSA, оставив только маршрут по умолчанию. Тип сети выбрал p2p на основе unnumbered loopback интерфейса. В итоге от ABR я получил один Router LSA с его loopback адресом и только один суммарный LSA c маршрутом по умолчанию. А со стороны тупикового роутера — один Router LSA с его loopback’ом. Теперь нужно было на ABR сформировать такой LSA, размер которого превысил бы 160 байт, и направить его по прямому линку в сторону тупикового роутера. Для этой цели я мог выбрать только Router LSA. Во-первых, потому, что у меня было p2p соединение, и тупиковая ария с отлючёнными суммарными аннонсами, так что других LSA у меня и быть не могло. Во-вторых, если бы даже я вернул суммарные, то они бы мне не подошли, потому что каждый новый аннонс сети, формировал бы один LSA, в котором был бы только одна добавленная сетка, без всех аннонсированных ранее, размер суммарного LSA всегда был бы один и тот же — 28 байт. Другое дело Router LSA — при добавлении новой сети оно вырастало на 12 байт, включало и старые сети и новую. Иными словами, одно LSA Update может содержать в себе несколько разных типов LSA, но суммарное LSA может содержать аннонс только одной сети, его размер всегда один и тот же, то время, как Router LSA может содержать в себе целую кучу (а точнее, 0×0000) сетей (numbers of link). Да, конечно, можно и в один LSA update запихать сколько угодно (а точнее 0×00000000) LSA (Number of LSAs), но для этого придётся создать и «закомитить» сразу множество OSPF активных интерфейсов. Короче, наращивать размер LSA Update было решено через Router LSA Type 1.

Далее нужно было понять, сколько сетей добавить на ABR, чтобы получить пакет размером больше 160-ти байт. 20 байт — IP заголовок, 24 байта — OSPF заголовок, 4 байта — под количество LSA (Number of LSAs), 36 байта — Router LSA, из которых 12 байт отводится под описание сети. Итого базовый размер Router LSA пакета c аннонсом одной сети равен 84 байта. Размер этого фрейма 98 байт (84 + 14 байта Ethernet заголовок). Значит нужно добавить 7 сетей, чтобы получить пакет LSA Update размером 168 байт. Добавил. «Закомитил». И произошло непредвиденное. Тупиковый роутер получил Router LSA размером 120 байт (24 байта + 8×12), или пакет размером 168 байт: 20 байт — IP заголовок, 24 байта -OSPF заголовок, 4 байта — под количество LSA (Number of LSAs), 24 байта — заголовок Router LSA-1, 96 байт — 8 сетей (по 12 байт на описание каждой сети). OSPF пакет 168 байт «пролетел» через MTU равным 160 байт входящего интерфейса тупикового роутера и был добавлена в lsdb. Не было отбрасывания пакета. Я перепроверил на другом продукте, другой прошивки. То же самое. Ошибки быть не могло. Проверил с помощью ICMP. Отправил с ABR пакет размером 133 байт без фрагментации. То есть с превышением на 1 байт (этот вендор добавляет +20 байт IP и +8 байт ICMP заголовки за сценой), итоговый размер получался 161 байт. Пакет прекрасно долетел и пришёл ответ. Я явно что-то упускал. А упускал я 30 лет развития технологий…

Ethernet давно был улучшен, концепция jumbo фрэймов давно реализована. Изучив способности обоих интерфейсов, я обнаружил прямо следом за параметром MTU и другой параметр — Maximum Frame Length. Он был равен 9216 байтам. Поддержка jumbo фрэймов была включена по умолчанию. Я мог отключить эту поддержку только одним способом — выставить минимальное допустимое значение фрейма в 1518 байт. Меньше выставить невозможно. Подозреваю, что это ограничение конкретной реализации. Размер фрейма меньше или равный 1518 байтам не является jumbo фрэймом [7]. «Что ж, если гора не хочет идти к Магомету, Магомет пойдёт к горе». Значит нужно было нарастить размер LSA со стороны ABR. Чтобы сформировать фрейм размером 1526 байт требовалось 120 сетей. Прежде чем отправить фрейм такого размера, я остановился на 119-ти сетях — хотел подойти к крайней границе и убедиться, что такой фрейм (размером 1514 байт) пройдет успешно. Он прошёл. Тупиковый роутер его принял и обновил lsdb. Но следующий фрейм с аннонсом 120 сетей он не принял. Фрейм в 1526 байт был отброшен. Счётчик ошибок на интерфейсе начал расти: Giants +1.

Есть одна деталь, которую я сокрыл намеренно для простоты изложения. На самом деле ABR не смог отправить один фрейм размером 1526 байт со 120-ю сетями, потому что размер этого пакета был 1512 байт, а это на 12 байт больше, чем сконфигурированное на нём MTU. ABR отправил два фрейма, использовав IP фрагментацию. ABR сделал сравнение размера пакета с MTU его исходящего интерфейса, в результате которого вычислил, что последнее меньше, чем размер пакета и фрагментировал пакет, отправив его двумя частями. И тупиковый роутер их принял, потому что оба эти пакеты: один в 1500 байт (фрейм 1514), и второй в 84 байта (фрейм 98)**** — прекрасно «лезли» через Maximum Frame Length в 1518 байт его принимающего интерфейса. Да, пришлось поднять MTU на исходящем интерфейсе ABR, чтобы избежать фрагментации и отправить действительно большой фрейм в 1526 байт. Тогда-то на тупиковом роутере счётчик сетей в lsdb (link counts) и застыл на 119-и, а счетчик ошибок начал расти: Giants +1.

В моём тесте пакет был отброшен и Giants +1 ошибка была сгенерирована. Не получая ACK, ABR продолжал слать это гигантское LSA, и счётчик ошибок на тупиковом роутере продолжал расти. Если бы MTU было согласовано, то такого сценария не произошло бы. Если бы ABR знал MTU тупикового роутера, то он выполнил бы фрагментацию. Перед отправкой пакета, он бы выполнил сравнение размера пакета не с MTU его исходящего интерфейса, а с OSPF-согласованным MTU! В этом суть. Если в результате первое оказалось больше второго — значит фрагментация. Если меньше или равно — пересылка без фрагментации. Другого исхода, при котором фрейм будет отброшен — нет.

Идея взаимосвязи Maximum Frame Length и MTU немного сводит с ума. В доке чётко написано [7], что на входящем интерфейсе размер пакета не проверяется, а проверяется размер фрейма — «лезет» ли он в Maximum Frame Length. О MTU роутер заботится во время отправки пакета, а во время приёма он заботится о Maximum Frame Length. Нужно осознать, что Maximum Frame Length не может быть меньше MTU.

У уважаемого читателя наверняка найдётся настольная книга в красивом твёрдом переплёте, которая лучше меня расскажет обо всех эти относительно новых улучшениях в Ethernet технологии. Моя задача состояла в том, чтобы поделиться личными опытом, а также материалами из авторитетных источников. Ясно, что опус вроде этой нельзя считать исчерпывающим. Вы, несомненно, добавите большое количество рекомендаций в свой личный перечень, также включив в него полезные инструкции от других инженеров. Я же подвожу черту под этим затянувшимся опусом кратким списком тезисов:

1.Согласование MTU — это опция, а не требование, и остаётся на усмотрение вендора.

2.Траблшутинг OSPF по причине MTU mismatch — пустая трата времени в тупиковых ариях.

3.Maximum Frame Length — новый игрок, который стоит на воротах.

4.MTU — старый игрок, который бьёт по мячу.

--

1.https://ru.wikipedia.org/wiki/%D0%9B%D0%B5%D1%81%D1%82%D0%BD%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D1%83%D0%BC.

2.OSPF Anatomy of an Internet Routing Protocol. John T.Moy, стр. 72, 60, 72.

3.Fragmentation Considered Harmful Christopher A. Kent, Jeffrey C. Mogul. http://ccr.sigcomm.org/archive/1995/jan95/ccr-9501-mogulf1.pdf, стр. 3.

4.https://datatracker.ietf.org/doc/html/rfc1583, A.1 Encapsulation of OSPF packets.

5.https://datatracker.ietf.org/doc/html/rfc2328#ref-Ref22, 10.8. Sending Database Description Packets.

6.https://support.huawei.com/hedex/hdx.do? docid=EDOC1100345000&id=EN-US_CLIREF_0000001907603308.

7.https://support.huawei.com/hedex/hdx.do? docid=EDOC1100345000&id=EN-US_CLIREF_0000001907600404.

8.https://datatracker.ietf.org/doc/html/rfc1191 Table 7–1: Common MTUs in the Internet.

--

*- ИТР — так называли внутренние тех. документы в конторе, где я работал когда-то.

** — для простоты так называю пира ABRa, с которым он устаналивает соседство в тупиковой арии. А не известную опцию stub-router, которая делает + 65535 к стоимости. https://support.huawei.com/hedex/hdx.do? docid=EDOC1100345000&id=EN-US_CLIREF_0000001907763288

*** — вендора не буду называть, потому что хочу оставаться в рамках рассмотрения концепции, а не отдельных реализаций

**** — это предположение. На этом этапе у меня сломался захватчик пакетов, поэтому точно не могу сказать какого размера были фрагменты.

***** — минимальное рекомендованное значение на этой железке.

© Habrahabr.ru