Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
17.4. Групповая адресация
hardorsoft
26.10.10 в 05:28
17.4. Групповая адресация
hardorsoft
26.10.10 в 05:28
|
|
Пакеты с групповой адресацией (multicast-пакеты) – предназначены для приема более чем одним хостом, но не всеми хостами. Эта возможность реализуется назначением специальных аппаратных адресов для группы хостов. Пакеты направляются на один специальный адрес, и принимаются всеми хостами в группе. В случае Ethernet, групповой адрес отличается тем, что в нем установлен младший бит, в первом октете адреса. А каждое устройство очищает этот бит в аппаратном адресе.
hardorsoft
26.10.10 в 05:28
|
|
Наиболее сложная часть работы с группами хостов и аппаратными адресами выполняется не драйвером, а приложениями и ядром.
hardorsoft
26.10.10 в 05:28
Наиболее сложная часть работы с группами хостов и аппаратными адресами выполняется не драйвером, а приложениями и ядром.
hardorsoft
26.10.10 в 05:28
|
|
Передавать multicast-пакеты – просто, это делается также как и для остальных пакетов. Интерфейс передает пакеты через коммуникационную среду, без анализа адреса назначения. Ядро назначает корректный аппаратный адрес, и метод устройства hard_header, если он определен, не должен анализировать этот адрес.
hardorsoft
26.10.10 в 05:28
|
|
Ядро отслеживает, какие multicast-адреса интересны хосту в настоящее время. Список может часто меняться, поскольку этим могут заниматься работающие приложения и пользователи. Драйвер должен принимать список multicast-адресов, и передавать ядру пакеты, посланные этим адресам. От того, как работает аппаратное обеспечение, зависит как в драйвере реализовано хранение списка multicast-адресов. Обычно, по тому, как аппаратура работает с групповой адресацией, она делится на 3 категории:
hardorsoft
26.10.10 в 05:29
|
|
Интерфейсы, которые не могут работать с групповой адресацией. Эти интерфейсы или принимают пакеты, предназначенные только для их аппаратных адресов (плюс широко вещательные пакеты), или принимают все пакеты. Они могут принимать multicast-пакеты, только обрабатывая каждый пакет, поэтому операционной системе придется иметь дело с огромным количеством ненужных пакетов. Обычно эти интерфейсы не поддерживают групповую адресацию, и не устанавливают флаг IFF_MULTICAST в dev->flags.
hardorsoft
26.10.10 в 05:29
|
|
Интерфейс точка-точка является отдельным случаем, ввиду того, что он принимает все пакеты, не производя аппаратную фильтрацию.
hardorsoft
26.10.10 в 05:29
|
|
Интерфейс может отличать пакты с групповой адресацией от прочих (пакетов идущих от хоста к хосту или широковещательных). Эти интерфейсы могут быть настроены на прием каждого multicast-пакета. В этом случае необходимо программно определять по адресу пакета, интересует ли он данный хост. Нагрузка в этом случае приемлема, поскольку в обычной сети количество multicast-пакетов – не велико.
hardorsoft
26.10.10 в 05:30
|
|
Интерфейсы, которые могут выполнять аппаратное детектирование multicast-адресов. Эти интерфейсы могут, просматривая список multicast-адресов, принимать или игнорировать пакеты с групповой адресацией. Для ядра эти интерфейсы – оптимальны, поскольку не нужно тратить процессорное время на обработку не нужных пакетов.
hardorsoft
26.10.10 в 05:30
|
|
Ядро пытается использовать возможности интерфейсов, поддерживающих третий класс устройств, они наиболее многофункциональны. Поэтому ядро сообщает драйверу о изменении списка групповых адресов, и передавая ему новый, чтобы он мог обновить аппаратный фильтр.
hardorsoft
26.10.10 в 05:30
|
|
17.14.1. Поддержка ядром групповой адресации
hardorsoft
26.10.10 в 05:31
|
|
Для групповой адресации используются: структура данных и флаги устройства.
hardorsoft
26.10.10 в 05:31
|
|
void (*dev->set_multicast_list)(struct net_device *dev);
hardorsoft
26.10.10 в 05:31
|
|
Этот метод вызывается при изменении списка multicast-адресов, ассоциированных с устройством. Также вызывается при модификации dev->flags, т.к. некоторые флаги (например IFF_PROMISC) нуждаются в репрограммировании аппаратного фильтра. Метод принимает указатель struct net_device *dev, в качестве аргумента, и возвращает void. Драйвер, не реализующий этот метод, может установить это поле в NULL.
hardorsoft
26.10.10 в 05:32
|
|
struct dev_mc_list *dev->mc_list;
hardorsoft
26.10.10 в 05:31
|
|
Список всех групповых адресов, ассоциированных с устройством. Определение структуры приведено в конце подраздела.
hardorsoft
26.10.10 в 05:32
|
|
|
|
|
Размер списка. Эта информация несколько избыточна, но проверка dev->mc_count==0, выполняется быстрее.
hardorsoft
26.10.10 в 05:32
|
|
|
|
|
Драйверам не устанавливающих этот флаг в dev->flags, интерфейс предлагает обработку пакетов с групповой адресацией. Однако ядро вызывает метод set_multicast_list когда изменяется dev->flags, т.к. Список mc_list может меняться при не активном интерфейсе.
hardorsoft
26.10.10 в 05:33
|
|
|
|
|
Флаг устанавливается в dev->flags, когда требуется, чтобы драйвер принимал все пакты с групповой адресацией из сети. Это происходит, когда разрешена multicast-маршрутиризация. При установленном флаге фильтрация пакетов по dev->mc_list не производится.
hardorsoft
26.10.10 в 05:33
|
|
|
|
|
Установка этого флага переводит интерфейс в не разборчивый (promiscuous) режим. Когда установлен этот флаг, каждый пакет принимается из сети не зависимо от dev->mc_list.
hardorsoft
26.10.10 в 05:33
|
|
Последний бит информации, необходимой разработчику драйвера, это определение структуры dev_mc_list, которое находится в <"linux/netdevice.h">:
hardorsoft
26.10.10 в 05:33
|
|
struct dev_mc_list { struct dev_mc_list __u8 unsigned char int int };
hardorsoft
26.10.10 в 05:34
|
|
Т.к. групповая адресация и аппаратные адреса независимы от среды передачи пакетов, эта структура портируется на различные сетевые реализации, и каждый адрес рассматривается как строка октетов некоторой длинны, так же как и dev->dev_addr.
hardorsoft
26.10.10 в 05:34
|
|
17.14.2. Типичная реализация
hardorsoft
26.10.10 в 05:34
|
|
Наилучшим образом описать работу set_multicast_list можно, показав вам псевдокод.
hardorsoft
26.10.10 в 05:34
|
|
Приведенная ниже функция – типичная реализация полнофункционального драйвера. Драйвер в этом интерфейсе управляет аппаратным фильтром пакетов, который содержит таблицу multicast- адресов, принимаемых хостом. Максимальный размер таблицы – FF_TABLE_SIZE.
hardorsoft
26.10.10 в 05:34
|
|
Функции с префиксом 'ff_', выполняют аппаратно-зависимые операции.
hardorsoft
26.10.10 в 05:35
|
|
void ff_set_multicast_list(struct net_device *dev) { struct dev_mc_list *mcptr; if (dev->flags & IFF_PROMISC) { ff_get_all_packets( ); return; } /* если присутствует больше адресов, чем мы можем обработать, то получаем все multicast-пакеты и обрабатываем их программно*/ if (dev->flags & IFF_ALLMULTI || dev->mc_count > FF_TABLE_SIZE) { ff_get_all_multicast_packets( ); return; } /* нет multicast-пакетов? Тогда получаем предназначенные нам*/ if (dev->mc_count = = 0) { ff_get_only_own_packets( ); return; } /* передадим все адреса в аппаратный фильтр */ ff_clear_mc_list( ); for (mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) ff_store_mc_address(mc_ptr->dmi_addr); ff_get_packets_in_multicast_list( ); }
hardorsoft
26.10.10 в 05:35
|
|
Эта реализация может быть упрощена, если интерфейс не поддерживает аппаратной фильтрации пакетов. В этом случае FF_TABLE_SIZE устанавливается в 0, и убираются последние 4 строчки кода.
hardorsoft
26.10.10 в 05:35
|
|
Ранее упоминалось, что интерфейс, который не может работать с multicast-пакетами, все же нуждается в методе set_multicast_list, для уведомлении об изменении dev->flags. Этот подход может быть назван “nonfeatured” (nf) – не характерной реализацией. Реализация очень проста, и показана ниже:
hardorsoft
26.10.10 в 05:35
|
|
void nf_set_multicast_list(struct net_device *dev) { if (dev->flags & IFF_PROMISC) nf_get_all_packets( ); else nf_get_only_own_packets( ); }
hardorsoft
26.10.10 в 05:35
|
|
Использование флага IFF_PROMISC – необходимо, т.к. иначе пользователь не мог бы использовать tcpdump или другой анализатор трафика сети. Если интерфейс работает на соединении точка-точка, то нет необходимости реализовывать set_multicast_list, т.к. все равно принимается каждый пакет.
hardorsoft
26.10.10 в 05:36
|
|