That's not bad at all. It seems to perform about as well as the current copy-structs-around ioctl() interface.
It's a bit verbose to do the serialisation, but nvlist isn't actually any better about that.
Does this imply that we're already sending data while we're generating it here?
I'm not getting that sense from a quick look at nlmsg_end(), but perhaps I'm missing something important.
It clearly works, but I'm not seeing how this interacts with VIMAGE. Is the netlink socket in userspace already linked to the correct vnet?
Yes, the socket is bound to the VNET ( https://cgit.freebsd.org/src/tree/sys/netlink/netlink_io.c#n304 ).
Also, somewhat random question: are we keeping the programming API identical (or close to) Linux?
Ah, that's what I was missing.
Do we have documentation about which calls can sleep (or allocate memory)? Sometimes we end up having to hold lock to export data, and it's not generally ideal to hold e.g. the pf write lock for extended periods (users get annoyed if we stop passing packets. They're very demanding like that.)
The short answer is yes.
The longer answer:
the kernel API is identical (e.g. headers provide the same macros, the values of families and attributes are the same).
There are some FreeBSD-specific attribures but the intention is to keep everying compatible (and there are the talks ongoing on the attribute allocation mechanism that'll keep it compatible).
That is, ip(8) works out-of-the-box for the supported interface. net/bird routing daemon netlink part didn't require _any_ changes to support FreeBSD.
The higher-level APIs may be different. Various opensource project either uses their own embedded library (like iproute2, bird or vrr) or uses libnl / libmnl. I have a plan to port libmnl but not sure on the timelines yet.
Though, all these libraries are based on the "low-level" kernel APIs that are the same (and have the intent to be the same/compatible).
In FreeBSD I'm using another custom higher-level API library (libsnl, wthich is, by definition, simple and inline). The reasons are the (1) full control over the evolution and (2) simplicity allowing to embed it to the critical utilies.