I've got everything working, now, and ready for others to take a look at. I've tested all functionality, and am quite happy with it. I'm attaching the patch for perusal and criticism. I gave in to a little bit of feature creep: I included source level compatibility with FreeBSD, as adding the IP_SENDSRCADDR control message was so quick and easy to do while I was in there anyway. Binary compatibility with existing applications is maintained: I've verified that existing compiled binaries continue to work as before. There are a couple of little things I'd like opinions on, though. More on that below. > 1) "#define ipi_spec_dst ipi_addr" in <netinet/in.h> Done. This alone makes lots of software compile that didn't. > 2) Change the IP_RECVPKTINFO option to control the generation of > IP_PKTINFO control messages, the way it's done in Solaris. Done. Using IP_PKTINFO will still work, though -- see below. > 3) Remove the superfluous IP_RECVPKTINFO control message. Done. It won't be missed -- nothing has ever used it. > 4) Change the IP_PKTINFO option to do different things depending on > the parameter it's supplied with: > - If it's sizeof(int), assume it's being used as in Linux: > - If it's non-zero, turn on the IP_RECVPKTINFO option. > - If it's zero, turn off the IP_RECVPKTINFO option. > - If it's sizeof(struct in_pktinfo), assume it's being used as in > Solaris, to set a default for the source interface and/or > source address for outgoing packets on the socket. Done, but only for setsockopt(2). The relevant kernel code knows the size of the data supplied, and can differentiate as described, and I do that. For getsockopt(2), however, it's not so simple. The size is not known (sopt->sopt_size is 0 during the IP socket option processing in ip_ctloutput() in sys/netinet/ip_output.c, which I'm tempted to call a bug), and thus I have no idea whether the caller expects an int or a struct in_pktinfo returned. For now, I've punted, and just return the int that Linux source code, and existing NetBSD applications, expect. Comments and suggestions are welcome. Another thing I'm unsure of here: when the application uses IP_PKTINFO to set a default source address for outgoing packets through a wildcard bound socket, I need a place to keep that address. I decided to add a new member to the PCB structure for this purpose. If that's stupid, and there's something else I should have done, someone please enlighten me. > 5) Fix our documentation. Both ip(4) and ip6(4) contain errors in > their descriptions of these particular options and control messages. Done, but only for ip(4). I still think ip6(4) needs to be looked at, but after perusing sys/netinet6/ip6_output.c, I'm not sure exactly how to go about it. Someone with more knowledge of that code is needed. 6) Add the IP_SENDSRCADDR control message, for FreeBSD compatibility. Done, too. :) > With this, we should have automatic source code compatibility with > pretty much everything, and orthogonality between IPv6 and IPv4. I'm pretty happy with the result: software written for FreeBSD, Linux, Solaris, and probably a few others, like AIX, should now compile and run with no changes to these particular bits. -tih
Attachment:
DIFFS.pktinfo.tih.2017-12-31T14:21:25
Description: Patch to improve handling of IP_PKTINFO and friends
-- Most people who graduate with CS degrees don't understand the significance of Lisp. Lisp is the most important idea in computer science. --Alan Kay