From owner-freebsd-net@FreeBSD.ORG Mon Sep 19 03:11:14 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 258AB16A41F for ; Mon, 19 Sep 2005 03:11:14 +0000 (GMT) (envelope-from brett@lariat.org) Received: from lariat.org (lariat.net [65.122.236.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 67D1E43D45 for ; Mon, 19 Sep 2005 03:11:13 +0000 (GMT) (envelope-from brett@lariat.org) Received: from anne-o1dpaayth1.lariat.org (IDENT:ppp1000.lariat.net@lariat.net [65.122.236.2]) by lariat.org (8.9.3/8.9.3) with ESMTP id VAA27997 for ; Sun, 18 Sep 2005 21:11:08 -0600 (MDT) X-message-flag: Warning! Use of Microsoft Outlook renders your system susceptible to Internet worms. Message-Id: <6.2.3.4.2.20050918205708.08cff430@localhost> X-Mailer: QUALCOMM Windows Eudora Version 6.2.3.4 Date: Sun, 18 Sep 2005 21:11:07 -0600 To: net@freebsd.org From: Brett Glass Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; format=flowed Cc: Subject: 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: Mon, 19 Sep 2005 03:11:14 -0000 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