I want to allow a range of ip addresses – two /24 subnets, which don’t fall under /23. I have two options:
- Use two rules with /24 masks and
- Use single rule with
-m iprangeand specify whole range of ip’s
Which is fastest, more optimal way for performance?
In this particular case, one
iprange rule might be slightly faster than two CIDR rules, but the difference is so small it will likely be unnoticeable. Unless you’re routing multiple gigabits per second, it’s not worth trying to optimize here, and if you are, you should probably buy a purpose-built router anyway.
I recommend you use CIDR comparisons anyway, as this will be faster if you ever add disjoint ranges (and you probably will sooner or later). And it’s cleaner and easier to understand.
What’s going on here?
Let’s say you are comparing an IP address 192.0.2.87 to a network and prefix of 192.0.2.0/24. First, the prefix is used as the netmask, which is literally the 32-bit value with the bits on the network side set to 1 and on the host side set to 0. So /24 would have been written 255.255.255.0, though internally it, and the IP address and network, are stored as raw 32-bit values. (I’m ignoring endianness here as it’s not relevant to understanding how this works.)
What happens is that the IP address will be bitwise ANDed with the netmask, and the result compared to the network. If they are the same, then the IP address is within the network/prefix.
In the IP range, you need two comparisons. In this case, the IP address is first compared to the starting IP address. If it is greater or equal, we continue on and compare it to the ending IP address. If it is less or equal, we have a match.
The difference in processor time between these comparisons is negligible, especially since there’s a lot of overhead for each rule before you even get to the relevant machine language instructions which do the comparison (register loads, etc).
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.