Daniel Hartmeier wrote:

On Fri, Dec 20, 2002 at 07:11:12PM +0100, Cedric Berger wrote:


Yes, it's a valid address, but not a valid mask :)

Oh, misread the 'm->'. Hmm, it's not an invalid mask, actually, but one
pfctl can't load yet. There were a couple of requests to allow arbitrary
masks (like 0.0.0.10/0x000000ff would match *.10), and the kernel would
already deal with them, just the parser doesn't support it.

I guess even when we reserve the option to eventually support more masks
than 'the left-most n bits are set' of /n, there is a mask that nobody
ever wants to use (like 0xCAFEBABE). pfctl could check and refuse that
value, when someone tries to use it normally.

Well, the pf part is small, and it's easily verified that it doesn't
break existing behavior (as long as you don't actually use the new
tables). And, well, the new code could simply be put into a separate
source file. Doesn't increase complexity or decrease stability of the
existing code in any way, if the new tables are not actually used.

There is one change that I'm worried, it's the following in calc_skip_steps:
- PF_AEQ(&s->src.addr.addr, &r->src.addr.addr, r->af) &&
- PF_AEQ(&s->src.mask, &r->src.mask, r->af) &&
+ PF_AEQ(&s->src.addr.addr, &r->src.addr.addr, 0) &&
+ PF_AEQ(&s->src.mask, &r->src.mask, 0) &&

I'm doing that because PF_AEQ only compare the first 32 bits if
AF_INET is used, but I need that code to compare the whole pf_addr
even in the case of AF_INET, when I store a table reference in there.

Now that change could result in a missed skip-step optimization if there
are two identical AF_INET addresses loaded with a different values in
words 1-3. I've added some code in pf_ioctl to always zero words 1-3
when we load the ruleset, but I'm not sure if I've cached all occurences.

We've just added anchors to deal with large sub-rulesets, for instance I
load 12000 rules like

 block in quick on kue0 from 1.2.3.4 to any port 25
 block in quick on kue0 from 2.3.4.5/28 to any port 25
 ...

into an anchor to keep it managable.

But, of course, using a hash table to put all 12000 source
addresses/networks into a single rule would solve that significantly
better. Wouldn't obsolete the anchors, as you'd still use them for
sub-rulesets that don't just consist of simple variations like the
above.

The patricia tree idea is excellent. We talked about using a simple hash
table, but that wouldn't have allowed to store networks (just
addresses). So, do I understand that right, I can store arbitrary CIDR
blocks and the lookup with an address of a packet is still O(1)? That's
very neat.

Yes, it works exactly like the routing table, with the following additional
feature: you can enter a "negative" entry. for example, you can put the
following into the tree:

   home# pfradix -s a:a 10.0.0.0/8 '!10.0.0.0/16' 10.0.0.1

This would cause the table to match 10/8 entries which are not in 10.0/16,
but 10.0.0.1 would also match, this can be verified with "pfradix -tv":

  home# pfradix -tv a:a 10.0.0.1 10.0.0.2 10.1.0.1
    10.0.0.1 match
    10.0.0.2 nomatch
    10.1.0.1 match

Cedric


Reply via email to