[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [SOLVED] Ограничение максимальной скорости по IP



В Срд, 16/01/2008 в 14:49 +0200, Покотиленко Костик пишет:
> Добрый день,
> 
> есть роутер на котором настроено разделение канала по группам клиентов
> (HTB). Сейчас в одной группе нужно сделать подгруппу для клиентов и
> безлимитными пакетами. Для этого им нужно ограничить максимальную
> скорость.
> 

Разобрался, сам себе и отвечу. Может кому пригодится.

Самый простой для моей ситуации оказался такой способ:

- Оставляем HTB классы разделения канала как есть.
- Добавляем только ещё один HTB класс со скоростью, например 1kbit/s -
это для приземления превышения скорости.
- Фильтрам к этим классам ставим приоритет повыше, например 100.
- На каждого безлимитчика добавляем 2 фильтра, один с приоритетом,
например, 10, который срабатывает только для скоростей меньших, чем
интересуемая скорость, второй с приоритетом 11 для остального трафика
(трафик превышающий лимит скорости).

Вот как выглядят у меня фильтры по одному интерфейсу:

# tc filter show dev eth3
filter parent 3: protocol ip pref 10 fw
filter parent 3: protocol ip pref 10 fw handle 0xa14 classid 3:2200
police 0x16 rate 128000bit burst 10Kb mtu 2Kb action continue
ref 1 bind 1
filter parent 3: protocol ip pref 11 fw
filter parent 3: protocol ip pref 11 fw handle 0xa14 classid 3:2300
filter parent 3: protocol ip pref 100 fw
filter parent 3: protocol ip pref 100 fw handle 0x7d64 classid 3:2100
filter parent 3: protocol ip pref 100 fw handle 0x799a classid 3:1130
filter parent 3: protocol ip pref 100 fw handle 0x7990 classid 3:1120
filter parent 3: protocol ip pref 100 fw handle 0x7986 classid 3:1110
filter parent 3: protocol ip pref 100 fw handle 0x79b8 classid 3:1160
filter parent 3: protocol ip pref 100 fw handle 0x79ae classid 3:1150
filter parent 3: protocol ip pref 100 fw handle 0x79a4 classid 3:1140
filter parent 3: protocol ip pref 100 fw handle 0x79d6 classid 3:1190
filter parent 3: protocol ip pref 100 fw handle 0x79cc classid 3:1180
filter parent 3: protocol ip pref 100 fw handle 0x7dc8 classid 3:2200
filter parent 3: protocol ip pref 100 fw handle 0x79c2 classid 3:1170
filter parent 3: protocol ip pref 100 fw handle 0x79e0 classid 3:1200
filter parent 3: protocol ip pref 100 fw handle 0x7e2c classid 3:2300
filter parent 3: protocol ip pref 100 fw handle 0x7e90 classid 3:2400
#

С помощью iptables пакетам первого безлимитчика ставится марка 0xa14.
Основной класс клиентов 3:2200, им классифицируются и пакеты
безлимитчиков до лимита скорости 128kbit (фильтр с приоритетом 10).
Когда начинается перебор фильтр с приоритетом 10 перестаёт срабатывать
и, поскольку в нём указано continue, обработка фильтров продолжается.
Пакеты трафика выше лимита скорости теперь попадают под фильтр с
приоритетом 11, который классифицирует их 3:2300, классом приземления.

Стоит отметить, что для фильтров я сначала использовал u32
классификатор. Потом полностью от него отказался вследствие его
ограничений и перешёл на iptables -j MARK + tc filter fw. На интерфейсе
смотрящем в Интернет настроен SNAT, и u32 видит адреса после SNAT, т.е.
он видит всегда один адрес отправителя :/

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

Скрипту передаются $IP, $IN_RATE, $OUT_RATE. IP из сети с маской /16 и
начиная с a.b.100.0:
------------------------------------
#!/bin/sh

LOGFILE="/var/log/iptables/iptables.log"

CALL_FILE="on_unlim_up"

IN_DEV=eth0
IN_PARENT_CLASS=1:0
IN_BASE_CLASS=1:3220
IN_LAND_CLASS=1:3230

OUT_DEV=eth3
OUT_PARENT_CLASS=3:0
OUT_BASE_CLASS=3:2200
OUT_LAND_CLASS=3:2300

IP3=`echo $IP | cut -d"." -f3`
IP4=`echo $IP | cut -d"." -f4`
HANDLE=`printf "%.3X" $[($IP3-100)*256+$IP4]`
HANDLE10=$[($IP3-100)*256+$IP4]
ret=0

  echo -n `date`: Insetring tc filter: $CALL_FILE: $IP \(ID: $HANDLE\)
at $IN_RATE"/"$OUT_RATE >> $LOGFILE

  # Inseting downstream filtering shaper rules
  iptables -t mangle -I shapIN 1 -d $IP -j RETURN
  iptables -t mangle -I shapIN 1 -d $IP -j MARK --set-mark $HANDLE10

  tc filter add dev $IN_DEV parent $IN_PARENT_CLASS protocol ip prio 10
handle $HANDLE10 fw police rate $IN_RATE buffer 10k continue classid
$IN_BASE_CLASS; ret=$[$ret+$?]
  tc filter add dev $IN_DEV parent $IN_PARENT_CLASS protocol ip prio 11
handle $HANDLE10 fw classid $IN_LAND_CLASS; ret=$[$ret+$?]

  # Inseting upstream filtering shaper rules
  iptables -t mangle -I shapOUT 1 -s $IP -j RETURN
  iptables -t mangle -I shapOUT 1 -s $IP -j MARK --set-mark $HANDLE10

  tc filter add dev $OUT_DEV parent $OUT_PARENT_CLASS protocol ip prio
10 handle $HANDLE10 fw police rate $OUT_RATE buffer 10k continue classid
$OUT_BASE_CLASS; ret=$[$ret+$?]
  tc filter add dev $OUT_DEV parent $OUT_PARENT_CLASS protocol ip prio
11 handle $HANDLE10 fw classid $OUT_LAND_CLASS; ret=$[$ret+$?]

  if [ $ret -ne 0 ]; then
  	echo FAILED \(sum ret: $ret\) >> $LOGFILE
  else
        echo Done >> $LOGFILE
  fi
------------------------------------

> Вопрос: есть ли дисциплина позволяющая ограничивать максимальную
> скорость до указанного значения для каждого IP отдельно, так чтобы не
> нужно было для каждого следующего безлимитчика добавлять класс
> ограничения?

Такой к сожалению нет. А с её помощью можно было бы обойтись
статическими настройками и ipset'ом.

-- 
Покотиленко Костик <casper@meteor.dp.ua>


Reply to: