>> Добавил ng_tee в разрыв между ng_ipfw и ng_patch, и таки да, в
>> netgraph ничего не влетает. Как такое возможно?!
> netgraph в ipfw на layer2 не вызывается. Оопс! Пападос!
В конечном итоге сделал это без ng_ipfw.
Схема такова:
1. разделяем с помощью двух нод ng_split трафик на восходящий и нисходящий.
2. Нисходящий трафик фильтруем с помощью ng_bpf.
3. Все нефильтрованное отправляем дальше по нисходящей через ng_one2many:many0
4. Все отфильтрованное направляем на обработку в ng_patch и оттуда дальше на ng_one2many:many1
Правило фильтрации очень простое:
udp src port 67
BPF коды выглядит так:
bpf_prog_len=16 bpf_prog=[ { code=40 jt=0 jf=0 k=12 } { code=21 jt=0 jf=4 k=34525 } { code=48 jt=0 jf=0 k=20 } { code=21 jt=0 jf=11 k=17 } { code=40 jt=0 jf=0 k=54 } { code=21 jt=8 jf=9 k=67 } { code=21 jt=0 jf=8 k=2048 } { code=48 jt=0 jf=0 k=23 } { code=21 jt=0 jf=6 k=17 } { code=40 jt=0 jf=0 k=20 } { code=69 jt=4 jf=0 k=8191 } { code=177 jt=0 jf=0 k=14 } { code=72 jt=0 jf=0 k=14 } { code=21 jt=0 jf=1 k=67 } { code=6 jt=0 jf=0 k=8192 } { code=6 jt=0 jf=0 k=0 } ]
Ноды создаем и связываем так:
# Создание восходящей ветви
ngctl mkpeer em1_512: split upper mixed
ngctl name em1_512:upper SPLITUP
ngctl mkpeer SPLITUP: split in out
ngctl name SPLITUP:in SPLITDOWN
ngctl connect SPLITDOWN: em1_512: mixed lower# Создание нисходящей ветви
# P.S. Этот кусок можно было было сделать после создания ноды BPF,
# но мне пришлось экспериментировать с нодой BPF, и потому ее создал последней.
ngctl mkpeer SPLITDOWN: one2many in one
ngctl name SPLITDOWN:in MIXER
ngctl mkpeer MIXER: patch many1 out
ngctl name MIXER:many1 SET_DF
# P.S. В этой точке работаем с кадром, а не пакетом. Поэтому и смещения
# больше указанного вначале.
ngctl msg SET_DF: setconfig { count=2 csum_flags=1 ops=[ { mode=7 value=0x1f length=1 offset=20 } { mode=8 value=0x40 length=1 offset=20 } ] }
# Фильтр выделения DHCP ответов.
ngctl mkpeer SPLITUP: bpf out input
ngctl name SPLITUP:out DISPATCH
ngctl msg DISPATCH: setprogram { thisHook="input" ifMatch="patched" ifNotMatch="normal" bpf_prog_len=16 bpf_prog=[ { code=40 jt=0 jf=0 k=12 } { code=21 jt=0 jf=4 k=34525 } { code=48 jt=0 jf=0 k=20 } { code=21 jt=0 jf=11 k=17 } { code=40 jt=0 jf=0 k=54 } { code=21 jt=8 jf=9 k=67 } { code=21 jt=0 jf=8 k=2048 } { code=48 jt=0 jf=0 k=23 } { code=21 jt=0 jf=6 k=17 } { code=40 jt=0 jf=0 k=20 } { code=69 jt=4 jf=0 k=8191 } { code=177 jt=0 jf=0 k=14 } { code=72 jt=0 jf=0 k=14 } { code=21 jt=0 jf=1 k=67 } { code=6 jt=0 jf=0 k=8192 } { code=6 jt=0 jf=0 k=0 } ] }
# В документации ничего не сказано о необходимости подключения хуков MATCHED и NOTMATCHED.
# Примеры тоже ничего не прояснили. Помог только эксперимент.
ngctl connect DISPATCH: MIXER: normal many0
ngctl connect DISPATCH: SET_DF: patched in
Так-же в документации ничего не сказано про хождение трафика через хуки ng_bpf. В частности двунаправленные они или нет. Экспериментировать уже нет желания. Поэтому сделал с помощью нод сплитеров. Если у кого есть опыт, поделитесь.
В дополнение.
У хуков ноды ng_one2many есть замечательное свойство, менять состояние на UP/DOWN.
Это я к тому, что приведенную схему можно напичкать нодами ng_bpf и ng_patch с разными свойствами фильтрации/правки, а включать/выключать их сменой состояний подключенных хуков ноды ng_one2many.