Nekto Posted September 27, 2016 · Report post На ядре 2.6.Х работала следующая конструкция шейпера: /sbin/tc qdisc del dev eth0 root /sbin/tc qdisc add dev eth0 root handle 1 htb default 30 r2q 32 /sbin/tc class add dev eth0 parent 1: classid 1:2 htb rate 100Mbit /sbin/tc filter add dev eth0 parent 1:0 prio 200 handle 2: protocol ip u32 divisor 256 /sbin/tc class add dev eth0 parent 1:2 classid 1:11 htb rate 20Mbit ceil 30Mbit burst 50k prio 3 /sbin/tc qdisc add dev eth0 parent 1:11 handle 11 sfq perturb 10 /sbin/tc filter add dev eth0 parent 1:0 protocol ip prio 100 handle 11 fw classid 1:11 /sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 200 u32 ht 2:0x05 match ip dst 192.168.0.5 flowid 1:11 /sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 200 u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 16 link 2: Собрал новую машину на ядре 4.4.18 и вылезла неожиданная проблема с vlan интерфейсами. Предыдущая конструкция работает только если указать в качестве интерфейся конкретный vlan - типа eth0.3 и только на карточке интел c MSI - похоже сама карточка тэг снимает. Только в этом случае теряется наследование класса. Нужно запустить фильтр на корневом интерфейсе eth0. На форуме здесь http://forum.nag.ru/forum/index.php?showtopic=98225 нашел решение которое работает С приведенным ниже конфигом все нормально работает на любой карточке: /sbin/tc qdisc del dev eth0 root /sbin/tc qdisc add dev eth0 root handle 1 htb default 30 r2q 32 /sbin/tc class add dev eth0 parent 1: classid 1:2 htb rate 100Mbit /sbin/tc filter add dev eth0 parent 1:0 prio 200 handle 2: protocol ip u32 divisor 256 /sbin/tc filter add dev eth0 parent 1: protocol all handle 0x5 basic match 'meta (vlan eq 3 )' action ok /sbin/tc class add dev eth0 parent 1:2 classid 1:11 htb rate 20Mbit ceil 30Mbit burst 50k prio 3 /sbin/tc qdisc add dev eth0 parent 1:11 handle 11 sfq perturb 10 /sbin/tc filter add dev eth0 parent 1:0 protocol ip prio 100 handle 11 fw classid 1:11 /sbin/tc filter add dev eth0 parent 1: protocol all handle ::5 u32 match ip dst 192.168.0.5 flowid 1:11 /sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 200 u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 16 link 2: Только в этом случае хэш не задействован. Подскажите, гуру, как реализовать возможность шэйпить виланы на корневом интерфейсе с использованием хэшей? Перелопатил кучу сайтов, но точного решения так и не нашел. Думаю данная проблема станет в скором времени актуальной для многих с переходом на новые ядра. Кто в теме - накидайте пример, буду весьма признателен. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
kayot Posted September 27, 2016 · Report post 'protocol all' поставьте везде, хеши и не могут работать из-за оставленного protocol ip. У меня "подобные конструкции" работают на любых картах и с разными ядрами, если запускать на интерфейсе(eth0.3) с protocol ip, если на корневом eth - то только с all, ибо трафик из-за смещений получается не IP. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 27, 2016 · Report post Попробовал как вы говорите - не работает. У меня на сутки еще только одно сообщение доступно :( Возможно не сразу отвечу. При добавлений правил ругани нет, но пакеты в фильтр не попадают. Что я делаю не так? /sbin/tc qdisc del dev eth0 root /sbin/tc qdisc add dev eth0 root handle 1 htb default 30 r2q 32 /sbin/tc class add dev eth0 parent 1: classid 1:2 htb rate 100Mbit /sbin/tc filter add dev eth0 parent 1:0 handle 2: protocol all u32 divisor 256 /sbin/tc class add dev eth0 parent 1:2 classid 1:11 htb rate 20Mbit ceil 30Mbit burst 50k prio 3 /sbin/tc qdisc add dev eth0 parent 1:11 handle 11 sfq perturb 10 /sbin/tc filter add dev eth0 parent 1:0 protocol all handle 11 fw classid 1:11 /sbin/tc filter add dev eth0 parent 1:0 protocol all u32 ht 2:0x05 match ip dst 192.168.0.5 flowid 1:11 /sbin/tc filter add dev eth0 parent 1:0 protocol all u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 16 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
SABRE Posted September 27, 2016 · Report post Интерфейсы Vlan созданы с reorder_hdr off? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 27, 2016 · Report post Пробовал ip link set eth0.3 type vlan reorder_hdr on/off На результат никак не влияет. Пробовал /sbin/tc filter add dev eth0 parent 1:0 protocol all u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 20 в надежде, что 4 бита сработают, но нет. Решения пока не нахожу. Ниже ссылки, но я уже окончательно запутался. Пробую разные варианты - никак не получается. Ниже несколько ссылок по теме. Как я понимаю в новых ядрах поменяли что-то. Без хэшей мне удалось все запустить, но с хэш пока ника не получается. Ссылка Ссылка До завтра мой лимит ссобщений исчерпан :( Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
kayot Posted September 27, 2016 · Report post Попробуйте другое ядро. На 3.18 у меня вообще qinq трафик(с 2 метками) шейпится прямо на bond1. Т.е. клиенты висят на bond1.100.200 etc. И все работает замечательно на разном железе и на ядрах 3.хх веток. Если заработает на 3.18 - значит что-то поменялось в ядре и разборе тегов. Если не заработает - где-то в ваших скриптах лажа, надо смотреть счетчики на каждое правило. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 28, 2016 · Report post Попробовал запустить без использования хэшей с указанием протокола all - работает! /sbin/tc qdisc del dev eth0 root /sbin/tc qdisc add dev eth0 root handle 1 htb default 30 r2q 32 /sbin/tc class add dev eth0 parent 1: classid 1:2 htb rate 100Mbit /sbin/tc class add dev eth0 parent 1:2 classid 1:11 htb rate 20Mbit ceil 30Mbit burst 50k prio 3 /sbin/tc qdisc add dev eth0 parent 1:11 handle 11 esfq perturb 10 hash dst /sbin/tc filter add dev eth0 parent 1:0 protocol all prio 200 handle 11 fw classid 1:11 /sbin/tc filter add dev eth0 parent 1:0 protocol all prio 100 u32 match ip dst 192.168.0.5 classid 1:11 Как только указываю использование хэш - ничего не работает. Пакеты в класс не направляются. Ниже пример: /sbin/tc qdisc del dev eth0 root /sbin/tc qdisc add dev eth0 root handle 1 htb default 30 r2q 32 /sbin/tc class add dev eth0 parent 1: classid 1:2 htb rate 100Mbit /sbin/tc filter add dev eth0 parent 1:0 prio 200 handle 2: protocol all u32 divisor 256 /sbin/tc class add dev eth0 parent 1:2 classid 1:11 htb rate 20Mbit ceil 30Mbit burst 50k prio 3 /sbin/tc qdisc add dev eth0 parent 1:11 handle 11 esfq perturb 10 hash dst /sbin/tc filter add dev eth0 parent 1:0 protocol all prio 100 handle 11 fw classid 1:11 /sbin/tc filter add dev eth0 protocol all parent 1:0 prio 200 u32 ht 2:0x05 match ip dst 192.168.0.5 flowid 1:11 /sbin/tc filter add dev eth0 protocol all parent 1:0 prio 200 u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 16 link 2: Выделил строки которые добавляются для хэша. С их появлением не работает. Подскажите - куда копать? В ссылках которые я приводил есть упоминание: VLAN tag is stripped from skb in recent kernels и там же примеры. Думаю проблемма именно в этом. Пока запустил без применения хэша, но хотелось бы уменьшить нагрузку на сервер. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
SABRE Posted September 29, 2016 · Report post Nekto Думаю проблема со смещением. Советую в скрипте создать все 256 фильтров нижнего уровня и посмотреть в какой попадает трафик, а на основании этого сделать вывод, какое смещение нужно. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 29, 2016 · Report post Методам построчного ввода заметили, что команда вида: /sbin/tc filter add dev eth0 protocol all parent 1:0 prio 200 u32 ht 2:0x05 match ip dst 192.168.0.5 flowid 1:11 не принимается - идет ругань на аргументы. Разобрались, что для запуска команды нужно указать протокол ip. если есть значение ht 2:0x05 протокол all не срабатывает. Без протокола all тегированный трафик tc не видит. аналогично с командой для субнета: sbin/tc filter add dev eth0 protocol all parent 1:0 prio 200 u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 16 link 2: протокол нужно указать ip Как заставить обрабатывать тегированный трафик для хэшей - не понимаю. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
kayot Posted September 29, 2016 · Report post А если указать HT 2:5, без всяких хексов? Оно и так хексовое дефолтно.. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 29, 2016 (edited) · Report post А если указать HT 2:5, без всяких хексов? Оно и так хексовое дефолтно.. Не получится. Нужно указать куда попадают данные из субнета - эта строка tc filter add dev eth0 protocol ip parent 1:0 prio 200 u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 16 link 2: Последняя запись из субнета попадает в свой divisor на свой link, а в нем откусывается только последня циферка по маске. правило с указателем protocol all не работает. tc не видит тэгированный трафик как ip пробую указать вид протокола 802,1q - получаю ту же ошибку: tc filter add dev eth0 protocol 802.1q parent 1:0 prio 200 u32 ht 800:: match ip dst 192.168.0.0/24 hashkey mask 0x000000ff at 16 link 2: RTNETLINK answers: Invalid argument We have an error talking to the kernel Без этого правила работать ничего не будет. Каким образом указать, что ip протокол нужно смотреть в конкретном vlan я не понимаю. Edited September 29, 2016 by Nekto Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
taf_321 Posted September 30, 2016 · Report post Скажите, этот трафик во вланах маршрутизируется на данной железке, или загнаны в бридж? Может подойдет такой вариант: ipset create shape-skb4 nethash family inet skbinfo ipset add shape-skb4 192.168.0.5 skbprio 1:11 iptables -t mangle -I POSTROUTING -o vlan* -j SET --map-set shape-skb4 dst --map-prio (создание класса 1:11 условно не показано) Получается, что весь исходящий трафик по интефейсам vlan* будет классифицироваться через сет, с выставлением нужного поля, и потом попадает в нужный класс. По производительности данная схема идет на равне с хэшами, но имеет два серьезных преимущества перед хэшами tc: 1 - можно нарезать скорости для сеток произвольного размера; 2 - схема применима и для нарезки скоростей для ipv6 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
NiTr0 Posted September 30, 2016 · Report post ухты, не знал что ipset такое умеет... давно на него не смотрел. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 30, 2016 · Report post Скажите, этот трафик во вланах маршрутизируется на данной железке, или загнаны в бридж? Трафик маршрутизируется. Нарезка на исходящих интерфейсах. Уже копал в сторону ipset. ПО мануалу tc последних версий его поддерживает из коробки. Пробовал правило приведенное ниже - не работает tc filter add dev eth0 parent 1:0 protocol all prio 100 basic match ipset'(test dst)' classid 1:11 Что интересно, nmap на этой машине тоже не работает. Говорит, что все хосты с закрытыми портами. Это так к слову. Пересобираю ядро на 3.18.42 по результатам отпишусь. Относительно вашего примера - не хочу плодить кучу правил iptables. Не копал на предмет skb ipset, но если ipset add shape-skb4 192.168.0.5 skbprio 1:11 загоняет трафик с ип прямо в нужный класс, то решение интересное. Для экономии времени - в первом примере: ipset create shape-skb4 nethash family inet skbinfo в последнее значение skbinfo, что заносится? Или готовый пример с конкретными цифрами если не сложно. Я пока почитаю по ipset, направление интересное. И да я на этой машине сейчас использую ipset для hash:ip и hash:ip,port 2000 прежних правил iptables уместились в 10, сэкономив 10% нагрузки на проц. шапер без хэшей сожрал экономию и даж чуть поднажал, но пока терпимо. Ядро скомпилилось - пойду тестить. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
vop Posted September 30, 2016 · Report post Для экономии времени - в первом примере: ipset create shape-skb4 nethash family inet skbinfo в последнее значение skbinfo, что заносится? Это значение резервирует место в ipset для добавления fw mark, класса и/или hw queue в список. Потом в iptables -j SET можно устанавливать отдельно какую-либо величину, либо все вместе. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
taf_321 Posted September 30, 2016 · Report post Относительно вашего примера - не хочу плодить кучу правил iptables. Цитирование сбилось, трудно понять о чем речь. В общем, https://www.altlinux.org/%D0%A8%D0%B5%D0%B9%D0%BF%D0%B5%D1%80%D0%94%D0%BB%D1%8F%D0%91%D0%BE%D0%BB%D1%8C%D1%88%D0%B8%D1%85%D0%A1%D0%B5%D1%82%D0%B5%D0%B9 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 30, 2016 (edited) · Report post Ура - решение найдено. Заработало! ipset create test hash:ip hashsize 64 ipset add test 192.168.0.5 tc qdisc add dev eth0 root handle 1 htb default 30 r2q 32 tc class add dev eth0 parent 1: classid 1:2 htb rate 100Mbit tc class add dev eth0 parent 1:2 classid 1:11 htb rate 20Mbit ceil 30Mbit burst 50k prio 3 tc qdisc add dev eth0 parent 1:11 handle 11 esfq perturb 10 hash dst tc filter add dev eth0 parent 1:0 protocol all prio 200 handle 11 fw classid 1:11 tc filter add dev eth0 parent 1:0 protocol all prio 100 basic match ipset'(test dst)' classid 1:11 Из ipset пакеты прямиком направляются в нужный класс шэйпера. Никаких промежуточных iptables не надо! Я правильно смотрел в направлении ipset. Теперь собственно о граблях, почему у меня сразу не получилось. Стояла стоковая версия ipset 6.20. Собрал 6.29, когда на skbinfo полезли ошибки - он после 6.22 включен. По случаю я в это время работал на ядре 3.18.42 - все прекрасно запустилось. Перешел на версию 4.4.18 - получил облом. На сегодняшний момент ядро 3.18.42 ipset 6.29 iproute2-4.7.0 - все работает на машине с vlan. У кого не используется vlan проблем скорее всего не возникнет с любым ядром. Осталось переписать скрипты под новый формат. Edited September 30, 2016 by Nekto Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
taf_321 Posted September 30, 2016 · Report post Погодите, в таком разрезе вы получите производиельность как без хэшей. По сути у вас будет портянка filters которую пакеты будут должны перебирать. В моем примере в одном правиле iptables сразу происходит присвоение нужного класса через хэширование в сете (то есть нет портянки линейных filters). В сет просто набиваются записи с указанием индивидуальных классов. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Nekto Posted September 30, 2016 (edited) · Report post Напишите пожалуйста пример для трех произвольных ип. Не понимаю, как я получу индивидуальные параметры скоростей для каждого ип, с одним правилом иптэйблов? В классическом использовании хэшей перебор идет по последнему знаку ип адреса, здесь перебор на уровне хэша выполнит ипсет и направит прямо в клас тц Edited September 30, 2016 by Nekto Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
taf_321 Posted September 30, 2016 · Report post Я там выше ссылку привел на описание. цитата: class add dev bondINT parent 1: classid 1:d est 1sec 8sec hfsc sc umax 1500b dmax 5ms rate 20480kbit ul rate 20480kbit qdisc add dev bondINT parent 1:d handle d: pfifo limit 200 class add dev bondEXT parent 1: classid 1:d est 1sec 8sec hfsc sc umax 1500b dmax 5ms rate 20480kbit ul rate 20480kbit qdisc add dev bondEXT parent 1:d handle d: pfifo limit 200 class add dev bondINT parent 1: classid 1:d44 est 1sec 8sec hfsc sc umax 1500b dmax 10ms rate 30720kbit ul rate 30720kbit qdisc add dev bondINT parent 1:d44 handle d44: pfifo limit 200 class add dev bondEXT parent 1: classid 1:d44 est 1sec 8sec hfsc sc umax 1500b dmax 10ms rate 30720kbit ul rate 30720kbit qdisc add dev bondEXT parent 1:d44 handle d44: pfifo limit 200 add shaper4 172.16.1.2/32 skbprio 1:d add shaper4 172.16.1.5/32 skbprio 1:d add shaper4 172.16.1.10/32 skbprio 1:d add shaper4 172.16.1.12/32 skbprio 1:d add shaper4 172.16.1.14/32 skbprio 1:d add shaper4 172.16.1.31/32 skbprio 1:d add shaper4 172.16.1.103/32 skbprio 1:d add shaper4 172.16.1.128/32 skbprio 1:d add shaper4 172.16.1.184/32 skbprio 1:d add shaper4 172.16.2.115/32 skbprio 1:d add shaper4 172.16.5.198/32 skbprio 1:d add shaper4 172.16.6.38/32 skbprio 1:d add shaper4 172.16.6.58/32 skbprio 1:d add shaper4 172.16.6.69/32 skbprio 1:d add shaper4 172.16.9.228/32 skbprio 1:d add shaper4 172.16.10.208/32 skbprio 1:d add shaper4 172.16.11.67/32 skbprio 1:d add shaper4 172.16.11.68/32 skbprio 1:d add shaper4 172.16.11.147/32 skbprio 1:d add shaper4 172.16.15.213/32 skbprio 1:d add shaper4 172.16.15.214/32 skbprio 1:d add shaper4 172.16.17.75/32 skbprio 1:d add shaper4 172.16.17.231/32 skbprio 1:d44 add shaper6 XXXX:4680:26:0:0:0:0:202/124 skbprio 1:d44 Итак, в этом примере на пачку адресов дается 20 мегабит, и делят они ее между собой как хотят, а вот для адреса 172.16.17.231 и префиксу сети ipv6 мы назначили скорость 30М. Правило iptables одно. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
vop Posted September 30, 2016 · Report post Не знал, что tc может сам в ipset заглядывать. Прикольно. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
taf_321 Posted September 30, 2016 · Report post Не знал, что tc может сам в ipset заглядывать. Прикольно. Когда классов меньше десятка, и по ним надо рассадить некислую пачку адресов, то фича весьма удобная. Но когда и адресов и классов сотни и тысячи, то получаем те же линейные фильтры со всеми их тормозами. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
vop Posted September 30, 2016 · Report post Когда классов меньше десятка, и по ним надо рассадить некислую пачку адресов, то фича весьма удобная. Но когда и адресов и классов сотни и тысячи, то получаем те же линейные фильтры со всеми их тормозами. А разве фильтр по classid выбирается линейным перебором списка? Или, все же, выбор идет по индексу id? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
taf_321 Posted September 30, 2016 · Report post tc filter add dev eth0 parent 1:0 protocol all prio 100 basic match ipset'(test dst)' classid 1:11 это просто случай расширенного линейного списка фильтров. Да, если нам в класс 1:11 надо запихать 100500 адресов по порядку или без, подсетями или россыпью, то будет весьма серьезный выигрыш. Но это фильтр, классифицирующий трафик для одного класса. Если классов 100500, то надо будет создавать 100500 (точнее 65536) линейных фильтров. В моем примере в сете задается соотвествие IP и значения поля skbinfo, записей можно задавать сколько душа пожелает ipset create shape-skb4 nethash family inet skbinfo ipset add shape-skb4 192.168.0.5 skbprio 1:11 ipset add shaper4 172.16.1.2/32 skbprio 1:d ipset add shaper4 172.16.17.231/32 skbprio 1:d44 А правило iptables -t mangle -I POSTROUTING -o vlan* -j SET --map-set shaper4 dst --map-prio Проверяет через обращение к сету есть ли для адреса в поле destination пакета запись, и если есть, то пакету проставляется соотвествующая служебная информация (как если бы пакет прошел соотвествующий tc filter), дальше с этой инофрмацией пакет попадет в нужный класс. Боевой шейпер: iptables -L POSTROUTING -nv -t mangle Chain POSTROUTING (policy ACCEPT 3920G packets, 3207T bytes) pkts bytes target prot opt in out source destination 1556G 469T SET all -- * bondEXT 0.0.0.0/0 0.0.0.0/0 map-set shaper4 src map-prio 2253G 2669T SET all -- * bondINT 0.0.0.0/0 0.0.0.0/0 map-set shaper4 dst map-prio tc class show dev bondEXT | wc -l 3784 ipset -L shaper4 | wc -l 4101 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
vop Posted September 30, 2016 · Report post Но это фильтр, классифицирующий трафик для одного класса. Если классов 100500, то надо будет создавать 100500 (точнее 65536) линейных фильтров. А разве ограничение в 0xffff классов не связано с тем, что фильтры для класса ищутся по массиву индексов, а не линейным перебором списка? Просто лень смотреть сырцы. Или я что-то не так спрашиваю... PS Если classid выставлять через ipset/iptables фильтры вообще не нужны. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...