sync netlink call with libnl

Thomas Haller thaller at redhat.com
Mon Aug 22 08:06:13 PDT 2016


On Mon, 2016-08-22 at 16:19 +0200, Hauke Mehrtens wrote:
> Hi,
> 
> I want to do a sync call from my user space program to a kernel
> driver 
> with libnl.
> For example to get the capabilities of a chip I want to do this:
> 1. create a message with the question for the driver
> 2. send that message with nl_send_auto()
> 3. kernel driver receives message
> 4. kernel driver sends answer to port id of sender and uses the same 
> sequence number as in the revived message
> 5. user space waits for the ack or nack with the sequence number of
> the 
> request or aborts after a timeout

Hi,


One way to do that is nl_wait_for_ack().
That has a very basic tracking of sequence-numbers.

If you need more controll, you must register your own callbacks that
wait for responses and call nl_recvmsgs(). See for example what
nl_wait_for_ack() does:

»·······nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
»·······err = nl_recvmsgs(sk, cb);
»·······nl_cb_put(cb);

See how all the synchronous functions in libnl are implemented:
for example: rtnl_link_get_kernel().




In the end, you can also implement receiving messages all yourself
and don't use nl_recvmsg().
That is for example what NetworkManager does:
https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/src/platform/nm-linux-platform.c?id=598bea3481b1216e16007057777ce1235593a6d8#n6083


Whether you use select/poll, depends on whether your socket is in
blocking mode -- and if it is not, how you handle EAGAIN which
indicates that the response is not yet ready.
In the NetworkManager example above, the socket is set to non-blocking
mode, that is why in certain cases we need to poll().
In the simplies case, you'd just send the request and block on reading
the response.


> 
> How do I implement 5. ?
> I am missing a function which waits for a message with a specific 
> sequence number and returns when this was received or a timeout 
> occurred.
> Should I use select() on the file descriptor and then do nl_recv()
> when 
> some data is there, parse it manually and retry if it wasn't the 
> expected message?
> 
> I also have use cases where the driver sends notifications to the
> user 
> space so netlink seams to be better fitted that ioctls.

if you receive async notifications and synchronous responses on the
same socket, it gets a bit complicated.

For that reason, in the past NetworkManager used two sockets: one for
async messages and one for doing synchronous requests. The problem with
that is that the two sockets are not in sync, i.e. you don't easily
know whether an event happened before or after your synchronous
request.

So, that was dropped and only one socket is used now. But then it
seemed complicated to implement that using the callback-mechanism with
nl_recvmsg(). Which is the reason why NetworkManager reimplements
nl_recvmsg() and takes care to properly handle async events together
with the sequence number for responses.


best,
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160822/6dfc008f/attachment.sig>


More information about the libnl mailing list