Для чего предназначена программа 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).

Читайте также: