С новите ядра (v2.2.x) Linux започна да придобива мрежовите възможности на Cisco router (благодарение на Алексей Кузнецов).
Тези възможности се включват от Network Options/Quality of Services и Network Options/Advanced routing". За да използваме тези възможности, ни е нужен пакета iproute2 (или iproute2+tc), достъпен от ftp.inr.ac.ru/ip-routing. В него се съдържат 2 основни програми - ip и tc. Първата служи за манипулация на интерфейси routing-таблици и т.н., а втората - за traffic control. За първата има дълго и подробно ръководство в пакета, а за втората е в процес на разработка. Тук ще опиша, доколкото ми е възможно, и двете команди.
dev <device> | интерфейс за манипулация |
up или down | дали е up (т.е. работещ) или down (т.е. не) |
arp <on или off> | дали интерфейсът да използва ARP или не (резулатът от ip link set arp off dev xxx, ако интерфейсът е up може да бъде много неприятен) |
multicase <on или off> | multicast поддръжка на интерфейса |
name <name> | сменя името на интерфейса (от eth0 на xxx0 например) |
txqueuelen <ADDRESS> | големина на transmit-опашката |
mtu <mtu> | сменя MTU-то (Maximum Transmit Unit) на интерфейса |
address <ADDRESS> | сменя link-layer-адреса (т.е. ethernet-адреса) |
broadcast или brd или peer <ADDRESS> | сменя broadcast или point-to-pointlink-layer-адреса на интерфейса. |
Този пример за използването на ip link конфигурира eth0 с адрес 2.3.4.5, да използва ARP и да включи интерфейса.
ip link set dev eth0 address 2.3.4.5Този ред пък увеличава transmit-опашката на ppp0-интерфейса, правейки го като ethernet - удобно е за ppp-on-ethernet връзки, за да се използва пълноценно преносната среда.
ip link set dev eth0 arp on
ip link set dev eth0 up
ip link set dev ppp0 txqueuelen 100На ip route могат да се подават следните команди: add, change, replace, delete, show, flush и get.
<[ * Кратка забележка: В linux-2.2.x типовете entry-та на routing-таблица са следните:
unicast | описва истински път до определено място |
unreachable | адресът е недостъпен, връща се ICMP съобщение "host unreachable", програмата, изпратила пакета, получава грешка EHOSTUNREACH. |
blackhole | адресът е недостъпен, не се връща ICMP съобщение, програмата, изпратила пакета, получава грешка EINVAL. |
prohibit | адресът е недостъпен, връща се ICMP съобщение "communication administratively prohibited", програмата, генерирала пакета, получава грешка EACCES. |
local | локален, всички пакети се връщат в локалната машина. |
broadcast | адресът е broadcast-адрес, пакетите се пращат като link broadcast-ове. |
throw | специален тип, използван с policy rules. Ако при lookup на таблицата се избере подобен път, lookup-ът се прекратява, като се казва, че няма подобен route в тая таблица (ако lookup-ът се прави с policy, а ако не е еквивалентно на липсата на route и се връща ICMP събщение "netork unreachable", а програмата изпратила пакета - грешка ENETUNREACH. |
nat | т.нар. "Network Address Translation", всички пакети с такъв source се маскират през адреса подаден с параметъра via. |
anycast | не е написан..... |
multicast | специален тип, използван в multicast routing-а. Не се среща в нормалните routing-таблици. |
ip route add, change и replace поддържат следните опции:
to <PREFIX> или to <TYPE> <PREFIX> | Отсрещна точка. Ако TYPE не е зададен, ip подразбира тип unicast. PREFIX е IP или IPv6 адрес с опционална netmask-а. Също така има един специален PREFIX - "default", който е еквивалентен в IPv4 на "0/0" или на "::/0"в IPv6. | ||||||||||
tos <TOS> или dsfield <TOS> | Type of Service (ToS, Тип на услугата). Използва се, за да могат да се използват различни пътища за пакети с различни ToS полета. | ||||||||||
metric <NUMBER> или preference <NUMBER> | Приоритет/дължина на route. NUMBER е нормално 32-битово число. | ||||||||||
table <TABLEID> | Таблица в която да се включи този route. TABLEID може да е е число или стринг, указващ файл в /etc/iproute2/rt_tables. Ако този параметър го няма, ip подразбира таблицата main, с изключение на таблица local, broadcast и nat route-овете, в които влиза по подразбиране в таблицата local. | ||||||||||
dev <NAME> | име на изходното устройство. | ||||||||||
via <ADDRESS> | адреса на следващия router. Фактически, значението зависи от типа route. За нормални unicast route-ове или чистия следващ router, или адреса на интерфейс, през който да се прати, ако е адрес инсталиран в BSD. За NAT route-ове това е адреса на маскиране на минаващите връзки. | ||||||||||
src <ADDRESS> | Изходен адрес, от който да се пращат пакетите, попадащи в това routing правило. | ||||||||||
realm <REALMID> | realm, в който попада този route. REALMID може да е число или стринг от файла /etc/iproute2/rt_realms. | ||||||||||
mtu <MTU> или mtu lock <MTU> | MTU-то по пътя до отсрещния адрес. Ако не се използва lock, MTU-то може да променя от kernel-а с Path MTU Discovery. Ако се използва lock, няма да се използва Path MTU Discovery. Всички пакети ще се изпращат без DF-бита в IPv4 случая или fragmented-бита за IPv6. | ||||||||||
window <NUMBER> | маклималният TCP прозорец за позволяване до тези места в байтове. Ограничава максималния поток от данни, които могат да бъдат пратени до хоста по TCP. | ||||||||||
rtt <NUMBER> |
началното RTT (Round Trip Time).
<[ * Бележка:Всъщност, в Linux-2.2.x (и 2.0.x) то не е точно RTT, а timeout-а при начало на TCP връзка. Kernel-а спира да го използва при първия получен валиден ACK. ]> |
||||||||||
nexthop <NEXTHOP> |
Следващият hop на multipath route. NEXTHOP е
комплексна стойност със синтаксис подобен на този на останалите
параметри от типа на add:
|
||||||||||
scope <SCOPE_VAL> | обхват (scope) от цели покривани от route-префикса. SCOPE_VAL може да е число или стринг от файла /etc/iproute2/rt_scopes. Ако този параметър се пропусне, ip приема обхвата global за всички unicast route-ове, минаващи през gateway-а, обхвата link за директни unicast route-ве и broadcast-и, както и обхват host за локалните route-ове. | ||||||||||
protocol <RTPROTO> |
"routing"-протокол за този "route". RTPROTO може да е число или
стринг от файла "/etc/iproute2/rt_protos". Ако не зададен такъв, "ip"
приема протокол "boot" (т.е. такъв, добавен от някой, който не знае
к'во прави). Няколко такива стойности имат фиксирано значение:
|
||||||||||
online | казва, че следващия hop е директно свързан за тази връзка, даже и ако не пасва на който и да е интерфейс. | ||||||||||
equalize | Позволява изравняване по произволен начин по multipath routes. Без тази опция route ще бъде определен до един следващ hop, така че разделянето на трафика ще се получава само на база трафик. equalize работи само на patch-нати kernel-и. (?) |
Тук имаме машина с две мрежови карти, която има три адреса: 192.168.1.1 на eth1, и 192.168.0.4 и 193.200.17.103 на eth0. Това е Samba server на мрежата и, когато осъществява връзки до 192.168.x.x използва 192.168.x.x адресите си, а се свързва към реални адреси, използва реалния си адрес. Също така има два хоста, за които минава през друг router (193.200.17.98), а не през главния си (193.200.17.97), както и три машини, които са и на LAN-а:
ip route add 192.168.0.0/24 dev eth0 srv 192.168.0.4Тук defaultroute се разделя между ppp0 и ppp1 поравно, т.е. прави се балансиране на натоварването (load balancing):
ip route add 192.168.1.0/24 dev eth1
ip route add 193.200.17.97 dev eth0 src 193.200.17.103 onlink
ip route add 193.200.17.101 dev eth0 src 193.200.17.103 onlink
ip route add 193.200.17.98 dev eth0 src 193.200.17.103 onlink
ip route add 193.200.17.105 via 193.200.17.98 src 193.200.17.103
ip route add 193.200.17.102 via 193.200.17.98 src 193.200.17.103
ip route add default via 193.200.17.97 src 193.200.17.103
ip route add default scope global nexthop dev ppp0 nexthop dev ppp1Тук се постига същото като в горния пример, но се използва по-добрия начин - с IP адреси, защото имената на интерфейсите са динамични, и се използва изравняване:
ip route add defaulte equalize scope global nexthop via 193.200.17.98 nexthop via 193.200.17.99ip route delete има подобни опции като ip route add, с тази разлика, че се изтрива route, който има същите опции, като тези подадени на командата, като обачене е задължително да се подадат докрай всички опции за този route, ако няма подобни на него в routing-таблицата.
ip route show също така има подобни опции, но с него се извеждат route-овете, които имат подобни параметри.
Ето един пример:
eosnw:~# ip route show 193.200.17.97 dev eth0 scope link 193.200.17.98 dev eth0 scope link 193.200.17.101 dev eth0 scope link 193.200.17.102 via 193.200.17.98 dev eth0 src 193.200.17.103 193.200.17.105 via 193.200.17.98 dev eth0 src 193.200.17.103 192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.1 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.4 default via 193.200.17.97 dev eth0 src 193.200.17.103Тук route-овете до 192.168.x.x са добавени от kernel-а, защото ifconfig при 2.2.x kernel-и автоматично добавя route към address/netmask през този интерфейс.
ip route flush пък се различава от ip route show само по това, че изтрива всички route-ове, които имат такива параметри като зададените на командата.
ip route get пък проверява през кой route ще мине пакет със свойства като тези, зададени на командата. (* Внимание! Това не е точно ip route show - при rules и т.н. резултатът може да е различен. ip route get повтаря действията на kernel-а при lookup в routing-таблиците.).
ip rule позволява да се задават правила, на база на които да се прави lookup в други routing-таблици - по този начин може да се прави routing, базиран не само на адреса на целта, но и на база на изходния адрес, на ToS, на входен интерфейс. ip rule има няколко възможни команди: add, delete и show.
Тези правила могат да бъдат следните типове:
unicast | Връща route от routing-таблицата, към която сочи правилото. |
blackhole | Дропва пакетите директно. |
unreachable | Връща грешка "Network is unreachable". |
prohibit | Връща грешка "Communication is administratively prohibited". |
nat | Правилото транслира изходния адрес. |
type <TYPE> | (по подразбиране) тип на правилото. |
from <PREFIX> | изходен адрес на пакета. |
to <PREFIX> | адрес на целта на пакета. |
iif <NAME> | избира входен интерфейс. Ако интерфейса е loopback-а, правилото обхваща само пакети, изпратени от този хост. По този начин могат да се направят routing-таблици за пакети, изпратени от хоста и за пренасочени пакети и така да се разделят изцяло двата трафика. |
tos <TOS> или dsfield <TOS> | самообясняващо се. |
fwmark <MARK> |
за какъв fwmark да се отнася.
<[ * Бележка:fwmark в възможност с ipchains на определени пакети да се поставя т.нар. fwmark, т.е. да се прави routing на базата на ipchains правила .... ]> |
priority <PREFERENCE> |
приоритет на правилото. Всяко правило би трябвало да има уникален
зададен приоритет.
<[ * Бележка: Всъщност, по исторически причини ip rule add не изисква никакъв приоритет. Ако потребителят не зададе никакъв приоритет, kernel-а му избирасамо, а ако зададе с такъв приоритет, който не съществува, го поставя преди всички по-стари правила със същия приоритет. Както казва Кузнецов: "It is mistake in design, not more. And it will be fixed one day, so that do not rely on this feature, use explicit priorities.". ]> |
table <TABLEID> | routing-таблица, в която да се прави lookup, ако пакетът отговаря на правилото. |
realms <FROM/TO> | realm-ове, които да се използват, ако пакетът отговаря на правилото. |
nat <ADDRESS> | База на блок от IP адреси за транслиране на изходния адрес. ADDRESS може да е или началото на блок от IP-адреси, избрани от NAT route-ове, или локален адрес (или дори нула). В последния случай router-а не ги транслира, а ги маскира с този адрес. |
Това routе-ира всичко от 192.203.80.0/24 през правилата на таблица 13:
ip rule add from 192.203.80.0/24 table 13 prio 220Това дропва всички пакети получени през eth0 от адреси 192.168.1.0/24:
ip rule add iif eth0 from 192.168.1.0/24 type blackhole prio 100Това изтрива предишното правило:
ip rule del iif eth0 prio 100С ip rule show се показва списък на правилата, дефинирани в момента.
Пример:
eosnw:~# ip rule show0: from all lookup local100: from 192.168.1.0/0 \ip address позволява добавяне/премахване на адрес от интерфейс - това е, което позволяваше ip aliasing-а, но в много по-добър вид. Сега може да имате 10000 vhosta-а на машината си без нито един виртуален интерфейс. Командата има 4 възможни подкоманди: add, delete, show и flush.
iif eth0 lookup main blackhole32766: from all lookup main32767: from all \
lookup 253
ip address add/delete имат следните параметри:
dev <NAME> | устройство, на което да бъде добавен адреса. | ||||||||
local <ADDRESS> | (по подразбиране) адрес на интерфейса. Форматът му зависи от това, дали е IPv4 или IPv6, и се записва по стандартните за тях начини. ADDRESS може да бъде следвано от "/" и число, което да задава директно цяла мрежа адреси на интерфейса. | ||||||||
peer <ADDRESS> | адрес на отсрещната точка. Пак както и при local, може да се използва "/" и число, определящи netmask-ата на адреса. Ако се задава такъв адрес, локалния адрес не може да има "/xx". | ||||||||
broadcast <ADDRESS> | broadcast-адрес за интерфейса. Възможно е да се използват "+" и "-" вместо самия адрес. В този случай, broadcast-адреса се смята, като се слагат/нулират битовете в host-частта на интерфейсния адрес. | ||||||||
label <NAME> | На всеки адрес може да се определя отделно устройство. За да се поддържа съжместимостта с alias-ите на linux 2.0.x, този стринг трябва да съвпада с името на интерфейса или да бъде името на интерфейса, следвано от ":" и номер. | ||||||||
scope <SCOPE_VALUE> |
обхват (scope) на зоната, в която този адрес е валиден.
Възможните обхвати са записани във файла /etc/iproute2/rt_scopes.
Специални такива стойности са:
|
Примери:
Тук например се създават три логически мрежи върху една физическа и те могат да работят независимо една от друга, независимо да им се прави shaping и accounting и т.н.:
ip address add 192.168.0.1 dev eth0Това дава primary-адрес на eth0 194.12.235.195 и създава alias eth0:0 с адрес 194.12.235.199:
ip address add 192.168.1.1 dev eth0
ip address add 192.168.2.1 dev eth0
ip route add 192.168.0.0/24 dev eth0 src 192.168.0.1
ip route add 192.168.1.0/24 dev eth0 src 192.168.1.1
ip route add 192.168.2.0/24 dev eth0 src 192.168.2.1
ip address add 194.12.235.195 dev eth0ip address show/flush имат еднакви параметви, а се различават само по това, че едната команда показва адресите, съответстващи на критерия, подаден на командата, а другата ги изтрива. Възможните параметри са:
ip address add 194.12.235.199 dev eth0 name eth0:0
dev <NAME> | (по подразбиране) име на интерфейса. |
scope <SCOPE_VAL> | само адресите в този обхват. |
to <PREFIX> | само адреси съвпадащи с PREFIX. |
label <PATTERN> | само адреси, чието име съвпада с PATTERN. PATTERN е нормален shell-ки модел ("eth*", "eth1:?" и т.н.) |
dynamic илиpermanent | (само за IPv6) само статични или динамични адреси. |
tentative | (само за IPv6) само адреси, които не прминават през duplicate address теста. |
deprecated | (само за IPv6) само безсмислени (ненужни) адреси. |
primary илиsecondary | само главни или вторични адреси. |
Така се виждат всички интерфейси:
eosnw:~# ip address show1: lo: <LOOPBACK,UP> mtu 3924 qdisc noqueuelink/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo2: teql0: <NOARP> mtu 1500 qdisc noop qlen 100 link/generic3: eth0: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 100link/ether 00:20:af:3c:07:f7 brd ff:ff:ff:ff:ff:ff inet 192.168.0.4/24 brd 192.168.0.255 scope global eth0inet 193.200.17.103/32 scope global eth04: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100link/ether 00:20:af:3c:08:0f brd ff:ff:ff:ff:ff:ff inet 192.168.1.1/24 brd 192.168.1.255 scope global eth1А така само тези, които се казват "eth*":
eosnw:~# ip address show label "eth*"3: eth0: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 100link/ether 00:20:af:3c:07:f7 brd ff:ff:ff:ff:ff:ff inet 192.168.0.4/24 brd 192.168.0.255 scope global eth0 inet 193.200.17.103/32 scope global eth04: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:20:af:3c:08:0f brd ff:ff:ff:ff:ff:ff inet 192.168.1.1/24 brd 192.168.1.255 scope global eth1Друго, което може да се прави с командата komandata ip, е да се създадат т.нар. "тунели". Например от типа IPv6-in-IPv4 (които позволяват на мрежи/хостове, които имат пряка връзка с мрежи/хостове поддържащи само IPv4, да ползват IPv6 като минават през друго място, което поддържа IPv6).
С ip tunnel се манипулират тези т.нар. тунели. Тази команда има следните подкоманди: add, change, delete, show.
ip tunnel add/change/delete има следните опции:
name <NAME> | (по подразбиране) Задава име NAME на тунела. |
mode <MODE> |
Задава тип на тунела. За момента съществуващи са ipip,
sit и gre.
<[ * Бележка: IPIP-тунелите са стандартна енкапсулация на пакет в пакет. GRE-тунелите са прoизведение на CISCO, което е препоръчително да се използва, ако отсрещната точка е CISCO рутер, а и този протокол поддържа multicast вътре в самия тунел (а и все пак CISCO си остават специалистите в тази област ;)) ]> |
remote <ADDRESS> | Задава адрес на отсрещната точка в тунела. |
local <ADDRESS> | Задава фиксиран изходен адрес на изпращаните през тунела пакети. Този адрес трябва да бъде адрес на някой интерфейс на машината. |
ttl <N> | Задава фиксирано TTL за тунелираните пакети. N е число от 1 до 255. 0 е специална стойност значеща, че пакетите не променят TTL-а си. |
tos <T> или dsfield <T> | Задава фиксиран TOS <T> за тунелираните пакети. По подразбиране не се променя. |
dev <NAME> | Задължава тунела на ползва интерфейса NAME, така че пакетите да не минават през други интерфейси, ако routing-а се промени. |
nopmtudisc | Маха Path MTU Discovery-то за тунела, което е включено по подразбиране. Тази опция е несъвместима с фиксирания TTL: тунел с фиксиран TTL винаги прави Path MTU Discovery. |
key <K>,ikey <K> иokey <K> | (само за GRE тунели) да използва 'keyed' GRE с ключ K. K е или число, или IP адрес. Параметърът key задава ключа за използване в двете посоки, а ikey и okey - съотверно само за изходящи и само за входящи пакети. |
csum,icsum иocsum | (само за GRE тунели) checksum-проверка за тунелираните пакети. ocsum проверява само изходящите пакети, а icsum - само за входящите пакети. csum е еквивалентно на комбинацията от двата флага icsum и ocsum. |
seq,iseq иoseq |
(само за GRE тунели) Да "сериализира" пакетите. Тук пак
oseq/iseq включват тази опция съответно за входните и
изходните пакети.
<[ * Бележка: Според Ал.Кузнецов, тази опция не работи или поне не е тествана. Не е и известно как точно трябва да работи и за какво точно са мислели да използват CISCO тази опция. ]> |
<[Това по-надолу е произведение на Renegade в/у traffic control-а ]>
За да се компилира кернела с тая поддръжка, трябва да се компилират в кернела, или като модули "Class Based Queueing (CBQ)", "Tocken Bucket Flow (TBF)", "Traffic Sharpers", както и RED. След това, необходима е iproute2, за да може да се използват тия функции на кернела. Тя може да се свали от ftp://ftp.sunet.se/pub/Linux/ip-routing. Принципът, на който работи "traffic control (tc)", е следния: входящите пакети се проверяват дали са за дадена точка, и, ако това е така, те се изпращат за обработка на по-висок слой. В противен случай се гледа routing-таблицата, за да се установи следващия hop за пакета. Също така, по-високия слой също може да генерира трафик, който да кара forwarding agent процесите да търсят следващия hop. Когато това стане, forwarding agent-а слага дадения пакет към изходния интерфейс за предаване. Именно тук Linux Traffic Control-а почва да върши работа.
Linux Traffic Control-а е базиран на три основни блока:
Всеки интерфейс има начин за обработване на опашките, асоциирани към него. Най-простата е FIFO. Има няколко типа на queueing, които се поддържат в момента:
2. Класове
Опашките и класовете са тясно свързани. Всеки клас има опашка. Класовете се индетифицират спрямо class ID и internal ID. Class ID-то се задава от потребителя, докато internal ID-то се задава от queueing-дисциплината. Class ID-то има структура "major:minor". Major-номера сочи инстанцията в queueing-дисциплината, от която зависи. Minor-номера идентифицира тоя клас в дадена дисциплина.
За повече подробности може да се види include/net/pkt_sched.h.
"tc (Traffic Controller)"
Traffic Controller (tc) е потребителска програма, която е грубо казано frontend към създаването и асоциирането на опашки към дадени изходни интерфейси. Тя се използва за създаването на различни видове опашки и асоцииране на класове към всяка от тези опашки. Също така може да се използва за слагане на филтри базирани на routing-таблицата, u32-класификаторите, както и RSVP-класификаторите. Тя използва netlink socket-ите като механизъм за комуникиране с мрежовите функции на кернела.
tc се използва по следния начин:
tc [-s[tatistics]] [-d[etails]] [-r[aw]] < qdiscp | class | filter > { COMMAND | help }, където:
-s[tatistics] | статистика |
-d[etails] | детйлна информация |
-r[aw] | говори само за себе си |
qdiscp | queueing-дисциплина |
class | клас |
filter | филтър |
Queuing-дисциплина:
Синтаксиса за задаване на queueing-дисциплина е следния:
tc qdisc [ add | del | replace | change | get ] dev STRING [ handle QHANDLE ] [ root | parent CLASSID ] [ estimator INTERVAL TIME_CONSTANT ] [ [ QDISC_KIND ] [ help | OPTIONS ] ], където:
tc qdisc show [ dev STRING ]
QDISC_KIND | може да има стойност pfifo, bfifo, tbf, prio, cbq, red или т.н., т.е. име на queueing-дисциплината |
hande | уникален handle, даден на дадената дисциплина от създателя. Не може да има две дисциплини с еднакъв handle. |
root | показва, че дадената дисциплина е root в sharing-йерархията. |
parent | показва родителя на дадената дисциплина. |
За да се създаде "class based queue (CBQ)":
tc qdisc [ add | del | replace | change | get ] dev STRING \, където:
cbq bandwidth BPS [ avpkt BYTES ] [ mpu BYTES ] [ cell BYTES ] [ ewma LOG ]
bandwidth | максимална скорост на дадения интерфейс |
mpu | минимални байтове, които да се изпращат в даден пакет |
Пример:
tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit allot 1514 cell 8 avpkt 1000 mpu 64
В дадения пример, Class Based Queue (CBQ) се създава и се връзва към eth0. handle-ът е 1: (което е 1:0). Общата възможна скорост е 10Mbit.
Класове:
Синтаксисът за създаване на класове е следния:
tc class [ add | del | change | get ] dev STRING [ classid CLASSID ] [ root | parent CLASSID ] [ [ QDISC_KIND ] [ help | OPTIONS ] ], където:
tc class show [ dev STRING ] [ root | parent CLASSID ]
QDISC_KIND | QDISC_KIND може да бъде някоя от queueing-дисциплините, които поддържат класове (prio, cbq и т.н.). |
classid | представлява handle-ът, който е даден на тоя клас от създателя. |
root | показва, че тоя клас е root-клас в sharing-йерархията. |
parent | показва handle-ът на родителя на дадената queueing-дисциплина. |
3. Class Based Queue
За да се създаде CBQ, синтаксисът е следния:
cbq bandwidth BPS rate BPS maxburst PKTS [ avpkt BYTES ] \, където:
[ minburst PKTS ] [ bounded ] [ isolated ] \
[ allot BYTES ] [ mpu BYTES ] [ weight RATE ] \
[ prio NUMBER ] [ cell BYTES ] [ ewma LOG ] \
[ estimator INTERVAL TIME_CONSTANT ] \
[ split CLASSID ] [ defmap MASK/CHANGE ]
bandwidth | показва максималната скорост, която е възможна за queueing-дисциплината от тоя клас. |
rate | представлява скоростта, която се дава на тоя клас. |
avpkt | представлява средния брой байтове в пакет, за тоя клас. |
bounded | показва, че тоя клас не може да "всзина назаем" неизползвана скорост от "parent"-класа си. |
isolated | показва, че класа няма да дели скорост с някой друг клас. |
tc class add dev eth1 parent 1:1 classid 1:2 cbq bandwidth 10Mbit \4. Филтри:
rate 1Mbit allot 1514 cell 8 weight 100Kbit prio 3 maxburst 20 \
avpkt 1000 split 1:0 defmap c0
Синтаксисът за създаване на филтри е:
tc filter [ add | del | change | get ] dev STRING \, където: FILTER_TYPE е типа на филтъра (rsvp, u32, fw, route и т.н.}, а форматът на FILTERID зависи от класификатора. prio показва приоритет на дадения филтер. Останалите опции бяха разгледани по-горе.
[ prio PRIO ] [ protocol PROTO ] [ root | classid CLASSID ] \
[ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ] \
tc filter show [ dev STRING ] [ root | parent CLASSID ]
Route-класификаторите класифицират пакетите спрямо routing-таблицата. Синтаксисът е следния:
tc filter [add | del | change | get] dev STRING \, където: PROTO е low-level протокола {ip, icmp или някой друг}
[parent PARENTID] [protocol PROTO] [prio PRIORITY] route
Ето и един пример:
tc filter add dev eth0 parent 1:0 protocol ip prio 100 routeЗа да се зададат правила към филтъра:
ip route add 129.237.125.150 via 129.237.125.146 dev eth0 flow 1:2Тук се зададе правило за IP 129.237.125.150 с Gateway 129.237.125.146, като целия трафик принадлежи към клас, чийто handle е 1:2.
И най-накрая, след толкова изписани глупости, нека да разгледам един реален пример:
Нека да имаме три компютъра: computer1, който е с IP 10.10.10.149. Нека средната големина на пакета да е 1000 байта. И да имаме два класа: един за трафика към машината с IP 10.10.10.146 (computer2), и трафика към машината 10.10.10.148 (computer3). Т.е. с една дума, да се ограничи трафика на машиниcomputer2 иcomputer3. Трафикът къмcomputer2 е с по-висок приоритет от тоя къмcomputer3. Къмcomputer2 се пуска 1Mbps, а към computer3 - 5Mbps.
На computer1:
--------------
# Attach-ваме queueing-дисциплина към eth0. (там са вързани
# другите две машини). Максималната възможна скорост е 10Mbps.
tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit \
cell 8 avpkt 1000 mpu 64
# Дефинираме root-класа. Той има 10Mbps.
tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit \
rate 10MBit allot 1514 cell 8 weight 1Mbit prio 8 maxburst 20 \
avpkt 1000
# Трафик към computer2. Приоритетът е 3, а скоростта е 1Mbps.
tc class add dev eth0 parent 1:1 classid 1:2 cbq bandwidth 10Mbit \
rate 1Mbit allot 1514 cell 8 weight 100Kbit prio 3 maxburst 20 \
avpkt 1000 split 1:0
# Трафик към computer3. Приоритетът е 7, а скоростта е 5Mbps.
tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 10Mbit \
rate 5Mbit allot 1514 cell 8 weight 800Kbit prio 7 maxburst 20 \
avpkt 1000 split 1:0
# Слагаме route класификатора
tc filter add dev eth0 parent 1:0 protocol ip prio 100 route
# Слагаме route и правила за computer2
ip route add 10.10.10.146 via 10.10.10.149 flow 1:2
# Слагаме route и правила за computer3
ip route add 10.10.10.148 via 10.10.10.149 flow 1:3