Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 8 Jun 2002 20:19:09 -0700
From:      Luigi Rizzo <>
Subject:   New ipfw code available
Message-ID:  <>

next in thread | raw e-mail | index | archive | help
[Bcc to -current because it is relevant there as well -- sorry for the

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 to any

translates to a couple of microinstructions (whose complete
implementation is below the instructions themselves):

	    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;

	    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 or or not 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

It replaces the following files from a recent (2002/05/14) version of -current.


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...

  Luigi RIZZO,  . Dip. di Ing. dell'Informazione  . Universita` di Pisa
  TEL/FAX: +39-050-568.533/522     . via Diotisalvi 2, 56126 PISA (Italy)
  Mobile   +39-347-0373137


To Unsubscribe: send mail to
with "unsubscribe freebsd-ipfw" in the body of the message

Want to link to this message? Use this URL: <>