The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

форумы  правила/FAQ  поиск  регистрация  вход/выход  слежка  RSS
"ng_patch. А включаешь, не работает!"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Открытые системы на сервере (Учет трафика, статистика / FreeBSD)
Изначальное сообщение [ Отслеживать ]

"ng_patch. А включаешь, не работает!"  +/
Сообщение от gardener email(ok) on 22-Май-17, 15:49 
Здравствуйте!

Есть у меня простенькая задача, на тестовом стенде сымитировать формат отправляемого пакета, для выяснения причин неработоспособности оборудования на продакшен-сети.
Стенд собран на freebsd

$ uname -srm
FreeBSD 11.0-STABLE i386

В состав входит ISC-DHCP

$ pkg info | grep isc-dhcp
isc-dhcp43-server-4.3.5        ISC Dynamic Host Configuration Protocol server

В частности сейчас передо мной стоит задача установить флаг DontFragment заголовка IP (старшие три бита в 7-ом байте от начала IP заголовка) в отправляемом DHCP пакете.

За основу беру пример из man ng_patch, но у меня на выходе ничего не модифицируется.
В частности ng_patch ниразу не срабатывает. (Самое ужасное, что не срабатывает и ни один из примеров из МАНа)

Мною проделано следующее:


sudo  /usr/sbin/ngctl -f- <<-SEQ
        mkpeer ipfw: patch 1 in
        name ipfw:1 SET_DF
        msg SET_DF: setconfig { count=2 csum_flags=1 ops=[ \
                { mode=7 value=0x1f length=1 offset=6 } \
                { mode=8 value=0x40 length=1 offset=6 } ] }
SEQ

sudo sysctl net.link.ether.ipfw=1
sudo sysctl net.inet.ip.fw.one_pass=0
sudo /sbin/ipfw add 150 netgraph 1 proto udp src-port 67 out xmit em1.512


И не смотря на то что правило 150 ловит пакеты, сам патч не срабатывает:

sudo /usr/sbin/ngctl msg ttl_add: getstats
Rec'd response "getstats" (3) from "[19]:":
Args:    {}

и на выходе неизмененные пакеты.

Вместе с тем, такой нижеследующий скрипт меняет байты в исходящих пакетах, но естественно во всех без разбора, что неверно:


sudo /usr/sbin/ngctl -f- <<-SEQ
        mkpeer em1_512: patch upper in
        name em1_512:upper SET_DF
        connect em1_512: SET_DF: lower out
        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 } ] }
SEQ

Подскажите, что упустил, где ошибся?

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "ng_patch. А включаешь, не работает!"  +/
Сообщение от gardener email(ok) on 23-Май-17, 10:40 
Добавил ng_tee в разрыв между ng_ipfw и ng_patch, и таки да, в netgraph ничего не влетает. Как такое возможно?!

Собрал вот такую схему:


+ show ipfw:
  Name: ipfw            Type: ipfw            ID: 00000017   Num hooks: 1
  Local hook      Peer name       Peer type    Peer ID         Peer hook      
  ----------      ---------       ---------    -------         ---------      
  1               MONIT           tee          00000033        left          
+ show MONIT:
  Name: MONIT           Type: tee             ID: 00000033   Num hooks: 2
  Local hook      Peer name       Peer type    Peer ID         Peer hook      
  ----------      ---------       ---------    -------         ---------      
  right           SET_DF          patch        00000035        in            
  left            ipfw            ipfw         00000017        1              
+ show SET_DF:
  Name: SET_DF          Type: patch           ID: 00000035   Num hooks: 1
  Local hook      Peer name       Peer type    Peer ID         Peer hook      
  ----------      ---------       ---------    -------         ---------      
  in              MONIT           tee          00000033        right          

а на выходе тишина:


# nghook -an MONIT: left2right

при том что ipfw счетчики растут:

00115       9      3483 count src-port 67 out xmit em1.512
00120       9      3483 count src-port 67 out via em1.512
00125      18      6858 count dst-port 67 in via em1.512
00130      21      3819 count out via em1.512
00195       9      3483 netgraph 1 proto udp src-port 67 out xmit em1.512

Кто же бажит? Я, ipfw или netgraph?
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "ng_patch. А включаешь, не работает!"  +1 +/
Сообщение от butcher (ok) on 24-Май-17, 11:58 
> Добавил ng_tee в разрыв между ng_ipfw и ng_patch, и таки да, в
> netgraph ничего не влетает. Как такое возможно?!

netgraph в ipfw на layer2 не вызывается. Можете попробовать патч из этого PR https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=213452

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "ng_patch. А включаешь, не работает!"  +1 +/
Сообщение от gardener email(ok) on 24-Май-17, 13:55 
>> Добавил 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.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "ng_patch. А включаешь, не работает!"  +/
Сообщение от gardener email(ok) on 24-Май-17, 16:46 
Осталась одна единственная проблема.

Манпейджес ng_patch говорят что

The csum_flags can be set to any combination of CSUM_IP, CSUM_TCP, CSUM_SCTP and CSUM_UDP (other values are ignored) for instructing the IP stack to recalculate the corresponding checksum before transmitting packet on output interface.

Однако при любом значении или их комбинации:

#define    CSUM_IP            0x00000001    /* IP header checksum offload */
#define    CSUM_IP_UDP        0x00000002    /* UDP checksum offload */
#define    CSUM_IP_TCP        0x00000004    /* TCP checksum offload */
#define    CSUM_IP_SCTP        0x00000008    /* SCTP checksum offload */

результат один и тот-же (bad cksum):
 ethertype IPv4 (0x0800), length 401: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 387, bad cksum 7247 (->7257)!)
[bad udp cksum 0x2270 -> 0xa270!]

Как победить?

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

5. "ng_patch. А включаешь, не работает!"  +1 +/
Сообщение от butcher (ok) on 24-Май-17, 22:05 
> Осталась одна единственная проблема.
> результат один и тот-же (bad cksum):
>
 ethertype IPv4 (0x0800), length 401: (tos 0x0, ttl 64, id 0, 
> offset 0, flags [DF], proto UDP (17), length 387, bad cksum
> 7247 (->7257)!)
> [bad udp cksum 0x2270 -> 0xa270!]

Опять же нужно понимать как в результате всех ваших netgraph нод пакет проходит через IP стек.
Эти флаги сами собой контрольные суммы не пересчитают. Они инструктируют сетевую карту выполнить пересчёт. IP стек проверяет, если карта не поддерживает оффлоад, то он пересчитывает контрольные суммы сам. Если же пакет не попадает в IP стек и карта не умеет оффлоад нужных контрольных сумм, то пакет уйдёт как есть. Вероятно, специально для вас написан модуль ng_checksum :)
Ещё если у вас карта умеет оффлоад, и вы смотрите в tcpdump на машине, которая отправляет пакет, то он может показывать что сумма не верна, т.к. она будет пересчитана только при передаче в провод. Т.е. при включенных флагах оффлоада это нормальное поведение tcpdump, и проверять корректность пакетов нужно на принимающей стороне.

Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "ng_patch. А включаешь, не работает!"  +/
Сообщение от gardener email(ok) on 26-Май-17, 09:26 
> пакет уйдёт как есть. Вероятно, специально для вас написан модуль ng_checksum
> :)

Если бы в man 4 netgraph было упоминание о таком модуле! Но и на диске пусто:


$ locate ng_checksum.ko
$ ls  /boot/kernel/ng_checksum.ko
ls: /boot/kernel/ng_checksum.ko: No such file or directory

> Т.е. при включенных флагах оффлоада это нормальное поведение tcpdump, и проверять
> корректность пакетов нужно на принимающей стороне.

И точно. Почему не догадался посмотреть на то что уходит с интерфейса в сеть?! В сети все посчитано!
Благодарю!

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

7. "ng_patch. А включаешь, не работает!"  +1 +/
Сообщение от butcher (ok) on 26-Май-17, 15:20 
>> пакет уйдёт как есть. Вероятно, специально для вас написан модуль ng_checksum
>> :)
> Если бы в man 4 netgraph было упоминание о таком модуле! Но
> и на диске пусто:
>
 
> $ locate ng_checksum.ko
> $ ls  /boot/kernel/ng_checksum.ko
> ls: /boot/kernel/ng_checksum.ko: No such file or directory
>

Он есть в stable/11 и head/. Будет и в предстоящем 11.1-RELEASE.
https://svnweb.freebsd.org/base?view=revision&revision=303612

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "ng_patch. А включаешь, не работает!"  +/
Сообщение от gardener email(ok) on 31-Май-17, 13:21 
> Он есть в stable/11 и head/. Будет и в предстоящем 11.1-RELEASE.
> https://svnweb.freebsd.org/base?view=revision&revision=303612

Вообще интересно получается. Ни стек, ни карточка, как выяснилось, суммы не пересчитывают. Я смотрел на клиенте. Но до него суммы пересчитывает промежуточное оборудование.

Вместе с тем в дереве исходников ng_checksum есть. Но по непонятной причине его нет в /usr/src/sys/modules/netgraph/Makefile!

Добавил строчку, пересобрал. Теперь и у меня есть:

# ls -l /boot/kernel/ng_checksum.ko 
-r-xr-xr-x  1 root  wheel  15112 May 31 13:17 /boot/kernel/ng_checksum.ko

Надеюсь заработает :)

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема


  Закладки на сайте
  Проследить за страницей
Created 1996-2017 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
Hosting by Ihor