Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Feb 1996 21:25:15 +0100
From:      Poul-Henning Kamp <phk@critter.tfs.com>
To:        hackers@freebsd.org
Subject:   IP filtering strawman, comments please.
Message-ID:  <12238.825366315@critter.tfs.com>

next in thread | raw e-mail | index | archive | help

Sorry for the wide cross-posting, followups to "hackers" only please !

		IP filtering in FreeBSD, a strawman proposal.

			       Poul-Henning Kamp

				  26 feb 1996

				   Ver: 1.1


This is a strawman intended to foster discussion about the future support
for IP packet filtering in the FreeBSD kernel.

Fig 1 shows a simplified schematic of the paths of IP packets in the
FreeBSD kernel, and various potential spots for applying filters.

===========================================================================

if0 --->(0i)--->+
                |
if1 --->(1i)--->+
                |              applications 
if2 --->(2i)--->+		     ^
                |                    |
                |                    v
                +--->(A)--->   protocol stack  --->(B)--->+
                |                                         |
                +--->(Ci)--->  route through ---->(Co)--->+
                                                          |
                                                          +--->(0o)---> if0
                                                          |
                                                          +--->(1o)---> if1
                                                          |
                                                          +--->(2o)---> if2

== Fig 1 ==================================================================

The present support (as of 960226) provides the following support:

	There is one chain of rules, and it is applied at (A), (B), (Ci)
	and (Co).  The following information is available, in addition
	to the packet itself:  At (A) and (Ci), receiving interface. 
	At (B) and (Co), destination interface.

Now, this is clearly not optimal from particular many points, therefore
I suggest the following model instead:

	There will be multiple chains of rules as follows:
	
		For each interface, two chains of rules.  One filters
		incoming packets, the other outgoing packets.  In Fig 1
		these are the pairs (0i/0o), (1i/1o) &c.  No information
		is available apart from the packet itself.

		There will be a filter-chain at (A) to filter what packets
		we let into the local protocol stack.  In addition to the
		packet, information about the arrival interface is available.

		There will be a filter-chain at (B) to filter what packets
		we let out of the local protocol stack.  In addition to the
		packet, information about the destination interface is 
		available.

		There will be two filter-chains at (Ci) and (Co) to filter
		what packets we route through this machine.  At (Ci) the
		arrival interface is known and at (Co) the destination 
		interface is known in addition to the packet itself.

	Rules are numbered with 16 bit integers, and can appear on any
	number of filter-chains, such that a conceptual matrix is formed,
	as illustrated in Fig 2:

===========================================================================

Rule#	criteria				0i 1i 2i A Ci Co B 0o 1o 2o
---------------------------------------------------------------------------
00010	Deny all loose source route		 X  X  X         X
00020   Deny all strict source route		 X  X  X         X
00030   Deny all traffic via if0		           X  X
00040   Deny all tcp setup packets				      X  X
65535   Allow all traffic			 X  X  X X X  X  X X  X  X
== Fig 2 ==================================================================

	At each filtering point, the rules are applied in numeric order,
	until one of them matches the packet, the action from that rule
	is then taken.

Just as important as where a rule can be applied, is what the rule can
express, I suggest this functionality, this is more or less what we have
now as well:

	Source-ip matches target+netmask
	Destination-ip matches target+netmask
	Protocol matches (any, udp, icmp, tcp, other).
	Packet has (not) ip-option(s) (loose source route, strict source route, 
		timestamp, record route, other).
	Interface matches name
	Interface matches IP.
	For UDP & TCP:
		source-port matches target(-range)
		destination-port matches target(-range)
	For TCP:
		packet has (not) TCP flags (syn, rst, psh, urg, ack).
	Packet is (not) a non-initial fragment.
	Packet is (not) a broadcast.
	Packet is (not) a multicast.

And finally, what should be done when the rule matches:

	"drop" the packet is discarded.
	"refuse" as drop, but an ICMP packet is sent if applicable.
	"pass" the packet is OK and continues it's merry way.
	"count" the counters for this rule is updated, but the rule doesn't
		match the packet, and the next rule is tried.
	"divert" the packet is sent to a (specific) instance of the tun#
		interface, where a user-mode process can have fun with it.

Some modifiers to this exist:
	"printf" register the match with printf.
	"syslog" register the match with syslog.
	"verbose" be very detailed.
	"hexdump" be very very detailed.

The changes to the code to support this scheme are rather simple:
	Add reference counts to each rule.
	Add two rule-chain headers to the if structure.
	Add the logic to specify what chains a rule applies to.
	Make sure ip_output knows if the packet was locally generated
	or routed.

Comments ?

Poul-Henning



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