netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mr Dash Four <mr.dash.four@googlemail.com>
To: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Cc: netfilter@vger.kernel.org, netfilter-devel@vger.kernel.org
Subject: Re: [ANNOUNCE] ipset 6.11 released
Date: Fri, 20 Jan 2012 16:45:44 +0000	[thread overview]
Message-ID: <4F199A38.5070702@googlemail.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1201201342400.11124@blackhole.kfki.hu>


> Doable, but needs time and would involve adding the logic to auto-merge 
> smaller subnets into larger ones and to make possible to delete subnets 
> from larger networks.
>   
Merging of ip ranges would be very difficult - I am having the same 
problem here as well. I use PostgreSQL as part of my setup and even 
though it has some nice capabilities to deal with "common" ip/range/net 
address operations, it is still very difficult, nigh-impossible to deal 
with ip range merges, simply because there are so many possible 
scenarios: any two ranges could be partially overlapping - like [ (] ), 
one range completely overlapping another - like [ () ], or two ranges 
"touching" one another - like [ ]( ) - that last one is very difficult 
to spot for merging and can't see it done very easily.

Just for testing ip range matches though, things could be a bit easier 
(pun intended).

If we assume that the whole ip address space (0.0.0.0-255.255.255.255, 
similar for ipv6 as well) occupies X number of bits (0...X-1), then each 
ip range (including a single ip address) could be represented by a 
starting bit number, length (in bits) and an end bit number (the latter 
is optional, but would ease ip range matching, if included). These 3 
components would have roughly the same memory footprint no matter what 
is the size of the actual ip range.

When adding such ip range in a set, I assume you just store their hash 
(to find them quickly when searching for exact set members). If you 
could add the above 3 elements, then matching ip ranges should be fairly 
easy: you take the starting bit from the ip range which needs to be 
tested and then isolate all those elements in the set which have their 
starting bit and ending bit in-between the starting bit of the testing 
range, i.e. test_start_bit between set_member_start_bit and 
set_member_end_bit, *or*, having their ending bit also between those 
ranges (i.e. test_end_bit between set_member_start_bit and 
srt_member_end_bit). You also need to discard duplicates, so that you 
don't test more than once.

Once you've isolated those potential matches, you can then construct a 
"partial" bitmap of these potential matches by using the 3 stored set 
member attributes - starting bit, length and end bit.

Then a simple bitwise "or" ("|") operation against each "partial" set 
member bitmap matched would suffice. By "partial" I mean applying the 
"or" only on the bit-range value we are interested in. This needs to be 
done recursively, whereby the result of the previous bitwise "or" 
operation should be applied to the partial bitmap of the next set 
member, so that you get partial matches accounted for.

If the end result after this leaves you with the exact bitmap of the ip 
range being tested, then there is a complete match. If you end up with 
something different, then there is either no or incomplete match. I hope 
I am making sense.

One very simple (and very crude) example to illustrate this: suppose the 
ip range we are interested in testing has a start bit value of 10 and 
its length is 16 (therefore the end bit = 25). Now, suppose we have 4 
set members with the following values stored in the set:

1. start-> 2, length-> 6
2. start-> 13, length-> 7
3. start-> 8, length-> 8
4. start-> 20, length-> 6

The "partial" bitmap of the ip range to be tested (stat bit = 10, end 
bit = 25) could be presented like this, after being "normalised" 
(position indicates bit number, starting from 0):

.........1111111111111111

Therefore, after initial scanning, we discard element 1 as it doesn't 
have its either start or end bit in the range we are interested in (10 - 
25) and that leaves us with the following set members:

.........0001111111000000
.......111111110000000000
.........0000000000111111

When we apply bitwise or ("|") on the range we are interested in (bits 
10-25) - recursively for each member left in the pot - we are left with 
a value of all 1's for the range of bits we are interested in (bits 
10-25), which is exactly the same as the ip range we are testing, so 
there is a complete match, otherwise there would either be no or 
incomplete match.

> I'm sure you are aware, this is a free time project.
>   
I am! I am also trying to help you with this as I would benefit from 
this bug being resolved.

> Sorry, for a while you have to use workarounds like you described.
>   
Pity that!


  reply	other threads:[~2012-01-20 16:45 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-14 14:52 [ANNOUNCE] ipset 6.11 released Jozsef Kadlecsik
2012-01-15 17:16 ` Mr Dash Four
2012-01-15 17:27   ` Jozsef Kadlecsik
2012-01-15 18:05     ` Mr Dash Four
2012-01-15 20:21       ` Jozsef Kadlecsik
2012-01-15 22:38         ` Mr Dash Four
2012-01-16  8:27           ` Jozsef Kadlecsik
2012-01-18 23:53             ` Mr Dash Four
2012-01-19 11:04               ` Jozsef Kadlecsik
2012-01-19 22:00                 ` Mr Dash Four
2012-01-20 12:49                   ` Jozsef Kadlecsik
2012-01-20 16:45                     ` Mr Dash Four [this message]
2012-01-21  8:12                       ` Amos Jeffries
2012-01-21 14:07                         ` Jozsef Kadlecsik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F199A38.5070702@googlemail.com \
    --to=mr.dash.four@googlemail.com \
    --cc=kadlec@blackhole.kfki.hu \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=netfilter@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).