>> DHCP не использует IP стек для отправки пакетов, пакеты формируются и отправляются
>> через BPF. От сюда и ограничение, чтобы ipfw мог видеть и
>> блокировать такие пакеты, вам нужно это делать на layer2. Читайте про
>> net.link.ether.ipfw.
> Я конечно не гуру, но по-моему BPF не интерфейс, а фильтр. Им
> могут фильтроваться, но не формироваться и не отправляться пакеты?Прочтите man 4 bpf
> И как может не участвовать стек IP, если dhcp пакет имеет заголовки
> вплоть до L7?
DHCP клиент формирует весь пакет со всеми заголовками и отправляет его прямо в интерфейс используя BPF и минуя IP стек.
> С другой стороны, на машине, на которой счетчики исправно растут (о чем
> я упоминал ранее) значение переменной net.link.ether.ipfw = 0.
В приведённом вами выводе счётчики растут только для входящих пакетов. Так как исходящий пакет отправляется мимо IP стека, PFIL хук файрвола не вызывается.
PFIL хуки вызываются из функций IP стека ip_input(), ip_output() и ip_tryforward(). В случае отправки пакета через BPF, пакет минует IP стек и отправляется из ether_output(). Чтобы файрвол увидел этот пакет, PFIL хук должен быть вызван из ether_output(), а это происходит только при включенном net.link.ether.ipfw.
Для входящих DHCP пакетов ситуация немного другая. Приложение, использующее BPF видит все пакеты, настроенные в фильтре, но изъять пакет из стека оно не может. Поэтому, т.к. пакет является IP пакетом, он попадает в ip_input(), а от туда уже в файрвол.
> Ну и все статьи о "net.link.ether.ipfw" касаются фильтрации по MAC. А мнене
> это ни к чему. Я не знаю MAC-ов. В том смысле
> что какие есть, все хороши.
На layer2 ipfw может выполнять бОльшую часть всех действий, которые он умеет, за исключением nat и fwd. Он точно так же парсит все пакеты до заголовков транспортного уровня и правила могут матчить по всем параметрам, которые доступны в layer3.
Фильтрация по MAC адресам тут является просто дополнительной возможностью, т.к. у пакета ещё не отброшен ethernet заголовок.