ipfilter blocking ip fragments

For some reason ipfilter is blocking inbound fragmented ip packets (the packets are larger than the interface's MTU) that are encapsulating UDP segments. The connection works, so I know ipfilter is letting some traffic through, it is just a lot slower than it should be.

Rules that allow the traffic:

pass in quick proto udp from pool/12 to any keep state
pass in quick proto tcp from pool/12 to any keep state

Rule ipmon reports as blocking the traffic (bottom line in ipf.conf):

block in log all

Sample log entries (hostname and IPs substituted for security reasons):

Dec   9 12:31:54 hostname ipmon[14093]: [ID 123456 site.warning] 12:31:54.543987 skge0 @0:39 b 127.0.0.1 -> 127.0.0.2 PR udp len 20 (1500) (frag 12001:1480@1480+-) IN
Dec   9 12:31:54 hostname ipmon[14093]: [ID 123456 site.warning] 12:31:54.544011 skge0 @0:39 b 127.0.0.1 -> 127.0.0.2 PR udp len 20 (1500) (frag 12001:1480@2960+-) IN

I should also add that when I turn ipfilter off, the connections performance improves drastically. In the listening services log, I see a lot of NACKs sent back to the sender with the firewall on, but hardly any with it off.

Any ideas?

Well, as I recall, IP fragments have no tcp or udp header, just the 20 byte ip header that says it is a UDP or TCP fragment, so no port number to filter on. Maybe you uncovered a bug. Your packet sizes bear this out.

IP Fragmentation is not a very robust way to deal with big data, and many apps manage the packet size within the MTU to avoid it. This may be why such a defect was not previously found. Either that, or some timer on how long to wait for reassembly in the filtering process is set too low. Unlike tcp segmentation, a lost packet cost you 100% of the application block, not on average 50% max., and you still have the 65K limit waiting for you if you do not have an app level fragmenter that integrates with smart retransmission.

1 Like

I was able to solve the problem but I don't understand why or how the fix works. Removing the keep state keyword seems to allow the IP fragments through.

Well, you cannot filter fragments unless you keep state, assuming the header fragment survives and arrives first. I guess if you wanted to be nice, you would store fragments for a while or until they are validated by a header fragment, and hold header fragments for a while, but state and storage makes the firewall vulnerable.

Can you make the UDP apps use smaller packets?

I always thought they messed up in http, making it tcp based, at least until http1.1 persistent connections with compression. I thought it might be nice to add a UDP flavored brother. A small graphic file GET would be one packet out, one back, no extra for SYN or FIN or ACK. DNS makes great use of UDP, one socket for an app that, for every packet in, sends one packet out, no fork, threads, poll, select, listen, accept or such.