Добавление нового сетевого протокола в ядро ​​Linux

Я знаю, что в ядре linux мы можем добавить собственный протокол на транспортном уровне, похожий на TCP, UDP и т.д.

Есть ли крючки для регистрации нового протокола на сетевом уровне, аналогичном IP, ARP, который может передавать пакеты в приложение и как добавить этот протокол в ядро ​​Linux?

Ответы

Ответ 1

Для обработки связи из пространства пользователя с вашим протоколом зарегистрируйте свой протокол с помощью API-интерфейса ядра. Это позволяет вам создать обычный сокет из пространства пользователя.

Ознакомьтесь с реализацией сокетов Bluetooth/RFCOM для соответствующих примеров кода.

static const struct proto_ops rfcomm_sock_ops = {
     .family         = PF_BLUETOOTH,
     .owner          = THIS_MODULE,
     .bind           = rfcomm_sock_bind,
     .connect        = rfcomm_sock_connect,
     .listen         = rfcomm_sock_listen,
     .
     .
     .
     .accept         = rfcomm_sock_accept,

};

static const struct net_proto_family rfcomm_sock_family_ops = {
     .family         = PF_BLUETOOTH,
     .owner          = THIS_MODULE,
     .create         = rfcomm_sock_create
};

Чтобы зарегистрировать протокол, вам необходимо заполнить структуру proto_ops. Эта структура следует объектно-ориентированному шаблону, который наблюдается в других местах ядра. Эта структура определяет интерфейс для разработчиков, реализующих свой собственный интерфейс сокетов.

Реализуйте функции, определяемые интерфейсом, такие как связывание, подключение, прослушивание и назначение указателя функции на элемент структуры. Определите ioctl для функциональности, не охватываемой интерфейсом операций.

В итоге вы получите структуру, которую позже встраиваете в структуру сокета, которую мы возвращаем из функции create.

Структура net_proto_family определяет новое семейство протоколов. Эта структура включает функцию create, где ваша реализация функции должна заполнять структуру сокета, заполненную структурой proto_ops.

После этого зарегистрируйте семейство в sock_register, и, если все в порядке, вы сможете создать надлежащий сокет из пространства пользователя.

Внутренне протокол должен использовать skbuffs1,[2],[3](pdf). общаться с сетевыми устройствами.

skbuffs - это универсальный способ обработки сетевых пакетов в ядре Linux. Пакеты принимаются сетевой картой, помещаются в некоторые skbuffs и затем передаются в сетевой стек, который все время использует skbuff.

Это базовая структура данных и путь ввода-вывода для реализации сетевого протокола внутри ядра Linux.

Мне не известен документ, описывающий эту процедуру от начала до конца. Источник с вами на этом.

Ответ 2

Чтобы реализовать протокол, напишите модуль ядра.

Модуль должен создать новое устройство в /dev. Затем приложение может использовать ioctl(), чтобы поговорить с вашим модулем, чтобы указать такие объекты, как целевой хост, параметры и т.д.

Подробнее о реализации ioctl() в модуле ядра см. главу 7 Руководства по программированию модуля ядра Linux.

Это сообщение в блоге также похоже на хорошее введение в эту тему.