Visualizing Linux Traffic Control Setup
In the past six months I had to deal with Linux traffic control (TC) a lot. I was literally blown away by the advanced features of the system. Of course, the versatility comes for the usual price: complexity. I definitely do not regret the time spent on understanding the principles of classes, qdiscs, filters, major and minor numbers, etc. However, I think I have found a way to work with them more easily.
When you want to see your TC configuration in full, you normally have to list qdiscs, classes, and filters separately and mentally piece the outputs together. For example:
$ tc qdisc show dev eth0 qdisc htb 1: root r2q 10 default 10 direct_packets_stat 0 qdisc sfq 10: parent 1:10 limit 127p quantum 1514b perturb 10sec qdisc sfq 11: parent 1:11 limit 127p quantum 1514b perturb 10sec qdisc sfq 19: parent 1:19 limit 127p quantum 1514b perturb 10sec qdisc sfq 31: parent 1:31 limit 127p quantum 1514b perturb 10sec $ tc class show dev eth0 class htb 1:11 parent 1:1 leaf 11: prio 0 rate 256000bit ceil 256000bit burst 15Kb cburst 1599b class htb 1:10 parent 1:1 leaf 10: prio 0 rate 128000bit ceil 128000bit burst 15Kb cburst 1599b class htb 1:1 root rate 10000Kbit ceil 10000Kbit burst 15Kb cburst 1600b class htb 1:31 parent 1:1 leaf 31: prio 0 rate 128000bit ceil 128000bit burst 15Kb cburst 1599b class htb 1:19 parent 1:1 leaf 19: prio 0 rate 512000bit ceil 512000bit burst 15Kb cburst 1599b $ tc filter show dev eth0 filter parent 1: protocol ip pref 1 fw filter parent 1: protocol ip pref 1 fw handle 0x1 classid 1:11 filter parent 1: protocol ip pref 1 fw handle 0x9 classid 1:19 filter parent 1: protocol ip pref 1 fw handle 0x15 classid 1:31
Since there is a certain hierarchy in TC configurations, I soon found myself drawing TC setups in trees. The idea to replace paper and pencil with Graphviz came not long after. Writing a simple script that parses the output of tc and converts it into a graph turned out to be surprisingly easy. Behold the glory of 181 lines of Python that beareth the name tcviz.
Note: Actually, I found a PERL script somewhere on the net that was doing precisely the same. However, the output was dead ugly for my eye. Tweaking the script was out of question since the PERL source looked even uglier. Hence, I took owls to Athens and wrote my own piece of software. It was fun.
The above configuration can be magically translated by tcviz into this picture:
Qdiscs and classes are displayed as boxes and ellipses, respectively. Filters are represented by arrows that point from the parent to the target of the filter.
The script only generates commands for dot (a part of Graphviz). To actually generate the graph, the output of tcviz has to be passed to dot. For instance:
$ ./tcviz.py eth0 | dot -Tpng > tc.png
To display the graph without saving it, one could use display from the ImageMagick package:
$ ./tcviz.py eth0 | dot -Tpng | display
tcviz is still in early stage of development. I have only tested it with tc versions iproute2-ss060323 and iproute2-ss071016. It’s possible that the format of tc’s output is different in other versions and tcviz won’t understand it. Bug reports are welcome. I even have a vague development plan, so there might be some new features in the future (not just bug-fix releases).
Feel free to give tcviz a try. I’ll be happy to hear your opinions and suggestions.
P.S.: The best resource on TC out there is Linux Advanced Routing & Traffic Control.
11 comments Add your own…
When I try you program it gives me an error at:
[root@BuffyTheVampireSlayer tcviz-1.0]# python tcviz.py eth0 | dot -Tpng tc.png
-bash: dot: command not found
Traceback (most recent call last):
File "tcviz.py", line 12, in ?
from Node import Node
File "/var/www/html/scripts/tcviz-1.0/Node.py", line 32
self.__parent = '1:0' if self.__nodeType == 'class' else None
^
SyntaxError: invalid syntax
Do you have any ideas as to why?
This looks extremely promising. Thanks Dave:)
Hello Dave,
there seem to be two distinct errors:
-bash: dot: command not foundmeans that you don't have Graphviz installed on your system. If you're on Debian or Ubuntu, tryapt-get install graphvizto get it. Other distros will surely have the package, too.SyntaxErrorcomes from Python and seems to indicate that you have a bit outdated version of Python. The ternary operator that appears on line 32 has been introduced in Python 2.5. Try runningpython -V(that's uppercase V) to see what version of Python you have.Hope this helps,
~ Vita
There's just one MAJOR problem. It won't work in my setup. And I'm very bad at python. In fact I never took the time to learn anything about it.
So, I thought you'd be able to help understand what's wrong from the verbatim copy of ./tcviz.py run that is following right below:
nondescript:~/tcviz/tcviz-1.0# ./tcviz.py ifb0 | dot -Tpng tc.png
Traceback (most recent call last):
File "./tcviz.py", line 63, in
sys.exit(main())
File "./tcviz.py", line 29, in main
filters = parse(f, Filter)
File "./tcviz.py", line 45, in parse
object = constructor(line)
File "/root/tcviz/tcviz-1.0/Filter.py", line 23, in __init__
self.parseSpec(spec)
File "/root/tcviz/tcviz-1.0/Filter.py", line 28, in parseSpec
self.__parent = self.__idNormalizer(spec.pop(0))
File "/root/tcviz/tcviz-1.0/Node.py", line 50, in normalizeId
return (id if id[-1] != ':' else id + '0')
IndexError: string index out of range
I have "Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)"
and
nondescript:~/tcviz/tcviz-1.0# dpkg -l |grep iproute
ii iproute 20080725-2
Looking forward to your reply!
Btw BIG thanks for making this script available to everyone!
Hi Ivan,
it seems that the script is crashing on some kind of setup that I haven't thought of. Could you please send me the output of these three commands?
I hope I will be able to fix the script quickly. Thanks!
Hi,
I've got good news and bad news. The good news is that your TC setup pointed me in the direction of several bugs. These are now fixed in tcviz 1.1 (announcement, project site). The script now generates Graphviz commands correctly.
The bad news is that Graphviz (dot) is choking on a graph of this size (about 190 classes and 280 filters). I tried Graphviz 2.16 and 2.20.2. Version 2.16 just creates a large but completely blank PNG. Version 2.20 complains that the width is too large (60,267px) and then segfaults.
I'm not sure how to tackle this. Maybe Graphviz could be persuaded to stack the nodes vertically as well as horizontally, so that the width wouldn't be getting so huge. However, my knowledge of Graphviz is rather limited. I don't know how to do it or if it is indeed possible...
One of my major:minor strings contained hexadecimal numbers:
qdisc ingress ffff: parent ffff:fff1 ----------------
Node.py:setId() choked on this (actually, map() choked on this:
ValueError).
So I hacked the code to do this:
def hexint(self, value):
try:
x = int(value)
return x
except ValueError:
return int(value, 16)
def setId(self, value):
(self.__major, self.__minor) = map(self.hexint,
self.normalizeId(value).s$
You can probably so this more elegantly than I can. In any case,
thanks for the very useful code. The pictures are quite nice.
Tom
[VIII]
Hello Tom, and thanks for the report! I've (hopefully) fixed the bug in tcviz 1.2 (announcement, project site). Please let me know if you encounter any problems.
with Linux TC...
I am unable to show the output for filter in linux. Please help me any one. I am configured below rule.
"tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match ip dst 0.0.0.1/0 match ip dport 250 0xffff police rate 256kbit burst 10k drop flowid :1"
My doubt is,
Is there any problem in rule ?
or
Is there any problem in my Linux m/c?
Let me know good documents for TC.
Thanks......
Speak your mind
Allowed HTML tags are a, blockquote, em, code, li, ol, p, pre, strong, ul. Links to other comments in the form “[IV]” or “[4]” are detected automatically.