broken ip checksum after frag reassemble of nfs READDIR?

Max Laier max at
Wed Apr 5 12:42:13 UTC 2006

On Tuesday 04 April 2006 17:34, Daniel Hartmeier wrote:
> Ok, I found the reason for all these IP checksum problems. The reason is
> that OpenBSD's bridge code always recalculates the IP checksum, while
> FreeBSD's doesn't.
> ...
> What I missed before is in bridge_filter(), right after the pf_test()
> call:
>                 if (pf_test(dir, ifp, &m, eh) != PF_PASS)
>                         goto dropit;
>                 if (m == NULL)
>                         goto dropit;
>                 /* Rebuild the IP header */
>                 if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL))
>                         return (NULL);
>                 if (m->m_len < sizeof(struct ip))
>                         goto dropit;
>                 ip = mtod(m, struct ip *);
>                 ip->ip_sum = 0;
>                 ip->ip_sum = in_cksum(m, hlen);
> FreeBSD has no such part that I can find. Hence, when pf_test() returns
> a packet with an invalid IP checksum, nothing fixes the checksum, maybe
> except for hardware-checksumming NICs.
> Andrew, what do you suggest we do about this? Are the FreeBSD semantics
> very clear and state that the IP checksum is pfil hook's responsibility,
> and other pfil hooks (besides pf) are doing exactly that? I haven't used
> the FreeBSD bridge code with other packet filters beside pf, so I simply
> don't know.
> If pf should return only IP packets to bridge which have correct IP
> checksums already, we can either force an unconditional recomputation in
> pf's pfil hook function (which wraps pf_test()), or we can go further
> down the road of doing incremental checksum fixups whenever pf changes
> the IP header internally. Once that would be complete, OpenBSD's bridge
> could remove the unconditional checksum recomputation, too.
> But I'm not sure what's cheaper, on average, fixing up the checksum
> on each header change (there might be multiple changes per packet
> processed), or simply doing it once, unconditionally, at the end.
> Right now, we're in the suboptimal middle. pf does some incremental
> fixups, but leaves the checksum incorrect in other cases.

AFAIR, we somewhat keep track of the checksum status with csum_flags in the 
pkthdr.  We have still some 8 bit left to use if we need them, but I think we 
can express everything that might happen already.  If we did that pf (or any 
other pfil consumer) could decide if it is worth to recalculate the cksum or 
if it is something to leave to the bridge/ip_output.  If it decides to fix 
the checksum no other action is required, if it decides not to fix the 
checksum it sets a flag indicating that the checksum needs to be 
recalculated.  The bridge code would then check with the outgoing interface's 
hardware capabilities and either leave the job to the hardware or do it in 
software itself.

The other big problem that just crossed my mind:  Reassembly in the bridge 
path!?  It doesn't look like the current bridge code on either OS is ready to 
deal with packets > MTU coming out of the filter.  The question here is 
probably how much IP processing we want to do in the bridge code?

/"\  Best regards,                      | mlaier at
\ /  Max Laier                          | ICQ #67774661
 X  | mlaier at EFnet
/ \  ASCII Ribbon Campaign              | Against HTML Mail and News
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url :

More information about the freebsd-pf mailing list