Advertisement
Guest User

Untitled

a guest
Sep 5th, 2013
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.61 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. # cbq.init v0.7.3
  4. # Copyright (C) 1999 Pavel Golubev <[email protected]>
  5. # Copyright (C) 2001-2004 Lubomir Bulej <[email protected]>
  6. #
  7. # chkconfig: 2345 11 89
  8. # description: sets up CBQ-based traffic control
  9. #
  10. # This program is free software; you can redistribute it and/or modify
  11. # it under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation; either version 2 of the License, or
  13. # (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program; if not, write to the Free Software
  22. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. #
  24. # To get the latest version, check on Freshmeat for actual location:
  25. #
  26. # http://freshmeat.net/projects/cbq.init
  27. #
  28. #
  29. # VERSION HISTORY
  30. # ---------------
  31. # v0.7.3- Deepak Singhal <singhal at users.sourceforge.net>
  32. # - fix timecheck to not ignore regular TIME rules after
  33. # encountering a TIME rule that spans over midnight
  34. # - Nathan Shafer <nicodemus at users.sourceforge.net>
  35. # - allow symlinks to class files
  36. # - Seth J. Blank <antifreeze at users.sourceforge.net>
  37. # - replace hardcoded ip/tc location with variables
  38. # - Mark Davis <mark.davis at gmx.de>
  39. # - allow setting of PRIO_{MARK,RULE,REALM} in class file
  40. # - Fernando Sanch <toptnc at users.sourceforge.net>
  41. # - allow underscores in interface names
  42. # v0.7.2- Paulo Sedrez
  43. # - fix time2abs to allow hours with leading zero in TIME rules
  44. # - Svetlin Simeonov <zvero at yahoo.com>
  45. # - fix cbq_device_list to allow VLAN interfaces
  46. # - Mark Davis <mark.davis at gmx.de>
  47. # - ignore *~ backup files when looking for classes
  48. # - Mike Boyer <boyer at administrative.com>
  49. # - fix to allow arguments to be passed to "restart" command
  50. # v0.7.1- Lubomir Bulej <pallas at kadan.cz>
  51. # - default value for PERTURB
  52. # - fixed small bug in RULE parser to correctly parse rules with
  53. # identical source and destination fields
  54. # - faster initial scanning of DEVICE fields
  55. # v0.7 - Lubomir Bulej <pallas at kadan.cz>
  56. # - lots of various cleanups and reorganizations; the parsing is now
  57. # some 40% faster, but the class ID must be in range 0x0002-0xffff
  58. # (again). Because of the number of internal changes and the above
  59. # class ID restriction, I bumped the version to 0.7 to indicate
  60. # something might have got broken :)
  61. # - changed PRIO_{U32,FW,ROUTE} to PRIO_{RULE,MARK,REALM}
  62. # for consistency with filter keywords
  63. # - exposed "compile" command
  64. # - Catalin Petrescu <taz at dntis.ro>
  65. # - support for port masks in RULE (u32) filter
  66. # - Jordan Vrtanoski <obeliks at mt.net.mk>
  67. # - support for week days in TIME rules
  68. # v0.6.4- Lubomir Bulej <pallas at kadan.cz>
  69. # - added PRIO_* variables to allow easy control of filter priorities
  70. # - added caching to speed up CBQ start, the cache is invalidated
  71. # whenever any of the configuration files changes
  72. # - updated the readme section + some cosmetic fixes
  73. # v0.6.3- Lubomir Bulej <pallas at kadan.cz>
  74. # - removed setup of (unnecessary) class 1:1 - all classes
  75. # now use qdisc's default class 1:0 as their parent
  76. # - minor fix in the timecheck branch - classes
  77. # without leaf qdisc were not updated
  78. # - minor fix to avoid timecheck failure when run
  79. # at time with minutes equal to 08 or 09
  80. # - respect CBQ_PATH setting in environment
  81. # - made PRIO=5 default, rendering it optional in configs
  82. # - added support for route filter, see notes about REALM keyword
  83. # - added support for fw filter, see notes about MARK keyword
  84. # - added filter display to "list" and "stats" commands
  85. # - readme section update + various cosmetic fixes
  86. # v0.6.2- Catalin Petrescu <taz at dntis.ro>
  87. # - added tunnels interface handling
  88. # v0.6.1- Pavel Golubev <pg at ksi-linux.com>
  89. # - added sch_prio module loading
  90. # (thanks johan at iglo.virtual.or.id for reminding)
  91. # - resolved errors resulting from stricter syntax checking in bash2
  92. # - Lubomir Bulej <pallas at kadan.cz>
  93. # - various cosmetic fixes
  94. # v0.6 - Lubomir Bulej <pallas at kadan.cz>
  95. # - attempt to limit number of spawned processes by utilizing
  96. # more of sed power (use sed instead of grep+cut)
  97. # - simplified TIME parser, using bash builtins
  98. # - added initial support for SFQ as leaf qdisc
  99. # - reworked the documentation part a little
  100. # - incorporated pending patches and ideas submitted by
  101. # following people for versions 0.3 into version 0.6
  102. # - Miguel Freitas <miguel at cetuc.puc-rio.br>
  103. # - in case of overlapping TIME parameters, the last match is taken
  104. # - Juanjo Ciarlante <jjo at mendoza.gov.ar>
  105. # - chkconfig tags, list + stats startup parameters
  106. # - optional tc & ip command logging (into /var/run/cbq-*)
  107. # - Rafal Maszkowski <rzm at icm.edu.pl>
  108. # - PEAK parameter for setting TBF's burst peak rate
  109. # - fix for many config files (use find instead of ls)
  110. # v0.5.1- Lubomir Bulej <pallas at kadan.cz>
  111. # - fixed little but serious bug in RULE parser
  112. # v0.5 - Lubomir Bulej <pallas at kadan.cz>
  113. # - added options PARENT, LEAF, ISOLATED and BOUNDED. This allows
  114. # (with some attention to config file ordering) for creating
  115. # hierarchical structures of shapers with classes able (or unable)
  116. # to borrow bandwidth from their parents.
  117. # - class ID check allows hexadecimal numbers
  118. # - rewritten & simplified RULE parser
  119. # - cosmetic changes to improve readability
  120. # - reorganization to avoid duplicate code (timecheck etc.)
  121. # - timecheck doesn't check classes without TIME fields anymore
  122. # v0.4 - Lubomir Bulej <pallas at kadan.cz>
  123. # - small bugfix in RULE parsing code
  124. # - simplified configuration parsing code
  125. # - several small cosmetic changes
  126. # - TIME parameter can be now specified more than once allowing you to
  127. # differentiate RATE throughout the whole day. Time overlapping is
  128. # not checked, first match is taken. Midnight wrap (eg. 20:00-6:00)
  129. # is allowed and taken care of.
  130. # v0.3a4- fixed small bug in IF operator. Thanks to
  131. # Rafal Maszkowski <rzm at icm.edu.pl>
  132. # v0.3a3- fixed grep bug when using more than 10 eth devices. Thanks to David
  133. # Trcka <trcka at poda.cz>.
  134. # v0.3a2- fixed bug in "if" operator. Thanks kad at dgtu.donetsk.ua.
  135. # v0.3a - added TIME parameter. Example: TIME=00:00-19:00;64Kbit/6Kbit
  136. # So, between 00:00 and 19:00 the RATE will be 64Kbit.
  137. # Just start "cbq.init timecheck" periodically from cron
  138. # (every 10 minutes for example). DON'T FORGET though, to run
  139. # "cbq.init start" for CBQ to initialize.
  140. # v0.2 - Some cosmetic changes. Now it is more compatible with old bash
  141. # version. Thanks to Stanislav V. Voronyi <stas at cnti.uanet.kharkov.ua>.
  142. # v0.1 - First public release
  143. #
  144. #
  145. # README
  146. # ------
  147. #
  148. # First of all - this is just a SIMPLE EXAMPLE of CBQ power.
  149. # Don't ask me "why" and "how" :)
  150. #
  151. # This script is meant to simplify setup and management of relatively simple
  152. # CBQ-based traffic control on Linux. Access to advanced networking features
  153. # of Linux kernel is provided by "ip" and "tc" utilities from A. Kuznetsov's
  154. # iproute2 package, available at ftp://ftp.inr.ac.ru/ip-routing. Because the
  155. # utilities serve primarily to translate user wishes to RTNETLINK commands,
  156. # their interface is rather spartan, intolerant and requires quite a lot of
  157. # typing. And typing is what this script attempts to reduce :)
  158. #
  159. # The advanced networking stuff in Linux is pretty flexible and this script
  160. # aims to bring some of its features to the not-so-hard-core Linux users. Of
  161. # course, there is a tradeoff between simplicity and flexibility and you may
  162. # realize that the flexibility suffered too much for your needs -- time to
  163. # face "ip" and "tc" interface.
  164. #
  165. # To speed up the "start" command, simple caching was introduced in version
  166. # 0.6.4. The caching works so that the sequence of "tc" commands for given
  167. # configuration is stored in a file (/var/cache/cbq.init by default) which
  168. # is used next time the "start" command is run to avoid repeated parsing of
  169. # configuration files. This cache is invalidated whenever any of the CBQ
  170. # configuration files changes. If you want to run "cbq.init start" without
  171. # caching, run it as "cbq.init start nocache". If you want to force cache
  172. # invalidation, run it as "cbq.init start invalidate". Caching is disabled
  173. # if you have logging enabled (ie. CBQ_DEBUG is not empty).
  174. #
  175. # If you only want cqb.init to translate your configuration to "tc" commands,
  176. # use "compile" command which will output "tc" commands required to build
  177. # your configuration. Bear in mind that "compile" does not check if the "tc"
  178. # commands were successful - this is done (in certain places) only when the
  179. # "start nocache" command is used, which is also useful when creating the
  180. # configuration to check whether it is completely valid.
  181. #
  182. # All CBQ parameters are valid for Ethernet interfaces only, The script was
  183. # tested on various Linux kernel versions from series 2.1 to 2.4 and several
  184. # distributions with KSI Linux (Nostromo version) as the premier one.
  185. #
  186. #
  187. # HOW DOES IT WORK?
  188. # -----------------
  189. #
  190. # Every traffic class must be described by a file in the $CBQ_PATH directory
  191. # (/etc/sysconfig/cbq by default) - one file per class.
  192. #
  193. # The config file names must obey mandatory format: cbq-<clsid>.<name> where
  194. # <clsid> is two-byte hexadecimal number in range <0002-FFFF> (which in fact
  195. # is a CBQ class ID) and <name> is the name of the class -- anything to help
  196. # you distinguish the configuration files. For small amount of classes it is
  197. # often possible (and convenient) to let <clsid> resemble bandwidth of the
  198. # class.
  199. #
  200. # Example of valid config name:
  201. # cbq-1280.My_first_shaper
  202. #
  203. #
  204. # The configuration file may contain the following parameters:
  205. #
  206. ### Device parameters
  207. #
  208. # DEVICE=<ifname>,<bandwidth>[,<weight>] mandatory
  209. # DEVICE=eth0,10Mbit,1Mbit
  210. #
  211. # <ifname> is the name of the interface you want to control
  212. # traffic on, e.g. eth0
  213. # <bandwidth> is the physical bandwidth of the device, e.g. for
  214. # ethernet 10Mbit or 100Mbit, for arcnet 2Mbit
  215. # <weight> is tuning parameter that should be proportional to
  216. # <bandwidth>. As a rule of thumb: <weight> = <bandwidth> / 10
  217. #
  218. # When you have more classes on one interface, it is enough to specify
  219. # <bandwidth> [and <weight>] only once, therefore in other files you only
  220. # need to set DEVICE=<ifname>.
  221. #
  222. ### Class parameters
  223. #
  224. # RATE=<speed> mandatory
  225. # RATE=5Mbit
  226. #
  227. # Bandwidth allocated to the class. Traffic going through the class is
  228. # shaped to conform to specified rate. You can use Kbit, Mbit or bps,
  229. # Kbps and Mbps as suffices. If you don't specify any unit, bits/sec
  230. # are used. Also note that "bps" means "bytes per second", not bits.
  231. #
  232. # WEIGHT=<speed> mandatory
  233. # WEIGHT=500Kbit
  234. #
  235. # Tuning parameter that should be proportional to RATE. As a rule
  236. # of thumb, use WEIGHT ~= RATE / 10.
  237. #
  238. # PRIO=<1-8> optional, default 5
  239. # PRIO=5
  240. #
  241. # Priority of class traffic. The higher the number, the lesser
  242. # the priority. Priority of 5 is just fine.
  243. #
  244. # PARENT=<clsid> optional, default not set
  245. # PARENT=1280
  246. #
  247. # Specifies ID of the parent class to which you want this class be
  248. # attached. You might want to use LEAF=none for the parent class as
  249. # mentioned below. By using this parameter and carefully ordering the
  250. # configuration files, it is possible to create simple hierarchical
  251. # structures of CBQ classes. The ordering is important so that parent
  252. # classes are constructed prior to their children.
  253. #
  254. # LEAF=none|tbf|sfq optional, default "tbf"
  255. #
  256. # Tells the script to attach specified leaf queueing discipline to CBQ
  257. # class. By default, TBF is used. Note that attaching TBF to CBQ class
  258. # shapes the traffic to conform to TBF parameters and prevents the class
  259. # from borrowing bandwidth from its parent even if you have BOUNDED set
  260. # to "no". To allow the class to borrow bandwith (provided it is not
  261. # bounded), you must set LEAF to "none" or "sfq".
  262. #
  263. # If you want to ensure (approximately) fair sharing of bandwidth among
  264. # several hosts in the same class, you might want to specify LEAF=sfq to
  265. # attach SFQ as leaf queueing discipline to that class.
  266. #
  267. # BOUNDED=yes|no optional, default "yes"
  268. #
  269. # If set to "yes", the class is not allowed to borrow bandwidth from
  270. # its parent class in overlimit situation. If set to "no", the class
  271. # will be allowed to borrow bandwidth from its parent.
  272. #
  273. # Note: Don't forget to set LEAF to "none" or "sfq", otherwise the class will
  274. # have TBF attached to itself and will not be able to borrow unused
  275. # bandwith from its parent.
  276. #
  277. # ISOLATED=yes|no optional, default "no"
  278. #
  279. # If set to "yes", the class will not lend unused bandwidth to
  280. # its children.
  281. #
  282. ### TBF qdisc parameters
  283. #
  284. # BUFFER=<bytes>[/<bytes>] optional, default "10Kb/8"
  285. #
  286. # This parameter controls the depth of the token bucket. In other
  287. # words it represents the maximal burst size the class can send.
  288. # The optional part of parameter is used to determine the length
  289. # of intervals in packet sizes, for which the transmission times
  290. # are kept.
  291. #
  292. # LIMIT=<bytes> optional, default "15Kb"
  293. #
  294. # This parameter determines the maximal length of backlog. If
  295. # the queue contains more data than specified by LIMIT, the
  296. # newly arriving packets are dropped. The length of backlog
  297. # determines queue latency in case of congestion.
  298. #
  299. # PEAK=<speed> optional, default not set
  300. #
  301. # Maximal peak rate for short-term burst traffic. This allows you
  302. # to control the absolute peak rate the class can send at, because
  303. # single TBF that allows 256Kbit/s would of course allow rate of
  304. # 512Kbit for half a second or 1Mbit for a quarter of second.
  305. #
  306. # MTU=<bytes> optional, default "1500"
  307. #
  308. # Maximum number of bytes that can be sent at once over the
  309. # physical medium. This parameter is required when you specify
  310. # PEAK parameter. It defaults to MTU of ethernet - for other
  311. # media types you might want to change it.
  312. #
  313. # Note: Setting TBF as leaf qdisc will effectively prevent the class from
  314. # borrowing bandwidth from the ancestor class, because even if the
  315. # class allows more traffic to pass through, it is then shaped to
  316. # conform to TBF.
  317. #
  318. ### SFQ qdisc parameters
  319. #
  320. # The SFQ queueing discipline is a cheap way for sharing class bandwidth
  321. # among several hosts. As it is stochastic, the fairness is approximate but
  322. # it will do the job in most cases. If you want real fairness, you should
  323. # probably use WRR (weighted round robin) or WFQ queueing disciplines. Note
  324. # that SFQ does not do any traffic shaping - the shaping is done by the CBQ
  325. # class the SFQ is attached to.
  326. #
  327. # QUANTUM=<bytes> optional, default not set
  328. #
  329. # This parameter should not be set lower than link MTU, for ethernet
  330. # it is 1500b, or (with MAC header) 1514b which is the value used
  331. # in Alexey Kuznetsov's examples.
  332. #
  333. # PERTURB=<seconds> optional, default "10"
  334. #
  335. # Period of hash function perturbation. If unset, hash reconfiguration
  336. # will never take place which is what you probably don't want. The
  337. # default value of 10 seconds is probably a good one.
  338. #
  339. ### Filter parameters
  340. #
  341. # RULE=[[saddr[/prefix]][:port[/mask]],][daddr[/prefix]][:port[/mask]]
  342. #
  343. # These parameters make up "u32" filter rules that select traffic for
  344. # each of the classes. You can use multiple RULE fields per config.
  345. #
  346. # The optional port mask should only be used by advanced users who
  347. # understand how the u32 filter works.
  348. #
  349. # Some examples:
  350. #
  351. # RULE=10.1.1.0/24:80
  352. # selects traffic going to port 80 in network 10.1.1.0
  353. #
  354. # RULE=10.2.2.5
  355. # selects traffic going to any port on single host 10.2.2.5
  356. #
  357. # RULE=10.2.2.5:20/0xfffe
  358. # selects traffic going to ports 20 and 21 on host 10.2.2.5
  359. #
  360. # RULE=:25,10.2.2.128/26:5000
  361. # selects traffic going from anywhere on port 50 to
  362. # port 5000 in network 10.2.2.128
  363. #
  364. # RULE=10.5.5.5:80,
  365. # selects traffic going from port 80 of single host 10.5.5.5
  366. #
  367. #
  368. #
  369. # REALM=[srealm,][drealm]
  370. #
  371. # These parameters make up "route" filter rules that classify traffic
  372. # according to packet source/destination realms. For information about
  373. # realms, see Alexey Kuznetsov's IP Command Reference. This script
  374. # does not define any realms, it justs builds "tc filter" commands
  375. # for you if you need to classify traffic this way.
  376. #
  377. # Realm is either a decimal number or a string referencing entry in
  378. # /etc/iproute2/rt_realms (usually).
  379. #
  380. # Some examples:
  381. #
  382. # REALM=russia,internet
  383. # selects traffic going from realm "russia" to realm "internet"
  384. #
  385. # REALM=freenet,
  386. # selects traffic going from realm "freenet"
  387. #
  388. # REALM=10
  389. # selects traffic going to realm 10
  390. #
  391. #
  392. #
  393. # MARK=<mark>
  394. #
  395. # These parameters make up "fw" filter rules that select traffic for
  396. # each of the classes accoring to firewall "mark". Mark is a decimal
  397. # number packets are tagged with if firewall rules say so. You can
  398. # use multiple MARK fields per config.
  399. #
  400. #
  401. # Note: Rules for different filter types can be combined. Attention must be
  402. # paid to the priority of filter rules, which can be set below using
  403. # PRIO_{RULE,MARK,REALM} variables.
  404. #
  405. ### Time ranging parameters
  406. #
  407. # TIME=[<dow>,<dow>, ...,<dow>/]<from>-<till>;<rate>/<weight>[/<peak>]
  408. # TIME=0,1,2,5/18:00-06:00;256Kbit/25Kbit
  409. # TIME=60123/18:00-06:00;256Kbit/25Kbit
  410. # TIME=18:00-06:00;256Kbit/25Kbit
  411. #
  412. # This parameter allows you to differentiate the class bandwidth
  413. # throughout the day. You can specify multiple TIME parameters, if
  414. # the times overlap, last match is taken. The fields <rate>, <weight>
  415. # and <peak> correspond to parameters RATE, WEIGHT and PEAK (which
  416. # is optional and applies to TBF leaf qdisc only).
  417. #
  418. # You can also specify days of week when the TIME rule applies. <dow>
  419. # is numeric, 0 corresponds to sunday, 1 corresponds to monday, etc.
  420. #
  421. ###
  422. #
  423. # Sample configuration file: cbq-1280.My_first_shaper
  424. #
  425. # --------------------------------------------------------------------------
  426. # DEVICE=eth0,10Mbit,1Mbit
  427. # RATE=128Kbit
  428. # WEIGHT=10Kbit
  429. # PRIO=5
  430. # RULE=192.128.1.0/24
  431. # --------------------------------------------------------------------------
  432. #
  433. # The configuration says that we will control traffic on 10Mbit ethernet
  434. # device eth0 and the traffic going to network 192.168.1.0 will be
  435. # processed with priority 5 and shaped to rate of 128Kbit.
  436. #
  437. # Note that you can control outgoing traffic only. If you want to control
  438. # traffic in both directions, you must set up CBQ for both interfaces.
  439. #
  440. # Consider the following example:
  441. #
  442. # +---------+ 192.168.1.1
  443. # BACKBONE -----eth0-| linux |-eth1------*-[client]
  444. # +---------+
  445. #
  446. # Imagine you want to shape traffic from backbone to the client to 28Kbit
  447. # and traffic in the opposite direction to 128Kbit. You need to setup CBQ
  448. # on both eth0 and eth1 interfaces, thus you need two config files:
  449. #
  450. # cbq-028.backbone-client
  451. # --------------------------------------------------------------------------
  452. # DEVICE=eth1,10Mbit,1Mbit
  453. # RATE=28Kbit
  454. # WEIGHT=2Kbit
  455. # PRIO=5
  456. # RULE=192.168.1.1
  457. # --------------------------------------------------------------------------
  458. #
  459. # cbq-128.client-backbone
  460. # --------------------------------------------------------------------------
  461. # DEVICE=eth0,10Mbit,1Mbit
  462. # RATE=128Kbit
  463. # WEIGHT=10Kbit
  464. # PRIO=5
  465. # RULE=192.168.1.1,
  466. # --------------------------------------------------------------------------
  467. #
  468. # Pay attention to comma "," in the RULE field - it denotes source address!
  469. #
  470. # Enjoy.
  471. #
  472. #############################################################################
  473.  
  474. export LC_ALL=C
  475.  
  476. ### Command locations
  477. TC=/sbin/tc
  478. IP=/sbin/ip
  479. MP=/sbin/modprobe
  480.  
  481. ### Default filter priorities (must be different)
  482. PRIO_RULE_DEFAULT=${PRIO_RULE:-100}
  483. PRIO_MARK_DEFAULT=${PRIO_MARK:-200}
  484. PRIO_REALM_DEFAULT=${PRIO_REALM:-300}
  485.  
  486. ### Default CBQ_PATH & CBQ_CACHE settings
  487. CBQ_PATH=${CBQ_PATH:-/etc/sysconfig/cbq}
  488. CBQ_CACHE=${CBQ_CACHE:-/var/cache/cbq.init}
  489.  
  490. ### Uncomment to enable logfile for debugging
  491. #CBQ_DEBUG="/var/run/cbq-$1"
  492.  
  493. ### Modules to probe for. Uncomment the last CBQ_PROBE
  494. ### line if you have QoS support compiled into kernel
  495. CBQ_PROBE="sch_cbq sch_tbf sch_sfq sch_prio"
  496. CBQ_PROBE="$CBQ_PROBE cls_fw cls_u32 cls_route"
  497. #CBQ_PROBE=""
  498.  
  499. ### Keywords required for qdisc & class configuration
  500. CBQ_WORDS="DEVICE|RATE|WEIGHT|PRIO|PARENT|LEAF|BOUNDED|ISOLATED"
  501. CBQ_WORDS="$CBQ_WORDS|PRIO_MARK|PRIO_RULE|PRIO_REALM|BUFFER"
  502. CBQ_WORDS="$CBQ_WORDS|LIMIT|PEAK|MTU|QUANTUM|PERTURB"
  503.  
  504.  
  505. #############################################################################
  506. ############################# SUPPORT FUNCTIONS #############################
  507. #############################################################################
  508.  
  509. ### Get list of network devices
  510. cbq_device_list () {
  511. ip link show| sed -n "/^[0-9]/ \
  512. { s/^[0-9]\+: \([a-z0-9._]\+\)[:@].*/\1/; p; }"
  513. } # cbq_device_list
  514.  
  515.  
  516. ### Remove root class from device $1
  517. cbq_device_off () {
  518. tc qdisc del dev $1 root 2> /dev/null
  519. } # cbq_device_off
  520.  
  521.  
  522. ### Remove CBQ from all devices
  523. cbq_off () {
  524. for dev in `cbq_device_list`; do
  525. cbq_device_off $dev
  526. done
  527. } # cbq_off
  528.  
  529.  
  530. ### Prefixed message
  531. cbq_message () {
  532. echo -e "**CBQ: $@"
  533. } # cbq_message
  534.  
  535. ### Failure message
  536. cbq_failure () {
  537. cbq_message "$@"
  538. exit 1
  539. } # cbq_failure
  540.  
  541. ### Failure w/ cbq-off
  542. cbq_fail_off () {
  543. cbq_message "$@"
  544. cbq_off
  545. exit 1
  546. } # cbq_fail_off
  547.  
  548.  
  549. ### Convert time to absolute value
  550. cbq_time2abs () {
  551. local min=${1##*:}; min=${min##0}
  552. local hrs=${1%%:*}; hrs=${hrs##0}
  553. echo $[hrs*60 + min]
  554. } # cbq_time2abs
  555.  
  556.  
  557. ### Display CBQ setup
  558. cbq_show () {
  559. for dev in `cbq_device_list`; do
  560. [ `tc qdisc show dev $dev| wc -l` -eq 0 ] && continue
  561. echo -e "### $dev: queueing disciplines\n"
  562. tc $1 qdisc show dev $dev; echo
  563.  
  564. [ `tc class show dev $dev| wc -l` -eq 0 ] && continue
  565. echo -e "### $dev: traffic classes\n"
  566. tc $1 class show dev $dev; echo
  567.  
  568. [ `tc filter show dev $dev| wc -l` -eq 0 ] && continue
  569. echo -e "### $dev: filtering rules\n"
  570. tc $1 filter show dev $dev; echo
  571. done
  572. } # cbq_show
  573.  
  574.  
  575. ### Check configuration and load DEVICES, DEVFIELDS and CLASSLIST from $1
  576. cbq_init () {
  577. ### Get a list of configured classes
  578. CLASSLIST=`find $1 \( -type f -or -type l \) -name 'cbq-*' \
  579. -not -name '*~' -maxdepth 1 -printf "%f\n"| sort`
  580. [ -z "$CLASSLIST" ] &&
  581. cbq_failure "no configuration files found in $1!"
  582.  
  583. ### Gather all DEVICE fields from $1/cbq-*
  584. DEVFIELDS=`find $1 \( -type f -or -type l \) -name 'cbq-*' \
  585. -not -name '*~' -maxdepth 1| xargs sed -n 's/#.*//; \
  586. s/[[:space:]]//g; /^DEVICE=[^,]*,[^,]*\(,[^,]*\)\?/ \
  587. { s/.*=//; p; }'| sort -u`
  588. [ -z "$DEVFIELDS" ] &&
  589. cbq_failure "no DEVICE field found in $1/cbq-*!"
  590.  
  591. ### Check for different DEVICE fields for the same device
  592. DEVICES=`echo "$DEVFIELDS"| sed 's/,.*//'| sort -u`
  593. [ `echo "$DEVICES"| wc -l` -ne `echo "$DEVFIELDS"| wc -l` ] &&
  594. cbq_failure "different DEVICE fields for single device!\n$DEVFIELDS"
  595. } # cbq_init
  596.  
  597.  
  598. ### Load class configuration from $1/$2
  599. cbq_load_class () {
  600. CLASS=`echo $2| sed 's/^cbq-0*//; s/^\([0-9a-fA-F]\+\).*/\1/'`
  601. CFILE=`sed -n 's/#.*//; s/[[:space:]]//g; /^[[:alnum:]_]\+=[[:alnum:].,:;/*@-_]\+$/ p' $1/$2`
  602.  
  603. ### Check class number
  604. IDVAL=`/usr/bin/printf "%d" 0x$CLASS 2> /dev/null`
  605. [ $? -ne 0 -o $IDVAL -lt 2 -o $IDVAL -gt 65535 ] &&
  606. cbq_fail_off "class ID of $2 must be in range <0002-FFFF>!"
  607.  
  608. ### Set defaults & load class
  609. RATE=""; WEIGHT=""; PARENT=""; PRIO=5
  610. LEAF=tbf; BOUNDED=yes; ISOLATED=no
  611. BUFFER=10Kb/8; LIMIT=15Kb; MTU=1500
  612. PEAK=""; PERTURB=10; QUANTUM=""
  613.  
  614. PRIO_RULE=$PRIO_RULE_DEFAULT
  615. PRIO_MARK=$PRIO_MARK_DEFAULT
  616. PRIO_REALM=$PRIO_REALM_DEFAULT
  617.  
  618. eval `echo "$CFILE"| grep -E "^($CBQ_WORDS)="`
  619.  
  620. ### Require RATE/WEIGHT
  621. [ -z "$RATE" -o -z "$WEIGHT" ] &&
  622. cbq_fail_off "missing RATE or WEIGHT in $2!"
  623.  
  624. ### Class device
  625. DEVICE=${DEVICE%%,*}
  626. [ -z "$DEVICE" ] && cbq_fail_off "missing DEVICE field in $2!"
  627.  
  628. BANDWIDTH=`echo "$DEVFIELDS"| sed -n "/^$DEVICE,/ \
  629. { s/[^,]*,\([^,]*\).*/\1/; p; q; }"`
  630.  
  631. ### Convert to "tc" options
  632. PEAK=${PEAK:+peakrate $PEAK}
  633. PERTURB=${PERTURB:+perturb $PERTURB}
  634. QUANTUM=${QUANTUM:+quantum $QUANTUM}
  635.  
  636. [ "$BOUNDED" = "no" ] && BOUNDED="" || BOUNDED="bounded"
  637. [ "$ISOLATED" = "yes" ] && ISOLATED="isolated" || ISOLATED=""
  638. } # cbq_load_class
  639.  
  640.  
  641. #############################################################################
  642. #################################### INIT ###################################
  643. #############################################################################
  644.  
  645. ### Check for presence of ip-route2 in usual place
  646. [ -x $TC -a -x $IP ] ||
  647. cbq_failure "ip-route2 utilities not installed or executable!"
  648.  
  649.  
  650. ### ip/tc wrappers
  651. if [ "$1" = "compile" ]; then
  652. ### no module probing
  653. CBQ_PROBE=""
  654.  
  655. ip () {
  656. $IP "$@"
  657. } # ip
  658.  
  659. ### echo-only version of "tc" command
  660. tc () {
  661. echo "$TC $@"
  662. } # tc
  663.  
  664. elif [ -n "$CBQ_DEBUG" ]; then
  665. echo -e "# `date`" > $CBQ_DEBUG
  666.  
  667. ### Logging version of "ip" command
  668. ip () {
  669. echo -e "\n# ip $@" >> $CBQ_DEBUG
  670. $IP "$@" 2>&1 | tee -a $CBQ_DEBUG
  671. } # ip
  672.  
  673. ### Logging version of "tc" command
  674. tc () {
  675. echo -e "\n# tc $@" >> $CBQ_DEBUG
  676. $TC "$@" 2>&1 | tee -a $CBQ_DEBUG
  677. } # tc
  678. else
  679. ### Default wrappers
  680.  
  681. ip () {
  682. $IP "$@"
  683. } # ip
  684.  
  685. tc () {
  686. $TC "$@"
  687. } # tc
  688. fi # ip/tc wrappers
  689.  
  690.  
  691. case "$1" in
  692.  
  693. #############################################################################
  694. ############################### START/COMPILE ###############################
  695. #############################################################################
  696.  
  697. start|compile)
  698.  
  699. ### Probe QoS modules (start only)
  700. for module in $CBQ_PROBE; do
  701. $MP $module || cbq_failure "failed to load module $module"
  702. done
  703.  
  704. ### If we are in compile/nocache/logging mode, don't bother with cache
  705. if [ "$1" != "compile" -a "$2" != "nocache" -a -z "$CBQ_DEBUG" ]; then
  706. VALID=1
  707.  
  708. ### validate the cache
  709. [ "$2" = "invalidate" -o ! -f $CBQ_CACHE ] && VALID=0
  710. if [ $VALID -eq 1 ]; then
  711. [ `find $CBQ_PATH -maxdepth 1 -newer $CBQ_CACHE| \
  712. wc -l` -gt 0 ] && VALID=0
  713. fi
  714.  
  715. ### compile the config if the cache is invalid
  716. if [ $VALID -ne 1 ]; then
  717. $0 compile > $CBQ_CACHE ||
  718. cbq_fail_off "failed to compile CBQ configuration!"
  719. fi
  720.  
  721. ### run the cached commands
  722. exec /bin/sh $CBQ_CACHE 2> /dev/null
  723. fi
  724.  
  725. ### Load DEVICES, DEVFIELDS and CLASSLIST
  726. cbq_init $CBQ_PATH
  727.  
  728.  
  729. ### Setup root qdisc on all configured devices
  730. for dev in $DEVICES; do
  731. ### Retrieve device bandwidth and, optionally, weight
  732. DEVTEMP=`echo "$DEVFIELDS"| sed -n "/^$dev,/ { s/$dev,//; p; q; }"`
  733. DEVBWDT=${DEVTEMP%%,*}; DEVWGHT=${DEVTEMP##*,}
  734. [ "$DEVBWDT" = "$DEVWGHT" ] && DEVWGHT=""
  735.  
  736. ### Device bandwidth is required
  737. if [ -z "$DEVBWDT" ]; then
  738. cbq_message "could not determine bandwidth for device $dev!"
  739. cbq_failure "please set up the DEVICE fields properly!"
  740. fi
  741.  
  742. ### Check if the device is there
  743. ip link show $dev &> /dev/null ||
  744. cbq_fail_off "device $dev not found!"
  745.  
  746. ### Remove old root qdisc from device
  747. cbq_device_off $dev
  748.  
  749.  
  750. ### Setup root qdisc + class for device
  751. tc qdisc add dev $dev root handle 1 cbq \
  752. bandwidth $DEVBWDT avpkt 1000 cell 8
  753.  
  754. ### Set weight of the root class if set
  755. [ -n "$DEVWGHT" ] &&
  756. tc class change dev $dev root cbq weight $DEVWGHT allot 1514
  757.  
  758. [ "$1" = "compile" ] && echo
  759. done # dev
  760.  
  761.  
  762. ### Setup traffic classes
  763. for classfile in $CLASSLIST; do
  764. cbq_load_class $CBQ_PATH $classfile
  765.  
  766. ### Create the class
  767. tc class add dev $DEVICE parent 1:$PARENT classid 1:$CLASS cbq \
  768. bandwidth $BANDWIDTH rate $RATE weight $WEIGHT prio $PRIO \
  769. allot 1514 cell 8 maxburst 20 avpkt 1000 $BOUNDED $ISOLATED ||
  770. cbq_fail_off "failed to add class $CLASS with parent $PARENT on $DEVICE!"
  771.  
  772. ### Create leaf qdisc if set
  773. if [ "$LEAF" = "tbf" ]; then
  774. tc qdisc add dev $DEVICE parent 1:$CLASS handle $CLASS tbf \
  775. rate $RATE buffer $BUFFER limit $LIMIT mtu $MTU $PEAK
  776. elif [ "$LEAF" = "sfq" ]; then
  777. tc qdisc add dev $DEVICE parent 1:$CLASS handle $CLASS sfq \
  778. $PERTURB $QUANTUM
  779. fi
  780.  
  781.  
  782. ### Create fw filter for MARK fields
  783. for mark in `echo "$CFILE"| sed -n '/^MARK/ { s/.*=//; p; }'`; 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 `echo "$CFILE"| sed -n '/^REALM/ { s/.*=//; p; }'`; 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 `echo "$CFILE"| sed -n '/^RULE/ { s/.*=//; p; }'`; 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.  
  863. ### Load DEVICES, DEVFIELDS and CLASSLIST
  864. cbq_init $CBQ_PATH
  865.  
  866. ### Run through all classes
  867. for classfile in $CLASSLIST; do
  868. ### Gather all TIME rules from class config
  869. TIMESET=`sed -n 's/#.*//; s/[[:space:]]//g; /^TIME/ { s/.*=//; p; }' \
  870. $CBQ_PATH/$classfile`
  871. [ -z "$TIMESET" ] && continue
  872.  
  873. MATCH=0; CHANGE=0
  874. for timerule in $TIMESET; do
  875. TIME_ABS=`cbq_time2abs $TIME_NOW`
  876.  
  877. ### Split TIME rule to pieces
  878. TIMESPEC=${timerule%%;*}; PARAMS=${timerule##*;}
  879. WEEKDAYS=${TIMESPEC%%/*}; INTERVAL=${TIMESPEC##*/}
  880. BEG_TIME=${INTERVAL%%-*}; END_TIME=${INTERVAL##*-}
  881.  
  882. ### Check the day-of-week (if present)
  883. [ "$WEEKDAYS" != "$INTERVAL" -a \
  884. -n "${WEEKDAYS##*$TIME_DOW*}" ] && continue
  885.  
  886. ### Compute interval boundaries
  887. BEG_ABS=`cbq_time2abs $BEG_TIME`
  888. END_ABS=`cbq_time2abs $END_TIME`
  889.  
  890. ### Midnight wrap fixup
  891. if [ $BEG_ABS -gt $END_ABS ]; then
  892. [ $TIME_ABS -le $END_ABS ] &&
  893. TIME_ABS=$[TIME_ABS + 24*60]
  894.  
  895. END_ABS=$[END_ABS + 24*60]
  896. fi
  897.  
  898. ### If the time matches, remember params and set MATCH flag
  899. if [ $TIME_ABS -ge $BEG_ABS -a $TIME_ABS -lt $END_ABS ]; then
  900. TMP_RATE=${PARAMS%%/*}; PARAMS=${PARAMS#*/}
  901. TMP_WGHT=${PARAMS%%/*}; TMP_PEAK=${PARAMS##*/}
  902.  
  903. [ "$TMP_PEAK" = "$TMP_WGHT" ] && TMP_PEAK=""
  904. TMP_PEAK=${TMP_PEAK:+peakrate $TMP_PEAK}
  905.  
  906. MATCH=1
  907. fi
  908. done ### timerule
  909.  
  910.  
  911. cbq_load_class $CBQ_PATH $classfile
  912.  
  913. ### Get current RATE of CBQ class
  914. RATE_NOW=`tc class show dev $DEVICE| sed -n \
  915. "/cbq 1:$CLASS / { s/.*rate //; s/ .*//; p; q; }"`
  916. [ -z "$RATE_NOW" ] && continue
  917.  
  918. ### Time interval matched
  919. if [ $MATCH -ne 0 ]; then
  920.  
  921. ### Check if there is any change in class RATE
  922. if [ "$RATE_NOW" != "$TMP_RATE" ]; then
  923. NEW_RATE="$TMP_RATE"
  924. NEW_WGHT="$TMP_WGHT"
  925. NEW_PEAK="$TMP_PEAK"
  926. CHANGE=1
  927. fi
  928.  
  929. ### Match not found, reset to default RATE if necessary
  930. elif [ "$RATE_NOW" != "$RATE" ]; then
  931. NEW_WGHT="$WEIGHT"
  932. NEW_RATE="$RATE"
  933. NEW_PEAK="$PEAK"
  934. CHANGE=1
  935. fi
  936.  
  937. ### If there are no changes, go for next class
  938. [ $CHANGE -eq 0 ] && continue
  939.  
  940. ### Replace CBQ class
  941. tc class replace dev $DEVICE classid 1:$CLASS cbq \
  942. bandwidth $BANDWIDTH rate $NEW_RATE weight $NEW_WGHT prio $PRIO \
  943. allot 1514 cell 8 maxburst 20 avpkt 1000 $BOUNDED $ISOLATED
  944.  
  945. ### Replace leaf qdisc (if any)
  946. if [ "$LEAF" = "tbf" ]; then
  947. tc qdisc replace dev $DEVICE handle $CLASS tbf \
  948. rate $NEW_RATE buffer $BUFFER limit $LIMIT mtu $MTU $NEW_PEAK
  949. fi
  950.  
  951. cbq_message "$TIME_NOW: class $CLASS on $DEVICE changed rate ($RATE_NOW -> $NEW_RATE)"
  952. done ### class file
  953. ;;
  954.  
  955.  
  956. #############################################################################
  957. ################################## THE REST #################################
  958. #############################################################################
  959.  
  960. stop)
  961. cbq_off
  962. ;;
  963.  
  964. list)
  965. cbq_show
  966. ;;
  967.  
  968. stats)
  969. cbq_show -s
  970. ;;
  971.  
  972. restart)
  973. shift
  974. $0 stop
  975. $0 start "$@"
  976. ;;
  977.  
  978. *)
  979. echo "Usage: `basename $0` {start|compile|stop|restart|timecheck|list|stats}"
  980. esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement