From owner-freebsd-net@FreeBSD.ORG Tue Sep 20 04:05:33 2005 Return-Path: X-Original-To: net@freebsd.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3A3C516A41F for ; Tue, 20 Sep 2005 04:05:33 +0000 (GMT) (envelope-from smithi@nimnet.asn.au) Received: from gaia.nimnet.asn.au (nimbin.lnk.telstra.net [139.130.45.143]) by mx1.FreeBSD.org (Postfix) with ESMTP id 785DB43D45 for ; Tue, 20 Sep 2005 04:05:28 +0000 (GMT) (envelope-from smithi@nimnet.asn.au) Received: from localhost (smithi@localhost) by gaia.nimnet.asn.au (8.8.8/8.8.8R1.4) with SMTP id OAA07842; Tue, 20 Sep 2005 14:04:50 +1000 (EST) (envelope-from smithi@nimnet.asn.au) Date: Tue, 20 Sep 2005 14:04:49 +1000 (EST) From: Ian Smith To: Brett Glass In-Reply-To: <6.2.3.4.2.20050919105218.07f5b0d8@localhost> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Cc: Luigi Rizzo , Jeremie Le Hen , net@freebsd.org Subject: Re: Efficient use of Dummynet pipes in IPFW X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Sep 2005 04:05:33 -0000 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