Показаны сообщения с ярлыком IPv6. Показать все сообщения
Показаны сообщения с ярлыком IPv6. Показать все сообщения

вторник, 4 апреля 2017 г.

Новые модули ядра ipfw_pmod, ipfw_nptv6 и ipfw_nat64

Вчера я закоммитил новый модуль для ipfw - ipfw_pmod, а так же смержил в stable/11 модули ipfw_nptv6 и ipfw_nat64.
Во FreeBSD 11.0 в ipfw было добавлено много нового, и среди прочего - поддержка "внешних действий", или external action. Она представляет собой интерфейс, который даёт возможность в рантайме добавлять и удалять в ipfw дополнительные действия для правил (actions, такие как allow, deny, count и прочие) . 
Как это планировалось использовать в теории. Предположим, у нас имеется стоковая FreeBSD, и ряд задач для ipfw, которые строго специфичны для нашей организации, и всем другим людям такие функции вряд ли потребуются. Чтобы не добавлять подобные функции в базовую систему, и в то же время, чтобы упростить поддержку внутри организации (адаптацию патчей с каждой новой версией), были добавлены несколько новых опкодов.
Этих опкодов (сначала их было два, теперь стало три) достаточно, чтобы реализовать практически любую новую функцию в ipfw. Имеются в виду опкоды типа action. Достаточно только подгрузить модуль ядра и правила, использующие эти новые действия будут работать. Даже стоковый бинарник ipfw(8) способен с некоторыми ограничениями отображать такие правила. Для добавления и модификации таких правил необходимо стороннее приложение, исходный код которого менять при обновлении нет необходимости.
В случае если подобный модуль достаточно полезен и для всех других людей, то достаточно включить код для добавления и отображения правил в состав ipfw(8). Ядерная же составляющая остаётся без изменений.
Используя этот интерфейс были созданы три, перечисленные в начале, модуля. Модуль ipfw_pmod предназначен для модификации пакетов различных протоколов. На данный момент он содержит в себе только опкод "tcp-setmss", который как нетрудно догадаться, модифицирует опцию TCP пакета MSS. Правило использующее это действие может выглядеть, например, так:
ipfw add tcp-setmss 1400 tcp from any to any
Работает оно примерно так же, как netgraph модуль ng_tcpmss. Но ещё и поддерживает IPv6. После обработки правилом, действие продолжается со следующего правила. Т.е. правило не прерывает поиск.

Модуль ipfw_nptv6 реализует транслятор IPv6 префиксов и работает по алгоритму, описанному в  RFC6296. Сразу хочу заметить, что трансляция IPv6 префиксов происходит несколько иначе, как можно было бы ожидать. Адреса не транслируются 1 в 1, например 2001:1000::1 не будет оттранслирован в 2a02:6b8::1. Согласно RFC адреса транслируются таким образом, что у транслятора нет необходимости делать пересчёт контрольных сумм. Поэтому в адрес добавляется некоторое число, которое делает вид адреса менее читаемым.
Использование этого модуля несколько отличается от ipfw_pmod. Здесь применяется концепция именованных экземпляров (instance) со своими собственными настройками. Прежде чем использовать nptv6 в правилах, необходимо создать именованный экземпляр и настроить его. После этого уже можно добавлять правила в ipfw:
ipfw nptv6 NPT create int_prefix fd00:dead:c0de:: ext_prefix 2001:470:7ad7:: prefixlen 48
ipfw add nptv6 NPT ip6 from any to any

Модуль ipfw_nat64 реализует транслятор IPv6 в IPv4. Он содержит две реализации stateful и stateless, и тоже использует концепцию именованных экземпляров. NAT64 без отслеживания состояний настраивается при помощи ключевого слова nat64stl. Он использует две таблицы, содержащие отображение IPv6->IPv4 и IPv4->IPv6. Согласен, это не очень удобно, но пока так.
NAT64 с отслеживанием состояний использует ключевое слово nat64lsn. Для его настройки нужен только используемый IPv4 префикс, который определяет количество ресурсов необходимых транслятору.
Оба транслятора используют Well-Known IPv6 префикс для NAT64 64:ff9b::/96. Ну и для работы конечно же нужен работающий DNS64.

понедельник, 9 января 2017 г.

Новая реализация fastfwd в FreeBSD 11

Не так давно я смержил в stable/11 обновлённую реализацию fastfwd из head/. А сегодня подошло время MFC аналогичной реализации для IPv6. Для тех кто не знает, поясню чем отличается fastfwd от обычной маршрутизации. До выхода 11-ой версии в FreeBSD было две sysctl переменных, управляющих поведением маршрутизатора: net.inet.ip.forwarding и net.inet.ip.fastforwarding. Первая включает собственно обычную маршрутизацию, т.е. пересылку входящих IPv4 пакетов, которые адресованы других хостам. Вторая - включает использование упрощённого варианта, который выполняет меньшее количество действий и не поддерживает IPsec.

Как это реализовано внутри: входящий пакет после обработки канальным уровнем (например, Ethernet) ставится в очередь обработки IP (netisr queue). Далее эта очередь обрабатывается стеком IP - функцией ip_input(). К пакету применяется ряд проверок на корректность, выполняется обработка пакетными фильтрами (на интерфейсе получения), затем определяется необходимость выполнить пересылку (т.к. пакет адресован не нам). После этого пакет передаётся в функцию маршрутизации ip_forward(). Тут у пакета уменьшается TTL, проверяется необходимость применения IPsec преобразований, выполняется поиск маршрута до адреса назначения и пакет передаётся в функцию отправки ip_output(). Здесь опять же выполняется ряд проверок, пакет передаётся на обработку пакетным фильтрам (уже на интерфейсе отправления); выполняется фрагментация, если нужно. И в конце концов пакет отправляется в канальный уровень, где после добавления Ethernet заголовка он передаётся в драйвер сетевой карты.

Вот такая, довольно громоздкая цепочка действий, в случае с включённым режимом fastforwarding, упрощается до следующих действий: входящий пакет сразу из канального уровня передаётся в функцию ip_fastforward(), где выполняются базовые проверки корректности; пакет обрабатывается пакетными фильтрами на интерфейсе получения; находится необходимый маршрут; уменьшается TTL и выполняется обработка пакетными фильтрами на интерфейсе отправления; после чего пакет сразу отправляется в канальный уровень (если нужна фрагментация, она делается тут же).

За счёт уменьшения числа действий и прямого исполнения без использования очередей netisr в итоге этот вариант получает довольно заметный прирост в производительности. Особенно если исключить из этих действий ещё и пакетные фильтры. На многоядерных процессорах и при использовании сетевых карт с несколькими очередями обработки fastfwd получает ещё более заметный прирост.

В FreeBSD 11 режим fastforwarding стал использоваться по-умолчанию. Последовательность обработки немного отличается от того, что описано выше, но принцип получения прироста производительности в общем-то сохранился.

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

Старый API, используемый для поиска маршрута, обладает таким недостатком. Поэтому обновлённая реализация использует API, который основан на наработках проекта projects/routing. Вот несколько графиков, демонстрирующих изменения в производительности от использования нового API на различном железе:

Тесты и графики построены автором проекта BSD Router Project Olivier Cochard-Labbé. Для IPv6 графиков не нашёл, но тоже можно ожидать примерно такого же роста. Ещё интересный график влияния изменений в FreeBSD CURRENT на производительность маршрутизации за 2016 год:


воскресенье, 2 декабря 2012 г.

Что нового?

Начнём с того, что я сменил работу, и теперь она напрямую связана с FreeBSD. Теперь у меня больше времени и возможностей, которые можно направить на улучшение системы. Правда, работодатель рассчитывает, что я буду прикладывать их в другое русло - оптимизация сетевой подсистемы и ipfw. Чем я и занимаюсь :)

Первой ласточкой стало то, чего давно хотелось. Ещё когда я не был коммитером, хотелось чтобы ipfw fwd работало без перекомпиляции ядра. Но тогда на моё предложение возразили, что этот функционал значительно снижает быстродействие сетевой подсистемы. Но как показали испытания, никакого снижения замечено не было. В системе хватает других мест, которые вносят значительные "тормоза".

Итак, вероятно некоторые уже заметили, что в src/UPDATING появилась запись, информирующая об удалении опции IPFIREWALL_FORWARD. Теперь этот функционал работает "из коробки", достаточно просто загрузить модуль ядра ipfw.ko. В stable/9 это изменение уже тоже есть, но в релиз оно не попадёт.

Другим крупным шагом был MFC изменений в загрузчике в stable/9. Теперь код загрузчиков в 9-ке практически идентичен тому, что в 10-ке. Я ещё думаю о переносе изменений в 8-ку, но, честно говоря не хочется этого делать. Уж очень сильно в 8-ке он отличается и придётся сделать MFC ещё для кучи ревизий. Так же, можно поблагодарить Андрея avg@ за исправление проблемы в загрузочном коде, которая обнаруживалась на некоторых "кривых" BIOS.

Кроме того, был осуществлён первых подход к изучению и тестированию IPv6 стека на производительность. Который показал плачевное состояние в этой области. Правда, благодаря профилированию и нескольким небольшим изменениям, удалось улучшить результаты почти в три раза. Не буду озвучивать цифры, они сильно зависят от железа. Но факт в том, что оптимизация IPv6 во FreeBSD - это ещё "напахано поле". Впрочем, в IPv4 базовая система тоже не блещет результатами и всего несколько строк в /boot/loader.conf и /etc/sysctl.conf может улучшить эти результаты в разы.

среда, 9 марта 2011 г.

Что нового?

... давно ничего не писал сюда (по-моему, сообщение, начинающееся с таких слов, уже было :)
На самом деле я переодически вспоминаю про блог, захожу, смотрю статистику, но почему-то не возникало желания черкнуть что-нибудь. А сегодня вот возникло.

Много всего произошло со времени написания последнего сообщения. На мой взгляд, наиболее интересные и обсуждаемые события (которые мне запомнились):
  1. Официальное объявление об окончании IPv4 адресов;
  2. Выход двух релизов FreeBSD - 7.4 и 8.2;
  3. Выход релиза Debian/kFreeBSD;
  4. Возобновление работ над новой программой установки FreeBSD;
  5. ZFS v28 наконец-то интегрирована в систему.
Забавно было наблюдать за всеобщим ажиотажем вокруг исчерпания адресного пространства IPv4. На различных сайтах то и дело появлялись новости "до исчерпания осталось N дней", и под конец люди уже часы считали. И вот, свершилось. В рассылках, форумах, чатах на несколько дней сразу активизировалось тестирование IPv6. Много вопросов о настройке, об обнаруженных проблемах... Но, прошёл месяц и что-то пыл активистов слегка угас :)
Сужу по организации где работаю я, ну и по ряду контор в нашей "деревне". У всех IPv4 адресов хватает, запасались заранее. Я даже /48 сетку IPv6 себе зарегистрировал почти 2 года назад... Хочется конечно потестировать IPv6, но в нашем городе никто из провайдеров не может обеспечить условий, на данный момент единственный способ - туннели. Изредка почитываю книжку "IPv6 Администрирование сетей", но времени пока на это нет.

Следуя уже устоявшейся традиции релизы FreeBSD были выпущены позднее предполагаемой даты. Если взглянуть на release notes, то видно, что разработка не стоит на месте и было сделано много нового. Хотя, я хронически сижу на CURRENT, и мне эти изменения как-то не особо заметны. Спасибо release notes'ам за весь список :)
Работа по подготовке и выпуску релизов проделана немалая, но не обошлось и без ложки дёгтя в бочке мёда. Как только стало известно о релизах, в списках рассылки и в gnats появились отчёты об обнаруженных проблемах. О чём это говорит? Народ не особо-то жаждет принимать участие в тестировании BETA версий, все надеются на то, что за них это сделают разработчики. А разработчики невсегда могут проверить всё и во всех возможных ситуациях.
От сюда вытекает целая тема для размышления - что запускать в промышленную эксплуатацию RELEASE, STABLE или может CURRENT? И я склоняюсь больше к последним двум, но это только моя точка зрения и она основана на моём опыте, моих задачах и количестве машин :)

Debian GNU/kFreeBSD - ещё одна штука, о которой много говорили. Даже в IRC канале разработчиков FreeBSD её вспоминали не раз и не два. Мнения разные, но стоит признать и принять то, что разработчики Debian достаточно настырные ребята. Я скачал один ISO образ, установил вчера в VirtualBox'е, но пока не смотрел.

Возобновление работ над новой программой установки было быстрым и неожиданным. Если не помните, то Warner Losh некоторое время назад начал работу над интеграцией PC-BSD'шной программы установки. Он даже в head/ уже интегрировал её. И вот, тут появился Nathan Whitehorn с ещё одним инсталлятором - bsdinstall. Причём появился он так внезапно и активно внедряя свой инсталлятор, что даже Warner растерялся. А ещё этот процесс сопровождался обновлением библиотеки libdialog.
Надо заметить, что новая библиотека libdialog коренным образом отличается от нашей старой. Она, конечно, в плане возможностей стала значительно интереснее, но всё так же не позволяет делать то, что хотелось мне реализовать в sade, в связи с чем я и сделал customdlg.
В итоге, Nathan и Warner нашли общий язык и согласились, что стоит объединить усилия и создать нечто на основе того, что уже сделано ими. Это нечто планируется сделать инсталлятором по-умолчанию для FreeBSD 9.0+, релиз которой, кстати, уже не за горами.
Что же касается sade, то Nathan признаёт, что он удобнее его partedit'а и было бы неплохо, интегрировать его в систему. Вот только нужно опять убить кучу времени на изучение этой libdialog и адаптацию того, что уже написано под неё :(

ZFS v28 уже в head/. Я вчера обновил систему на домашнем компе, но ZFS пока не обновлял. На первый взгляд вроде всё работает после обновления, хотя некоторые жалуются на аномально высокую нагрузку. Через пару дней попробую обновиться...

О своей деятельности сказать особо нечего, закрыл несколько PR связанных с паниками в GEOM, в ноду ng_one2many добавил новый алгоритм NG_ONE2MANY_XMIT_FAILOVER (патч от Максима Игнатенко). Вчера добавил новый ключик для команды `gpart show -p`. Предназначен он для вывода имён провайдеров вместо индексов разделов:

> gpart show -p
=>       34  156301421    ada0  GPT  (75G)
         34        512  ada0p1  freebsd-boot  (256K)
        546    8388608  ada0p2  freebsd-swap  (4.0G)
    8389154  147912301  ada0p3  freebsd-zfs  (71G)