Advertisement
Guest User

htb.init

a guest
Oct 14th, 2012
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.58 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. # htb.init v0.8.4
  4. # Copyright (C) 2002 Lubomir Bulej <pallas@kadan.cz>
  5. #
  6. # chkconfig: 2345 11 89
  7. # description: script to set up HTB traffic control
  8. #
  9. # This program is free software; you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation; either version 2 of the License, or
  12. # (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. #
  23. # To get the latest version, check on Freshmeat for actual location:
  24. #
  25. # http://freshmeat.net/projects/htb.init
  26. #
  27. #
  28. # VERSION HISTORY
  29. # ---------------
  30. # v0.8.4- Lubomir Bulej <pallas at kadan.cz>
  31. # - fixed small bug in RULE parser to correctly parse
  32. # rules with identical source and destination fields
  33. # - removed the experimental INJECT keyword
  34. # - ignore *~ backup files when looking for classes
  35. # - Mike Boyer <boyer at administrative.com>
  36. # - fix to allow arguments to be passed to "restart" command
  37. # - <face at pos.sk>
  38. # - fix to preserve class priority after timecheck
  39. # v0.8.3- Lubomir Bulej <pallas at kadan.cz>
  40. # - use LC_COLLATE="C" when sorting class files
  41. # - Paulo Sedrez
  42. # - fix time2abs to allow hours with leading zero in TIME rules
  43. # v0.8.2- Lubomir Bulej <pallas at kadan.cz>
  44. # - thanks to Hasso Tepper for reporting the following problems
  45. # - allow dots in interface names for use with VLAN interfaces
  46. # - fixed a thinko resulting from "cosmetic overdosage" :)
  47. # v0.8.1- Lubomir Bulej <pallas at kadan.cz>
  48. # - added function alternatives for sed/find with less features. To
  49. # enable them, you need to set HTB_BASIC to nonempty string.
  50. # - added posibility to refer to RATE/CEIL of parent class when
  51. # setting RATE/CEIL for child class. Look for "prate" or "pceil"
  52. # in the documentation.
  53. # - fixed broken "timecheck" invocation
  54. # v0.8 - Lubomir Bulej <pallas at kadan.cz>
  55. # - simplified and converted CBQ.init 0.7 into HTB.init
  56. # - changed configuration file naming conventions
  57. # - lots of HTB specific changes
  58. #
  59. #
  60. # INTRODUCTION
  61. # ------------
  62. #
  63. # This script is a clone of CBQ.init and is meant to simplify setup of HTB
  64. # based traffic control. HTB setup itself is pretty simple compared to CBQ,
  65. # so the purpose of this script is to allow the administrator of large HTB
  66. # configurations to manage individual classes using simple, human readable
  67. # files.
  68. #
  69. # The "H" in HTB stands for "hierarchical", so while many people did not use
  70. # (or know about) the possibility to build hierarchical structures using
  71. # CBQ.init, it should be obvious thing to expect from HTB.init :-)
  72. #
  73. # In HTB.init this is done differently, compared to CBQ.init: the usage of
  74. # PARENT keyword was dropped and instead, class file naming convetion was
  75. # introduced. This convention allows the child class to determine ID of its
  76. # parent class from the filename and also (if not abused :) enforces file
  77. # ordering so that the parent classes are created before their children.
  78. #
  79. # HTB.init uses simple caching mechanism to speed up "start" invocation if the
  80. # configuration is unchanged. When invoked for the first time, it compiles the
  81. # configuration files into simple shell script containing the sequence of "tc"
  82. # commands required to setup the traffic control. This cache-script is stored
  83. # in /var/cache/htb.init by default and is invalidated either by presence of
  84. # younger class config file, or by invoking HTB.init with "start invalidate".
  85. #
  86. # If you want to HTB.init to setup the traffic control directly without the
  87. # cache, invoke it with "start nocache" parameters. Caching is also disabled
  88. # if you have logging enabled (ie. HTB_DEBUG is not empty).
  89. #
  90. # If you only want HTB.init to translate your configuration to "tc" commands,
  91. # invoke it using the "compile" command. Bear in mind that "compile" does not
  92. # check if the "tc" commands were successful - this is done (in certain places)
  93. # only when invoked with "start nocache" command. When you are testing your
  94. # configuration, you should use it to check whether it is completely valid.
  95. #
  96. # In case you are getting strange sed/find errors, try to uncomment line with
  97. # HTB_BASIC setting, or set the variable to nonempty string. This will enable
  98. # function alternatives which require less advanced sed/find functionality. As
  99. # a result, the script will run slower but will probably run. Also the caching
  100. # will not work as expected and you will have to invalidate the cache manually
  101. # by invoking HTB.init with "start invalidate".
  102. #
  103. #
  104. # CONFIGURATION
  105. # -------------
  106. #
  107. # Every traffic class is described by a single file in placed in $HTB_PATH
  108. # directory, /etc/sysconfig/htb by default. The naming convention is different
  109. # compared to CBQ.init. First notable change is missing 'htb-' prefix. This
  110. # was replaced by interface name to improve human readability and to separate
  111. # qdisc-only configuration.
  112. #
  113. # Global qdisc options are placed in $HTB_PATH/<ifname>, where <ifname> is
  114. # (surprisingly) name of the interface, made of characters and numbers. This
  115. # file must be present if you want to setup HTB on that interface. If you
  116. # don't have any options to put into it, leave it empty, but present.
  117. #
  118. # Class options belong to files with names matching this expression:
  119. # $HTB_PATH/<ifname>-<clsid>(:<clsid>)*<description>
  120. #
  121. # <clsid> is class ID which is hexadecimal number in range 0x2-0xFFFF, without
  122. # the "0x" prefix. If a colon-delimited list of class IDs is specified, the
  123. # last <clsid> in the list represents ID of the class in the config file.
  124. #
  125. # <clsid> preceding the last <clsid> is class ID of the parent class. To keep
  126. # ordering so that parent classes are always created before their children, it
  127. # is recommended to include full <clsid> path from root class to the leaf one.
  128. #
  129. # <description> is (almost) arbitrary string where you can put symbolic
  130. # class names for better readability.
  131. #
  132. # Examples of valid names:
  133. #
  134. # eth0-2 root class with ID 2, on device eth0
  135. # eth0-2:3 child class with ID 3 and parent 2, on device eth0
  136. # eth0-2:3:4 child class with ID 4 and parent 3, on device eth0
  137. # eth1-2.root root class with ID 2, on device eth1
  138. #
  139. #
  140. # The configuration files may contain the following parameters. For detailed
  141. # description of HTB parameters see http://luxik.cdi.cz/~devik/qos/htb.
  142. #
  143. ### HTB qdisc parameters
  144. #
  145. # The following parameters apply to HTB root queuening discipline only and
  146. # are expected to be put into $HTB_PATH/<ifname> files. These files must
  147. # exist (even empty) if you want to configure HTB on given interface.
  148. #
  149. # DEFAULT=<clsid> optional, default 0
  150. # DEFAULT=30
  151. #
  152. # <dclsid> is ID of the default class where UNCLASSIFIED traffic goes.
  153. # Unlike HTB qdisc, HTB.init uses 0 as default class ID, which is
  154. # internal FIFO queue that will pass packets along at FULL speed!
  155. #
  156. # If you want to avoid surprises, always define default class and
  157. # allocate minimal portion of bandwidth to it.
  158. #
  159. # R2Q=<number> optional, default 10
  160. # R2Q=100
  161. #
  162. # This allows you to set coefficient for computing DRR (Deficit
  163. # Round Robin) quanta. The default value of 10 is good for rates
  164. # from 5-500kbps and should be increased for higher rates.
  165. #
  166. # DCACHE=yes|no optional, default "no"
  167. #
  168. # This parameters turns on "dequeue cache" which results in degraded
  169. # fairness but allows HTB to be used on very fast network devices.
  170. # This is turned off by default.
  171. #
  172. ### HTB class parameters
  173. #
  174. # The following are parameters for HTB classes and are expected
  175. # to be put into $HTB_PATH/<ifname>-<clsid>(:<clsid>)*.* files.
  176. #
  177. # RATE=<speed>|prate|pceil mandatory
  178. # RATE=5Mbit
  179. #
  180. # Bandwidth allocated to the class. Traffic going through the class is
  181. # shaped to conform to specified rate. You can use Kbit, Mbit or bps,
  182. # Kbps and Mbps as suffices. If you don't specify any unit, bits/sec
  183. # are used. Also note that "bps" means "bytes per second", not bits.
  184. #
  185. # The "prate" or "pceil" values will resolve to RATE or CEIL of parent
  186. # class. This feature is meant to help humans to keep configuration
  187. # files consistent.
  188. #
  189. # CEIL=<speed>|prate|pceil optional, default $RATE
  190. # CEIL=6MBit
  191. #
  192. # The maximum bandwidth that can be used by the class. The difference
  193. # between CEIL and RATE amounts to bandwidth the class can borrow, if
  194. # there is unused bandwidth left.
  195. #
  196. # By default, CEIL is equal to RATE so the class cannot borrow bandwidth
  197. # from its parent. If you want the class to borrow unused bandwidth, you
  198. # must specify the maximal amount it can use, if available.
  199. #
  200. # When several classes compete for the unused bandwidth, each of the
  201. # classes is given share proportional to their RATE.
  202. #
  203. # BURST=<bytes> optional, default computed
  204. # BURST=10Kb
  205. #
  206. # CBURST=<bytes> optional, default computed
  207. # CBURST=2Kb
  208. #
  209. # BURST and CBURST parameters control the amount of data that can
  210. # be sent from one class at maximum (hardware) speed before trying
  211. # to service other class.
  212. #
  213. # If CBURST is small (one packet size) it shapes bursts not to
  214. # exceed CEIL rate the same way PEAK works for TBF.
  215. #
  216. # PRIO=<number> optional, default 0
  217. # PRIO=5
  218. #
  219. # Priority of class traffic. The higher the number, the lesser the
  220. # priority. Also, classes with higher priority are offered excess
  221. # bandwidth first.
  222. #
  223. # LEAF=none|sfq|pfifo|bfifo optional, default "none"
  224. #
  225. # Tells the script to attach specified leaf queueing discipline to HTB
  226. # class. By default, no leaf qdisc is used.
  227. #
  228. # If you want to ensure (approximately) fair sharing of bandwidth among
  229. # several hosts in the same class, you should specify LEAF=sfq to attach
  230. # SFQ as leaf queueing discipline to the class.
  231. #
  232. # MTU=<bytes> optional, default "1600"
  233. #
  234. # Maximum packet size HTB creates rate maps for. The default should
  235. # be sufficient for most cases, it certainly is for Ethernet.
  236. #
  237. ### SFQ qdisc parameters
  238. #
  239. # The SFQ queueing discipline is a cheap way to fairly share class bandwidth
  240. # among several hosts. The fairness is approximate because it is stochastic,
  241. # but is not CPU intensive and will do the job in most cases. If you desire
  242. # real fairness, you should probably use WRR (weighted round robin) or WFQ
  243. # queueing disciplines. Note that SFQ does not do any traffic shaping - the
  244. # shaping is done by the HTB class the SFQ is attached to.
  245. #
  246. # QUANTUM=<bytes> optional, qdisc default
  247. #
  248. # Amount of data in bytes a stream is allowed to dequeue before next
  249. # queue gets a turn. Defaults to one MTU-sized packet. Do not set
  250. # this parameter below the MTU!
  251. #
  252. # PERTURB=<seconds> optional, default "10"
  253. #
  254. # Period of hash function perturbation. If unset, hash reconfiguration
  255. # will never take place which is what you probably don't want. The
  256. # default value of 10 seconds is probably a good value.
  257. #
  258. ### PFIFO/BFIFO qdisc parameters
  259. #
  260. # Those are simple FIFO queueing disciplines. They only have one parameter
  261. # which determines their length in bytes or packets.
  262. #
  263. # LIMIT=<packets>|<bytes> optional, qdisc default
  264. # LIMIT=1000
  265. #
  266. # Number of packets/bytes the queue can hold. The unit depends on
  267. # the type of queue used.
  268. #
  269. ### Filtering parameters
  270. #
  271. # RULE=[[saddr[/prefix]][:port[/mask]],][daddr[/prefix]][:port[/mask]]
  272. #
  273. # These parameters make up "u32" filter rules that select traffic for
  274. # each of the classes. You can use multiple RULE fields per config.
  275. #
  276. # The optional port mask should only be used by advanced users who
  277. # understand how the u32 filter works.
  278. #
  279. # Some examples:
  280. #
  281. # RULE=10.1.1.0/24:80
  282. # selects traffic going to port 80 in network 10.1.1.0
  283. #
  284. # RULE=10.2.2.5
  285. # selects traffic going to any port on single host 10.2.2.5
  286. #
  287. # RULE=10.2.2.5:20/0xfffe
  288. # selects traffic going to ports 20 and 21 on host 10.2.2.5
  289. #
  290. # RULE=:25,10.2.2.128/26:5000
  291. # selects traffic going from anywhere on port 50 to
  292. # port 5000 in network 10.2.2.128
  293. #
  294. # RULE=10.5.5.5:80,
  295. # selects traffic going from port 80 of single host 10.5.5.5
  296. #
  297. #
  298. #
  299. # REALM=[srealm,][drealm]
  300. #
  301. # These parameters make up "route" filter rules that classify traffic
  302. # according to packet source/destination realms. For information about
  303. # realms, see Alexey Kuznetsov's IP Command Reference. This script
  304. # does not define any realms, it justs builds "tc filter" commands
  305. # for you if you need to classify traffic this way.
  306. #
  307. # Realm is either a decimal number or a string referencing entry in
  308. # /etc/iproute2/rt_realms (usually).
  309. #
  310. # Some examples:
  311. #
  312. # REALM=russia,internet
  313. # selects traffic going from realm "russia" to realm "internet"
  314. #
  315. # REALM=freenet,
  316. # selects traffic going from realm "freenet"
  317. #
  318. # REALM=10
  319. # selects traffic going to realm 10
  320. #
  321. #
  322. #
  323. # MARK=<mark>
  324. #
  325. # These parameters make up "fw" filter rules that select traffic for
  326. # each of the classes accoring to firewall "mark". Mark is a decimal
  327. # number packets are tagged with if firewall rules say so. You can
  328. # use multiple MARK fields per config.
  329. #
  330. #
  331. # Note: Rules for different filter types can be combined. Attention must be
  332. # paid to the priority of filter rules, which can be set below through
  333. # the PRIO_{RULE,MARK,REALM} variables.
  334. #
  335. ### Time ranging parameters
  336. #
  337. # TIME=[<dow><dow>.../]<from>-<till>;<rate>[/<burst>][,<ceil>[/<cburst>]]
  338. # TIME=60123/18:00-06:00;256Kbit/10Kb,384Kbit
  339. # TIME=18:00-06:00;256Kbit
  340. #
  341. # This parameter allows you to change class bandwidth during the day or
  342. # week. You can use multiple TIME rules. If there are several rules with
  343. # overlapping time periods, the last match is taken. The <rate>, <burst>,
  344. # <ceil> and <cburst> fields correspond to parameters RATE, BURST, CEIL
  345. # and CBURST.
  346. #
  347. # <dow> is single digit in range 0-6 and represents day of week as
  348. # returned by date(1). To specify several days, just concatenate the
  349. # digits together.
  350. #
  351. #
  352. #
  353. # TRIVIAL EXAMPLE
  354. # ---------------
  355. #
  356. # Consider the following example:
  357. # (taken from Linux Advanced Routing & Traffic Control HOWTO)
  358. #
  359. # You have a Linux server with total of 5Mbit available bandwidth. On this
  360. # machine, you want to limit webserver traffic to 5Mbit, SMTP traffic to 3Mbit
  361. # and everything else (unclassified traffic) to 1Kbit. In case there is unused
  362. # bandwidth, you want to share it between SMTP and unclassified traffic.
  363. #
  364. # The "total bandwidth" implies one top-level class with maximum bandwidth
  365. # of 5Mbit. Under the top-level class, there are three child classes.
  366. #
  367. # First, the class for webserver traffic is allowed to use 5Mbit of bandwidth.
  368. #
  369. # Second, the class for SMTP traffic is allowed to use 3Mbit of bandwidth and
  370. # if there is unused bandwidth left, it can use it but must not exceed 5Mbit
  371. # in total.
  372. #
  373. # And finally third, the class for unclassified traffic is allowed to use
  374. # 1Kbit of bandwidth and borrow unused bandwith, but must not exceed 5Mbit.
  375. #
  376. # If there is demand in all classes, each of them gets share of bandwidth
  377. # proportional to its default rate. If there unused is bandwidth left, they
  378. # (again) get share proportional to their default rate.
  379. #
  380. # Configuration files for this scenario:
  381. # ---------------------------------------------------------------------------
  382. # eth0 eth0-2.root eth0-2:10.www eth0-2:20.smtp eth0-2:30.dfl
  383. # ---- ----------- ------------- -------------- -------------
  384. # DEFAULT=30 RATE=5Mbit RATE=5Mbit RATE=3Mbit RATE=1Kbit
  385. # BURST=15k BURST=15k CEIL=5Mbit CEIL=5Mbit
  386. # LEAF=sfq BURST=15k BURST=15k
  387. # RULE=*:80, LEAF=sfq LEAF=sfq
  388. # RULE=*:25
  389. # ---------------------------------------------------------------------------
  390. #
  391. # Remember that you can only control traffic going out of your linux machine.
  392. # If you have a host connected to network and want to control its traffic on
  393. # the gateway in both directions (with respect to the host), you need to setup
  394. # traffic control for that host on both (or all) gateway interfaces.
  395. #
  396. # Enjoy.
  397. #
  398. #############################################################################
  399.  
  400. export LANG=C
  401.  
  402. ### Default filter priorities (must be different)
  403. PRIO_RULE=${PRIO_RULE:-100}
  404. PRIO_MARK=${PRIO_MARK:-200}
  405. PRIO_REALM=${PRIO_REALM:-300}
  406.  
  407. ### Default HTB_PATH & HTB_CACHE settings
  408. HTB_PATH=${HTB_PATH:-/etc/sysconfig/htb}
  409. HTB_CACHE=${HTB_CACHE:-/var/cache/htb.init}
  410.  
  411. ### Uncomment for sed/find with less features (useful for busybox)
  412. #HTB_BASIC="yes"
  413.  
  414. ### Uncomment to enable logfile for debugging
  415. #HTB_DEBUG="/var/run/htb-$1"
  416.  
  417. ### Modules to probe for. Uncomment the last HTB_PROBE
  418. ### line if you have QoS support compiled into kernel
  419. HTB_PROBE="sch_htb sch_sfq cls_fw cls_u32 cls_route"
  420. #HTB_PROBE=""
  421.  
  422. ### Config keywords
  423. HTB_QDISC="DEFAULT\|DCACHE\|R2Q"
  424. HTB_CLASS="RATE\|CEIL\|BURST\|CBURST\|PRIO\|LEAF\|MTU"
  425. HTB_CLASS="$HTB_CLASS\|LIMIT\|QUANTUM\|PERTURB"
  426.  
  427.  
  428. #############################################################################
  429. ############################# SUPPORT FUNCTIONS #############################
  430. #############################################################################
  431.  
  432. if [ -z "$HTB_BASIC" ]; then
  433. ### List of network devices
  434. all_device_list () {
  435. ip link show \
  436. | sed -n "/^[0-9]/ { s/[[:space:]]//g; \
  437. s/^[0-9]\+:\([^@-]\+\)\(@.\+\)\?:<.*/\1/; p; }"
  438. } # all_device_list
  439.  
  440.  
  441. ### Load & filter file $HTB_PATH/$1
  442. htb_filter_file () {
  443. sed -n "s/#.*//; s/[^a-zA-Z0-9.,;:=/*-]\+//g; \
  444. /^[a-zA-Z0-9]\+=[a-zA-Z0-9.,:;/*-]\+$/ p" $HTB_PATH/$1
  445. } # htb_filter_file
  446.  
  447.  
  448. ### Parse class ID chain from file name
  449. htb_clsid_chain () {
  450. echo "${1#*-}" \
  451. | sed -n "/^[0-9a-fA-F]/ { s/^\([0-9a-fA-F:]\+\).*/\1/; \
  452. s/::/:/g; s/:$//; p; }"
  453. } # htb_clsid_chain
  454.  
  455.  
  456. ### List of classes in $HTB_PATH
  457. htb_class_list () {
  458. for dev in `htb_device_list`; do
  459. find $HTB_PATH -maxdepth 1 -type f -name "$dev-*" \
  460. -not -name '*~' -printf "%f\n"| sort
  461. done
  462. } # htb_class_list
  463.  
  464. ### Gather $1 rules from $CFILE
  465. htb_cfile_rules () {
  466. echo "$CFILE"| sed -n "/^$1=/ { s/.*=//; p; }"
  467. } # htb_cfile_rules
  468.  
  469.  
  470. ### Validate cache against config files
  471. htb_valid_cache () {
  472. for dev in `htb_device_list`; do
  473. [ `find $HTB_PATH -maxdepth 1 -type f -name "$dev*" \
  474. -newer $HTB_CACHE| wc -l` -gt 0 ] && VALID=0
  475. [ $VALID -ne 1 ] && break
  476. done
  477. } # htb_valid_cache
  478.  
  479.  
  480. ### Find class config for device $1, which is newer than cache
  481. htb_cache_older () {
  482. [ `find $HTB_PATH -maxdepth 1 -type f -name "$1*" \
  483. -newer $HTB_CACHE| wc -l` -gt 0 ] && return 0
  484. return 1
  485. } # htb_cache_older
  486.  
  487.  
  488. ### Get current RATE and CEIL
  489. htb_class_state () {
  490. tc class show dev $1 \
  491. | sed -n "s/[[:space:]]\+/ /g; /^class htb 1:$2 / \
  492. { s/.*rate \(.\+\) burst.*/\1/; p; q; }"
  493. } # htb_class_state
  494.  
  495. else ### Less feature-hungry versions of above functions
  496.  
  497. all_device_list () {
  498. ip link show \
  499. | grep "^[0-9]" \
  500. | sed "s/[[:space:]]//g; \
  501. s/^[0-9]\+:\([^@-]\+\)\(@.\+\)\?:<.*/\1/"
  502. } # all_device_list
  503.  
  504. htb_filter_file () {
  505. sed 's/#.*//; s/[^a-zA-Z0-9.,;:=/*-]\+//g' $HTB_PATH/$1 \
  506. | grep '^[a-zA-Z0-9]\+=[a-zA-Z0-9.,;:/*-]\+$'
  507. } # htb_filter_file
  508.  
  509. htb_clsid_chain () {
  510. echo "${1#*-}" \
  511. | grep '^[a-fA-F0-9]' \
  512. | sed 's/^\([a-fA-F0-9:]\+\).*/\1/; s/::/:/g; s/:$//'
  513. } # htb_clsid_chain
  514.  
  515. htb_class_list () {
  516. PFX=`echo "$HTB_PATH"| sed 's/\//\\\\\//g'`
  517. for dev in `htb_device_list`; do
  518. find $HTB_PATH -type f -name "$dev-*" \
  519. | grep "^$HTB_PATH/$dev-[^/]\+[^~]$" \
  520. | sed "s/$PFX\///" \
  521. | sort
  522. done
  523. } # htb_class_list
  524.  
  525. htb_cfile_rules () {
  526. echo "$CFILE"| grep "^$1="| cut -d"=" -f2
  527. } # htb_cfile_rules
  528.  
  529. htb_cache_older () {
  530. ### cache is always up-to-date
  531. return 1
  532. } # htb_cache_older
  533.  
  534. htb_class_state () {
  535. tc class show dev $1 \
  536. | sed 's/[[:space:]]\+/ /g' \
  537. | grep "^class htb 1:$2 " \
  538. | sed 's/.*rate \(.\+\) burst.*/\1/'
  539. } # htb_class_state
  540. fi # HTB_BASIC
  541.  
  542.  
  543. ### List of HTB devices
  544. htb_device_list () {
  545. for dev in `all_device_list`; do
  546. [ -f $HTB_PATH/$dev ] && echo $dev
  547. done
  548. } # htb_device_list
  549.  
  550.  
  551. ### Remove root class from device $1
  552. htb_device_off () {
  553. tc qdisc del dev $1 root 2> /dev/null
  554. } # htb_device_off
  555.  
  556.  
  557. ### Remove HTB from all devices
  558. htb_off () {
  559. for dev in `htb_device_list`; do
  560. htb_device_off $dev
  561. done
  562. } # htb_off
  563.  
  564.  
  565. ### Prefixed message
  566. htb_message () {
  567. echo -e "**HTB: $@"
  568. } # htb_message
  569.  
  570. ### Failure message
  571. htb_failure () {
  572. htb_message "$@"
  573. exit 1
  574. } # htb_failure
  575.  
  576. ### Failure w/htb_off
  577. htb_fail_off () {
  578. htb_message "$@"
  579. htb_off
  580. exit 1
  581. } # htb_fail_off
  582.  
  583.  
  584. ### Convert time to absolute value
  585. htb_time2abs () {
  586. local min=${1##*:}; min=${min##0}
  587. local hrs=${1%%:*}; hrs=${hrs##0}
  588. echo $[hrs*60 + min]
  589. } # htb_time2abs
  590.  
  591.  
  592. ### Display traffic control setup
  593. htb_show () {
  594. for dev in `all_device_list`; do
  595. [ `tc qdisc show dev $dev| wc -l` -eq 0 ] && continue
  596. echo -e "### $dev: queueing disciplines\n"
  597. tc $1 qdisc show dev $dev; echo
  598.  
  599. [ `tc class show dev $dev| wc -l` -eq 0 ] && continue
  600. echo -e "### $dev: traffic classes\n"
  601. tc $1 class show dev $dev; echo
  602.  
  603. [ `tc filter show dev $dev| wc -l` -eq 0 ] && continue
  604. echo -e "### $dev: filtering rules\n"
  605. tc $1 filter show dev $dev; echo
  606. done
  607. } # htb_show
  608.  
  609.  
  610.  
  611. ### Derive DEVICE, CLASS and PARENT from $1
  612. ### Check validity of CLASS and PARENT class IDs
  613. ### Load class configuration from $HTP_PATH/$1
  614. ### Configure class parameters from CFILE
  615. htb_load_class () {
  616. DEVICE=${1%%-*}
  617. CLSIDS=`htb_clsid_chain $1`
  618. CLASS=${CLSIDS##*:}; [ -z "$CLASS" ] &&
  619. htb_fail_off "$1 has invalid class ID!"
  620.  
  621. [ $[0x$CLASS] -lt 2 -o $[0x$CLASS] -gt 65535 ] &&
  622. htb_fail_off "class ID of $1 must be in range 0x2-0xFFFF!"
  623.  
  624. CLSIDS=${CLSIDS%$CLASS}; CLSIDS=${CLSIDS%:}
  625. PARENT=${CLSIDS##*:}; [ -n "$PARENT" ] &&
  626. [ $[0x$PARENT] -lt 2 -o $[0x$PARENT] -gt 65535 ] &&
  627. htb_fail_off "parent ID of $1 must be in range 0x2-0xFFFF!"
  628.  
  629. CFILE=`htb_filter_file $1`
  630.  
  631.  
  632. ### Set defaults & load class
  633. MTU=""; LEAF=none; PERTURB=10
  634. RATE=""; BURST=""; CEIL=""; CBURST=""
  635. PRIO=""; LIMIT=""; QUANTUM=""
  636.  
  637. eval `echo "$CFILE"| grep "^\($HTB_CLASS\)="`
  638. RNAME=""; CNAME=""
  639.  
  640. ### Resolve RATE if needed
  641. [ "$RATE" = "prate" ] && RNAME=RATE_$PARENT
  642. [ "$RATE" = "pceil" ] && RNAME=CEIL_$PARENT
  643. [ -n "$RNAME" ] && RATE=${!RNAME}
  644.  
  645. ### RATE is required
  646. [ -z "$RATE" ] &&
  647. htb_fail_off "missing or unresolvable RATE in $1!"
  648.  
  649. ### Resolve CEIL if needed
  650. [ "$CEIL" = "prate" ] && CNAME=RATE_$PARENT
  651. [ "$CEIL" = "pceil" ] && CNAME=CEIL_$PARENT
  652. [ -n "$CNAME" ] && CEIL=${!CNAME}
  653.  
  654. ### Store CEIL & RATE for children
  655. eval RATE_$CLASS=$RATE
  656. eval CEIL_$CLASS=${CEIL:-$RATE}
  657. } # htb_load_class
  658.  
  659.  
  660. #############################################################################
  661. #################################### INIT ###################################
  662. #############################################################################
  663.  
  664. ### Check iproute2 tools
  665. [ -x /sbin/tc -a -x /sbin/ip ] ||
  666. htb_failure "iproute2 utilities not installed or executable!"
  667.  
  668. ### Check $HTB_PATH directory
  669. [ -d $HTB_PATH -a -r $HTB_PATH -a -x $HTB_PATH ] ||
  670. htb_failure "$HTB_PATH does not exist or is not readable!"
  671.  
  672. ### Various tweaks
  673. if [ "$1" = "compile" ]; then
  674. ### no module probing
  675. HTB_PROBE=""
  676.  
  677. ### echo-only version of "tc" command
  678. tc () {
  679. echo "tc $@"
  680. } # tc
  681.  
  682. elif [ -n "$HTB_DEBUG" ]; then
  683. echo -e "# `date`" > $HTB_DEBUG
  684.  
  685. ### Logging version of "ip" command
  686. ip () {
  687. echo -e "\n# ip $@" >> $HTB_DEBUG
  688. /sbin/ip "$@" 2>&1 | tee -a $HTB_DEBUG
  689. } # ip
  690.  
  691. ### Logging version of "tc" command
  692. tc () {
  693. echo -e "\n# tc $@" >> $HTB_DEBUG
  694. /sbin/tc "$@" 2>&1 | tee -a $HTB_DEBUG
  695. } # tc
  696. fi # command logging
  697.  
  698.  
  699. case "$1" in
  700.  
  701. #############################################################################
  702. ############################### START/COMPILE ###############################
  703. #############################################################################
  704.  
  705. start|compile)
  706.  
  707. ### Probe QoS modules (start only)
  708. for module in $HTB_PROBE; do
  709. modprobe $module || htb_failure "failed to load module $module"
  710. done
  711.  
  712. ### If we are in compile/nocache/logging mode, don't bother with cache
  713. if [ "$1" != "compile" -a "$2" != "nocache" -a -z "$HTB_DEBUG" ]; then
  714. VALID=1
  715.  
  716. ### validate the cache
  717. [ "$2" = "invalidate" -o ! -f $HTB_CACHE ] && VALID=0
  718. [ $VALID -eq 1 ] && for dev in `htb_device_list`; do
  719. htb_cache_older $dev && VALID=0
  720. [ $VALID -ne 1 ] && break
  721. done
  722.  
  723. ### compile the config if the cache is invalid
  724. if [ $VALID -ne 1 ]; then
  725. $0 compile > $HTB_CACHE ||
  726. htb_fail_off "failed to compile HTB configuration!"
  727. fi
  728.  
  729. ### run the cached commands
  730. exec /bin/sh $HTB_CACHE 2> /dev/null
  731. fi
  732.  
  733.  
  734. ### Setup root qdisc on all configured devices
  735. DEVICES=`htb_device_list`
  736. [ -z "$DEVICES" ] && htb_failure "no configured devices found!"
  737.  
  738. for dev in $DEVICES; do
  739. ### Retrieve root qdisc options
  740. DEFAULT=""; DCACHE=""; R2Q=""
  741. eval `htb_filter_file $dev| grep "^\($HTB_QDISC\)="`
  742. [ "$DCACHE" = "yes" ] && DCACHE="dcache" || DCACHE=""
  743.  
  744. ### Remove old root qdisc from device
  745. htb_device_off $dev
  746.  
  747. ### Setup root qdisc for the device
  748. tc qdisc add dev $dev root handle 1 htb \
  749. default ${DEFAULT:-0} ${R2Q:+r2q $R2Q} $DCACHE ||
  750. htb_fail_off "failed to set root qdisc on $dev!"
  751.  
  752. [ "$1" = "compile" ] && echo
  753. done # dev
  754.  
  755.  
  756. ### Setup traffic classes (if configured)
  757. for classfile in `htb_class_list`; do
  758. htb_load_class $classfile
  759.  
  760. ### Create the class
  761. tc class add dev $DEVICE parent 1:$PARENT classid 1:$CLASS \
  762. htb rate $RATE ${CEIL:+ceil $CEIL} ${BURST:+burst $BURST} \
  763. ${PRIO:+prio $PRIO} ${CBURST:+cburst $CBURST} ${MTU:+mtu $MTU} ||
  764. htb_fail_off "failed to add class $CLASS with parent $PARENT on $DEVICE!"
  765.  
  766. ### Create leaf qdisc if set
  767. if [ "$LEAF" != "none" ]; then
  768. if [ "$LEAF" = "sfq" ]; then
  769. LEAFPARM="${PERTURB:+perturb $PERTURB} ${QUANTUM:+quantum $QUANTUM}"
  770. elif [ "$LEAF" = "pfifo" -o "$LEAF" = "bfifo" ]; then
  771. LEAFPARM="${LIMIT:+limit $LIMIT}"
  772. else
  773. htb_fail_off "unknown leaf qdisc ($LEAF) in $classfile!"
  774. fi
  775.  
  776. tc qdisc add dev $DEVICE \
  777. parent 1:$CLASS handle $CLASS $LEAF $LEAFPARM ||
  778. htb_fail_off "failed to add leaf qdisc to class $CLASS on $DEVICE!"
  779. fi
  780.  
  781.  
  782. ### Create fw filter for MARK fields
  783. for mark in `htb_cfile_rules MARK`; do
  784. ### Attach fw filter to root class
  785. tc filter add dev $DEVICE parent 1:0 protocol ip \
  786. prio $PRIO_MARK handle $mark fw classid 1:$CLASS
  787. done ### mark
  788.  
  789. ### Create route filter for REALM fields
  790. for realm in `htb_cfile_rules REALM`; do
  791. ### Split realm into source & destination realms
  792. SREALM=${realm%%,*}; DREALM=${realm##*,}
  793. [ "$SREALM" = "$DREALM" ] && SREALM=""
  794.  
  795. ### Convert asterisks to empty strings
  796. SREALM=${SREALM#\*}; DREALM=${DREALM#\*}
  797.  
  798. ### Attach route filter to the root class
  799. tc filter add dev $DEVICE parent 1:0 protocol ip \
  800. prio $PRIO_REALM route ${SREALM:+from $SREALM} \
  801. ${DREALM:+to $DREALM} classid 1:$CLASS
  802. done ### realm
  803.  
  804. ### Create u32 filter for RULE fields
  805. for rule in `htb_cfile_rules RULE`; do
  806. ### Split rule into source & destination
  807. SRC=${rule%%,*}; DST=${rule##*,}
  808. [ "$SRC" = "$rule" ] && SRC=""
  809.  
  810.  
  811. ### Split destination into address, port & mask fields
  812. DADDR=${DST%%:*}; DTEMP=${DST##*:}
  813. [ "$DADDR" = "$DST" ] && DTEMP=""
  814.  
  815. DPORT=${DTEMP%%/*}; DMASK=${DTEMP##*/}
  816. [ "$DPORT" = "$DTEMP" ] && DMASK="0xffff"
  817.  
  818.  
  819. ### Split up source (if specified)
  820. SADDR=""; SPORT=""
  821. if [ -n "$SRC" ]; then
  822. SADDR=${SRC%%:*}; STEMP=${SRC##*:}
  823. [ "$SADDR" = "$SRC" ] && STEMP=""
  824.  
  825. SPORT=${STEMP%%/*}; SMASK=${STEMP##*/}
  826. [ "$SPORT" = "$STEMP" ] && SMASK="0xffff"
  827. fi
  828.  
  829.  
  830. ### Convert asterisks to empty strings
  831. SADDR=${SADDR#\*}; DADDR=${DADDR#\*}
  832.  
  833. ### Compose u32 filter rules
  834. u32_s="${SPORT:+match ip sport $SPORT $SMASK}"
  835. u32_s="${SADDR:+match ip src $SADDR} $u32_s"
  836. u32_d="${DPORT:+match ip dport $DPORT $DMASK}"
  837. u32_d="${DADDR:+match ip dst $DADDR} $u32_d"
  838.  
  839. ### Uncomment the following if you want to see parsed rules
  840. #echo "$rule: $u32_s $u32_d"
  841.  
  842. ### Attach u32 filter to the appropriate class
  843. tc filter add dev $DEVICE parent 1:0 protocol ip \
  844. prio $PRIO_RULE u32 $u32_s $u32_d classid 1:$CLASS
  845. done ### rule
  846.  
  847. [ "$1" = "compile" ] && echo
  848. done ### classfile
  849. ;;
  850.  
  851.  
  852. #############################################################################
  853. ################################# TIME CHECK ################################
  854. #############################################################################
  855.  
  856. timecheck)
  857.  
  858. ### Get time + weekday
  859. TIME_TMP=`date +%w/%k:%M`
  860. TIME_DOW=${TIME_TMP%%/*}
  861. TIME_NOW=${TIME_TMP##*/}
  862. TIME_ABS=`htb_time2abs $TIME_NOW`
  863.  
  864. ### Check all classes (if configured)
  865. for classfile in `htb_class_list`; do
  866. ### Load class and gather all TIME rules
  867. htb_load_class $classfile
  868. TIMESET=`htb_cfile_rules TIME`
  869. [ -z "$TIMESET" ] && continue
  870.  
  871. MATCH=0; CHANGE=0
  872. for timerule in $TIMESET; do
  873. ### Split TIME rule to pieces
  874. TIMESPEC=${timerule%%;*}; PARAMS=${timerule##*;}
  875. WEEKDAYS=${TIMESPEC%%/*}; INTERVAL=${TIMESPEC##*/}
  876. BEG_TIME=${INTERVAL%%-*}; END_TIME=${INTERVAL##*-}
  877.  
  878. ### Check the day-of-week (if present)
  879. [ "$WEEKDAYS" != "$INTERVAL" -a \
  880. -n "${WEEKDAYS##*$TIME_DOW*}" ] && continue
  881.  
  882. ### Compute interval boundaries
  883. BEG_ABS=`htb_time2abs $BEG_TIME`
  884. END_ABS=`htb_time2abs $END_TIME`
  885.  
  886. ### Midnight wrap fixup
  887. if [ $BEG_ABS -gt $END_ABS ]; then
  888. [ $TIME_ABS -le $END_ABS ] &&
  889. TIME_ABS=$[TIME_ABS + 24*60]
  890.  
  891. END_ABS=$[END_ABS + 24*60]
  892. fi
  893.  
  894. ### If time period matches, remember params and set MATCH flag
  895. if [ $TIME_ABS -ge $BEG_ABS -a $TIME_ABS -lt $END_ABS ]; then
  896. RATESPEC=${PARAMS%%,*}; CEILSPEC=${PARAMS##*,}
  897. [ "$RATESPEC" = "$CEILSPEC" ] && CEILSPEC=""
  898.  
  899. NEW_RATE=${RATESPEC%%/*}; NEW_BURST=${RATESPEC##*/}
  900. [ "$NEW_RATE" = "$NEW_BURST" ] && NEW_BURST=""
  901.  
  902. NEW_CEIL=${CEILSPEC%%/*}; NEW_CBURST=${CEILSPEC##*/}
  903. [ "$NEW_CEIL" = "$NEW_CBURST" ] && NEW_CBURST=""
  904.  
  905. MATCH=1
  906. fi
  907. done ### timerule
  908.  
  909.  
  910. ### Get current RATE and CEIL of a class
  911. read RATE_NOW JUNK CEIL_NOW <<-EOT
  912. `htb_class_state $DEVICE $CLASS`
  913. EOT
  914.  
  915. [ -z "$RATE_NOW" -o -z "$CEIL_NOW" ] && continue
  916.  
  917.  
  918. ### Fill empty values if matched
  919. if [ $MATCH -ne 0 ]; then
  920. NEW_RATE=${NEW_RATE:-$RATE_NOW}
  921. NEW_CEIL=${NEW_CEIL:-$CEIL_NOW}
  922.  
  923. NEW_BURST=${NEW_BURST:-$BURST}
  924. NEW_CBURST=${NEW_CBURST:-$CBURST}
  925.  
  926. ### Force configured values if not matched
  927. else
  928. NEW_RATE=$RATE; NEW_CEIL=$CEIL
  929. NEW_BURST=$BURST; NEW_CBURST=$CBURST
  930. fi
  931.  
  932.  
  933.  
  934. ### Check for RATE and CEIL changes
  935. [ "$RATE_NOW" != "$NEW_RATE" ] && CHANGE=1
  936. [ "$CEIL_NOW" != "$NEW_CEIL" ] && CHANGE=1
  937.  
  938. ### If there are no changes, go for next class
  939. [ $CHANGE -eq 0 ] && continue
  940.  
  941.  
  942. ### Replace HTB class
  943. tc class change dev $DEVICE classid 1:$CLASS htb \
  944. prio $PRIO rate $NEW_RATE ${NEW_CEIL:+ceil $NEW_CEIL} \
  945. ${NEW_BURST:+burst $NEW_BURST} ${NEW_CBURST:+cburst $NEW_CBURST}
  946.  
  947. htb_message "$TIME_NOW: change on $DEVICE:$CLASS ($RATE_NOW/$CEIL_NOW -> $NEW_RATE/$NEW_CEIL)"
  948. done ### class file
  949. ;;
  950.  
  951.  
  952. #############################################################################
  953. ################################## THE REST #################################
  954. #############################################################################
  955.  
  956. stop)
  957. htb_off
  958. rm -f $HTB_CACHE
  959. ;;
  960.  
  961. list)
  962. htb_show
  963. ;;
  964.  
  965. stats)
  966. htb_show -s
  967. ;;
  968.  
  969. restart)
  970. shift
  971. $0 stop
  972. $0 start "$@"
  973. ;;
  974.  
  975. *)
  976. echo "Usage: `basename $0` {start|compile|stop|restart|timecheck|list|stats}"
  977. esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement