Для чего предназначена программа netlink кратко
Обновлено: 07.07.2024
NETLINK
Протокол netlink используется для передачи информации между ядром ипроцессами в пользовательском пространстве. Он состоит из стандартного,основанного на сокетах, интерфейса для процессов пользователя и внутреннегоAPI ядра, предназначенного для модулей ядра. Внутренний интерфейс ядра вэтой странице не описан. Кроме того, существует устаревший интерфейсnetlink, работающий через символьные устройства netlink. Этот интерфейсздесь также не описан; он предназначен только для обратной совместимости.
Netlink обеспечивает для приложений сервис передачи датаграмм. В качестве socket_type могут использоваться типы сокетов как SOCK_RAW , так и SOCK_DGRAM . Несмотря на это, протокол netlink не различает датаграмные инеструктурированные (raw) сокеты.
После каждого nlmsghdr следует полезная нагрузка:
Заметим, что NLM_F_ATOMIC требует мандата CAP_NET_ADMIN илиэффективного UID 0.
Дополнительные биты флагов для запросов NEW | |
NLM_F_REPLACE | Переписать существующий подходящий объект. |
NLM_F_EXCL | Не перезаписывать, если объект уже существует. |
NLM_F_CREATE | Создать объект, если он ещё не существует. |
NLM_F_APPEND | Добавить в конец списка объектов. |
Тип поля nlmsg_seq и nlmsg_pid скрыт в ядре netlink.
Форматы адресов
Структура sockaddr_nl описывает клиент netlink в пространствепользователя или в ядре. Она может быть как одноадресной (передачаинформации только на один адрес), так и посылаться многоадресной группеnetlink (значение nl_groups не равно нулю).
nl_pid — одиночный адрес сокета netlink. Он всегда равен 0, если местомназначения является ядро. Для процесса пользовательского пространствазначение nl_pid , обычно, равно PID процесса, которому принадлежит сокетназначения. Однако, значением nl_pid определяется сокет netlink, а непроцесс. Если процессу принадлежит несколько сокетов netlink, то значение nl_pid может быть равно ID процесса только у одного сокета. Есть дваспособа назначить nl_pid сокету netlink. Если приложение задаёт nl_pid до вызова bind (2), то приложение само должно убедиться, что значение nl_pid уникально. Если приложение устанавливает его равным 0, топрисвоение уникального значения выполняется ядром. Первому сокету netlinkядро назначает ID процесса, который его открыл, а всем последующимсоздаваемым процессом сокетам netlink, будет назначено уникальное значение nl_pid .
Параметры сокета
ВЕРСИИ
Linux 2.0 поддерживал более примитивный интерфейс на основе устройств(который всё ещё доступен для совместимости). Этот устаревший интерфейсздесь не описывается.
ЗАМЕЧАНИЯ
В большинстве случаев лучше использовать netlink с помощью функций библиотек libnetlink или libnl , а не через низкоуровневый интерфейс ядра.
ДЕФЕКТЫ
ПРИМЕР
В следующем примере создаётся сокет netlink семейства NETLINK_ROUTE ,который будет прослушивать многоадресные группы RTMGRP_LINK (события осоздании/удалении/включении/выключении сетевых интерфейсов) и RTMGRP_IPV4_IFADDR (события о добавлении/удалении адресов IPv4).
Сокет Netlink используется для достиженияПользовательский процесспротивПроцесс ядраСпециальная межпроцессная связь (IPC) также является наиболее часто используемым интерфейсом для связи между сетевыми приложениями и ядром.
В ядре Linux есть много приложений, которые используют netlink для связи с ядром, например
- Демон маршрутизации (NETLINK_ROUTE)
- Протокол сокета пользовательского режима (NETLINK_USERSOCK)
- Брандмауэр (NETLINK_FIREWALL)
- подсистема netfilter (NETLINK_NETFILTER)
- События ядра для уведомления пользовательского режима (NETLINK_KOBJECT_UEVENT)
- Общий сетевой канал (NETLINK_GENERIC)
Netlink - очень хороший способ двусторонней передачи данных между ядром и пользовательскими приложениями.Приложения пользовательского режима могут использовать стандартные API-интерфейсы сокетов для использования мощных функций, предоставляемых netlink, в то время как режим ядра должен использовать специальные API-интерфейсы ядра для использования netlink.
Вообще говоря, существует три способа связи между пользовательским пространством и пространством ядра: /proc、ioctl、Netlink . Первые два являются однонаправленными, и Netlink может реализовать дуплексную связь.
По сравнению с системными вызовами, файловой системой ioctl и / proc, Netlink имеет следующие преимущества:
Протокол Netlink основан на сокете BSD и AF_NETLINK Кластер адресов, использующий 32-битную адресацию номера порта, каждый протокол Netlink обычно связан с одной или группой основных служб / компонентов, таких как NETLINK_ROUTE Используется для получения и установки информации о маршрутах и ссылках, NETLINK_KOBJECT_UEVENT Используется ядром для отправки уведомлений процессу udev в пользовательском пространстве и т. Д.
Два, структура данных пользовательского режима
Приложения пользовательского режима используют стандартные API-интерфейсы сокетов, такие как sendto (), recvfrom (), sendmsg (), recvmsg ().
Связь Netlink похожа на обычную связь UDP Socket, struct sockaddr_nl Это коммуникационный адрес netlink, который совпадает с обычным socket struct sockaddr_in похожий.
1. Структура struct sockaddr_nl:
2. Структура struct nlmsghd:
3. Структура struct msghdr
Три, структура данных ядра netlink
2. Часто используемые макросы Netlink:
3. Общие функции ядра Netlink
Функция ядра netlink_kernel_create используется для создания сокета ядра и взаимодействия с пользовательским режимом.
4. Одноадресная передача netlink_unicast () и многоадресная передача netlink_broadcast ()
Однажды, в одном из проектов, мне понадобилось организовать строгий и надежный контроль над всеми сетевыми интерфейсами, таблицами маршрутизации, а так же получать нотификации о каких-либо изменениях. Было принято стратегическое решение — не использовать старые-добрые ioctl netdevice (SIOCGIFMETRIC, SIOCSIFNAME и т.п.) или непосредственные вызовы соответствующих утилит (ifconfig, route и т.д.), а найти более современное и болле удобное решение. Оно было найдено — libnetlink. Это библиотека, предоставляющая большое количество методов для коммуникации с ядром, с помощью механизма netlink. Данная библиотека идеально подходила для моих целей, позволяя решить огромное количество задач. К сожалению, у библиотеки оказался не особо удобный и довольно сложный API, требовавший совершать множество непонятных действий. Особого веселья добавляло практически полное отсутствие документации и вообще любых материалов на эту тему.
Подумав, я решил как следует разобраться в netlink и написать свою библиотеку. В данный момент реализован весь функционал для работы с нотификацией, сетевыми интерфейсами, таблицами маршрутизации, разумеется поддерживаются IPv4 и IPv6. В достаточно скором времени данный проектик будет представлен на суд общественности :) А пока я бы хотел познакомить всех интересующихся с прекрасным миром netlink, на примере простого монитора сетевых интерфейсов.
Что такое netlink?
Создание сокета netlink.
Объявление netlink сокета выглядит вполне стандартно:
socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
Где AF_NETLINK — протокол netlink
SOCK_RAW — тип сокета
NETLINK_ROUTE — семейство netlink протокола.
Последний параметр может быть различным, в зависимости от того, что мы именно хотим получить от netlink.
Приведу таблицу со наиболее интересными параметрами (полный список параметров можно посмотреть в документации):
NLM_F_REPLACE — заменить существующий аналогичный объект
NLM_F_EXCL — не заменять, если такой объект уже существует
NLM_F_CREATE — создать объект, если он не существует
NLM_F_APPEND — добавить объект в список к уже существующему
Для идентификации клиентов (на уровне ядра и на пользовательском уровне) существует специальная адресная структура — nladdr:
nl_groups — это битовая маска, каждый бит которой представляет номер группы netlink. При вызове bind() для сокета netlink следует указывать битовую маску группы, которую желает прослушивать приложение, в данном контексте. Различные группы могут быть объединены с помощью логического или.
Основные группы определены в заголовочном файле netlink.
Пример некоторых из них:
RTMGRP_LINK — эта группа получает уведомления об изменениях в сетевых интерфейсах (интерфейс удалился, добавился, опустился, поднялся)
RTMGRP_IPV4_IFADDR — эта группа получает уведомления об изменениях в IPv4 адресах интерфейсов (адрес был добавлен или удален)
RTMGRP_IPV6_IFADDR — эта группа получает уведомления об изменениях в IPv6 адресах интерфейсов (адрес был добавлен или удален)
RTMGRP_IPV4_ROUTE — эта группа получает уведомления об изменениях в таблице маршрутизации для IPv4 адресов
RTMGRP_IPV6_ROUTE — эта группа получает уведомления об изменениях в таблице маршрутизации для IPv6 адресов
После структуры заголовка nlmsghdr всегда расположен указатель на блок данных. Доступ к нему можно получить с помощью макросов, о которых будет рассказано далее.
Макросы netlink
От теории к практике.
Ну что же. Думаю, что я уже успел надоесть со скучной теорией :) Может быть что-то показалось запутанным или не понятным — постараюсь разжевать все в наглядных примерах, там на самом деле нет ничего сложного.
Ниже приведено обещанное приложение, которое будет получать уведомления об изменениях в сетевых интерфейсах и таблице маршрутизации.
В примере введен целый ряд новых структур:
Эта структура непосредственно передается через сокет. Она содержит в себе указатель на блок полезных данных, количество данных блоков, а так же ряд дополнительных флагов и полей, пришедших, по большей части, с платформы BSD.
Эта структура используется для представления сетевого устройства, его семейства, типа, индекса и флагов.
Эта структура служит для представления сетевого адреса, назначенного на сетевой интерфейс.
Эта структура служит для хранения какого либо параметра соединения или адреса.
Исходный код, монитор
Компиляция программы:
gcc monitor.c -o monitor
И результат работы:
Вот и все. Очень надеюсь, что данный материал будет полезен кому-то.
Если будет достаточное количество желающих (больше одного человека:) ) — могу написать продолжение и рассмотреть, например, взаимодействие с модулем ядра или реализацию работы с IPv6.
- NETLink – основной модуль по организации и поддержанию коммуникационного канала
- NETLinkConfig – конфигуратор модуля NETLink
- NETLinkLogger – монитор журнала событий активности соединений GSM шлюзов и ПО сбора данных
Описание
Пользовательскому ПО предоставляется два варианта обмена данными с приборами на удаленном объекте:
Гибкость в выборе вариантов дает возможность применения также и программы производителя прибора учета в целях конфигурирования, чтения данных и т.п., что позволяет отказаться от дополнительных затрат на организацию выезда специалиста на объект для настройки прибора учета.
Дополнительные возможности программы:
Конвертация форматов Modbus позволяет подсоединять к GSM шлюзам на удаленных объектах оборудование, работающее по последовательному порту с использованием протокола Modbus/RTU. После выполнения конвертации, данные в пользовательское приложение, поступают по протоколу Modbus TCP. Это предоставляет возможность сбора данных с оборудования объекта средствами SCADA-систем.
При использовании GSM шлюзов RG 104/105 в модификации с дискретными входами/выходами Сервер соединений обеспечивает считывание информации о состоянии входов и управление выходами по протоколу Modbus TCP.
ОПИСАНИЕ
Протокол netlink используется для передачи информации между ядром и процессами в пользовательском пространстве. Он состоит из стандартного, основанного на сокетах, интерфейса для процессов пользователя и внутреннего API ядра, предназначенного для модулей ядра. Внутренний интерфейс ядра в этой странице не описан. Кроме того, существует устаревший интерфейс netlink, работающий через символьные устройства netlink. Этот интерфейс здесь также не описан; он предназначен только для обратной совместимости.
Netlink обеспечивает для приложений сервис передачи датаграмм. В качестве socket_type могут использоваться типы сокетов как SOCK_RAW, так и SOCK_DGRAM. Несмотря на это, протокол netlink не различает датаграмные и неструктурированные (raw) сокеты.
По значению netlink_family выбирается модуль ядра или группа netlink для связи. В данный момент определены следующие семейства netlink:
После каждого nlmsghdr следует полезная нагрузка:
Заметим, что NLM_F_ATOMIC требует мандата CAP_NET_ADMIN или эффективного UID 0.
Дополнительные биты флагов для запросов NEW | |
NLM_F_REPLACE | Переписать существующий подходящий объект. |
NLM_F_EXCL | Не перезаписывать, если объект уже существует. |
NLM_F_CREATE | Создать объект, если он ещё не существует. |
NLM_F_APPEND | Добавить в конец списка объектов. |
Тип поля nlmsg_seq и nlmsg_pid скрыт в ядре netlink.
Форматы адресов
Структура sockaddr_nl описывает клиент netlink в пространстве пользователя или в ядре. Она может быть как одноадресной (передача информации только на один адрес), так и посылаться многоадресной группе netlink (значение nl_groups не равно нулю).
nl_pid — одиночный адрес сокета netlink. Он всегда равен 0, если местом назначения является ядро. Для процесса пользовательского пространства значение nl_pid, обычно, равно PID процесса, которому принадлежит сокет назначения. Однако, значением nl_pid определяется сокет netlink, а не процесс. Если процессу принадлежит несколько сокетов netlink, то значение nl_pid может быть равно ID процесса только у одного сокета. Есть два способа назначить nl_pid сокету netlink. Если приложение задаёт nl_pid до вызова bind(2), то приложение само должно убедиться, что значение nl_pid уникально. Если приложение устанавливает его равным 0, то присвоение уникального значения выполняется ядром. Первому сокету netlink ядро назначает ID процесса, который его открыл, а всем последующим создаваемым процессом сокетам netlink, будет назначено уникальное значение nl_pid.
ВЕРСИИ
Linux 2.0 поддерживал более примитивный интерфейс на основе устройств (который всё ещё доступен для совместимости). Этот устаревший интерфейс здесь не описывается.
NETLINK_SELINUX появился в Linux 2.6.4.
NETLINK_AUDIT появился в Linux 2.6.6.
NETLINK_KOBJECT_UEVENT появился в Linux 2.6.10.
NETLINK_W1 и NETLINK_FIB_LOOKUP появились в Linux 2.6.13.
NETLINK_INET_DIAG, NETLINK_CONNECTOR и NETLINK_NETFILTER появились в Linux 2.6.14.
NETLINK_GENERIC и NETLINK_ISCSI появились в Linux 2.6.15.
ЗАМЕЧАНИЯ
В большинстве случаев лучше использовать netlink с помощью функций библиотек libnetlink или libnl, а не через низкоуровневый интерфейс ядра.
ДЕФЕКТЫ
ПРИМЕР
В следующем примере создаётся сокет netlink семейства NETLINK_ROUTE, который будет прослушивать многоадресные группы RTMGRP_LINK (события о создании/удалении/включении/выключении сетевых интерфейсов) и RTMGRP_IPV4_IFADDR (события о добавлении/удалении адресов IPv4).
Читайте также: