Семья гнезда Netlink — ядерный интерфейс Linux, используемый для коммуникации межпроцесса (IPC) между ядром и процессами userspace, а также между пользовательскими процессами в пути, подобном гнездам области Unix. Однако в отличие от гнезд INET, коммуникация Netlink не может пересечь границы хозяина, потому что Netlink обрабатывает адреса идентификаторами процесса (PIDs), которые являются неотъемлемо местными.
Нетлинк разрабатывается и используется для передачи разной сетевой информации между ядерным пространством и процессами userspace. Сетевые утилиты, такие как iproute2 семья и утилиты, используемые для формирования находящихся в mac80211 беспроводных драйверов, используют Нетлинка, чтобы общаться с ядром Linux от userspace. Нетлинк обеспечивает стандартный основанный на гнезде интерфейс для процессов userspace и API ядерной стороны для внутреннего пользования ядерными модулями. Первоначально, Нетлинк использовал семью гнезда.
Netlink разработан, чтобы быть более гибким преемником ioctl; RFC 3549 описывает протокол подробно.
TM 6 не открывается выбора типа проекта
История
Netlink был создан Алексеем Кузнецовым как более гибкая альтернатива сложному, но неловкому коммуникационному методу, который программное обеспечение использовало для урегулирования и получения внешних вариантов гнезда. Ядро Linux продолжает поддерживать для обратной совместимости. Это может использоваться следующим образом:
Netlink сначала предоставили в 2,0 сериях ядра Linux, осуществленного как устройство характера. К 2013 этот интерфейс устаревший, но все еще формирует ioctl коммуникационный метод; сравните использование. Интерфейс гнезда Netlink появился в 2,2 сериях ядра Linux.
Структура пакета
В отличие от доступа гнезда BSD к интернет-протоколам, таким как TCP, где заголовки, определяющие флаги и место назначения, самозарождены, заголовок сообщения Netlink (доступный как) должен быть подготовлен посетителем, потому что гнездо обычно работает в — как способ, даже если использовался, чтобы создать его.
Часть данных тогда содержит определенное для подсистемы сообщение, которое может быть далее вложено.
Семьи гнезда Netlink
Семья предлагает многократные подмножества протокола. Каждый взаимодействует к различному ядерному компоненту и имеет различное передающее подмножество. На следующий протокол ссылаются в области ниже:
Недостаток в стандарте, и, как гарантируют, не будет осуществлен в данном Linux (или другой OS) выпуск. Некоторые источники заявляют, что оба варианта законны, и ссылка ниже от Красных государств Шляпы, который всегда является параметром, однако iproute2 использует обоих попеременно.
Протоколы Netlink
Неисчерпывающий список поддержанных записей протокола следует:
обеспечивает информация о связи и направление. Эта информация используется прежде всего для демонов направления пространства пользователя. Linux осуществляет большое подмножество сообщений:
- Слой связи: RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK, RTM_SETLINK
- Параметры настройки адреса: RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR
- Таблицы маршрутизации: RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE
- Соседний тайник: RTM_NEWNEIGH, RTM_DELNEIGH, RTM_GETNEIGH
- Правила направления: RTM_NEWRULE, RTM_DELRULE, RTM_GETRULE
- Стоящие в очереди параметры настройки дисциплины: RTM_NEWQDISC, RTM_DELQDISC, RTM_GETQDISC
- Транспортные классы использовали с очередями: RTM_NEWTCLASS, RTM_DELTCLASS, RTM_GETTCLASS
- Транспортные фильтры: RTM_NEWTFILTER, RTM_DELTFILTER, RTM_GETTFILTER
- Другие: RTM_NEWACTION, RTM_DELACTION, RTM_GETACTION, RTM_NEWPREFIX, RTM_GETPREFIX, RTM_GETMULTICAST, RTM_GETANYCAST, RTM_NEWNEIGHTBL, RTM_GETNEIGHTBL, RTM_SETNEIGHTBL
обеспечивает интерфейс для приложения пространства пользователя, чтобы получить пакеты от брандмауэра.
Ethernet на пальцах
обеспечивает интерфейс раньше общался между используемым Netfilter и iptables.
обеспечивает интерфейс, чтобы управлять столом ARP от пространства пользователя.
обеспечивает интерфейс контрольной подсистеме, найденной в ядерных версиях Linux 2.6.6 и позже.
обеспечивает интерфейс, чтобы транспортировать пакеты от netfilter до пространства пользователя.
обеспечивает интерфейс, чтобы управлять сопоставлением безопасности IPsec и базами данных политики безопасности — главным образом используемый демонами ключевого менеджера, использующими интернет-Ключ Обменный протокол.
Определенный пользователями протокол Netlink
Пользователи могут добавить укладчика Netlink в своем собственном ядерном распорядке. Это позволяет развитию дополнительных протоколов Netlink обращаться к новым ядерным модулям.
См. также
- Сравнение общедоступных беспроводных драйверов – находящиеся в mac80211 водители полагается на netlink как на API к пространству пользователя
- POSIX
Внешние ссылки
- Пабло Неира Айусо, Рафаэль М. Гэска, Лоран Лефевр. Сообщение между ядром и пространством пользователя в использовании Linux гнезда Netlink. Программное обеспечение: Практика и Опыт, 40 (9):797-810, август 2010
- Почему и как использовать гнезда Netlink
- http://netfilter .org/projects/libmnl — “минималистская Библиотека для Netlink” — userspace библиотека для строительства и парсинга сообщений Netlink
- http://www .infradead.org / ~ tgr/libnl = «Netlink Protocol Library Suite» — полная функциональная библиотека, покрывающая почти все аспекты работы с netlink гнездами
- Управление сетевой окружающей средой Используя RTNETLINK
- Гнезда Netlink – обзор
- Netlink Protocol Library Suite
- Сообщение между ядром и пространством пользователя в использовании Linux гнезда Netlink
- «Ядро Linux, общающееся через Интернет» Рами Розеном, Apress 2013: глава 2, гнезда Netlink
Источник: ru.knowledgr.com
Глубокое погружение в Linux namespaces, часть 4
В завершающем посте этой серии мы рассмотрим Network namespaces. Как мы упоминали в вводном посте, network namespace изолирует ресурсы, связанные с сетью: процесс, работающий в отдельном network namespace, имеет собственные сетевые устройства, таблицы маршрутизации, правила фаервола и т.д. Мы можем непосредственно увидеть это на практике, рассмотрев наше текущее сетевое окружение.
Команда ip
Поскольку в этом посте мы будем взаимодействовать с сетевыми устройствами, мы вернем жесткое требование наличия прав суперпользователя, которое мы смягчили в предыдущих постах. С этого момента мы будем предполагать, что как ip , так и isolate будут запускаться с sudo .
$ ip link list 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:96:2e:3b brd ff:ff:ff:ff:ff:ff
Звездой шоу здесь является команда ip — швейцарский армейский нож для работы с сетью в Linux — и мы будем активно использовать её в этом посте. Прямо сейчас мы только что выполнили подкоманду link list , чтобы увидеть, какие сетевые устройства в настоящее время доступны в системе (здесь есть lo — loopback-интерфес и `ens33, ethernet-интерфейс LAN.
Как и со всеми другими пространствами имён, система стартует с начальным network namespace, которому принадлежат все процесс процессы, если не задано иное. Выполнение команды ip link list как есть показывает нам сетевые устройства, принадлежащие изначальному пространству имён (поскольку и наш шелл, и команда ip принадлежат этому пространству имён).
Именованные пространства имён Network
Давайте создадим новый network namespace:
$ ip netns add coke $ ip netns list coke
И снова мы использовали команду ip . Подкоманда netns позволяет нам играться с пространствами имён network: например, мы можем создавать новые сетевые пространства network с помощью подкоманды add команды netns и использовать list для их вывода.
Вы могли заметить, что list возвращал только наш вновь созданный namespace. Разве он не должен возвращать по крайней мере два, одним из которых был бы исходным namespace, о котором мы упоминали ранее? Причина этого в том, что ip создаёт то, что называется named network namespace, который является просто network namespace, идентифицируемый уникальным именем (в нашем случае coke ). Только именованные пространства имён network отображаются подкомандой list , а изначальный network namespace не именованный.
Проще всего получить именованные пространства имён network. Например, в каждом именованном network namespace создаётся файл в каталоге /var/run/netns и им сможет воспользоваться процесс, который хочет переключиться на свой namespace. Другое свойство именованных пространств имён network заключается в том, что они могут существовать без наличия какого-либо процесса — в отличие от неименованных, которые будут удалены как только завершатся все принадлежащие им процессы.
Теперь, когда у нас есть дочерний network namespace, мы можем взглянуть на сеть с его точки зрения.
Мы будем использовать приглашение командной строки C$ для обозначения шелла, работающего в дочернем network namespace.
$ ip netns exec coke bash C$ ip link list 1: lo: mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
Запуск субкоманды exec $namespace $command выполняет $command в именованном network namespace $namespace . Здесь мы запустили шелл внутри пространства имён coke и посмотрели доступные сетевые устройства. Мы видим, что, по крайней мере, наше устройство ens33 исчезло. Единственное устройство, которое видно, это лупбек и даже этот интерфейс погашен.
C$ ping 127.0.0.1 connect: Network is unreachable
Linux, Netlink и Go — Часть 3: пакеты netlink, genetlink и wifi
Я перемещаю содержимое своего блога на mdlayher.com. Пожалуйста, смотрите обновленную версию этого контента по адресу:
В Части 1 и Части 2 этой серии я описал некоторые фундаментальные концепции netlink и общих netlink. Предполагается, что читатели уже знакомы с netlink и универсальным netlink из предыдущих сообщений этой серии.
В этом посте я подробно расскажу о концепциях высокого уровня и использовании моих пакетов Go:
- netlink: обеспечивает низкоуровневый доступ к сокетам netlink Linux.
- genetlink: общие взаимодействия сетевых ссылок и типы данных.
- Wi-Fi: обеспечивает доступ к действиям и статистике устройства IEEE 802.11 WiFi.
Сериал разделен на следующие части:
- Часть 1: netlink: введение в netlink.
- Часть 2: универсальные сетевые ссылки: введение в универсальные сетевые ссылки, семейство сетевых ссылок, предназначенное для упрощения создания новых семейств.
- Часть 3 (этот пост): пакеты netlink, genetlink и wifi: использование Go для управления взаимодействиями с netlink, generic netlink и nl80211.
Пакет netlink
Когда я впервые решил изучить возможность получения информации об устройстве Wi-Fi в Linux, мой коллега указал мне на netlink как на возможное решение. Я был знаком с несколькими существующими пакетами netlink для Go, но не смог найти тот, который, по моему мнению, соответствовал моим потребностям.
Некоторые из существующих популярных пакетов приняли решения, которые меня не устроили:
- отсутствие документации
- отсутствие тестов
- раздутый API
- API Go, похожий на C
Кроме того, многие из этих пакетов объединяли понятия netlink, route netlink и семейство утилит iproute2. По этим причинам я решил начать сборку собственного пакета.
Важно отметить, что пакет netlink предназначен для использования в качестве строительного блока для других пакетов семейства netlink. Как правило, вместо этого вы будете использовать пакет более высокого уровня, например genetlink . Чтобы обеспечить максимальное повторное использование кода, создавайте специальные пакеты для любых семейств сетевых ссылок высокого уровня вместо того, чтобы строить их поверх пакета netlink в вашем приложении.
В этом разделе будут обсуждаться некоторые распространенные варианты использования пакета netlink, но вы можете обратиться к исходному коду и документации для получения дополнительной информации.
netlink.Conn: подключение к netlink
Тип netlink.Conn используется для создания подключений к netlink. Семейство netlink указывается в вызове netlink.Dial вместе с дополнительной конфигурацией, если это необходимо.
Важно отметить, что, когда netlink.Conn больше не нужен, необходимо вызвать netlink.Conn.Close , чтобы закрыть сокет и избежать утечки файловых дескрипторов.
Как только соединение установлено, его можно использовать для отправки запроса, получения ответа и проверки ответа на запрос. Многие поля заголовка запроса могут быть опущены, чтобы позволить пакету netlink вычислить и присвоить эти значения автоматически.
Проверка ошибок опущена для краткости. Пожалуйста, проверьте все ошибки в вашем коде.
// Dial generic netlink. const genetlink = 16 conn, _ := netlink.Dial(genetlink, nil) defer conn.Close() // Ask netlink to echo back an acknowledgement to our request. flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsAcknowledge m := netlink.Message< Header: netlink.Header< Flags: flags, // Other fields assigned automatically by package netlink. >, > // Perform a send, receive, and validate cycle. req, _ := conn.Send(m) replies, _:= conn.Receive() err := netlink.Validate(req, replies)
Для удобства метод Conn.Execute можно использовать как ярлык для Conn.Send , Conn.Receive и Validate .
msgs, _ := conn.Execute(m)
Для прослушивания групп многоадресной рассылки используйте методы Conn.JoinGroup и Conn.LeaveGroup . Сообщения можно получать, используя Conn.Receive , как обычно.
// Listen to rtnetlink for modification of network interfaces const rtnetlink = 0 const rtmGroupLink = 0x1 conn, _ := netlink.Dial(rtnetlink, nil) defer conn.Close() // Join multicast group: Receive will block until messages arrive. _ = conn.JoinGroup(rtmGroupLink) msgs, _ := conn.Receive() _ = conn.LeaveGroup(rtmGroupLink)
Наконец, имея дело с приложением netlink с высокой пропускной способностью, можно использовать фильтры BPF для явного приема или отклонения пакетов на основе их содержимого.
Фильтры BPF можно подключить, вызвав Conn.SetBPF с фильтром, собранным с помощью x/net/bpf . См. Интеграционные тесты BPF для примера использования фильтров BPF с netlink.
Пакет genetlink
Пакет genetlink — это эталонный пример пакета семейства netlink, созданного с использованием пакета netlink . Он предоставляет очень похожий API, но обрабатывает некоторые общие операции netlink от имени своего пользователя.
Этот пакет позволяет отправлять и получать сообщения netlink, но также предлагает помощника Conn.Family , использующего шаблон сервис, популяризированный go-github.
Если вы хотите погрузиться в подробности, вы можете ссылаться на исходный код или документацию, когда читаете этот раздел.
genetlink.Conn: подключение к общей сетевой ссылке.
genetlink.Conn — это, по сути, специализированная оболочка типа netlink.Conn для взаимодействия с универсальным. Он прозрачно добавляет и удаляет netlink.Message типа там, где это необходимо, и позволяет вызывающей стороне использовать только genetlink.Message в большинстве случаев.
Как и в случае с netlink.Conn , когда genetlink.Conn больше не нужен, необходимо вызвать genetlink.Conn.Close , чтобы закрыть сокет и избежать утечки файловых дескрипторов.
Методы Conn.Send , Conn.Receive и Conn.Execute в пакете genetlink используются для работы с общими сообщениями netlink. Фактически, при использовании Conn.Execute вообще нет необходимости иметь дело с какими-либо netlink.Message типами.
conn, _ := genetlink.Dial(nil) defer conn.Close() const ( ctrlVersion = 1 ctrlCommandGetFamily = 3 ) // Ask nlctrl to list all known families. req := genetlink.Message< Header: genetlink.Header< Command: ctrlCommandGetFamily, Version: ctrlVersion, >, > flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump msgs, _ := conn.Execute(req, genetlink.Controller, flags)
Наконец, все методы Conn.JoinGroup , Conn.LeaveGroup и Conn.SetBPF доступны в genetlink.Conn . Они выполняют те же действия, что и с netlink.Conn .
genetlink.Family: общие семейства сетевых ссылок
Поскольку запросы информации о семействе от универсального контроллера netlink очень распространены, genetlink.Conn предоставляет для этого специальные методы и типы.
Тип genetlink.Family предоставляет информацию о данном общем семействе сетевых ссылок, включая его идентификатор, версию, имя и группы многоадресной рассылки.
Помощник Conn.Family используется для обеспечения доступа к этим методам:
conn, _ := genetlink.Dial(nil) defer conn.Close() // Ask if nl80211 is available on this system. If it is not, // an error compatible with os.IsNotExist is returned. if _, err := conn.Family.Get(«nl80211»); os.IsNotExist(err)
Доступны два метода:
- Conn.Family.Get : найдите отдельную семью по ее названию.
- Conn.Family.List : поиск всех семейств в системе.
Как обсуждалось во второй части этой серии статей, взаимодействие с общим семейством сетевых ссылок включает в себя указание его идентификатора семейства и версии в запросе:
conn, _ := genetlink.Dial(nil) defer conn.Close() f, _ := conn.Family.Get(«nl80211») // Ask nl80211 for a list of all WiFi interfaces. req := genetlink.Message< Header: genetlink.Header< Command: nl80211.CmdGetInterface, // Specify the version of nl80211 we are speaking. Version: uint8(f.Version) >, > // Specify the ID of nl80211 in call to Execute. flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump msgs, _ := conn.Execute(req, f.ID, flags)
Пакет Wi-Fi
Пакет wifi обеспечивает доступ к действиям и статистике устройства WiFi IEEE 802.11. В настоящее время он работает только с Linux, хотя я хотел бы включить поддержку большего количества операционных систем в будущем.
Возможно, вы захотите сослаться на исходный код или документацию для этого пакета при чтении этого раздела.
В Linux пакет wifi работает с использованием nl80211: общего семейства netlink, которое предоставляет определения заголовков ядра C для всех своих команд и атрибутов netlink. Чтобы легко создать пакет Go из этих констант, я воспользовался прекрасным инструментом cgogen Максима Куприянова. Максим даже любезно предоставил исходный сгенерированный код для работы с nl80211 на Go.
wifi.Client: доступ к Wi-Fi-устройствам с Go
Поскольку основу составляют пакеты netlink и genetlink , использование пакета wifi в Linux довольно просто. Помните, что Client.Close должен вызываться, когда он больше не нужен, для очистки базового сокета netlink.
В этом примере извлекается список всех сетевых интерфейсов с поддержкой Wi-Fi и выбирается SSID, связанный с каждым устройством:
client, _ := wifi.New() defer client.Close() ifis, _ := client.Interfaces() for _, ifi := range ifis < // For more information about what a «BSS» is, see: // https://en.wikipedia.org/wiki/Service_set_(802.11_network). bss, _ := client.BSS(ifi) fmt.Printf(«%s: %qn», ifi.Name, bss.SSID) >
Вот и все! Netlink, generic netlink и nl80211 выполняют тяжелую работу по запросу и извлечению данных из ядра, их декодированию и упаковке, удобной для пользователя.
Резюме
На этом я завершаю серию статей о Linux, Netlink и Go! Надеюсь, вам понравился сериал и он оказался информативным. Если вы хотите начать работу с netlink, я рекомендую вам ознакомиться с исходным кодом следующих проектов:
- Github.com/mdlayher/wifi: использует сетевую ссылку и общую сетевую ссылку для связи с nl80211 в Linux. client_linux.go , в частности, может оказаться весьма полезным, если вы хотите работать с другими общими семействами сетевых ссылок в Go.
- Github.com/jsimonetti/rtnetlink: использует netlink и маршрутизирует netlink в Linux для управления сетевыми интерфейсами.
Если вы хотите начать работу над новым семейным пакетом netlink, я буду рад получить известие от вас! Мне сказали, что кто-то работает над пакетом netfilter netlink в настоящее время, но исходный код еще не доступен.
Я с радостью приветствую вклад во все пакеты, обсуждаемые в этой серии. Сообщите о проблеме, если хотите внести свой вклад!
Что дальше?
Для семейства пакетов netlink я хотел бы создать хороший тестовый пакет, подобный net/http/httptest , чтобы избежать необходимости «имитировать» соединения netlink с помощью интерфейса. Это значительно упростило бы тестирование пакетов семейства netlink и обеспечило бы аналогичные преимущества для потребительских пакетов, таких как wifi .
Помимо работы с netlink, я сейчас работаю над несколькими разными проектами, о которых хотел бы написать в будущем:
- Https://github.com/mdlayher/vsock: предоставляет доступ к сокетам виртуальных машин Linux (AF_VSOCK) для связи между гипервизором и его виртуальными машинами.
- Https://github.com/mdlayher/alg: предоставляет доступ к сокетам Linux AF_ALG для связи с криптографическим API ядра Linux.
- Https://github.com/mdlayher/raw: включает чтение и запись данных на уровне драйвера устройства для сетевого интерфейса.
Не стесняйтесь обращаться через комментарии, Twitter или Gophers Slack (имя пользователя: mdlayher), если у вас есть какие-либо комментарии или вопросы.
Спасибо вам большое за ваше время. Мне было приятно писать эту серию, и я получил отличные отзывы от самых разных читателей. Я продолжу писать, если ты продолжишь читать! До скорого!
Источник: digitrain.ru