Я пытаюсь понять, как работают сетевые драйверы под Linux. Эти вопросы и ответы показали, что сетевое устройство в Linux не представлено файлом устройства. В нем говорится, что сетевые драйверы работают с sockets
.
Например, здесь говорится о том, как настроить сетевые устройства с помощью ioctl
вызовов. ioctl
однако требуется дескриптор файла , поскольку файлов сетевых драйверов для устройств нет, единственный дескриптор файла, который можно передать, это дескриптор из сокета.
Это подводит меня к сути вопроса. До сих пор кажется, что сетевой интерфейс, который будет программным представлением физической сетевой карты, на самом деле является подчиненным объектом сокета.
Но что такое сокет в этом абстрактном смысле, это просто другое имя файла устройства, который поддерживает push-уведомления? Я понимаю сокеты TCP в терминах точек подключения, привязанных приложением пространства пользователя к паре адрес: порт на сетевом интерфейсе. Я не понимаю сокет как обязательное условие для настройки сетевого интерфейса.
Может ли сетевой интерфейс в Linux (как
eth0
указано в спискеifconfig
) существовать без сокета?Имеет ли
ifconfig
какой-либо демон сетевого менеджера открытый сокет, позволяющий нам устанавливать параметры сетевого интерфейса?
источник
Ответы:
Давайте быстро рассмотрим файлы устройств: в Linux прикладные программы передают в ядро операции write и write с помощью файловых дескрипторов . Это прекрасно работает для файлов, и оказалось, что один и тот же API можно использовать для символьных устройств, которые генерируют и потребляют потоки символов, и для блочных устройств, которые читают и записывают блоки фиксированного размера по адресу произвольного доступа, просто притворяясь, что они также файлы.
Но был необходим способ настройки этих устройств (установка скорости передачи и т. Д.), И для этого был изобретен вызов ioctl . Он просто передает структуру данных, специфичную для устройства, и тип управления вводом / выводом, используемый ядром, и возвращает результаты в той же структуре данных, так что это очень универсальный расширяемый API, который можно использовать для многих целей. ,
Теперь, как вписываются сетевые операции? Типичное приложение сетевого сервера хочет привязать к некоторому сетевому адресу, прослушивать определенный порт (например, 80 для HTTP или 22 для ssh), и, если клиент подключается , он хочет отправлять данные и получать данные от этого клиента. И двойные операции для клиента.
Не очевидно, как это согласовать с файловыми операциями (хотя это можно сделать, см. Plan 9 ), поэтому дизайнеры UNIX изобрели новый API: сокеты . Вы можете найти подробную информацию в справочных страницах раздела 2 для
socket
,bind
,listen
,connect
,send
иrecv
. Обратите внимание, что, хотя он отличается от API ввода-вывода файлов,socket
вызов, тем не менее, также возвращает дескриптор файла. Есть множество уроков по использованию сокетов в сети, немного погуглите.Пока это все чисто UNIX, никто не говорил о сетевых интерфейсах в то время, когда были изобретены сокеты. И поскольку этот API действительно старый, он определен для множества сетевых протоколов, помимо интернет-протокола (посмотрите на
AF_*
константы), хотя в Linux поддерживаются только некоторые из них.Но поскольку компьютеры начали получать несколько сетевых карт, для этого потребовалась некоторая абстракция. В Linux это сетевой интерфейс (NI). Он используется не только для аппаратного обеспечения, но также и для различных туннелей, конечных точек пользовательских приложений, которые представляют собой такие туннели, как OpenVPN и т. Д. Как было объяснено, API сокетов не основан на (специальных) файлах и не зависит от файловой системы. Точно так же сетевые интерфейсы также не отображаются в файловой системе. Однако NIs сделаны доступными в
/proc
и/sys
файловой системы (а также другие сетевые переменные вручную ).NI - это просто абстракция ядра конечной точки, в которую сетевые пакеты входят и выходят из ядра. Сокеты, с другой стороны, используются для обмена пакетами с приложениями. Нет необходимости использовать сокет для обработки пакета. Например, когда включена пересылка, пакет может входить в один NI и уходить в другой. В этом смысле сокеты и сетевые интерфейсы полностью независимы.
Но должен был быть способ настройки NI, точно так же, как вам нужен был способ настройки блочных и символьных устройств. А поскольку сокеты уже возвращали дескриптор файла, было несколько логично просто разрешить
ioctl
дескриптор этого файла. Это интерфейс сетевого устройства, который вы связали.Существует довольно много других злоупотреблений системными вызовами подобным образом, например, для фильтрации пакетов, захвата пакетов и т. Д.
Все это росло по частям, и во многих местах это не особенно логично. Если бы он был спроектирован сразу, можно было бы сделать более ортогональный API.
источник
Sockets as the network communications API were already not represented in the filesystem, so the NI didn't get one, either.
Это опечатка?