Is divert(4) ready for IPv6 at all??

The manpage divert(4) says this:

Code:
     Packets are received and sent unchanged, except that packets read as out-
     going have    invalid    IP header checksums, and packets written as outgoing
     have their    IP header checksums overwritten    with the correct value.     Pack-
     ets written as incoming and having    incorrect checksums will be dropped.
     Otherwise,    all header fields are unchanged    (and therefore in network or-
     der).

This is irrelevant with IPv6, since there is no IP header checksum.
But, as I am observing, the UDPv6/TCPv6 checkums are also wrong on the outgoing path (probably for the same reason: we dont yet know the interface, but might be able to offload calculation to hw).
This obviousely only applies to locally generated packets (there is no checksum change in IPv6 when gatewaying).

The problem with divert then is: when passing thru a divert socket and back from it, then on final transmit the checksums in the local packets do not get filled in, and the packets go out with wrong checksum and get then discarded at next hop.
As it seems, the fact that the packet was inserted locally (and does therefore not yet have calculated checksums) gets somehow lost when passing thru a divert socket and back.

I am not sure who is to blame for that, but could it be that divert(4) does not properly support IPv6? There is a mention of divert(4) here: https://wiki.freebsd.org/IPv6/ToDo - but that was there ten years ago already...
 
Looking closer: in the code I find this, which seems to concern IPv4:

Code:
        /* Delayed checksums are currently not compatible with divert. */
        if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
                in_delayed_cksum(m);
                m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
        }

But, while there are code parts to handle IPv6, there is apparently no corresponding part to handle IPv6 checksums.

Also, in netstat we see the divert sockets labelled as div4:

Code:
udp6       0      0 *.514                  *.*                   
div4       0      0 *.8677                 *.*                   
icm4    7023      0 *.*                    *.*                    
icm6       0      0 *.*                    *.*

So what does that mean, and how do we run software that requires a divert socket, with IPv6?
 
Fixed it. It's four lines of code that are missing - it seems they have just forgotten to write them. :(
 
So, PR? Things like that should be fixed…

The tragedy with IPv6 is that there are still lots of bugs hidden everywhere (e.g. in Linux, as someone from an IPv6 administrators group told me), because too many people still just ignore it, although it would be desperately needed…
 
The author knows the issue, the patch is here: https://people.freebsd.org/~ae/ipv6_divert_csum.diff
Then, a PR would still be the correct way. If that patch isn't committed, I'd have to assume there's something wrong with it… 🤔 (and if not, some PRs do need some nagging for someone to get active).
Well, identifying (and, if possible, fixing) the problems is only part of the job. Describing them on the forum might be interesting, but to get things moving, take them to bugzilla ;)
 
Then, a PR would still be the correct way. If that patch isn't committed, I'd have to assume there's something wrong with it… 🤔 (and if not, some PRs do need some nagging for someone to get active).

Well, identifying (and, if possible, fixing) the problems is only part of the job.
Which job?
Describing them on the forum might be interesting, but to get things moving, take them to bugzilla ;)
See https://forums.freebsd.org/threads/zpool-crashing-history-full.70311/post-423238
 
Back
Top