Принципы функционирования сетевой подсистемы, многопоточная модель сетевого стека
Как и другие системные службы микроядерной операционной системы, сетевая подсистема реализована в виде отдельного от ядра процесса. Разработчикам предоставляет единый унифицированный интерфейс независимый от конфигурации и количества задействованных сетей.
Такой подход позволяет:
Сетевая подсистема ЗОСРВ «Нейтрино» состоит из исполняемого модуля сетевого менеджера ( io-pkt-ksz, io-pkt-v4, io-pkt-v4-hc или io-pkt-v6-hc) и одного или нескольких модулей разделяемых библиотек. Эти модули могут включать в себя протоколы (например, lsm-qnet.so) и драйверы ( devnp-e1000.so).
Действуя как своего рода редиректор/мультиплексор пакетов, io-pkt-* отвечает за загрузку драйверов и модулей на базе настроек переданных в командной строке (или при помощи команды mount после того, как io-pkt-* запущен).
Основной принцип организации компонентов сетевой подсистемы – нулевое копирование данных (англ. zero-copy). Исполняемый модуль io-pkt-* динамически загружает несколько сетевых протоколов или драйверов (например, lsm-qnet.so) на лету. Все эти модули являются разделяемыми библиотеками.
Стек схож по архитектуре с другими подсистемами. На нижнем уровне расположены драйверы, которые обеспечивают приёмо-передачу данных и интерфейс с оборудованием. Они подключаются к следующему, многопоточному, уровню, который также выполняет функцию моста и ретранслятора пакетов. Данный уровень связывает все драйвера вместе и обеспечивает унифицированный интерфейс передачи пакетов в модули стека, отвечающие за обработку протоколов. К ним относятся, например, обработка IP-пакетов и протоколов более высокого уровня, таких как TCP и UDP.
В вершине стека функционирует менеджер ресурсов, выполняющий роль посредника в передаче сообщений между стеком и пользовательскими приложениями. Он предоставляет стандартный тип интерфейса, поддерживающий клиентские вызовы open(), read(), write() и ioctl(). Сетевые приложения, разработанные пользователями стека, линкуются с сетевой библиотекой сокетов ( libsocket). Она преобразует интерфейс передачи сообщений, предоставляемый стеком, в API стандартных BSD-сокетов, являющийся стандартом для большинства сетевых приложений.
На уровне драйверов предоставляются интерфейсы для Ethernet трафика и управления кадрами 802.11. Вариант стека с суффиксом hc также включает отдельное аппаратное криптографическое API, которое позволяет стеку использовать криптографическую подсистему для кодирования и декодирования данных для защищённых каналов. Динамические библиотеки драйверов можно загрузить в стек используя опцию -d при вызове io-pkt-*. Драйверы обычно размещаются в каталоге /lib/dll
и имеют префикс devnp-
для драйверов нового типа и devn-
для старых однопоточных драйверов.
Программные интерфейсы, предоставляющее возможность контроля пакетов Ethernet или IP в потоке данных, позволяет модулям протоколов сосуществовать в процессе стека. Протоколы (такие, как Qnet) также выполнены в виде разделяемых библиотек. Они напрямую связаны с IP или Ethernet уровнями и функционируют в контексте стека. Файлы этих библиотек начинаются с префикса lsm (от англ. loadable shared module). Их можно загрузить в стек используя опцию -p. Протокол tcpip (-ptcpip) – это специальный аргумент, который не используется для загрузки модуля в стек, поскольку IP уровень загружается всегда (встроен в стек). Однако, опцию -ptcpip можно использовать для передачи дополнительных параметров IP протокола. Например, -ptcpip prefix=/alt указывает стеку регистрировать префикс /alt/dev/socket
в качестве имени менеджера ресурсов.
Протокол, требующий взаимодействия с клиентским приложением, расположенного вне процесса стека, может включать свою собственную программную инфраструктуру (например, собственный менеджер ресурсов) для взаимодействия и динамического конфигурирования. Это требуется, например, протоколу распределенной сети Qnet.
В дополнение к драйверам и протоколам, стек также включает средства пакетной фильтрации. Основные интерфейсы, поддерживающие фильтрацию:
В обычном режиме работы менеджер io-pkt-* создаёт по одному потоку на каждый процессор в системе. Стек io-pkt-* полностью многопоточный на втором уровне. Однако, только один поток может получить доступ к "контексту стека" для обработки пакетов на верхнем уровне. Если требуется одновременное обслуживание множества источников прерываний, они могут быть обслужены несколькими потоками. При этом только один поток будет обслуживать конкретное прерывание в единицу времени. Прерывание от сетевого устройства обычно указывает, что были получены пакеты, требующие обработки. Поток, который отвечает за приём, может позже передать эти пакеты другому интерфейсу. Примером может служить мост второго уровня и быстрая пересылка (fast-forwarding) IP-пакетов (англ. ipflow).
Стек использует пул потоков для обслуживания событий, которые генерируются другими частями системы. Такими события могут быть:
Приоритет, на котором запускается поток приёма пакетов, может быть установлен при помощи опции драйвера, заданной в командной строке. Клиентские соединения обслуживаются с плавающим приоритетом – приоритет обслуживающего потока совпадает с приоритетом клиентского потока, обратившегося к менеджеру ресурсов стека.
Когда поток получает событие, он анализирует его тип и определяет его источник – аппаратное событие, событие стека или "другое":
Возможность переключаться потока с обслуживания аппаратных событий на обслуживание внутренних, исключает необходимость переключения контекстов, что значительно повышает производительность приема пакетов, предназначенных для локального узла.
Модули протоколов отвечают за реализацию конкретного сетевого протокола (например, Qnet и TCP/IP). Все модули протоколов реализованы в виде отдельных разделяемых объектов (например, lsm-qnet.so) и могут функционировать одновременно и независимо.
Например, следующая строка из файла построения загрузочного образа, требует загрузки io-pkt-ksz с двумя протоколами (TCP/IP неявно и Qnet явно), указанными с помощью опции -p:
io-pkt-v4 -de1000 -pqnet
Параметры опции -p:
Протокол Qnet также поддерживает политики качества обслуживания QoS (англ. Quality of Service) для обеспечения надежности передачи данных.
Более подробные сведения о данных протоколах можно найти в следующих статьях:
Данные модули сетевого стека отвечают за управление конкретными сетевыми адаптерами и по своей сути являются драйверами. Каждый из них реализуется как отдельный разделяемый объект и может быть независимо загружен сетевым стеком io-pkt-*.
После запуска io-pkt-* появляется возможность динамической загрузки драйверов из командной строки с помощью утилиты mount. В следующем примере запускается вариант сетевого стека io-pkt-v6-hc и только после этого подгружается драйвер адаптеров семейства Broadcom 57xx:
io-pkt-v6-hc & mount -T io-pkt devnp-bge.so
Все современные драйвера сетевых устройств являются разделяемыми объектами с именем виде devnp-driver.so. Типичное место их размещения – /lib/dll
.
![]() | Менеджер сетевого стека io-pkt-* также поддерживает устаревшие сетевые драйвера, имеющие формат имени devn-driver.so. Они не поддерживают применяемую модель многопоточности и исполняются в однопоточном режиме, что делает их условно низко производительными.
В общем случае их применение не рекомендуется. В некоторых случаях могут существовать одноименные драйвера с разными префиксами, определяющими их вид. Приоритет следует отдавать современным драйверам и внимательно контролировать оптимальность конфигурации проектируемой системы. |
После загрузки и инициализации драйвера, они со стеком вызывают друг друга для решения общих задач: драйвер вызывает стек, например, при получении данных от устройства, в ответ, стек обращается к драйверу при передаче пакетов от приложений.
Для выгрузки устаревшего драйвера используется команда umount:
umount /dev/io-net/en0
Для драйверов любого типа также может быть использована команда ifconfig destroy:
ifconfig bge0 destroy
Подробные сведения о драйверах сетевых устройств можно найти на странице документации Драйверы :: Сетевая подсистема.
Предыдущий раздел: перейти