Шукати в цьому блозі

четвер, 4 червня 2009 р.

Как настроить шейпер на локальную сеть, с корректным/справедливым делением входящего и исходящего трафика?

Вместо предисловия.
Задача, для простых конфигураций, состоит из двух этапов решения.
В качестве препроцессора для формирования tc будем использовать tcng. Категорически советую общественности наконец обратить внимание на этот замечательный инструментарий.
Как правило задача ограничить ширину канала из Интернета к локальным хостам не вызывает особых проблем, ведь этот трафик для сервера, по отношению к клиентским хостам, определяется как egress. В основном "мучения" наступают когда надо ограничить ширину канала из локалки в Интернет. Ниже мы постараемся решить и эту небольшую проблему.

Вводные данные.
Пусть ISP на eth0 - 100Мбит/с, и на нём поднимается ppp0. Пропускная способность ppp0 - 1Мбит/с . Локалка eth1 - 100Мбит/с.
Предположим, что ip адрес выданный провайдером на ppp0 - 100.100.100.100, а на eth1 поднят адрес 10.100.1.1/24. В локальной сети есть четыре привилегированных адреса (10.100.1.254, 10.100.1.253, 10.100.1.252 и 10.100.1.251) на которых поровну делится половина канала в Интернет (512Кбит/с по 128Кбит/с на каждый хост), остальные хосты в сети работают на второй половине канала (512Кбит/с) и нас особо не интересует как они между собой поделят эту скорость.

Первый этап решения.
Описываем правила iptables для трафика приходящего к нам из локалки и уходящий в Интернет:
Код:
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
[0:0] -A PREROUTING -s 10.100.1.254/32 -j MARK --set-xmark 1001
[0:0] -A PREROUTING -s 10.100.1.254/32 -j RETURN
[0:0] -A PREROUTING -s 10.100.1.253/32 -j MARK --set-xmark 2002
[0:0] -A PREROUTING -s 10.100.1.253/32 -j RETURN
[0:0] -A PREROUTING -s 10.100.1.252/32 -j MARK --set-xmark 3003
[0:0] -A PREROUTING -s 10.100.1.252/32 -j RETURN
[0:0] -A PREROUTING -s 10.100.1.251/32 -j MARK --set-xmark 4004
[0:0] -A PREROUTING -s 10.100.1.251/32 -j RETURN
COMMIT
В приведенном примере трафик маркируется в PREROUTING, хотя это транзитный трафик и его с таким же успехом можно промаркировать в цепочке FORWARD таблицы mangle.

Дальше, рисуем скрипт для tcng:
Код:
#define IFACE0  ppp0
#define LOCALRT 102400
#define RATE    1024
#define R2Q     7

$rate01 = (RATE/2)/4;
$rate02 = (RATE/2)/4;
$rate03 = (RATE/2)/4;
$rate04 = (RATE/2)/4;
$rate_other = RATE/2;

dev IFACE0 {
egress {
class (<$mark01>)       if meta_nfmark==1001;
class (<$mark02>)       if meta_nfmark==2002;
class (<$mark03>)       if meta_nfmark==3003;
class (<$mark04>)       if meta_nfmark==4004;
class (<$low>)          if 1;
htb ( rate LOCALRT kbps, r2q R2Q ) {
class ( rate RATE kbps ) {
$mark01 = class ( rate $rate01 kbps ) { sfq(); }
$mark02 = class ( rate $rate02 kbps ) { sfq(); }
$mark03 = class ( rate $rate03 kbps ) { sfq(); }
$mark04 = class ( rate $rate04 kbps ) { sfq(); }
$low = class ( rate $rate_other kbps ) { sfq(); }
}
}
}
}
Преобразуем скрипт tcng в правила tc:
Код:
$ tcng -r linuxforum.ru-topic-79544.ppp0.tcc
tc qdisc del dev ppp0 root
tc qdisc del dev ppp0 ingress

# ================================ Device ppp0 ================================

tc qdisc add dev ppp0 handle 1:0 root dsmark indices 8 default_index 0
tc qdisc add dev ppp0 handle 2:0 parent 1:0 htb r2q 7
tc class add dev ppp0 parent 2:0 classid 2:1 htb rate 128000bps
tc class add dev ppp0 parent 2:1 classid 2:2 htb rate 16000bps
tc qdisc add dev ppp0 handle 3:0 parent 2:2 sfq
tc class add dev ppp0 parent 2:1 classid 2:3 htb rate 16000bps
tc qdisc add dev ppp0 handle 4:0 parent 2:3 sfq
tc class add dev ppp0 parent 2:1 classid 2:4 htb rate 16000bps
tc qdisc add dev ppp0 handle 5:0 parent 2:4 sfq
tc class add dev ppp0 parent 2:1 classid 2:5 htb rate 16000bps
tc qdisc add dev ppp0 handle 6:0 parent 2:5 sfq
tc class add dev ppp0 parent 2:1 classid 2:6 htb rate 64000bps
tc qdisc add dev ppp0 handle 7:0 parent 2:6 sfq
tc filter add dev ppp0 parent 2:0 protocol all prio 1 tcindex mask 0x7 shift 0
tc filter add dev ppp0 parent 2:0 protocol all prio 1 handle 5 tcindex classid 2:6
tc filter add dev ppp0 parent 2:0 protocol all prio 1 handle 4 tcindex classid 2:5
tc filter add dev ppp0 parent 2:0 protocol all prio 1 handle 3 tcindex classid 2:4
tc filter add dev ppp0 parent 2:0 protocol all prio 1 handle 2 tcindex classid 2:3
tc filter add dev ppp0 parent 2:0 protocol all prio 1 handle 1 tcindex classid 2:2
tc filter add dev ppp0 parent 1:0 protocol all prio 1 handle 1001 fw classid 1:1
tc filter add dev ppp0 parent 1:0 protocol all prio 1 handle 2002 fw classid 1:2
tc filter add dev ppp0 parent 1:0 protocol all prio 1 handle 3003 fw classid 1:3
tc filter add dev ppp0 parent 1:0 protocol all prio 1 handle 4004 fw classid 1:4
tc filter add dev ppp0 parent 1:0 protocol all prio 2 u32 match u32 0x0 0x0 at 0 classid 1:5
Что имеем на данном этапе? Спроектированный egress для интерфейса ppp0. Жёсткие ограничения в скорости установленные для наших локальных адресов 10.100.1.254, 10.100.1.253, 10.100.1.252 и 10.100.1.251. Все остальные хосты нашей сети используют остаток канала, который останется после распределения нагрузки этих хостов.

Второй этап решения.
Рисуем скрипт tcng для eth1:
Код:
#define IFACE0  eth1
#define LOCALRT 102400
#define RATE    1024
#define R2Q     7
#define MY_IP   10.100.1.1

$rate01 = (RATE/2)/4;
$rate02 = (RATE/2)/4;
$rate03 = (RATE/2)/4;
$rate04 = (RATE/2)/4;
$rate_other = RATE/2;

$localrate = LOCALRT-RATE;

dev IFACE0 {
egress {
class (<$local>)        if ip_src == MY_IP && ip_dst/24 == 10.100.1.0;
class (<$mark01>)       if ip_dst == 10.100.1.254;
class (<$mark02>)       if ip_dst == 10.100.1.253;
class (<$mark03>)       if ip_dst == 10.100.1.252;
class (<$mark04>)       if ip_dst == 10.100.1.251;
class (<$low>)          if ip_dst/24 == 10.100.1.0;
htb ( rate LOCALRT kbps, r2q R2Q ) {
class ( rate $localrate kbps ) {
$local = class ( rate $localrate kbps ) { sfq(); }
}
class ( rate RATE kbps ) {
$mark01 = class ( rate $rate01 kbps ) { sfq(); }
$mark02 = class ( rate $rate02 kbps ) { sfq(); }
$mark03 = class ( rate $rate03 kbps ) { sfq(); }
$mark04 = class ( rate $rate04 kbps ) { sfq(); }
$low = class ( rate $rate_other kbps ) { sfq(); }
}
}
}
}
Преобразуем скрипт tcng в правила tc:
Код:
$ tcng -r linuxforum.ru-topic-79544.eth1.tcc
tc qdisc del dev eth1 root
tc qdisc del dev eth1 ingress

# ================================ Device eth1 ================================

tc qdisc add dev eth1 handle 1:0 root dsmark indices 8 default_index 0
tc qdisc add dev eth1 handle 2:0 parent 1:0 htb r2q 7
tc class add dev eth1 parent 2:0 classid 2:1 htb rate 12672000bps
tc class add dev eth1 parent 2:1 classid 2:2 htb rate 12672000bps
tc qdisc add dev eth1 handle 3:0 parent 2:2 sfq
tc class add dev eth1 parent 2:0 classid 2:3 htb rate 128000bps
tc class add dev eth1 parent 2:3 classid 2:4 htb rate 16000bps
tc qdisc add dev eth1 handle 4:0 parent 2:4 sfq
tc class add dev eth1 parent 2:3 classid 2:5 htb rate 16000bps
tc qdisc add dev eth1 handle 5:0 parent 2:5 sfq
tc class add dev eth1 parent 2:3 classid 2:6 htb rate 16000bps
tc qdisc add dev eth1 handle 6:0 parent 2:6 sfq
tc class add dev eth1 parent 2:3 classid 2:7 htb rate 16000bps
tc qdisc add dev eth1 handle 7:0 parent 2:7 sfq
tc class add dev eth1 parent 2:3 classid 2:8 htb rate 64000bps
tc qdisc add dev eth1 handle 8:0 parent 2:8 sfq
tc filter add dev eth1 parent 2:0 protocol all prio 1 tcindex mask 0x7 shift 0
tc filter add dev eth1 parent 2:0 protocol all prio 1 handle 6 tcindex classid 2:8
tc filter add dev eth1 parent 2:0 protocol all prio 1 handle 5 tcindex classid 2:7
tc filter add dev eth1 parent 2:0 protocol all prio 1 handle 4 tcindex classid 2:6
tc filter add dev eth1 parent 2:0 protocol all prio 1 handle 3 tcindex classid 2:5
tc filter add dev eth1 parent 2:0 protocol all prio 1 handle 2 tcindex classid 2:4
tc filter add dev eth1 parent 2:0 protocol all prio 1 handle 1 tcindex classid 2:2
tc filter add dev eth1 parent 1:0 protocol all prio 1 u32 match u32 0xa640101 0xffffffff at 12 match u32 0xa640100 0xffffff00 at 16 classid 1:1
tc filter add dev eth1 parent 1:0 protocol all prio 1 u32 match u32 0xa6401fe 0xffffffff at 16 classid 1:2
tc filter add dev eth1 parent 1:0 protocol all prio 1 u32 match u32 0xa6401fd 0xffffffff at 16 classid 1:3
tc filter add dev eth1 parent 1:0 protocol all prio 1 u32 match u32 0xa6401fc 0xffffffff at 16 classid 1:4
tc filter add dev eth1 parent 1:0 protocol all prio 1 u32 match u32 0xa6401fb 0xffffffff at 16 classid 1:5
tc filter add dev eth1 parent 1:0 protocol all prio 1 u32 match u32 0xa640100 0xffffff00 at 16 classid 1:6
Собственно все. Не мудрствуя лукаво мы решили поставленную задачу.

Послесловие.
Естественно, что правила в tcng можно/нужно рисовать свои условия - они индивидуальны для каждого.
Этот пример носят лишь характер "для справки" и способствуют систематизации некоторых знаний :)

Немає коментарів: