Translate Linux IP_PKTINFO socket options and ancillary data to their
FreeBSD equivalents.
For setsockopt(SOL_IP, IP_PKTINFO), enable both IP_RECVDSTADDR and
IP_RECVIF. FreeBSD supplies the destination address and receiving
interface in separate control messages, while Linux expects a single
in_pktinfo structure.
When receiving a datagram, combine IP_RECVDSTADDR and IP_RECVIF into a
Linux IP_PKTINFO control message. Populate ipi_ifindex from the
receiving interface and set both ipi_spec_dst and ipi_addr to the
destination address.
Also handle IP_PKTINFO control messages passed to sendmsg(). Linux
applications use ipi_spec_dst to select the source address of an
outgoing IPv4 datagram. Translate this field into a FreeBSD
IP_SENDSRCADDR control message.
This is required by wireguard-go and wireproxy. Without the sendmsg()
translation, an incoming WireGuard handshake is received, but sending
the handshake response fails with EINVAL:
Failed to send handshake response:
write udp 0.0.0.0:51820: sendmmsg: invalid argumentThe implementation is currently limited to IPv4. Interface selection
through ipi_ifindex is not translated for outgoing datagrams;
ipi_spec_dst is sufficient for the wireguard-go use case.
MFC after: 2 weeks
PR https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=264835