From owner-freebsd-net@FreeBSD.ORG Sat Aug 2 12:55:11 2008 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0891E1065670 for ; Sat, 2 Aug 2008 12:55:11 +0000 (UTC) (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 CD2FB8FC16 for ; Sat, 2 Aug 2008 12:55:07 +0000 (UTC) (envelope-from smithi@nimnet.asn.au) Received: from localhost (smithi@localhost) by gaia.nimnet.asn.au (8.8.8/8.8.8R1.5) with SMTP id WAA11611; Sat, 2 Aug 2008 22:54:38 +1000 (EST) (envelope-from smithi@nimnet.asn.au) Date: Sat, 2 Aug 2008 22:54:37 +1000 (EST) From: Ian Smith To: Mike Makonnen In-Reply-To: <4892E735.1000105@wubethiopia.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Cc: Patrick Tracanelli , freebsd-net@freebsd.org Subject: Re: Application layer classifier for 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: Sat, 02 Aug 2008 12:55:11 -0000 On Fri, 1 Aug 2008, Mike Makonnen wrote: > Patrick Tracanelli wrote: > > Mike Makonnen escreveu: > >> Hi, > >> > >> An Internet Cafe I do some work for was recently having problems with > >> very slow internet access. It turns out customers were running P2P > >> file sharing applications which were hogging all the bandwidth. I > >> looked for programs that would allow me to shape traffic according > >> to the application layer protocol, but couldn't find any for FreeBSD. > >> I found a couple: l7-filter and ipp2p, but these are Linux specific. > >> So, I decided to write one. The result is ipfw-classifyd : > >> http://people.freebsd.org/~mtm/ipfw-classifyd.tar.bz2 This is great, Mike. I've been 'waiting for this' for a very similar situation for months now, getting by with dummynet bandwidth limiting and wondering about weighted queuing, but this is a much sharper tool. > >> As the name implies it uses ipfw(4) to implement a userland daemon > >> that classifies TCP and UDP packets according to regular expression > >> patterns for various protocols. It's intended to be used with > >> divert(4) sockets and dummynet(4) so you can do traffic shaping > >> depending on the application level protocol. The protocol patterns > >> are from the l7-filter project. Any GPL issues with using these patterns? > >> Basically, you use ipfw(8) to divert tcp/udp packets to the damon. It > >> reads its configuration file for a list of protocols and ipfw(8) > >> rules. Then, when it detects a matching session it re-injects the > >> packet back at the specified rule number. The tarball has a sample > >> configuration file and firewall script to get you started. I was confused by 'back at the specified rule number' too, especially as you used a rule 1000 in the example, being the rule handling NON matched packets. So I had a browse through the code, finding: /* * Inform divert(4) what rule to send it to by * modifying the port number of the associated sockaddr_in * structure. Note: we subtract one from the ipfw(4) rule * number because processing in ipfw(4) will start with * the next rule *after* the supplied rule number. */ if (flow->if_fwrule != 0) { pkt->fp_saddr.sin_port = flow->if_fwrule; goto enqueue; } and noticed that we weren't subtracting one .. I don't believe it's quite correct to say 'ipfw will start with the next rule after the supplied rule number'. If there were (legitimately) multiple rules having the same number (either divert rules themselves or at the target rule), the ipfw divert-return code skips past duplicates to the next rule that has a higher rule number, which may not amount to the same thing. (Sorry, Julian made me study ipfw execution behaviour months ago :) I thought at first that this behaviour is fine, and just needed a bit better describing. But I'm starting to wonder if subtracting one isn't really a better idea? > >> While I have not done extensive testing, preliminary tests are > >> encouraging and it seems to work, so I thought I'd announce it to the > >> rest of the world in case anyone else is interested in this kind of > >> application. > >> > >> Comments and suggestions highly appreciated. > >> > >> Cheers. > > > > Wont compile on RELENG_6 but is working perfectly on REL_7. I am > > trying hard with ssh, soulseek and msn. Its working like a charm with > > the suggested rc.firewall. > Can you email me the compile error? I'd like to run it on a 4.8 filtering bridge .. ah, never mind :) > > I have configured ipfw-classfyd.conf changing the rules, for a number > > of L7 patterns, and now I try to understand why the "diverted" rules > > only match if the rule number is 1 after the configured, ie, I put > > soulseek to 65530 and a rule wont match there, but the very same rule > > matches 65531. I will read the code, but it seems that reinjection of > > the packet is made +1, correct? > > > The application doesn't do that, it's the firewall that does that. > Basically, when > ipfw(4) diverts a packet to the application it includes the rule > that caused the packet to be diverted (so that when it gets it back it knows > where to continue processing from). When it gets the packet back it > continues > processing the packet at the rule *after* the one that caused it to be > diverted Rather, 'at the first rule having a higher rule number than the one ..' > (otherwise the packet would get diverted in an endless loop). In the sample > script rule 1000 is the rule that passes the packets that do not get > diverted, so > I configured ipfw-classifyd to modify the information that comes with the > packet to point to rule 1000 (in classifyd.conf). So, when ipfw(4) gets the > packet back it continues processing it at the next rule after 1000, which is > the rule that sends all diverted packets through the pipe. Yeah figuring out how rule 1000 had anything to do with it confused me at first, when any number after the divert rule/s would do. I think it may need stating really explicitly, something perhaps better put than: The rule number configured for the specified traffic type is that of the last rule number *before* the target ipfw rule for a match. Which is still harder to describe (or get one's head around) than being able to specify the desired target rule number in the config file? As long as you don't subtract one for the non-match packets reinjected normally, and do subtract one from the matching packet's config rule, so directly skipping to the specified rule, it would need an awful lot less explaining to users .. > Hope that helps. Oh yes :) Might even have to upgrade that bridge at long last. cheers, Ian