voron Опубликовано 10 декабря, 2009 (изменено) · Жалоба или все IP в классе будут делить полосу? скорее всего это. Если нужен индивидуальный шейп - нет смысла лепить несколько IP в один класс. Изменено 10 декабря, 2009 пользователем voron Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 10 декабря, 2009 (изменено) · Жалоба "Несколько IP на один класс" - каждый IP будет шейпится индивидуально? или все IP в классе будут делить полосу? Ну естественно, несколько IP на одну очередь будут делить одну полосу пропускания. С другой стороны, я не хочу сейчас включать эту возможность, т.к. она ломает некоторые команды (show, list, операции с базой), и их под это дело нужно будет полностью переписывать. К тому же, не стоит провоцировать внедрение этой неоптимальной политики QoS. Изменено 10 декабря, 2009 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
shicoy Опубликовано 10 декабря, 2009 · Жалоба Из какого набора хэшей Ipset беруться данные для шейпера? Или создается несколько каждая под свой диапазон IP? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 10 декабря, 2009 (изменено) · Жалоба ipset и iptables при использовании u32 вообще не нужны, т.к. можно просто создать tc filter с policy, блокирующий весь неклассифицированный трафик. classid и номера фильтров генерируются из списков сетей. Допускаются сети от /31 до /16 с одинаковыми последними октетами. Для классов суммарное количество хостов во всех подсетях не должно превышать ffff. В конфиге теперь это выглядит примерно так: # сети для вычисления classid network = 10.0.0.0/17 172.16.0.0/22 172.16.5.0/24 172.16.254.0/24 # для построения фильтров filter_network = 10.0.0.0/17 172.16.0.0/16 При создании фильтров нужно использовать примерно тот же принцип, что и для route aggregation: одним хэш-фильтром для 172.16.0.0/16 можно классифицировать трафик для подсетей 172.16.0.0/22, 172.16.5.0/24 и 172.16.254.0/24. Изменено 10 декабря, 2009 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
shicoy Опубликовано 10 декабря, 2009 · Жалоба Круто! Уже хочется скрипт посмотреть =) Реально очень сложная работа Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
shaytan Опубликовано 11 декабря, 2009 (изменено) · Жалоба ipset и iptables при использовании u32 вообще не нужны, т.к. можно просто создать tc filter с policy, блокирующий весь неклассифицированный трафик. Куда нужно помещать правило которое будет отлавливать не классифицированные пакеты? Правило которое вычисляет ключ и направляет в нужный ht уже проматчит все пакеты. filter parent 1: protocol ip pref 5 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 5 u32 fh 800::800 order 2048 key ht 800 bkt 0 link 2: (rule hit 2721032302 success 0) match 00000000/00000000 at 16 (success 2721032302 ) hash mask 000000ff at 16 Остаётся вариант с добавлением правила с максимальным prio в каждую из 255 ht. Я сейчас при матче в ht делаю маркировку пакета, а в iptables пропускаю пакеты с установленным fwmark, остальные дропаю. filter parent 1: protocol ip pref 5 u32 fh 2:fd:2 order 2 key ht 2 bkt fd flowid 1:5c6 (rule hit 1093575 success 772508) match 0a310ffd/ffffffff at 12 (success 772508 ) action order 72097: tablename: mangle hook: NF_IP_POST_ROUTING target MARK xset 0x2/0xffffffff index 3754 ref 1 bind 1 installed 247061 sec used 39797 sec Action statistics: Sent 92823432 bytes 772508 pkt (dropped 0, overlimits 0 requeues 0) rate 0bit 0pps backlog 0b 0p requeues 0 Изменено 11 декабря, 2009 пользователем shaytan Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
a0d75 Опубликовано 11 декабря, 2009 · Жалоба ipset и iptables при использовании u32 вообще не нужны, т.к. можно просто создать tc filter с policy, блокирующий весь неклассифицированный трафик. classid и номера фильтров генерируются из списков сетей Это хорошо, однако лучше ipset все же оставить, т. к. удобно перенаправлять трафик ipt_netflow. А если не использовать ipset - будет попадать трафик из заблокированных сетей. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 11 декабря, 2009 (изменено) · Жалоба Куда нужно помещать правило которое будет отлавливать не классифицированные пакеты? Правило которое вычисляет ключ и направляет в нужный ht уже проматчит все пакеты.Да, в default queue с полосой 1bps такой трафик уже не попадает, но можно пойти другим путем. Если в хэше нет краевого фильтра $ht:$key:800, указывающего на какой-то конкретный flowid 1:x, то пакет проходит по фильтрам дальше. И здесь его можно отбросить с помощью правила, добавленного в конец, и желательно с более высоким значением pref: tc filter add dev $DEV parent 1: protocol ip pref 30 u32 match u32 0x0 0x0 at 0 police mtu 1 action drop Это хорошо, однако лучше ipset все же оставить, т.к. удобно перенаправлять трафик ipt_netflow. А если не использовать ipset - будет попадать трафик из заблокированных сетей.Я полагаю, что шейпер по возможности лучше делать в виде простого моста, на чистом tc, чтобы не связываться с iptables и его проблемами с блокировками. А всевозможные Netflow и NAT делать на других машинах. В принципе, потом можно будет придумать какую-то опцию для совместного использования u32 и ipset, но сейчас главное получить правильно работающую функцию, которая отображает IP-адреса из указанных сетей на пространства классов и фильтров. Изменено 11 декабря, 2009 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 12 декабря, 2009 (изменено) · Жалоба Предварительная версия скрипта, классифицирующего подсети с одинаковыми последними октетами с помощью u32 hashing filters: http://mercurial.intuxication.org/hg/sc/archive/tip.tar.gz Теперь в конфиге нужно указывать подсети к которым принадлежат IP-адреса. Из-за вышеупомянутого фильтра, который блокирует весь трафик, сам шейпер будет иметь выход в Интернет только если для него тоже создан аккаунт. Наверное, стоит прикрутить добавление u32-фильтров для одиночных IP-адресов, чтобы в network и filter_network можно было указывать хосты с маской /32. Изменено 12 декабря, 2009 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
shicoy Опубликовано 14 декабря, 2009 · Жалоба Спасибо, будем изучать. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 23 декабря, 2009 · Жалоба Вопрос с генератором хэширующих фильтров решен. Я довел дело до релиза: http://sourceforge.net/projects/sc-tool/ Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
shicoy Опубликовано 23 декабря, 2009 · Жалоба Спасибо, хорошая работа! Результаты боевой эксплуатации отпишу после НГ. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
shicoy Опубликовано 23 декабря, 2009 · Жалоба Кстати, а каким образом можно осуществить быструю загрузку большого кол-ва (от 10к) фильтров? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 23 декабря, 2009 (изменено) · Жалоба Команда sc load. Перед этим, естественно, нужно иметь заполненную базу данных. Нагенерировать случайные данные для теста можно скриптом genbase. Изменено 23 декабря, 2009 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 10 января, 2010 (изменено) · Жалоба Исправил в версии 1.1.1 ошибку в фильтрах, возникающую если несколько раз подряд выполнить sc add <ip> <rate> для одного и того же IP-адреса. Синтаксис tc для фильтра u32 довольно неоднозначен. Например, одинаковые с виду команды tc filter replace dev eth1 parent 1: pref 20 handle 100:1 u32 ht 100:1: match ip src 10.0.0.2 flowid 1:3 tc filter replace dev eth1 parent 1: pref 20 handle 100:1:800 u32 ht 100:1: match ip src 10.0.0.2 flowid 1:3 tc filter replace dev eth1 parent 1: pref 20 u32 ht 100:1: match ip src 10.0.0.2 flowid 1:3 делают разные вещи. Изменено 10 января, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Max P Опубликовано 13 января, 2010 · Жалоба а удвоение скоростей есть? (типа ночью в два раза выше) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 13 января, 2010 (изменено) · Жалоба Мне не нравится два раза в сутки перезагружать несколько тысяч правил. Это подрывает стабильность работы. К тому же, в базе скорость одна, а в правилах будет другая, нужно переписывать код, отвечающий за синхронизацию. Могу сделать опцию, содержащую множитель для скоростей, но не более того. Менять его по расписанию и перезагружать правила лучше по крону из стороннего скрипта. Изменено 13 января, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Max P Опубликовано 13 января, 2010 · Жалоба да не, просто вопрос кто как это делает обычно... мне вот тоже не нравилось делать delete/add, наваял вот скриптец на баше #/bin/bash case $1 in "up" ) for iface in $(echo "eth3 ifb0"); do tc class show dev $iface | awk -v iface=$iface '$5 ~ "1:4" || $5 ~ "1:5" { match($14,/([0-9]*)([Aa-Zz]*)/,arr); system("tc class replace dev " iface " parent " $5 " classid " $3 " hfsc sc m1 0 d 1s m2 " arr[1]*2arr[2] " ul rate " arr[1]*2arr[2]) }' done ;; "down" ) for iface in $(echo "eth3 ifb0"); do tc class show dev $iface | awk -v iface=$iface '$5 ~ "1:4" || $5 ~ "1:5" { match($14,/([0-9]*)([Aa-Zz]*)/,arr); system ("tc class replace dev " iface " parent " $5 " classid " $3 " hfsc sc m1 0 d 1s m2 " arr[1]/2arr[2] " ul rate " arr[1]/2arr[2]) }' done ;; * ) echo "Error! What do you want to go today?!" ;; esac может кто красивее знает решение? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 14 января, 2010 (изменено) · Жалоба да не, просто вопрос кто как это делает обычно... мне вот тоже не нравилось делать delete/add, наваял вот скриптец на баше Очевидно, что красивое решение должно читать данные из базы для всех адресов за один раз и использовать tc -batch для перезагрузки правил, чтобы не было накладных расходов на создание процессов tc. И вместо shell с костылями лучше использовать Perl. Изменено 14 января, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Max P Опубликовано 15 января, 2010 · Жалоба для меня перл с модулями - костыль :) городить его везде... шелл есть везде, авк тоже. имхо решение должно использовать текущее состояние шейпера, иначе можно напороться на какой нить косяк в стиле в базе нет, а в шейпере есть и наоборот, либо предварительно делать синхронизацию... кстате, наверно можно переделать скрипт чтобы вначале выгружал tc show в файл, скрипт генерит batch-файл с удвоенными скоростями и потом заливает... надо попробовать :) спасибо за наводку :) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 15 января, 2010 (изменено) · Жалоба Простые вещи, вроде тех, что делают shell, awk и sed, на Perl решаются без модулей. Он для этого и был задуман. При этом не нужно использовать временные файлы, т.к. там можно работать с пайпами как с обычными файлами, а не только строить цепочки из них: open my $FH, "tc class show dev eth1 |"; my @out = <$FH>; close $FH; open my $FH2, "| tc -batch"; print $FH2 "class replace ...\n"; close $FH2; Изменено 16 января, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
vadislaus Опубликовано 11 февраля, 2010 (изменено) · Жалоба Это у меня глюк, что при sc init отваливается сервер от сети (при filter_method = u32)? Детально пока еще не изучал, да и tc с хэшем только в теории понимаю. Изменено 11 февраля, 2010 пользователем vadislaus Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 12 февраля, 2010 (изменено) · Жалоба Сеть отваливается, т.к. в правилах используется фильтр, блокирующий весь нефильтрованный трафик. Добавьте в базу аккаунт для шейпера командой sc dbadd <shaper-ip> и загружайте правила с помощью sc load. sc init -- команда только для тестовых целей, она создает корневые классы и дисциплины, не загружая аккаунты из базы. Изменено 12 февраля, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
a0d75 Опубликовано 15 марта, 2010 (изменено) · Жалоба "Несколько IP на один класс" - каждый IP будет шейпится индивидуально? или все IP в классе будут делить полосу?Ну естественно, несколько IP на одну очередь будут делить одну полосу пропускания. С другой стороны, я не хочу сейчас включать эту возможность, т.к. она ломает некоторые команды (show, list, операции с базой), и их под это дело нужно будет полностью переписывать. К тому же, не стоит провоцировать внедрение этой неоптимальной политики QoS. Подскажите, как включить эту возможность? Работа с базой не нужна, после трех дней изучения понял, что моих навыков в PERL не хватает для правки :( Хотелось бы указывать несколько IP на класс, в качестве идентификатора использовать первый IP либо строку (логин), что предпочтительнее. Например вызывать sc add 192.168.1.12 1024 sc add 192.168.1.30 1024 192.168.1.12 sc add 192.168.1.31 1024 192.168.1.12 либо sc add 192.168.1.12 1024 login_1 sc add 192.168.1.30 1024 login_1 sc add 192.168.1.31 1024 login_1 Дополнение: все-таки удалось запустить, сделал небольшой патч, реализующий первый предложенный мной вариант: --- sc.save 2010-03-15 15:11:46.000000000 +0300 +++ sc 2010-03-15 15:38:49.000000000 +0300 @@ -82,7 +82,7 @@ # database handler (optional) 'dbhandler' => \&cmd_dbadd, # arguments (optional) - 'arg' => '<ip> <rate>', + 'arg' => '<ip> <rate> <parent_ip>', # command description 'desc' => 'add rules', # check root privileges before execution (optional) @@ -1465,12 +1465,18 @@ sub cmd_add { - my ($ip, $rate) = @_; + my ($ip, $rate, $parent_ip) = @_; + my $cid; arg_check(\&is_ip, $ip, 'IP'); $rate = arg_check(\&is_rate, $rate, 'rate'); - my $cid = ip_classid($ip); - return $rul_add->($ip, $cid, $rate); + if($parent_ip){ + $parent_ip = arg_check(\&is_ip, $parent_ip, 'parent_ip'); + $cid = ip_classid($parent_ip); + } else { + $cid = ip_classid($ip); + } + return $rul_add->($ip, $cid, $rate, $parent_ip); } sub cmd_del Изменено 15 марта, 2010 пользователем a0d75 Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
a0d75 Опубликовано 15 марта, 2010 · Жалоба Дополнение: чтобы не было "кто первый встал - того и тапки" поставил leaf_qdisc = 'sfq perturb 10'. Все работает отлично, однако почему-то команды типа "/sbin/tc qdisc replace dev ifb0 parent 1:800e handle 800e:0 sfq perturb 10" отрабатывают с ошибкой для каждого последующего IP адреса, добавляемого к первому. Если сделать сначала del вместо replace - все работает как нужно. Хотя это не принципиально в моем случае. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...