Efficient use of Dummynet pipes in IPFW
Ian Smith
smithi at nimnet.asn.au
Mon Sep 19 21:05:33 PDT 2005
On Mon, 19 Sep 2005, Brett Glass wrote:
> At 10:20 AM 9/19/2005, Luigi Rizzo wrote:
>
> >original
> >
> > ipfw add 1000 dosomething cond1 cond2 cond3 cond4 cond5 ... condN
> >
> >negated:
> >
> > ipfw add 1000 skipto 1001 cond1 cond2 cond3 cond4 cond5 ... condN
> > ipfw add 1000 dosomething
>
> This doesn't work, because you must transform cond1 && cond2 && cond3...
> into multiple rules that implement ~(cond1 || cond2 || cond3...). So,
.. later corrected? to ..
> I should have said that you must implement !(!cond1 || !cond2 || !cond3...).
That would be silly, either way. It does work. You started off saying:
| Unfortunately, because IPFW doesn't have a "not" that can cover the
| "and" of all the conditions in the rule -- that is, you can't say
| "not (ip from A to any in via fxp1)" -- it's very difficult to do
| this with a single rule containing a "skipto" action. What's more,
| there's no "resume at" clause available in IPFW that would change
| where a packet was reinjected, and no such thing as a "come from" [..]
So what Luigi says is absolutely correct for that desired negation. No,
you can't do it with a SINGLE rule; it is low level, consider it RISC.
> you'd need do do the following:
>
> ipfw add 1000 skipto 1001 not cond1
> ipfw add 1000 skipto 1001 not cond2
> ... (N rules total)
> ipfw add 1000 skipto 1001 not condN
> ipfw add 1000 dosomething
> ipfw add 1000 skipto 5000 // Where to resume on success
> ipfw add 1001 // Jump target; implemented in IPFW as "count ip from any to any"
1000 skipto 1001 cond1 cond2 cond3 .. # ie (cond1 AND cond2 AND ..)
1000 dosomethingsuchasyourpipe # performed on NOT (cond1 AND ...)
1000 skipto 5000 ip from any to any # your 'resume after pipe' ..
rule 1001, your 'jump target' will just be your next test, or the next
rule can be any number rule >= 1001. So there's extra no cost for it.
And as Luigi pointed out, skipto is fast.
> The other way to do it is via "spaghetti rules:"
>
> ipfw add 1000 skipto 1002 cond1 cond2 cond3 cond4 cond5 ... condN
> ipfw add 1001 skipto 1003
> ipfw add 1002 dosomething
> ipfw add 1002 skipto 5000 // Where to resume on success
> ipfw add 1003 // Jump target; implemented inside IPFW as "count ip from any to any"
Spaghetti like that is just not needed. See above.
> Or you can do the entire pattern match twice:
>
> ipfw add 1000 dosomething cond1 cond2 cond3 cond4 cond5 ... condN
> ipfw add 1000 skipto 5000 cond1 cond2 cond3 cond4 cond5 ... condN
I can't see your desire to save ONE rule is worth trying to convince
somebody ELSE to tackle the code for a feature only you seem to want.
And if lots of similar rulesets are needed, write a script or use the
preprocessor as suggested (the latter's beyond me, but not the former)
cheers, Ian
More information about the freebsd-net
mailing list