I want to handle ip fragments in user-space, and I am using the iptables NF_QUEUE to direct packets to user-space.
The problem is that IPv4 packets are always re-assembled and delivered as one packet rather than individual fragments. For IPv6, fragments are delivered as they should.
I thought that the conntracker might be causing it and disabled it in the raw
iptables table, but it turns out that the packet is already re-assembled when it reaches the raw table:
# iptables -t raw -nvL
Chain PREROUTING (policy ACCEPT 58 packets, 62981 bytes)
pkts bytes target prot opt in out source destination
1 30028 CT all -- * * 0.0.0.0/0 10.0.0.0/24 NOTRACK
This is when sending a 30000 byte UDP packet over IPv4. The corresponding for IPv6:
# ip6tables -t raw -nvL
Chain PREROUTING (policy ACCEPT 46 packets, 62304 bytes)
pkts bytes target prot opt in out source destination
21 31016 CT all * * ::/0 1000:: NOTRACK
This is in a virtual environment kvm/qemu with virtio network devices, mtu=1500. Some HW offload does not seem to cause this, since I can see all IPv4 fragments with tcpdump -ni eth2 host 10.0.0.0
.
So my question is what in the Linux kernel can force IPv4 packets to be re-assembled before the raw/PREROUTING
netfilter chain?
I suspect "ingress/qdisc" as it is in between AF_PACKET (tcpdump) and the raw/PREROUTING chain, but I can't find the problem.
Packet flow: https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg