Re: Support for nv(9) in if_clone

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Sat, 18 Oct 2025 08:37:00 UTC
On 16 Oct 2025, at 22:56, Vadim Goncharov wrote:
> On Wed, 15 Oct 2025 11:15:03 +0330
> Seyed Pouria Mousavizadeh Tehrani <info@spmzt.net> wrote:
>
>> Currently our ifreq interface supports nv(9) lists via ifreq_nv_req.
>> This allows network interface drivers to implement their 
>> configuration
>> using nvlists (for example: if_ovpn, if_pf*).
>>
>> There is a problem: an interface that is implemented entirely via 
>> nv(9)
>> cannot be configured during the cloning phase (via if_clone_create).
>> if_clone_create converts the ifreq struct to ifdrv and only copies
>> ifr_data to params, so the ifru_nv field is lost during cloning.
>>
>> I am interested in implementing a solution to this issue and am
>> considering two possible approaches:
>>
>>  1. Extend the ifdrv struct to include the ifreq_nv_req struct, and
>>     verify/make sure that other implemented modules are not affected.
>>  2. Introduce a new ioctl, SIOCIFCREATENV, to handle the nv part
>>     separately, which would be more complicated but potentially less
>>     disruptive to existing modules.
>>
>> Which one do you think would be more suitable, or do you have any
>> alternative suggestions?
>
> I'd vote for the latter, because it also will make task easier 
> when/if/ever
> the nvlist plague will be replaced by something more sane.
>
Absent detail this isn’t particularly useful feedback.

Having used nvlists in pf I’ve found them to be fairly useful in 
defining extensible interfaces.
There are a few downsides though. The big one being horrendous 
performance and memory use for large requests. This likely isn’t a 
problem for this use case. It really only bit pf for state export, which 
is potentially very large.

The other downside, and the reason I’d be inclined to look at just 
transitioning entirely to netlink is that dealing with them is annoying, 
because you have to cope with three sizes: the size of the nvlist passed 
from userspace, the size of the buffer userspace allocated and the size 
of the kernel’s reply (if applicable). It also leaves userspace to 
deal with ‘Is this buffer large enough?’, which isn’t really 
something you have to think about with netlink.

As an aside, because you mention if_ovpn: I wound up using nvlists 
because netlink wasn’t available yet for FreeBSD. The Linux equivalent 
uses netlink (of course), and it would have been very nice to be able to 
have the same interface on Linux and FreeBSD.

Best regards,
Kristof