Hello all, Pardon the long mail, I'll accept flames if I have irritated anybody. Here are three snippets of different ways to approach a tcng configuration. Unfortunately, I must not quite understand tcng syntax.... I could work around it, build a new kernel and so forth, but I'm curious about this behaviour of tcng. It almost strikes me as "by-design" or a feature of the language--I'd just like to understand why this is happening, and if there is a way I can solve my conundrum! Intended goal: - support nested HTB classes; top level class to limit total bandwidth, - add internal classes to limit (and isolate) certain types of traffic. - use tcng; much more readable (Thank goodness!) Working example (simpler than reality...lab/test sort of thing) has all filters attached to 1:0, and traffic is divided up roughly like this (see example): - class 1:1 HTB ( rate = ceil = 1544k ) - class 1:2 ( rate = 128k, ceil = 512k ), interactive traffic - class 1:3 ( rate = 512k, ceil = 1544k ), bulk (mail/web/scp) - class 1:4 ( rate = 128k, ceil = 768k ), default If I use the tcng class selection path construct (see Example #1), I'll need support for dsmark in my kernel, and being a lazy admin, I'd rather work around this requirement.... This was not unexpected, since Werner clearly outlined the requirement of dsmark support on this very list (if not elsewhere): http://mailman.ds9a.nl/pipermail/lartc/2002q3/004504.html If I put my classifiers in the internal classes (1:2, 1:3, 1:4) (see Example #2), then the filters are attached to parent 1:1, which means that they never get called. This is intuitive given the syntax and structure of the tcng language. My clever workaround failed miserably, however, when I tried to select all IP packets with TCP segments in class 1:1 the class closest to the root (see Example #3). I'm not sure what to make of this. My questions: - How can I nest classes with filters without using dsmark? - Am I overlooking a very simple solution? - What section of the manual should I re-read? - Anybody have an example of nested HTB classes or CBQ classes without dsmark or class selection path? Thanks in advance, -Martin # -- Example #1 class selection path; requires dsmark kernel support # #include "fields.tc" #include "ports.tc" # dev eth0 { egress { class ( <$ssh> ) if tcp_sport == 22 || ip_tos_delay == 1 ; class ( <$bulk> ) if tcp_sport == 22 || tcp_dport == 80 ; class ( <$other> ) if 1 ; htb () { class ( rate 1544kbps, ceil 1544kbps ) { $ssh = class ( rate 128kbps, ceil 512kbps ) ; $bulk = class ( rate 512kbps, ceil 1544kbps ) ; $other = class ( rate 128kbps, ceil 768kbps ) ; } } } } # # -- most output suppressed...; word wrapped/shell escaped for # readability # $ tcc lartc-example-1.tcc | grep filter | head -4 tc filter add dev eth0 parent 2:0 protocol all \ prio 1 tcindex mask 0x3 shift 0 tc filter add dev eth0 parent 2:0 protocol all \ prio 1 handle 3 tcindex classid 2:4 tc filter add dev eth0 parent 2:0 protocol all \ prio 1 handle 2 tcindex classid 2:3 tc filter add dev eth0 parent 2:0 protocol all \ prio 1 handle 1 tcindex classid 2:2 # <-- more lines of "tc filter" would have been here --> # -- Example #2; all tc filter commands attach to parent 1:1 # #include "fields.tc" #include "ports.tc" # dev eth0 { htb { class ( rate 1544kbps, ceil 1544kbps ) { class ( rate 128kbps, ceil 512kbps ) \ if tcp_dport == 22 && ip_tos_delay == 1 { sfq ( perturb 10s ); } class ( rate 512kbps, ceil 1544kbps ) \ if tcp_dport == 25 || tcp_dport == 80 { sfq ( perturb 10s ); } class ( rate 128kbps, ceil 768kbps ) { sfq ( perturb 10s ); } } } } # # -- word wrapped/shell escaped for readability # $ tcc lartc-example-2.tcc | grep filter | head -4 tc filter add dev eth0 parent 1:1 protocol all prio 1 \ handle 1:0:0 u32 divisor 1 tc filter add dev eth0 parent 1:1 protocol all prio 1 \ u32 match u8 0x6 0xff at 9 offset at 0 mask 0f00 \ shift 6 eat link 1:0:0 tc filter add dev eth0 parent 1:1 protocol all prio 1 \ handle 1:0:1 u32 ht 1:0:0 match u16 0x16 0xffff at 2 \ match u8 0x10 0x10 at 1 classid 1:2 tc filter add dev eth0 parent 1:1 protocol all prio 1 \ handle 2:0:0 u32 divisor 1 # -- Example #3; differs from #2 in line 3, "if ip_proto == IPPROTO_TCP" # only one tc filter command appears in output--filter command for # selecting IP packets with TCP segments # #include "fields.tc" #include "ports.tc" # dev eth0 { htb { class ( rate 1544kbps, ceil 1544kbps ) if ip_proto == IPPROTO_TCP { class ( rate 128kbps, ceil 512kbps ) \ if tcp_dport == 22 && ip_tos_delay == 1 { sfq ( perturb 10s ); } class ( rate 512kbps, ceil 1544kbps ) \ if tcp_dport == 25 || tcp_dport == 80 { sfq ( perturb 10s ); } class ( rate 128kbps, ceil 768kbps ) { sfq ( perturb 10s ); } } } } # # -- word wrapped/shell escaped for readability # $ tcc lartc-example-3.tcc | grep filter tc filter add dev eth0 parent 1:0 protocol all prio 1 \ u32 match u8 0x6 0xff at 9 classid 1:1 -- Martin A. Brown --- SecurePipe, Inc. --- mabrown@xxxxxxxxxxxxxx