rtnl_link_delete returns 0 instead of -NLE_NODEV when a link cache is created

Thomas Haller thaller at redhat.com
Wed Apr 30 07:53:57 PDT 2014


On Fri, 2014-04-11 at 11:19 +0200, Nicolas CARRIER wrote:
> Hello,
> I ran into the following problem while coding a networking utility library on 
> top of libnl.
> When I delete a non-existant network interface, I expect rtnl_link_delete() to 
> return -NLE_NODEV. In general, it seems to work, but if I :
>   1. add a link cache with nl_cache_mngr_add()
>   2. create another link with rtnl_link_add()
>   3. delete a non-existant network interface with rtnl_link_delete()
> 
> then rtnl_link_delete() returns 0.
> 
> Please find attached a working code to reproduce the behaviour. Then one can 
> issue the following commands to reproduce :
> 
> gcc main.c -o libnl-test -I/usr/include/libnl3/ -lnl-3 -lnl-route-3
> sudo ./libnl-test
> #return of rtnl_link_delete is -31: No such device
> # -> this is the expected behaviour I think
> sudo ./libnl-test foo
> #create link cache
> #return of rtnl_link_delete is 0: Success
> 
> I'm using a debian sid with libnl version 3.2.24-1.
> 
> Am I doing something wrong ?
> 
> Thank you in advance.


Hi Nicolas,


sorry for the late reply.


I think that the problem is, that when you pass the socket to the cache
manager the cache manager owns it. Especially it will call
nl_socket_add_memberships() on the socket to receive notifications via
this socket.

The socket is exposed to the user, so that he might select on it, and
call nl_cache_mngr_data_ready() when there is data available for the
cache manager to process.
This is an alternative operation mode then using nl_cache_mngr_poll().



So, in your example program you receive the success message, because you
send the delete request using sk. But in sk there is already a ACK
message waiting -- so the function reads it and thinks that your command
was successful.

If you change:

    atexit(cleanup);  

+   while (nl_cache_mngr_poll (mngr, 1000) > 0);

    /* delete another link which doesn't exist */
    link_2 = rtnl_link_alloc();

then you get the NLE_NODEV.

But this is not the real fix. The solution is to leave the socket to the
cache manager and create your own socket.



Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140430/115b20e9/attachment.sig>


More information about the libnl mailing list