From owner-freebsd-ipfw Sat Jun 8 20:19:31 2002 Delivered-To: freebsd-ipfw@freebsd.org Received: from iguana.icir.org (iguana.icir.org [192.150.187.36]) by hub.freebsd.org (Postfix) with ESMTP id 2EDB737B403; Sat, 8 Jun 2002 20:19:10 -0700 (PDT) Received: (from rizzo@localhost) by iguana.icir.org (8.11.6/8.11.3) id g593J9q41863; Sat, 8 Jun 2002 20:19:09 -0700 (PDT) (envelope-from rizzo) Date: Sat, 8 Jun 2002 20:19:09 -0700 From: Luigi Rizzo To: ipfw@freebsd.org Subject: New ipfw code available Message-ID: <20020608201909.A41807@iguana.icir.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i Sender: owner-freebsd-ipfw@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG [Bcc to -current because it is relevant there as well -- sorry for the crosspost] Hi, over the past 2-3 weeks I have done an extensive rewrite of the ipfw code (userland + kernel) in an attempt to make it faster and more flexible. The idea (which I discussed a few times on the mailing lists) was to replace the current ipfw rules (macroinstructions) with a set of microinstructions, each of them performing a single operation such as matching an address, or a port range, or a protocol flag, etc. -- much in the spirit of BPF and derivatives -- and to let the userland front-end compile ipfw(8) commands into an appropriate set of microinstructions. There are several advantages in using this technique: first of all, instructions are typically shorter and faster, because the former code had to check for the presence of all the possible options in a rule, whereas the new one can simply do just the things that are required -- e.g. an instruction like allow ip from 1.2.3.0/24 to any translates to a couple of microinstructions (whose complete implementation is below the instructions themselves): O_IP_DST if (((ipfw_insn_ip *)cmd)->addr.s_addr == (dst_ip.s_addr & ((ipfw_insn_ip *)cmd)->mask.s_addr)) goto cmd_match; goto cmd_fail; O_ACCEPT: retval = 0; /* accept */ goto accept; But there is a lot more -- the instruction set is easily extensible, and without backward compatibility problems. Furthermore, you can build (and I have already implemented them) more complex rules by assembling microinstructions with OR and NOT operands. I.e. you can write something like: pipe 10 tcp from 1.2.3.4 or 1.2.3.7 or not 1.2.3.0/28 21-25,1024-4095 \ to any in recv ed0 or recv fxp1 or recv dc0 uid 35 or uid 50 You get the idea... I have a fairly complete version of the above code at the moment, which is only missing a small set of functionalities (ip/tcp flags matching, "log" and fixing hooks to the stateful code). However the glue to implement all the missing pieces is already there, it is just a matter of adding a few lines of code and testing things. Other than that, the code is meant to be fully compatible with the old syntax so you will not have to rewrite your existing rulesets. I have put a preliminary snapshot of this code (for CURRENT) at http://info.iet.unipi.it/~luigi/ipfw5.20020609.tgz It replaces the following files from a recent (2002/05/14) version of -current. sys/netinet/ip_dummynet.c sys/netinet/ip_fw.c sys/netinet/ip_fw.h sbin/ipfw/ipfw.c I would be very grateful if someone could have a look at the code, maybe give it a try, and see e.g. how it compiles your typical ruleset and whether the new extensions can make your ipfw rulesets simpler. Feedback welcome, both on the architecture and on the implementation. NOTE: if people wonder why I did not use BPF and reinvented the wheel: the keyword is "backward compatiblity" -- i thought it was a bit too complex to compile the existent ipfw syntax into BPF, especially because BPF at least as far as i know does not handle UIDs, and GIDs and interface matches and different "actions" than match or not match, so i would have had to extend the code anyways, at which point i thought I could as well write my own microinstruction set... cheers luigi -----------------------------------+------------------------------------- Luigi RIZZO, luigi@iet.unipi.it . Dip. di Ing. dell'Informazione http://www.iet.unipi.it/~luigi/ . Universita` di Pisa TEL/FAX: +39-050-568.533/522 . via Diotisalvi 2, 56126 PISA (Italy) Mobile +39-347-0373137 -----------------------------------+------------------------------------- to thanks luigi To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ipfw" in the body of the message