Иванов Денис Posted February 24, 2012 Posted February 24, 2012 (edited) Господа, прошу помочь советом. :) Имеется бридж, который производит шейпинг входящего трафика нескольких тысяч абонентов. Всё это реализовано средствами Linux Traffic Control (tc). Т.к. приходится создавать тысячи классов и фильтров, была организована иерархия классов дисциплины HTB. Таким образом для каждого пакета может производится не от 1 до тысяч проверок, а от 3 до нескольких сотен (для нашей сети). 10.1.0.0/16 / \ / \ 10.1.2.0/24 10.1.3.0/24 / \ / \ / \ / \ 10.1.2.3 10.1.2.4 10.1.3.4 10.1.3.5 Как Вы думаете, если вдруг понадобится увеличить производительность, то поможет ли следующий подход: Средствами ipset для каждого тарифа создаётся iphash таблица. В таблицы добавляются IP адреса абонентов с соответствующими тарифами. ipset -N 8mbit ipset -A 10.1.2.123 # ... и т.д. ... ipset -N 50mbit ipset -A 10.1.2.124 # ... и т.д. ... ipset -N 2mbit ipset -A 10.10.9.234 # ... и т.д. ... Средствами iptables на внешнем интерфейсе пакеты маркируются идентификаторами тарифов. iptables -t mangle -A PREROUTING -i bond0 -m set --set 8mbit dst -j MARK --set-mark 8 iptables -t mangle -A PREROUTING -i bond0 -m set --set 50mbit dst -j MARK --set-mark 50 iptables -t mangle -A PREROUTING -i bond0 -m set --set 2mbit dst -j MARK --set-mark 2 А для tc остаётся создать несколько простых дисциплин, классов и фильтров: # внутренний сетевой интерфейс DEV='bond1' # скорость по умолчанию DEFAULT_RATE='100mbit' # сброс tc qdisc del dev $DEV root handle 1: htb # корневые дисциплина и класс tc qdisc add dev $DEV root handle 1: htb default 9999 tc class add dev $DEV parent 1: classid 1:1 htb rate $DEFAULT_RATE # краевые классы, фильтры и дисциплины для каждого тарифа: tc class add dev $DEV parent 1:1 classid 1:8 htb rate 8mbit tc filter add dev $DEV protocol ip parent 1:0 handle 8 flowid 1:8 tc class add dev $DEV parent 1:1 classid 1:50 htb rate 50mbit tc filter add dev $DEV protocol ip parent 1:0 handle 50 flowid 1:50 tc class add dev $DEV parent 1:1 classid 1:2 htb rate 2mbit tc filter add dev $DEV protocol ip parent 1:0 handle 2 flowid 1:2 # краевые класс и дисиплина по умолчанию tc class add dev $DEV parent 1:1 classid 1:9999 htb rate $DEFAULT_RATE tc qdisc add dev $DEV parent 1:9999 handle 2: sfq perturb 10 Стоит попробовать, или лучше сразу смотреть в сторону других решений? На всякий случай, пример текущей реализации без iptables и ipset: # сетевой интерфейс DEV='bond1' # скорость по умолчанию DEFAULT_RATE='100mbit' # сброс tc qdisc del dev $DEV root handle 1: htb # корневые дисциплина и класс tc qdisc add dev $DEV root handle 1: htb default 9999 tc class add dev $DEV parent 1: classid 1:1 htb rate $DEFAULT_RATE # классы и фильтры для 10-и сетей /16 tc class add dev $DEV parent 1:1 classid 1:2 htb rate $DEFAULT_RATE tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.1.0.0/16 flowid 1:2 tc class add dev $DEV parent 1:1 classid 1:3 htb rate $DEFAULT_RATE tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.2.0.0/16 flowid 1:3 # ... и т.д. ... tc class add dev $DEV parent 1:1 classid 1:11 htb rate $DEFAULT_RATE tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.10.0.0/16 flowid 1:11 # краевые класс и дисиплина по умолчанию tc class add dev $DEV parent 1:1 classid 1:9999 htb rate $DEFAULT_RATE tc qdisc add dev $DEV parent 1:9999 handle 2: sfq perturb 10 # классы и фильтры для 100-а сетей /24 tc class add dev $DEV parent 1:2 classid 1:12 htb rate $DEFAULT_RATE tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.1.0.0/24 flowid 1:12 tc class add dev $DEV parent 1:2 classid 1:13 htb rate $DEFAULT_RATE tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.1.1.0/24 flowid 1:13 # ... и т.д. ... tc class add dev $DEV parent 1:11 classid 1:112 htb rate $DEFAULT_RATE tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.10.9.0/24 flowid 1:112 # краевые классы, фильтры и дисциплины для пары тысяч абонентов tc class add dev $DEV parent 1:5 classid 1:113 htb rate 8mbit tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.1.2.123 flowid 1:113 tc qdisc add dev $DEV parent 1:113 handle 3: sfq perturb 10 tc class add dev $DEV parent 1:5 classid 1:114 htb rate 50mbit tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.1.2.124 flowid 1:114 tc qdisc add dev $DEV parent 1:114 handle 4: sfq perturb 10 # ... и т.д. ... tc class add dev $DEV parent 1:112 classid 1:2345 htb rate 2mbit tc filter add dev $DEV protocol ip parent 1:0 u32 match ip dst 10.10.9.234 flowid 1:2345 tc qdisc add dev $DEV parent 1:2345 handle 2232: sfq perturb 10 Edited February 27, 2012 by Иванов Денис Вставить ник Quote
NiTr0 Posted February 24, 2012 Posted February 24, 2012 Вы документацию прежде читать не пробовали? :) Вы в результате получите 3 класса, с лимитами по каждому классу, и эта скорость класса будет распределяться между всеми адресами, попавшими в этот класс. Стройте хеш-таблицы правил, и соответственно фильтры. Других вариантов ИМХО нет. Либо - уже готовый скрипт sc, либо - не менее готовый скрипт из LEAF... Вставить ник Quote
Иванов Денис Posted March 7, 2012 Author Posted March 7, 2012 (edited) NiTr0, благодарю за отклик! :) Вы в результате получите 3 класса, с лимитами по каждому классу, и эта скорость класса будет распределяться между всеми адресами, попавшими в этот класс. Действительно, это совсем не то что нам нужно. Либо - уже готовый скрипт sc К сожалению SC не дружит с большим количеством подсетей, поэтому нам не подходит. Стройте хеш-таблицы правил, и соответственно фильтры. Попробовал хеш-фильтр и производительность увеличилась в разы. Спасибо, за отличный совет! :) Пример для 4х сетей, в которых по 254 абонента: 10.0.0.0/24 10.0.1.0/24 10.0.2.0/24 10.0.3.0/24 #!/bin/bash # сетевой интерфейс DEV='bond1' # скорость по умолчанию DEFAULT_RATE='2000mbit' # сброс tc q d dev $DEV root handle 1: htb # корневые дисциплина и класс tc q a dev $DEV root handle 1: htb default ffff tc c a dev $DEV parent 1: classid 1:1 htb rate $DEFAULT_RATE # хеш-фильтр tc f a dev $DEV parent 1:0 prio 5 protocol ip u32 tc f a dev $DEV parent 1:0 prio 5 handle 2: protocol ip u32 divisor 256 tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 800:: match ip dst 10.0.0.0/8 hashkey mask 0x000000ff at 16 link 2: # краевые класс и дисиплина по умолчанию tc c a dev $DEV parent 1:1 classid 1:ffff htb rate $DEFAULT_RATE tc q a dev $DEV parent 1:ffff handle 2: sfq perturb 10 # краевые классы, фильтры и дисциплины для ключа 1 tc c a dev $DEV parent 1:1 classid 1:2 htb rate 10mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:1: match ip src 10.0.0.1 flowid 1:2 tc q a dev $DEV parent 1:2 handle 3: sfq perturb 10 tc c a dev $DEV parent 1:1 classid 1:3 htb rate 5mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:1: match ip src 10.0.1.1 flowid 1:3 tc q a dev $DEV parent 1:3 handle 4: sfq perturb 10 tc c a dev $DEV parent 1:1 classid 1:4 htb rate 20mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:1: match ip src 10.0.2.1 flowid 1:4 tc q a dev $DEV parent 1:4 handle 5: sfq perturb 10 tc c a dev $DEV parent 1:1 classid 1:5 htb rate 1mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:1: match ip src 10.0.3.1 flowid 1:5 tc q a dev $DEV parent 1:5 handle 6: sfq perturb 10 # ... еще 252 аналогичных блока ... # ... для ключа 254 (0xFE) tc c a dev $DEV parent 1:1 classid 1:100 htb rate 50mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:fe: match ip src 10.0.0.254 flowid 1:100 tc q a dev $DEV parent 1:100 handle 101: sfq perturb 10 tc c a dev $DEV parent 1:1 classid 1:101 htb rate 8mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:fe: match ip src 10.0.1.254 flowid 1:101 tc q a dev $DEV parent 1:101 handle 102: sfq perturb 10 tc c a dev $DEV parent 1:1 classid 1:102 htb rate 1mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:fe: match ip src 10.0.2.254 flowid 1:102 tc q a dev $DEV parent 1:102 handle 103: sfq perturb 10 tc c a dev $DEV parent 1:1 classid 1:103 htb rate 20mbit tc f a dev $DEV protocol ip parent 1:0 prio 5 u32 ht 2:fe: match ip src 10.0.3.254 flowid 1:103 tc q a dev $DEV parent 1:103 handle 104: sfq perturb 10 Edited March 7, 2012 by Иванов Денис Вставить ник Quote
Tracert Posted March 15, 2012 Posted March 15, 2012 (edited) Может кому понадобится, как связался с хеш фильтрами написал скрипт генерящий их на перле. На входе имеем БД где есть связка IP - номер договора, на выходе - список фильтров. У нас у юзера может быть несколько IP на договор, поэтому использование других способов фильтрации оказалось неприемлемым. #!/usr/bin/perl -w use IO::Socket; use Switch; use DBI; use File::Temp qw(tempfile); my $mysqlhost = "адрес БД"; my $dbuser = "юзер бд"; my $dbpasswd = "пароль бд"; my $database = "база БД"; my $eth="eth1.32"; my %dbIPDOG=(); $dsn = "DBI:mysql:database=$database;host=$mysqlhost"; $dbh = DBI->connect($dsn, $dbuser, $dbpasswd); $sth = $dbh->prepare("SELECT ip,dogovor FROM users WHERE ip like '10.2.%'"); $sth->execute or die "1: Не могу выпольнить запрос к БД: $!\n"; while (my @row = $sth->fetchrow_array) { if($row[0]=~/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/) #проверяем на формат ip адрсеа и записываем побайтно в многомерный хеш. { $dbIPDOG{$1}{$2}{$3}{$4}=$row[1]; } else { print "Не правильный формат IP адреса, пропускаем: ".$row[0]."\n"; } } my $counter=10; my ($tmp_fh, $tmp_filename ) = tempfile("speed_rules-eth0.10.XXXXX", DIR => "/tmp",UNLINK => 1); #Инициализация фильтра, внимание попадают только 0x150 отмаркированные фаерволом, для отключения уберите match mark 0x150 print $tmp_fh "filter add dev $eth parent 1:0 prio 5 protocol ip u32\n"; print $tmp_fh "filter add dev $eth parent 1:0 prio 5 handle $counter: protocol ip u32 divisor 256\n"; print $tmp_fh "filter add dev $eth protocol ip parent 1:0 prio 5 u32 ht 800:: match ip dst 0.0.0.0/0 match mark 0x150 0xffff hashkey mask 0xff000000 at 16 link $counter:\n\n"; my $prev=$counter; while (my ($key, $hash_b1) = each %dbIPDOG) { $counter++; my $prev_b1=$counter; #print "$key:\n"; print $tmp_fh "\t #$key\n"; print $tmp_fh "\t filter add dev $eth parent 1:0 prio 5 handle $counter: protocol ip u32 divisor 256\n"; print $tmp_fh "\t filter add dev $eth protocol ip parent 1:0 prio 5 u32 ht $prev:".lc(sprintf("%.2x",$key)).": match ip dst 0.0.0.0/0 hashkey mask 0xff0000 at 16 link $counter:\n\n"; while (my ($key2, $hash_b2) = each %$hash_b1) { $counter++; $prev_b2=$counter; print $tmp_fh "\t\t #$key.$key2\n"; print $tmp_fh "\t\t filter add dev $eth parent 1:0 prio 5 handle $counter: protocol ip u32 divisor 256\n"; print $tmp_fh "\t\t filter add dev $eth protocol ip parent 1:0 prio 5 u32 ht $prev_b1:".lc(sprintf("%.2x",$key2)).": match ip dst 0.0.0.0/0 hashkey mask 0xff00 at 16 link $counter:\n\n"; while (my ($key3, $hash_b3) = each %$hash_b2) { #print " $key3:\n"; $counter++; print $tmp_fh "\t\t\t #$key.$key2.$key3\n"; print $tmp_fh "\t\t\t filter add dev $eth parent 1:0 prio 5 handle $counter: protocol ip u32 divisor 256\n"; print $tmp_fh "\t\t\t filter add dev $eth protocol ip parent 1:0 prio 5 u32 ht $prev_b2:".lc(sprintf("%.2x",$key3)).": match ip dst 0.0.0.0/0 hashkey mask 0xff at 16 link $counter:\n\n"; while (my ($key4, $value3) = each %$hash_b3) { print $tmp_fh "\t\t\t\t filter add dev $eth protocol ip parent 1:0 prio 5 u32 ht $counter:".lc(sprintf("%.2x",$key4)).": match ip dst 0.0.0.0/0 flowid 1:$value3\n"; } print $tmp_fh ("\n"); } } } system ("/sbin/tc -b $tmp_filename"); print "Done.\n"; Работает очень быстро около 7 тысяч правил грузятся ощутимо менее 1 секунды. При желании можете поиграться с параметрами, тут фильтруется уходящй на клиентов из одной подсети. Для того чтобы фильтровать трафик уходящий от клиентов надо заменить везде mask маска at 16 на mask маска at 12. Если очень надо могу запустить и создание самих классов, но там ничего сложного совсем. Видел С прогу делающую тоже самое, но не знал о ее существовании когда писал скрипт. Edited March 15, 2012 by Tracert Вставить ник Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.