Hello again all,
I''m proud to say that with the help of a good friend and some serious
tinkering, I have finally figured out filtering within tc.
But alas, I am having an issue I know I should not be having.
I am trying to filter all IRC traffic on my network so that it neither
consumes large amounts of band width nor gets to little band width.
I originally wanted to filter just ports 6660-6669 but quickly realized
that the bit masking wouldn''t allow for a single rule to cover them, so
I opted instead to filter ports 6656-66671 which would give me the use
of all 4 bits in that range. For reference, 6656 = 0x1a00, 6671 = 0x1a0f.
As such, I have the following rules in my setup:
eth0 egress to the internet (eth0 is the external interface):
tc filter add dev eth0 parent 1: protocol ip prio 0 u32 \
match ip protocol 6 0xff \
match u16 0x1a00 0x1a0f at 22 \
flowid 1:10
eth1 egress to the LAN (eth1 is the internal interface):
tc filter add dev eth1 parent 2: protocol ip prio 0 u32 \
match ip protocol 6 0xff \
match u16 0x1a00 0x1a0f at 20 \
flowid 2:10
Now, to further verify that these bit masks do indeed work, I used a
simple C app that I have had for several years now to do the
verification. Here is the output from this C app: (Be sure to view this
in a fixed width font so that everything lines up correctly)
Start: 6655 End: 6675
6655 masked by 6671: 6159
Bit Field: 0001100111111111
Bit Mask: 0001101000001111
Bit Result: 0001100000001111
No Match!
6656 masked by 6671: 6656
Bit Field: 0001101000000000
Bit Mask: 0001101000001111
Bit Result: 0001101000000000
Match!
6657 masked by 6671: 6657
Bit Field: 0001101000000001
Bit Mask: 0001101000001111
Bit Result: 0001101000000001
Match!
6658 masked by 6671: 6658
Bit Field: 0001101000000010
Bit Mask: 0001101000001111
Bit Result: 0001101000000010
Match!
6659 masked by 6671: 6659
Bit Field: 0001101000000011
Bit Mask: 0001101000001111
Bit Result: 0001101000000011
Match!
6660 masked by 6671: 6660
Bit Field: 0001101000000100
Bit Mask: 0001101000001111
Bit Result: 0001101000000100
Match!
6661 masked by 6671: 6661
Bit Field: 0001101000000101
Bit Mask: 0001101000001111
Bit Result: 0001101000000101
Match!
6662 masked by 6671: 6662
Bit Field: 0001101000000110
Bit Mask: 0001101000001111
Bit Result: 0001101000000110
Match!
6663 masked by 6671: 6663
Bit Field: 0001101000000111
Bit Mask: 0001101000001111
Bit Result: 0001101000000111
Match!
6664 masked by 6671: 6664
Bit Field: 0001101000001000
Bit Mask: 0001101000001111
Bit Result: 0001101000001000
Match!
6665 masked by 6671: 6665
Bit Field: 0001101000001001
Bit Mask: 0001101000001111
Bit Result: 0001101000001001
Match!
6666 masked by 6671: 6666
Bit Field: 0001101000001010
Bit Mask: 0001101000001111
Bit Result: 0001101000001010
Match!
6667 masked by 6671: 6667
Bit Field: 0001101000001011
Bit Mask: 0001101000001111
Bit Result: 0001101000001011
Match!
6668 masked by 6671: 6668
Bit Field: 0001101000001100
Bit Mask: 0001101000001111
Bit Result: 0001101000001100
Match!
6669 masked by 6671: 6669
Bit Field: 0001101000001101
Bit Mask: 0001101000001111
Bit Result: 0001101000001101
Match!
6670 masked by 6671: 6670
Bit Field: 0001101000001110
Bit Mask: 0001101000001111
Bit Result: 0001101000001110
Match!
6671 masked by 6671: 6671
Bit Field: 0001101000001111
Bit Mask: 0001101000001111
Bit Result: 0001101000001111
Match!
6672 masked by 6671: 6656
Bit Field: 0001101000010000
Bit Mask: 0001101000001111
Bit Result: 0001101000000000
No Match!
6673 masked by 6671: 6657
Bit Field: 0001101000010001
Bit Mask: 0001101000001111
Bit Result: 0001101000000001
No Match!
6674 masked by 6671: 6658
Bit Field: 0001101000010010
Bit Mask: 0001101000001111
Bit Result: 0001101000000010
No Match!
6675 masked by 6671: 6659
Bit Field: 0001101000010011
Bit Mask: 0001101000001111
Bit Result: 0001101000000011
No Match!
So, as you can see, if I mask the u16 with 0x1a0f (6671), tc should
match both the source and destination port within the range of
6656-6671...but it does not. Having watched the output of "watch -d -n 1
tc -s filter show dev eth0" and "watch -d -n 1 tc -s filter show dev
eth1", and having played with the port to start checking from (IE:
0x1a0c, 0x1a0d, 0x1a0d, etc), I have come to the conclusion that TC is
ONLY matching on the original port that a gave it. It does not in fact
match on any port within the given range of ports that I provide in the
masks.
Just as a case of verifying my method, I also tried (in my C app) the
following:
6656-6675 masked by 0xfff0 (65520) - matches on ports 6656 and 6672
6656-6675 masked by 0x1a07 (6663) - matches on ports 6656-6663
I even went the extra step of verifying (most of) the bit masks by hand
(grid paper is wonderful). So, in short, I know that my bit mask is
working just fine.
Is this how tc is supposed to work? Does it only match on the value it
is given based on whether or not the mask matches? IE: u16 0x1a00 0x1a0f
at 22 (dest port 6656 ONLY), u16 0x1a0b 0x1a0f at 22 (dest port 6667 ONLY)
If so, how can you match a range of ports (in my example, or a range of
anything for that matter) in tc?
Any help is greatly appreciated.
Vadtec