Re: Tc Filter - Port Ranges Calculate Mask Value
|[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]|
anshul makkar wrote:
Hi, I need to support port ranges in tc filter rules. I know how to formulate the rule but , I am not able to understand how to calculate the mask value for a perticular range so as to segregate the port values that lie within this range . I got the following sample "tc filter add dev eth1 parent 1:1 protocol ip prio 10 u32 match ip sport 0x1ae0 0x1ff0 flowid 1:10 This rule will match all ports from 6880 to 6895. " This rule correctly matches port range from 6880 to 6895. But I am unable to figure out , how the mask value has been calculated.
First you need to have a good understanding of logical operations (and specifically AND). If you do not - do some reading until you at least can give the answer to something like 0b101 & 0b100.
Once you understand this is very easy if you convert all the numbers to binary (we use 16 bits, since the port numbers are 16bit). You have:
result 0x1AE0 == 0b0001101011100000 mask 0x1FF0 == 0b0001111111110000 So what happens is: 1) u32 extracts the sport 2) ANDs the extracted value with 0b0001111111110000 3) compares the result to 0b0001101011100000 This means that anything from0b0001101011100000 to 0b0001101011101111 inclusive will result in a match (since the mask essentially strips the last 4 bits). If you convert this range back to decimal you get:
0b0001101011100000 == 6880 0b0001101011101111 == 6895
I am picking up port ranges from GUI. So the range can be any and I need to calculte mask value so as to find out which ports lie within the entered range.
Unfortunately this is impossible.As you probably noticed the range you are matching causes variation of only the last 4 bits in the entire number. The first bits always stay the same (0b000110101110xxxx). If your range is _continuous_ (i.e. without "holes" in it), and this is exactly your case - such a range _must_ be aligned so that the start has N least significant 0's and the end has N least significant 1's. What does this mean in practice:
The size of the range R must be of the form 2^N (to guarantee trailing 0's). In your case 6895 - 6880 + 1 = 16[*] which is 2^4.
The start of the range S must be larger then R and also divisible by it. In your case 6880 / 16 = 430.
Based on the above you can easily calculate the end of the range E: E = S + R - 1[*]. In your case: 6880 + 16 - 1 = 6895.You might wonder why for a continuous range the last N bits of the mask must be 0. Think of it in decimal terms: Assume we want the range of all numbers between 130 and 139. We can say - we change the last digit to 0, and we check if the number equals 130. If we want a range between 100 and 199 - no problem again. Now what if we want the range between 130 and 149? We can say - we change the last digit to 0 and check if the number equals 130 or 140. Well there - a single mask does not work :)
HTH Peter[*] You might be wondering where the +1/-1 comes from. Well take the numbers from 3 to 6 inclusive, and count how many there actually are. 6 - 3?
_______________________________________________ LARTC mailing list LARTC@xxxxxxxxxxxxxxx http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc