Possible infinite loop with ipfw and kernel nat

Hello!

First of all, I'm new to this forum, so nice to meet you all.

I've recently (re-)discovered (the hard way) that it's possible to freeze a fbsd FreeBSD box with stateful ipfw rules and kernel NAT if you're not careful enough. I tried searching for similar issues and only found a few cases that might or might not be related, so I'm posting this here.

Here's how to hang your box:
  1. Install 8.3-RELEASE (I reproduced with this one, but other could also be affected). Minimal system, GENERIC kernel.
  2. Do the following as root (IP and NIC are just an example):
    Code:
    fbsd# kldload ipfw
    fbsd# kldload ipfw_nat
    fbsd# ipfw disable one_pass
    fbsd# ipfw nat 1 config if em0
    ipfw nat 1 config if em0
    fbsd# ipfw add 10 skipto 11 tcp from any to 192.168.0.1 setup keep-state
    00010 skipto 11 tcp from any to 192.168.0.1 setup keep-state
    fbsd# ipfw add 20 nat 1 all from any to any via em0
    00020 nat 1 ip from any to any via em0
    fbsd# ipfw add 30 check-state
    00030 check-state
  3. Now we need some traffic to 192.168.0.1
    Code:
    nc -zv 192.168.0.1 80

Hard hang. Must hit reset button.

If I remember correctly, it's not possible to return the packet to a lower-numbered rule with skipto. And without rule 20 no hangs occur. But it seems that when rule 20 is in place (and with one_pass disabled), rule 30 actually applies rule 10 to the packet, which then goes again into NAT and so on indefinitely.

I know that rules in my example don't make much sense, but sometimes such patterns occur by mistake. I have a pretty complicated set of ipfw rules with NAT and Dummynet, and not so long ago a new rule with customary setup keep-state at the end took a day out of my life.

Actually, I'm not really sure if this is a bug or a case of "should've thought better with those rules". Even if latter is true, I think it's still worth mentioning somewhere in the docs.
 
Back
Top