I'm having an issue with u32 masking

Linux Advanced Routing and Traffic Control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


_______________________________________________
LARTC mailing list
LARTC@xxxxxxxxxxxxxxx
http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc

[Index of Archives]     [LARTC Home Page]     [Netfilter]     [Netfilter Development]     [Network Development]     [Bugtraq]     [GCC Help]     [Yosemite News]     [Linux Kernel]     [Fedora Users]
  Powered by Linux