Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Sep 2005 23:56:59 -0700
From:      Luigi Rizzo <rizzo@icir.org>
To:        Brett Glass <brett@lariat.org>
Cc:        net@freebsd.org
Subject:   Re: Efficient use of Dummynet pipes in IPFW
Message-ID:  <20050918235659.B60185@xorpc.icir.org>
In-Reply-To: <6.2.3.4.2.20050918205708.08cff430@localhost>; from brett@lariat.org on Sun, Sep 18, 2005 at 09:11:07PM -0600
References:  <6.2.3.4.2.20050918205708.08cff430@localhost>

next in thread | previous in thread | raw e-mail | index | archive | help
[see long original request below]

Bret, you want a block structured ipfw control language, but
ipfw is an assembly language. You have to live with that.
Your only way out is
A. write a translator from high level to low level language
   (many people do use sh scripts to generate ipfw configurations)

B. write the sequential blocks of instructions you need,
   and connect them through skipto. It can be tedious, but generally
   ipfw configurations are not so complex, _and_ when they are
   is not terribly complex to generate this through scripts.

The way i usually write things is the following:

1) do not put the action in the filtering rules: rather, put a 'skipto N'
   in the matching rules. So if there are 20 different paths that
   lead to the same action (e.g. pipe, queue, deny, icmp, whatever)
   they all end up to rule N

   This makes your life a lot easier when you need to add/remove paths,
   whereas if you hand-optimize rulesets, you might end up having to
   rewrite (and revalidate) blocks of rules just because the ipfw
   opcode syntax does not support the new configuration.

2) at rule N, do whatever processing is necessary, without any filtering:
   It could be as simple as

	ipfw pipe 12 ip from any to any

   but if you need to add more rules afterwards then you can easily do that
   without making the configuration any harder to read.

cheers
luigi

On Sun, Sep 18, 2005 at 09:11:07PM -0600, Brett Glass wrote:
> For years, we've used "Dummynet" in FreeBSD for bandwidth control. 
> Unfortunately, the semantics of IPFW can, at times, make the use of 
> Dummynet awkward and inefficient. For example, suppose you want to 
> create a set of rules that does bandwidth limiting first
> and then blocks certain ports (e.g. TCP ports 137 through 139). You 
> want to throttle first and then block ports, so that (a) blocked 
> packets count against the user's bandwidth limit and (b) a flood of 
> packets will be bandwidth-limited before it runs
> through the rest of the rules.
> 
> If net.ip.fw.one_pass is set to 0, packets emerging from a Dummynet 
> pipe or queue will re-emerge at the next rule. This is good, 
> because the packet can be passed on to the rules that block ports. 
> But there's a problem: you usually do not want to go to the next 
> rule (which is likely to be one that tests the packet to see if it 
> is to go into a different Dummynet pipe). Rather, you want the 
> packet to next be tested against a rule farther down -- after all 
> of the rules involving bandwidth limiting.
> 
> Here's an example of what I mean. Suppose you have several groups 
> of users, at IP addresses 0.0.0.1, 0.0.0.2, etc. Each group has a 
> separate pipe regulating its bandwidth consumption. You might have 
> rules like this:
> 
> # First group
> 
> ${fwcmd} pipe 1 config bw 512kbit/s
> ${fwcmd} pipe 2 config bw 512kbit/s
> 
> ${fwcmd} add pipe 1 ip from 0.0.0.0/24{55,56,57} to any in via fxp1
> ${fwcmd} add pipe 2 ip from any to 0.0.0.0/24{55,56,57} out via fxp1
> 
> # Second group
> 
> ${fwcmd} pipe 3 config bw 1024bit/s
> ${fwcmd} pipe 4 config bw 1024kbit/s
> 
> ${fwcmd} add pipe 3 ip from 0.0.0.0/24{35-40} to any in via fxp1
> ${fwcmd} add pipe 4 ip from any to 0.0.0.0/24{35-40} out via fxp1
> 
> # Filtering here
> 
> What you'd really like is to have any packet that satisfies one of 
> the "pipe" rules jump down to the filtering rules after being 
> reinjected into IPFW.
> 
> 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" 
> directive (something that's often joked about in programming 
> classes). So, what's the best way get a packet to skip past the 
> remaining bandwidth limiting rules once it was selected to go into a pipe?
> 
> --Brett Glass
> 
> _______________________________________________
> freebsd-net@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050918235659.B60185>