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, | [EMAIL PROTECTED] \ / Max Laier | ICQ #67774661 X http://pf4freebsd.love2party.net/ | [EMAIL PROTECTED] / \ ASCII Ribbon Campaign | Against HTML Mail and News
pgpzkgA03wtHl.pgp
Description: PGP signature