high cpu usage on natd / dhcpd

Ian Smith smithi at nimnet.asn.au
Fri Feb 8 14:10:55 UTC 2013


On Thu, 7 Feb 2013 12:50:51 +0000, Eggert, Lars wrote:
 > Hi,
 >
 > On Feb 7, 2013, at 13:40, Ian Smith <smithi at nimnet.asn.au> wrote:
 > > On Thu, 7 Feb 2013 08:08:59 +0000, Eggert, Lars wrote:
 > >> On Jan 31, 2013, at 16:03, Matthew Luckie <mjl at luckie.org.nz> wrote:
 > >>> 
 > >>> 00510 allow ip from me to not me out via em1
 > >>> 00550 divert 8668 ip from any to any via em1
 > >>> 
 > >>> Rule 510 fixes it.
 > >> 
 > >> Yep, it does. Can I ask someone to commit this to rc.firewall?
 > > 
 > > The ruleset Matthew posted bears no resemblance to rc.firewall, so I 
 > > don't see that (or how) it solves any generic problem.
 > 
 > sorry for having been imprecise. What I was asking for was this change:
 > 
 > --- /usr/src/etc/rc.firewall	2012-11-17 12:36:10.000000000 +0100
 > +++ rc.firewall	2013-02-06 11:35:45.000000000 +0100
 > @@ -155,6 +155,7 @@
 >  	case ${natd_enable} in
 >  	[Yy][Ee][Ss])
 >  		if [ -n "${natd_interface}" ]; then
 > +			${fwcmd} add 49 allow ip from me to not me out via ${natd_interface}
 >  			${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface}
 >  		fi
 >  		;;

That could break the 'client' ruleset, which also includes this section, 
so to do this you may need another case for just 'open' to add that 
allow first, then the existing code for 'client' as well.  Bit messy. My 
patch made it a setup_nat() function called with or without rule number, 
so it could be used in 'simple' too, which currently lacks kernel nat.

That allows all outbound IP (4 or 6) from any address on your box (me) 
without trying to divert it via natd - which is a sensible aim for 
'open', and as julian@ has said (paraphrasing perhaps) "Never waste 
natd's time with a packet it doesn't care about", which these are.

I think you'd do better for this case to either put these few rules you 
need, including the following '65000 allow all..' into /etc/my.rules and 
set firewall_type="/etc/my.rules", or copy rc.firewall to rc.mywall, 
modify only that and set firewall_script="/etc/rc.mywall" in rc.conf ?
 
Either way you'll still get setup_loopback() and setup_ipv6_mandatory()
rules.  If it improves performance, can you instrument that at all?

 > >> (And I wonder if the rules for the ipfw kernel firewall need a 
 > >> similar addition, because the system locks up under heavy network 
 > >> load if I use that instead of natd.)

Perhaps finding the root cause of 'lock up' would be useful to pursue?

Is there any ipv6 involved with this?  Is your upstream DHCP server 
giving you an address in public or RFC1918 space?  What packet rates?

 > > Which rc.firewall ruleset are you referring to?
 > 
 > My rc.conf has:
 > 
 > 	gateway_enable="YES" 
 > 	firewall_enable="YES" 
 > 	firewall_type="OPEN" 
 > 	natd_enable="YES"
 > 	natd_interface="bce0"
 > 
 > With the patch above, that seems to work fine.
 > 
 > I tried to replace the natd_* lines with:
 > 
 > 	firewall_nat_enable="YES"
 > 	firewall_nat_interface="bce0"
 > 
 > which caused the machine to lock up under load, similar to when natd 
 > started eating CPU cycles. This made me wonder if a similar patch to 
 > the above for the firewall_nat_* case in rc.firewall might be needed.

Well it shouldn't, but maybe you've reached some load / pps limit on 
your hardware in ipfw_nat too?  Again, avoiding trying to do NAT on 
ineligible (outbound, from me) packets is not a bad idea per se.

One of the issues in outstanding PRs for /etc/rc.d/ipfw is that if you 
still have natd_enable set, it won't load the ipfw_nat module needed, ie 
you currently need to know you must disable natd when enabling ipfw_nat.

 > > I suggest following up to ipfw@ (cc'd) rather than net@
 > 
 > Will subscribe, thanks.
 > 
 > Lars

I'll leave you to pull this out of net@ if you think it best.

cheers, Ian


More information about the freebsd-ipfw mailing list