Jump to content
Калькуляторы

Покритикуйте схему шейпинга на ppp интерфейсе linux tc shaping htb ppp

Задача:

Организовать шейпинг на ppp интерфейсах pppoe сервера. С возможностью шейпить отдельно локальный трафик.

Трафик через пппое сервера планируется приличный, поэтому правила фильтрации и шейпинга должны быть минимальны. Иначе это приведет к серьезной загрузке ЦПУ.

Сама идея шейпить исходящий через HTB, а входящий "полисить" с помощью специальных фильтров и дисциплины ingress - не нова. Тут вся фишка в том, что с помошью наследования классов и приоритетов фильтров как мне кажется удалось дешево и сердито обеспечить шейпинг инет трафика при неограниченном локальном.

 

 

/etc/ppp/if-up:

#!/bin/sh

 

LOCALNET="10.0.0.0/8 192.168.0.1/24 172.16.0.0/24"

 

if [ -f /var/run/radattr.$1 ]

then

MAXSPEED=102400

DOWNSPEED=`/usr/bin/awk '/PPPD-Downstream-Speed-Limit/ {print $2}' /var/run/radattr.$1`

UPSPEED=`/usr/bin/awk '/PPPD-Upstream-Speed-Limit/ {print $2}' /var/run/radattr.$1`

/sbin/tc qdisc del dev $1 root > /dev/null

/sbin/tc qdisc del dev $1 handle ffff: ingress > /dev/null

 

##########################################################################

## -->customer

##

if [ "$DOWNSPEED" != "" ] ;

then

LOCALSPEED=$[$MAXSPEED-$DOWNSPEED]

/sbin/tc qdisc add dev $1 root handle 1: htb default 20

/sbin/tc class add dev $1 parent 1: classid 1:1 htb rate ${MAXSPEED}kbit ceil ${MAXSPEED}kbit #parent class (общий класс, от которого ведется наследование)

/sbin/tc class add dev $1 parent 1:1 classid 1:10 htb rate ${LOCALSPEED}kbit ceil ${MAXSPEED}kbit #local net class (этот клас может занимать полосу у класса 20. локалка должна быть быстрой -;)

/sbin/tc class add dev $1 parent 1:1 classid 1:20 htb rate ${DOWNSPEED}kbit burst 20k #inet class (он же дефаулт)

for i in $LOCALNET

do

/sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip src $i flowid 1:10 #фильтры для локалки.

done

fi

##########################################################################

## <--customer

##

if [ "$UPSPEED" != "" ] ;

then

/sbin/tc qdisc add dev $1 handle ffff: ingress

for i in $LOCALNET

do

/sbin/tc filter add dev $1 parent ffff: protocol ip prio 30 u32 match ip dst $i police rate ${MAXSPEED}kbit burst 20k drop flowid :1 # приоритет этих фильтров выше, сначала сработают они.

done

/sbin/tc filter add dev $1 parent ffff: protocol ip prio 40 u32 match ip src 0.0.0.0/0 police rate ${UPSPEED}kbit burst 20k drop flowid :1# этот приоритет ниже. Если не сработали фильтры prio 30 - значит трафик - инет.

fi

fi

Share this post


Link to post
Share on other sites

под линуксом правда нет таблиц ipfw как на FreeBSD, таблицы не так кушают процессор как фильтрация и шейпинг по отдельным адресам, возможно как то на линуксе возможно это реализовать, либо если адреса у пользователей статические то вынести это на отдельную машину где нарисовать таблицы для всех пользователей и преодически их обновлять

Share this post


Link to post
Share on other sites

>Я на аплоад IFB использую

 

Покажите пример. Насколько я понимаю, там тоже есть свои сложности.

 

Share this post


Link to post
Share on other sites

 

А я вообще не режу аплоад. Результаты такие, что он редко когда превышает download, так что как мне кажется, это не нужно. Статистика по двум провайдерам.

Share this post


Link to post
Share on other sites

То что относится к IFB (вместо /sbin/tc filter add dev $1 parent ffff: protocol ... )

интерфейсы создаются предварительно, с рассчетом что их будет достаточно (я создаю 1024), при загрузке модуля.

В ходе работы траффик всегда передается с pppXX на ifbXX что б не хранить нигде сопоставления.

...
DEV_PPP=$1
NAS_PORT=`echo $DEV_PPP |  cut -b 4-`
DEV_IFB=ifb$NAS_PORT

....

#перенаправлять входящие пакеты с eth0 в ifb0
$ip link set dev $DEV_IFB up
$tc qdisc add dev $DEV_PPP ingress
$tc filter add dev $DEV_PPP parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $DEV_IFB

$tc qdisc add dev $DEV_IFB root handle 1:0 htb default 1201 r2q $r2q          
$tc class add dev $DEV_IFB parent 1: classid 1:1 htb rate ${SUM_RATE_UP}kbit burst 1000k quantum 3100
    class_add $DEV_IFB 1 1201 "htb rate ${REAL_RATE_UP}kbit ceil ${REAL_RATE_UP}kbit burst 20k" 1 3100 $MTU

Share this post


Link to post
Share on other sites

Первичный инит

$TC qdisc add dev ifb0 root handle 1: htb default 1000

$TC class add dev ifb0 parent 1:0 classid 1:1 htb rate 100Mbit ceil 100Mbit quantum 1600

$TC filter add dev ifb0 parent 1:0 prio 1000 protocol ip u32 match ip dst 0.0.0.0/0 classid 1:131
$TC filter add dev ifb0 protocol ip pref 32 parent 1: handle 1 flow map key priority baseclass 1:64

 

 

При запуске юзера

    lowid=$((${id}))
    id=$((${id}+100))
    id=`printf "%x" ${id}`
    lowid=`printf "%x" ${lowid}`

class del dev ifb0 classid 1:${id} parent 1:0 (точно эту строку не помню)
class add dev ifb0 classid 1:${id} parent 1:0 htb rate ${rate}bit
echo "qdisc add dev ifb0 parent 1:${id} handle ${id}: bfifo limit ${buffer}

....

filter add dev $2 parent ffff: protocol ip prio 10 u32 \
match u32 0 0 flowid 1:1 \
action skbedit priority 0x${lowid} pipe \
action mirred egress redirect dev ifb0

....

Соответственно у меня ОДИН фильтр на всех, и единственное что делаю с ifb - дергаю классы в ifb0. Нет кучи интерфейсов, нет кучи фильтров! Собственно за это я долго и боролся

skbedit появился только в последнем ядре.

Я не буду пастить весь код, но предупреждаю - есть заморочки с oct/hex, с этим нужно повнимательнее.

Share this post


Link to post
Share on other sites

>Собственно за это я долго и боролся

Вот и я за тоже борюсь...

 

А есть практический пример разницы между шейпингом и полисингом ?На скоростях 2-20 Мб.

Share this post


Link to post
Share on other sites

nuclearcat

Не уловил логику работы совершенно (

Не могли бы Вы поделиться ссылкой где почитать что есть action skbedit priority 0x${lowid} pipe \

 

PS

Похоже совершенно другой полход от моего.

 

PPS

а чем плохо много интерфейсов?

Share this post


Link to post
Share on other sites
nuclearcat

Не уловил логику работы совершенно (

Не могли бы Вы поделиться ссылкой где почитать что есть action skbedit priority 0x${lowid} pipe \

действие skbedit по сути меняет значение поля priority структуры sk_buff далее конвейером идет действие перенаправляющее на ifb, к ifb уже прикреплен flow-фильтр который классифицирует трафик в зависимости от значения priority (который уже изменил skbedit) и раскидывает по классам.

Вообще интересно получается :)

 

PS вообще с документацией tc всё плохо, а по новым "фишкам" тем более :(

может пригодится это, еще рассылки netdev, ну и исходники

 

2 nuclearcat

flow в качестве ключа поддерживает iif, возможно ли его применить в этой схеме?

 

KEY := [ src | dst | proto | proto-src | proto-dst | iif | priority |

mark | nfct | nfct-src | nfct-dst | nfct-proto-src |

nfct-proto-dst | rt-classid | sk-uid | sk-gid |

Edited by DemYaN

Share this post


Link to post
Share on other sites

а что если микротик использовать? шейпит отлично.

у меня сейчас на машине примерно 1300-1700 правил шейпинга - загрузка процессора где-то 10-20%

Share this post


Link to post
Share on other sites

DemYaN - во первых в ifb iif еще не присутствует, во вторых там насколько я помню номер, который incremental и никак не соотносится с pppN, и соотносить его реальный гемор.

 

Микротик просто говно. Во первых регулярно сталкиваюсь с глюками(от пакетлоссов до крашей) вызванными горой нестандартных патчей не входящих в mainline, во вторых, идеологически - это пижженный (сорри за ругательство, но раскрывать исходники соответственно условиям GPL они не торопяться) линукс для неграмотных.

Единственное что мне у них нравится более-менее - wireless. В остальном - говно.

Share this post


Link to post
Share on other sites

ip link sh ppp0
56328: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1480 qdisc htb state UNKNOWN qlen 3

 

56328 - не iif ли это?

 

Share this post


Link to post
Share on other sites

кажется в самом первом посте нет дисциплин для краевых классов

Share this post


Link to post
Share on other sites

У меня похожий шейпер, в связке с PPTP (ppptd/accel-pptpd) даёт иногда глючок: тоннель работает, а пакеты не ходют. Может быть дело в шейпере или копать дальше?

/sbin/tc qdisc del dev $1 root

/sbin/tc qdisc del dev $1 ingress

на глючном ифейсе не меняет ситуации. Вот не знаю - переписывать ли шейпер с IFB или дело не в этом?

Edited by Abram

Share this post


Link to post
Share on other sites

думаю не в шейпере

Share this post


Link to post
Share on other sites

Возник такой вопрос, как будет быстрее в плане нагрузки на процессор организовать шейпинг по направлениям? Направлений всего 4. Внутренние сети - пару сетей, трафик между пользователями - тоже буквально несколько сетей, местный IX - где то 100 сетей, ну и все остальное - мир

рассматриваю такие варианты:

 

1 Маркировка по направлениям в ipt и разброс по разным очередям fw классификатором на ppp интерфейсе, и разброс аплоада на разные ifb(согласно направлению) тоже fw классификатором + редактирование priority . На ifb предложенный способ с priority в качестве ключа.

2 То же самое с одним ifb но для разных направлений по fw устанавливаются разные priority

3 Использовать классификатор route для разброса по направлениям. Из плюсов - возможность динамически кваггой метить роуты.

 

Подозреваю что последний способ наиболее производительный. Есть ли какие то еще способы, и кто как пробовал?

Share this post


Link to post
Share on other sites

Если на этой же машине не планируется устраивать per-user shaping, то фильтров будет мало при любом способе. Вариант с route конечно предпочтительнее. IFB не нужен, т.к. есть возможность шейпить трафик как исходящий на физических интерфейсах.

 

Кстати говоря, классификацию типа IP -> classid проще всего делать с помощью классификатора flow, появившегося в последних ядрах: http://www.mail-archive.com/netdev@vger.ke...g/msg60638.html

Edited by photon

Share this post


Link to post
Share on other sites

думаю не в шейпере

Угу, переписал с IFB - всё то же. Трейсю pppd.

Share this post


Link to post
Share on other sites

Я не до конца описал, планируется именно для каждого юзера на 4 направления. Не хочется делать основываясь на ip пользователя, поэтому и смотрю в сторону iif

Edited by 2c2i

Share this post


Link to post
Share on other sites

наверное буду на одном ifb cначала по priority затем по route

Share this post


Link to post
Share on other sites

Интересно, как вы собираетесь делать шейпинг (предоставлять каждому гарантированную полосу пропускания), если у каждого юзера не будет своего класса обслуживания? Без разницы, по какому признаку классифицировать: по IP или по iif. В любом случае это будет или HTB с кучей дочерних классов на одном физическом интерфейсе, или по одному классу с дисциплиной TBF на каждом из виртуальных интерфейсов. IFB -- это не волшебная палочка, решающая все проблемы, это всего лишь псевдоустройство, на которое можно завернуть тот или иной трафик. Будет намного проще, если разнести шейпинг интернет-трафика и внутрисетевую маршрутизацию на разные машины. Сервак на Linux все равно рано или поздно перестанет справляться с внутрисетевым трафиком, придется ставить L3-коммутатор.

Edited by photon

Share this post


Link to post
Share on other sites

Внутрисетевой трафик в моем случае - это трафик между pppoe туннелями. Для юзеров с реал ип при закачке торрентов он довольно не мал. Я не представляю как заставить такой трафик пойти через отдельный роутер/l3 свитч.

Для шейпинга аплоада, я таки планирую HTB с кучей дочерних классов, но на ifb. На ifb мне удобнее, так как аплинк интерфейс не всегда один.

Edited by 2c2i

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this