Bug 46564

Summary: IPFilter and IPFW processing order is not sensible>
Product: Base System Reporter: mk
Component: kernAssignee: Andre Oppermann <andre>
Status: Closed FIXED    
Severity: Affects Only Me CC: mk
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description mk 2002-12-27 23:00:19 UTC
When both ipfilter and ipfw are loaded, incoming/outgoing packets are
checked in the following order:

incoming:
-> ipfw -> ipnat -> ipfilter ->

outgoing:
-> ipfw -> ipfilter -> ipnat ->

This does not make sense - if ipfw is checked first for incoming packets,
then it should be checked last for outgoing packets, or vice versa. This
applies especially when using ipnat:
incoming packets will be seen in ipfw with an un-NAT-ed public destination
IP address, while outgoing packets will have an internal IP address as their
source. Together with ipnat, this also breaks ipfw's keep-state feature, as
it won't see the same source/destination tuplet for incoming and outgoing
packets belonging to the same connection.

Fix: 

My suggestion is to reverse the processing order in sys/netinet/ip_output.c
so ipfw gets checked before ipfilter. That would at least provide consistent
behaviour.
An even better solution would be to make the processing order configurable,
preferably with a sysctl.
How-To-Repeat: Use both ipfilter and ipfw at the same time and observe the order in which
they get checked for incoming and outgoing packets (try using ipnat, too).
Comment 1 mk 2002-12-27 23:13:03 UTC
SORRY, I confused the ordering - the description is wrong! Actually, at the
moment, ipfilter is always checked BEFORE ipfw for both incoming and
outgoing packets, so the order really is:

incoming:
-> ipnat -> ipfilter -> ipfw

outgoing:
-> ipfilter -> ipnat -> ipfw

The problem is still the same (outgoing packets are seen with a public
source IP address, incoming packets will have a private/internal destination
address when used with ipnat), and the fix is correct.
Comment 2 Johan Karlsson freebsd_committer freebsd_triage 2003-05-06 21:02:05 UTC
Responsible Changed
From-To: freebsd-bugs->ipfw

Over to ipfw maintainers who will hopefully know 
if this is the correct solution.
Comment 3 Johan Karlsson freebsd_committer freebsd_triage 2003-05-06 22:09:41 UTC
Adding to the audit-trail.

----- Forwarded message from Pawel Malachowski <pawmal@unia.3lo.lublin.pl> -----

From: "Pawel Malachowski" <pawmal@unia.3lo.lublin.pl>
To: johan@FreeBSD.org, freebsd-bugs@FreeBSD.org, ipfw@FreeBSD.org
Subject: Re: kern/46564: IPFilter and IPFW processing order is not sensible>
Date: 	Tue, 06 May 2003 22:47:21 +0200

Hello,

	Here is some example:

(private IPs)LAN---(fxp1)BOX(fxp0)---Internet

There are:
. dummynet running on fxp0
. ipnat running on fxp0

Right now outgoing packets on fxp0 go through ipnat and then through
dummynet. It is not possible to shape this traffic on per-user
basis (for example with src-ip mask) cause after ipnatting all packets
have the same source IP. Possible sollutions are:
. use dummynet on fxp0
	This is not so good idea if I have a huge number of
	local NICs and subnets cause I have to make exceptions
	(ipfw skip) for local traffic.
	It is very easy and natural to use dummynet on fxp0
	interface for bandwith limitaion of `Internet' traffic.
. use natd instead of ipnat
	Sucessfully tested, but I simply prefer ipnat. :)

So, probably packets flow should be:
	incoming: IPFilter -> IPFW
	outgoing: IPFW -> IPFilter

This code is `for private use' and is quite bad but does that (4.8):
http://unia.3lo.lublin.pl/~pawmal/freebsd/ip_output-ipfw-ipf.diff

I know submitter tried something similar on his own, too.

However, allowing user to decide about order (using sysctls?) would
be the best solution.


regards,
-- 
Pawel Malachowski

----- End forwarded message -----

-- 
Johan Karlsson		mailto:johan@FreeBSD.org
Comment 4 Andre Oppermann freebsd_committer freebsd_triage 2004-08-24 19:01:21 UTC
Responsible Changed
From-To: ipfw->andre

Take over.
Comment 5 Andre Oppermann freebsd_committer freebsd_triage 2004-08-24 19:01:47 UTC
State Changed
From-To: open->closed

The behaviour will not be changed for FreeBSD 4.x because the change is too 
intrusive.  Running ipfilter and ipfw is officially not supported.  In 5.3 
ipfw has been converted to use the PFIL_HOOKS as well and here the order 
will be observed.  The first loaded packet filter will get the packet first 
on input and last on output.