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

субота, 29 вересня 2012 р.

Шейпим трафик, используя ifb и hash фильтры tc

В дополнение к предыдущей статье о шейпинге, где исходящий от клиента трафик маркировался на входящем интерфейсе маршрутизатора и соответствующим образом формировались правила на исходящем интерфейсе, хочется сделать небольшой репост для ещё одного метода, который также имеет право на жизнь.

Итак, есть следующая схема сети:

На сервере присутствуют две сетевых карты:
  • eth0 - ip 192.168.0.10/24, смотрит в мир и на ней поднят nat
    iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.10
  • eth1 - ip 192.168.200.254/24, смотрит в локальную сеть.
Шейпить можно только исходящий трафик с интерфейса. Для клиентов (pc0 - ip 192.168.200.10 и pc1 - ip 192.168.200.20) скорость закачки (download) шейпим на интерфейсе eth1, т.к. для этого интерфейса трафик будет исходящим в сторону клиента.

Логично для отдачи (upload) использовать eth0, но тут есть один нюанс, на этом интерфейсе прописан nat и шейпить на нем исходящий трафик от клиентов не получиться. Чтобы решить данную проблему, завернём весь входящий трафик от клиентов на интерфейсе eth1 в виртуальный интерфейс ifb0, тем более, на данный момент, поддержка IFB есть в ядре.

Для начала нарежем download:
  • Создаем корневую дисциплину на интерфейсе eth1:
    tc qdisc add dev eth1 root handle 1: htb default 20
  • Далее создаем корневой класс для наших клиентских классов. Скорость у него будет 1 mbit, для тестов достаточно:
    tc class add dev eth1 parent 1: classid 1:1 htb rate 1024kbit
  • Теперь создадим таблицу 10 на 256 ячеек:
    tc filter add dev eth1 parent 1:0 prio 1 handle 10: protocol ip u32 divisor 256
  • Создаем фильтр, направлящий весь трафик в хеш таблицу с ID 10:
    tc filter add dev eth1 parent 1:0 protocol ip u32 ht 800:: match ip dst 192.168.200.0/24 hashkey mask 0x000000ff at 16 link 10:
  • Ну а теперь нарежем скорость для наших двух клиентов, для pc0 - 256 kbit, а для pc1 - 512 kbit:
    • Создаем класс 100 со скоростью 256 kbit для pc0:
      tc class add dev eth1 parent 1:1 classid 1:100 htb rate 256kbit ceil 256kbit prio 2 quantum 15365
    • Создаем дисциплину шейпирования для конечного класса:
      tc qdisc add dev eth1 parent 1:100 handle 100: sfq perturb 10
    • Заворачиваем весть трафик для ip 192.168.200.10 в класс 100:
      tc filter add dev eth1 protocol ip prio 2 u32 ht 10:a: match ip dst 192.168.200.10/32 flowid 1:100
    • То же самое, но для pc1:
      tc class add dev eth1 parent 1:1 classid 1:200 htb rate 512kbit ceil 512kbit prio 2 quantum 15365
      tc qdisc add dev eth1 parent 1:200 handle 200: sfq perturb 10
      tc filter add dev eth1 protocol ip prio 2 u32 ht 10:14: match ip dst 192.168.200.20/32 flowid 1:200
  • Весь трафик, который не подпадает под указанные правила будет заворачиваться в класс по умолчанию 20:
    tc class add dev eth1 parent 1:1 classid 1:20 htb rate 32kbit ceil 32kbit prio 2 quantum 15365
    tc qdisc add dev eth1 parent 1:20 handle 20: sfq perturb 10

Теперь upload. Для этого будем использовать виртуальный интерфейс ifb0, куда будет заворачиваться весь входящий трафик от пользователей на интерфейс eth1.
  • Подключаем модуль ядра для ifb:
    modprobe ifb
  • Поднимаем интерфейс ifb0:
    ip link set dev ifb0 up
  • Создаем корневую дисциплину для входящего трафика на интерфейсе eth1:
    tc qdisc add dev eth1 ingress
  • Теперь непосредственно заворачиваем трафик в ifb0:
    tc filter add dev eth1 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
  • А далее по аналогии с исходящим трафиком с интерфейса eth1:
    • Создаем корневую дисциплину и класс:
      tc qdisc add dev ifb0 root handle 1: htb default 20
      tc class add dev ifb0 parent 1: classid 1:1 htb rate 1024kbit
    • Описываем правила для pc0:
      tc class add dev ifb0 parent 1:1 classid 1:100 htb rate 256kbit ceil 256kbit prio 2 quantum 15365
      tc qdisc add dev ifb0 parent 1:100 handle 100: sfq perturb 10
      tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 192.168.200.10/32 flowid 1:100
    • Теперь для pc1:
      tc class add dev ifb0 parent 1:1 classid 1:200 htb rate 512kbit ceil 512kbit prio 2 quantum 15365
      tc qdisc add dev ifb0 parent 1:200 handle 200: sfq perturb 10
      tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 192.168.200.20/32 flowid 1:200
  • Ну и про класс по умолчанию не забываем:
    tc class add dev ifb0 parent 1:1 classid 1:20 htb rate 32kbit ceil 32kbit prio 2 quantum 15365
    tc qdisc add dev ifb0 parent 1:20 handle 20: sfq perturb 10
    
psht 10:14: ; ht 10:a: ; ht 800:: - это значения не в десятичной, а шестнадцатеричной системе исчисления.

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