Shaper tables: Использование хеш-таблиц для уменьшания числа правил шейпера: различия между версиями
Материал из noname.com.ua
Перейти к навигацииПерейти к поискуSirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) м (Sirmax переименовал страницу Shaper tables в Shaper tables: Использование хеш-таблиц для уменьшания числа правил шейпера) |
||
(не показано 9 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
+ | [[Категория:Заготовка Статьи]] |
||
+ | [[Категория:Linux]] |
||
+ | [[Категория:QOS]] |
||
+ | [[Категория:shaper]] |
||
+ | [[Категория:tc]] |
||
=Шейпера и таблицы= |
=Шейпера и таблицы= |
||
Строка 24: | Строка 29: | ||
#корневая дисциплина |
#корневая дисциплина |
||
cmd="$tc qdisc add dev $DEV root handle 1:0 htb default 3" |
cmd="$tc qdisc add dev $DEV root handle 1:0 htb default 3" |
||
+ | </PRE> |
||
+ | |||
+ | Конструкция вида |
||
<PRE> |
<PRE> |
||
+ | echo $cmd;$cmd; |
||
+ | </PRE> |
||
+ | используется для дебага - и вывести команду на экран и выполнить ее. |
||
+ | <PRE> |
||
+ | cmd="$tc filter add dev $DEV parent 1:0 protocol ip u32" |
||
+ | echo $cmd;$cmd; |
||
+ | </PRE> |
||
+ | #корневой класс |
||
+ | <PRE> |
||
+ | class_add $DEV 1: 1:0 "htb rate ${RATE}kbit ceil ${RATE}kbit burst 10k" 1 $QUANTUM $MTU |
||
+ | </PRE> |
||
+ | <PRE> |
||
+ | HTHDL=257 |
||
+ | # Конструкции ниже абсолютно эквивалентны - перевод числа в хекс |
||
+ | #HTHDLhex=`printf %X$HTHDL` |
||
+ | printf -v HTHDLhex %X $HTHDL |
||
+ | #HTHDLhex=${hex[HTHDL]} |
||
+ | #хеш-таблица для подсетей, 256 элементов |
||
+ | cmd="$tc filter add dev $DEV parent 1:0 handle $HTHDLhex: protocol ip u32 divisor 256" |
||
echo $cmd;$cmd; |
echo $cmd;$cmd; |
||
+ | |||
− | |||
+ | #разбиваем по подсетям |
||
− | cmd="$tc filter add dev $DEV parent 1:0 protocol ip u32" |
||
+ | # Это правило следует читать так: |
||
− | echo $cmd;$cmd; |
||
+ | # Для любого адреса источника из сети 94.154.32.0/21 |
||
− | |||
+ | # по смещению 12 байт наложить маску. Т.е. наложить маску на сам адрес источника. |
||
− | |||
+ | # В результате (см маску) - будет выделен 3-й октет (в пример он может принимать значения 32-39) |
||
− | #корневой класс |
||
+ | # и этот октет будет использован как указатель, т.е. пакет перенаправлен в правило $HTHDLhex:Номер_Подсети |
||
− | class_add $DEV 1: 1:0 "htb rate ${RATE}kbit ceil ${RATE}kbit burst 10k" 1 $QUANTUM $MTU |
||
+ | # |
||
− | |||
+ | cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht 800:: match ip src 94.154.32.0/21 hashkey mask 0x0000ff00 at 12 link $HTHDLhex:" |
||
− | #class_add device parent classid "CLASS_SPECEFIC" prio quantum mtu |
||
+ | echo $cmd;$cmd; |
||
− | #qdisc_add dev parent handle "QDISC_SPECEFIC" |
||
+ | </PRE> |
||
− | #filter_add dev parent prio "FILTER_SPECEFIC" flowid |
||
+ | ==1== |
||
− | |||
+ | Для каждой из подсетей создаем свою хеш-таблицу полностью аналогичную таблице выше |
||
− | #exit |
||
+ | <PRE> |
||
− | HTHDL=257 |
||
+ | for i in `seq 32 39`;do |
||
− | #HTHDLhex=`printf %X $HTHDL` |
||
+ | printf -v ihex %X $i |
||
− | printf -v HTHDLhex %X $HTHDL |
||
+ | let l=i+1 |
||
− | #HTHDLhex=${hex[HTHDL]} |
||
+ | printf -v lhex %X $l |
||
− | #хеш-таблица для подсетей, 256 элементов |
||
+ | |||
− | cmd="$tc filter add dev $DEV parent 1:0 handle $HTHDLhex: protocol ip u32 divisor 256" |
||
+ | # хеш-таблица для подсети $i |
||
− | echo $cmd;$cmd; |
||
+ | # она создается предварительно, и к одному из се элементов пакет будет передан следующим правилом |
||
− | #разбиваем по подсетям |
||
+ | # |
||
− | cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht 800:: match ip src 94.154.32.0/21 hashkey mask 0x0000ff00 at 12 link $HTHDLhex:" |
||
+ | cmd="$tc filter add dev $DEV parent 1:0 handle $lhex: protocol ip u32 divisor 256" |
||
− | |||
+ | echo $cmd;$cmd; |
||
− | echo $cmd;$cmd; |
||
+ | |||
− | |||
+ | # Это собственно элементы таблицы и пакет будет направлен сразу в одно из 4( в моем приемере) правил |
||
− | |||
+ | # $ihex - это и есть номер подсети, о котором написано выше. |
||
− | for i in `seq 32 39`;do |
||
+ | # разбиваем внутри подсети $i |
||
− | #for i in `seq 244 255`;do |
||
+ | # А тут аналогично подсети но используется уже другой последний элемент. В результате пакет уйдет в правило под номером совпадающее |
||
− | printf -v ihex %X $i |
||
+ | # с последней цифрой IP адреса таблицы lhex. lhex - номер таблички в хексе, т.к. не модет быть равен нулю то отсюда +1. Замечу сто пример более общий - маска может быть шире. |
||
− | let l=i+1 |
||
+ | # |
||
− | #lhex=`printf %X $l` |
||
+ | cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht $HTHDLhex:$ihex match ip src 94.154.$i.0/24 hashkey mask 0x000000ff at 12 link $lhex:" |
||
− | printf -v lhex %X $l |
||
+ | echo $cmd;$cmd; |
||
− | |||
+ | |||
− | #lhex=${hex[l]} |
||
+ | # аналогично - для IP адресов. |
||
− | #хеш-таблица для подсети $i |
||
+ | for j in `seq 0 255`;do |
||
− | cmd="$tc filter add dev $DEV parent 1:0 handle $lhex: protocol ip u32 divisor 256" |
||
+ | printf -v jhex %X $j |
||
− | echo $cmd;$cmd; |
||
+ | let k=i*256+j+1; |
||
− | |||
+ | printf -v khex %X $k |
||
− | |||
+ | |||
− | #разбиваем внутри подсети $i |
||
+ | let kk=k+1 |
||
− | cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht $HTHDLhex:$ihex match ip src 94.154.$i.0/24 hashkey mask 0x000000ff at 12 link $lhex:" |
||
+ | if [ $kk -ge 65536 ];then |
||
− | echo $cmd;$cmd; |
||
+ | break fi |
||
− | |||
+ | #kkhex=`printf %X $kk` |
||
− | |||
+ | printf -v kkhex %X $kk |
||
− | |||
+ | #kkhex=${hex[kk]} |
||
− | for i in `seq 32 39`;do |
||
+ | #фильтры внутри подсети для заворота в нужный класс |
||
− | #for i in `seq 244 255`;do |
||
+ | #Вычисляем номер IFB что бы однозначно сопоставить ip и номер IFB куда делать редирект |
||
− | printf -v ihex %X $i |
||
+ | # -32 - что бы вести счет от 0, итого получаем возможные значения от 0 до 2047 - что и соответствует числу IP адресов. |
||
− | let l=i+1 |
||
+ | let IFB=(i-32)*256+j |
||
− | #lhex=`printf %X $l` |
||
+ | # Это собственно конечный элемент таблицы, куда будет перенаправлен пакет таблица lhex (напомню, их у нас в примере 4), номер правила совпадает с последней цифрой адреса. |
||
− | printf -v lhex %X $l |
||
+ | cmd="/sbin/tc filter add dev $DEV parent 1: prio 1 protocol ip u32 ht $lhex:$jhex match ip src 94.154.$i.$j action mirred egress redirect dev ifb${IFB}" |
||
− | |||
+ | echo $cmd;$cmd; |
||
− | #lhex=${hex[l]} |
||
+ | done; |
||
− | #хеш-таблица для подсети $i |
||
− | cmd="$tc filter add dev $DEV parent 1:0 handle $lhex: protocol ip u32 divisor 256" |
||
− | echo $cmd;$cmd; |
||
− | |||
− | |||
− | #разбиваем внутри подсети $i |
||
− | cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht $HTHDLhex:$ihex match ip src 94.154.$i.0/24 hashkey mask 0x000000ff at 12 link $lhex:" |
||
− | echo $cmd;$cmd; |
||
− | |||
− | |||
− | |||
− | # exit |
||
− | for j in `seq 0 255`;do |
||
− | printf -v jhex %X $j |
||
− | let k=i*256+j+1; |
||
− | #khex=`printf %X $k` |
||
− | printf -v khex %X $k |
||
− | #khex=${hex[k]} |
||
− | let kk=k+1 |
||
− | if [ $kk -ge 65536 ];then |
||
− | break |
||
− | fi |
||
− | #kkhex=`printf %X $kk` |
||
− | printf -v kkhex %X $kk |
||
− | #kkhex=${hex[kk]} |
||
− | # { |
||
− | #класс клиента |
||
− | # class_add $DEV 1:1 1:$khex "htb rate ${RATE2}kbit ceil ${RATE}kbit burst 6k" 1 $QUANTUM $MTU |
||
− | # let perturb=120+RANDOM%20 |
||
− | # qdisc_add $DEV 1:$khex $kkhex: "sfq limit 1024 perturb $perturb quantum $QUANTUM" |
||
− | #фильтры внутри подсети для заворота в нужный класс |
||
− | # filter_add $DEV 1: 1 "protocol ip u32 ht $lhex:$jhex match ip src 10.0.$i.$j" 1:$khex |
||
− | let IFB=(i-32)*256+j |
||
− | cmd="/sbin/tc filter add dev $DEV parent 1: prio 1 protocol ip u32 ht $lhex:$jhex match ip src 94.154.$i.$j action mirred egress redirect dev ifb${IFB}" |
||
− | echo $cmd;$cmd; |
||
− | # /sbin/tc filter add dev $DEV parent ffff: protocol ip u32 match ip src 94.154.36.222 action mirred egress redirect dev ifb1650 |
||
− | # |
||
− | # } & |
||
− | #cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht $lhex:`printf %X $j` match ip src 10.0.$i.$j flowid 1:$khex"; |
||
− | #echo $cmd;$cmd; |
||
− | done; |
||
done |
done |
Текущая версия на 15:23, 12 марта 2020
Шейпера и таблицы
Давно собирадся написать заметку про использование хеш-таблиц в шейперах.
Итак, для того чот бы избежать кучи последовательных проверок, применяется следующая конструкция:
Заголовки, и прочяя ерунда
#!/bin/bash . func.tc tc=/sbin/tc debug=1 DEV=eth3.1800 MTU=1500 QUANTUM=1600 RATE=1000000 #1GBit
Традиционно - очистить то что было, и строить заново
$tc q d dev $DEV root &>/dev/null #корневая дисциплина cmd="$tc qdisc add dev $DEV root handle 1:0 htb default 3"
Конструкция вида
echo $cmd;$cmd;
используется для дебага - и вывести команду на экран и выполнить ее.
cmd="$tc filter add dev $DEV parent 1:0 protocol ip u32" echo $cmd;$cmd;
- корневой класс
class_add $DEV 1: 1:0 "htb rate ${RATE}kbit ceil ${RATE}kbit burst 10k" 1 $QUANTUM $MTU
HTHDL=257 # Конструкции ниже абсолютно эквивалентны - перевод числа в хекс #HTHDLhex=`printf %X$HTHDL` printf -v HTHDLhex %X $HTHDL #HTHDLhex=${hex[HTHDL]} #хеш-таблица для подсетей, 256 элементов cmd="$tc filter add dev $DEV parent 1:0 handle $HTHDLhex: protocol ip u32 divisor 256" echo $cmd;$cmd; #разбиваем по подсетям # Это правило следует читать так: # Для любого адреса источника из сети 94.154.32.0/21 # по смещению 12 байт наложить маску. Т.е. наложить маску на сам адрес источника. # В результате (см маску) - будет выделен 3-й октет (в пример он может принимать значения 32-39) # и этот октет будет использован как указатель, т.е. пакет перенаправлен в правило $HTHDLhex:Номер_Подсети # cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht 800:: match ip src 94.154.32.0/21 hashkey mask 0x0000ff00 at 12 link $HTHDLhex:" echo $cmd;$cmd;
1
Для каждой из подсетей создаем свою хеш-таблицу полностью аналогичную таблице выше
for i in `seq 32 39`;do printf -v ihex %X $i let l=i+1 printf -v lhex %X $l # хеш-таблица для подсети $i # она создается предварительно, и к одному из се элементов пакет будет передан следующим правилом # cmd="$tc filter add dev $DEV parent 1:0 handle $lhex: protocol ip u32 divisor 256" echo $cmd;$cmd; # Это собственно элементы таблицы и пакет будет направлен сразу в одно из 4( в моем приемере) правил # $ihex - это и есть номер подсети, о котором написано выше. # разбиваем внутри подсети $i # А тут аналогично подсети но используется уже другой последний элемент. В результате пакет уйдет в правило под номером совпадающее # с последней цифрой IP адреса таблицы lhex. lhex - номер таблички в хексе, т.к. не модет быть равен нулю то отсюда +1. Замечу сто пример более общий - маска может быть шире. # cmd="$tc filter add dev $DEV protocol ip parent 1:0 u32 ht $HTHDLhex:$ihex match ip src 94.154.$i.0/24 hashkey mask 0x000000ff at 12 link $lhex:" echo $cmd;$cmd; # аналогично - для IP адресов. for j in `seq 0 255`;do printf -v jhex %X $j let k=i*256+j+1; printf -v khex %X $k let kk=k+1 if [ $kk -ge 65536 ];then break fi #kkhex=`printf %X $kk` printf -v kkhex %X $kk #kkhex=${hex[kk]} #фильтры внутри подсети для заворота в нужный класс #Вычисляем номер IFB что бы однозначно сопоставить ip и номер IFB куда делать редирект # -32 - что бы вести счет от 0, итого получаем возможные значения от 0 до 2047 - что и соответствует числу IP адресов. let IFB=(i-32)*256+j # Это собственно конечный элемент таблицы, куда будет перенаправлен пакет таблица lhex (напомню, их у нас в примере 4), номер правила совпадает с последней цифрой адреса. cmd="/sbin/tc filter add dev $DEV parent 1: prio 1 protocol ip u32 ht $lhex:$jhex match ip src 94.154.$i.$j action mirred egress redirect dev ifb${IFB}" echo $cmd;$cmd; done; done