Сетевые интерфейсы и водопроводчики протокола
В этой главе описываются сетевой интерфейс KPI. Этот интерфейс программирования позволяет KEXT присоединять новые сетевые интерфейсы, связываться с и управлять сетевыми интерфейсами и создавать новые виртуальные интерфейсы.
Механизм, рекомендуемый для поддержки новых интерфейсов, зависит от природы интерфейса. Рекомендуемые механизмы:
Драйверы Ethernet — разделяют на подклассы
IOEthernetControllerиIOEthernetInterfaceклассы от Набора I/O I/O Сетевая семья.Другие аппаратные сетевые контроллеры — разделяют на подклассы
IONetworkControllerиIONetworkInterfaceклассы.Виртуальные интерфейсы — интерфейс KPI, описанный в этом разделе, рекомендуется.
Эта глава также описывает водопроводчиков протокола. Водопроводчики протокола используются для присоединения сетевых протоколов к интерфейсам.
При создании поддержки интерфейсного типа, который штабель уже не поддерживает (такие как ATM), независимо от того, использует ли KEXT Набор I/O, необходимо зарегистрировать водопроводчиков протокола для присоединения существующих протоколов к новому интерфейсному типу.
Функциональность в сетевом интерфейсе используется и интерфейсным драйвером и стеками протоколов, как показано на рисунке 7-1.

Обратные вызовы сетевого интерфейса
Ваш сетевой интерфейс должен определить следующие обратные вызовы, которые вызывают протоколы и драйверы:
ifnet_add_proto_func, который вызывают каждый раз, когда протокол присоединен к интерфейсу.ifnet_check_multi, когда групповой адрес добавляется к интерфейсу, который вызывают. Это позволяет интерфейсу отклонять недопустимые групповые адреса, прежде чем они будут добавлены к интерфейсу.ifnet_del_proto_func, когда протокол отсоединяется от интерфейса, который вызывают.ifnet_demux_func, который вызывают с необработанным пакетом от интерфейса и возвращает семейные ценности протокола протокола, который должен обработать пакет. Это может сделать это использование любого дескрипторы демультиплексора, зарегистрированные вifnet_add_proto_funcили трудно кодированная логика. Если пакет не соответствует протокола, функция должна возвратитьсяENOENT.ifnet_detached_func, когда Ваш интерфейс отсоединяется, который вызывают.ifnet_event_func, когда событие имеет место в определенном интерфейсе, который вызывают.ifnet_framer_func, который вызывают с исходящими пакетами прежде, чем отправить их в фильтры исходящего интерфейса и, как ожидают, обернет пакет со стековым фреймом, надлежащим интерфейсному типу.ifnet_ioctl_func, который вызывают каждый раз, когда ioctl получен для интерфейса. Сетевой интерфейс, как ожидают, передаст их на драйвер Набора I/O, если это будет необходимым и надлежащим сделать так. Все неопределенные ioctls резервируются для будущего использования Apple. Необходимо использоватьkern_controlесли необходимо добавить дополнительные механизмы управления.ifnet_output_func, который вызывают с пакетом, который готов быть отосланным провод. Сетевой интерфейс, как ожидают, передаст пакет и освободит mbuf, связанный с ним. Для сетевых интерфейсов, поддержанных драйверами Набора I/O, этот обратный вызов обычно вызывает функцию в драйвере Набора I/O, обрабатывающем обе из этих задач.ifnet_set_bpf_tap, который вызывает штабель для установки функции касания BPF, установленной в интерфейсе. Этот обратный вызов является дополнительным, но рекомендуемый; если Вы не добавляете эту функцию, BPF не может использоваться с Вашим интерфейсом.
Хорошие примеры многих из этих функций могут быть найдены в bsd/net/ether_if_module.c в xnu (ядро) исходное дерево.
Установка и удаление сетевых интерфейсов
Следующие функции обычно вызываются (в следующем порядке) для поддержки динамической вставки и демонтажа сетевых интерфейсов:
ifnet_allocate, который выделяет интерфейсную структуру.ifnet_attach, который присоединяет интерфейс к глобальному интерфейсному списку.bpfattach, который включает поддержку BPF в (дополнительном) интерфейсе.ifnet_detach, который удаляет интерфейс из глобального интерфейсного списка.ifnet_release, который выпускает ссылку на интерфейсную структуру. Если подсчет ссылок достигнет нуля (0), то структура будет освобождена. Этот выпуск соответствуетifnet_allocateвызовите ранее, и должен быть вызван после вызоваifnet_detach.
Связанная функция ifnet_reference может использоваться (обычно другим KEXTs) для увеличения подсчета ссылок интерфейсной структуры. Эти вызовы должны быть сбалансированы равным количеством вызовов к ifnet_release.
Водопроводчики протокола
Водопроводчики протокола, как упомянуто ранее, ответственны за присоединение протокола к сетевому интерфейсу. Когда протокол должен присоединить к интерфейсу, он вызывает функцию, ищущую водопроводчика, назначенного для того протокола и интерфейсного типа, затем вызывающую вертикальный обработчик того водопроводчика.
Водопроводчики протокола определяют следующие обратные вызовы, которые вызывают протоколы:
proto_plumb_handler, который вызывают для присоединения протокола к интерфейсу. Это обычно состоит из вызова к интерфейсуifnet_attach_protocolобратный вызов.proto_unplumb_handler, который вызывают для отсоединения протокола от интерфейса. Невертикальный обработчик должен вызватьifnet_detach_protocolфункция, но может сделать другую очистку, такую как освобождение любого хранения, выделенного вproto_plumb_handlerобратный вызов.
При присоединении протокола к интерфейсу водопроводчик протокола обычно заполняет следующие поля в ifnet_attach_proto_param структура, многие из которых могут быть определены как часть самого протокола. Этот механизм предоставляет возможность для водопроводчика протокола, чтобы прервать эти вызовы и принять интерфейсно-специфичные меры при необходимости.
proto_media_detached(дополнительный), который используется, чтобы уведомить протокол, что он отсоединяется.proto_media_event(дополнительный), который вызывают для уведомления протокола об интерфейсно-специфичных событиях.proto_media_input(требуемый), который используется для поставки входящего пакета протоколу для обработки.proto_media_ioctl(дополнительный), который обычно является ioctl протокола, обрабатывающим функцию.proto_media_preout(требуемый), который вызывают непосредственно перед тем, как пакет передается. Это позволяет протоколу указывать специфичный для носителей тип кадра и место назначения.proto_media_resolve_multi(дополнительный), который используется для получения адреса канального уровня для данного группового адреса протокольного уровня. Если Ваши интерфейсные поддержки многоадресно передают, это только необходимо.proto_media_send_arp(дополнительный), который используется для получения адреса канального уровня, соответствующего данному индивидуальному адресу протокольного уровня. Это необходимо для всех интерфейсов не«точка-точка».
Примеры этих функций могут быть найдены в bsd/net/ether_inet_pr_module.c в xnu (ядро) исходное дерево.
Отправка данных
Следующие шаги описывают процесс отправки пакета, с помощью Ethernet в качестве носителя в качестве примера:
ip_outputподпрограмма в вызовах стека протоколов IPifnet_output.ifnet_outputвызовы функции водопроводчик протоколаproto_media_preoutфункция. В случае IP, это вызовы функцииinet_arp_lookup.Если кэш ARP не содержит запись для IP-адреса,
inet_arp_lookupтогда вызывает водопроводчика протоколаproto_media_send_arpобратный вызов для разрешения целевого IP-адреса в адрес управления доступом к среде (MAC).Когда
proto_media_preoutвозвраты обратного вызова,ifnet_outputвызовы функции сетевой интерфейсifnet_framer_funcфункция. Эта функция структурирования предварительно ожидает интерфейсно-специфичные данные кадра к пакету.Если какие-либо интерфейсные фильтры присутствуют, их
iff_output_funcобратные вызовы вызывают последовательно.ifnet_outputвызовы функции сетевой интерфейсifnet_output_funcобратный вызов, передающий пакет и освобождающий mbuf.
Получение данных
Следующие шаги описывают процесс получения пакета:
Драйвер оборудования или его поддержка кодируют вызовы
ifnet_inputс указателями наifnetструктура (ifnet_t) иmbufцепочка (mbuf_t).Пакет ставится в очередь. Обработка резюме на различном потоке.
ifnet_inputвызовы функции сетевой интерфейсifnet_demux_funcфункция для интерфейса.Функция демультиплексирования идентифицирует кадр и возвращает a
protocol_family_tзначение для указания, какой протокол должен обработать пакет.ifnet_inputвызовы функции присоединенные интерфейсные фильтры (если таковые имеются) последовательно.Любые пакеты, не соответствующие присоединенный протокол, отбрасываются, как любые разнородные пакеты.
ifnet_inputвызовы функции водопроводчик протоколаproto_media_inputфункция. Водопроводчик является определенным для данной комбинации протокола/интерфейса.