thom311 / libnl

Netlink Library Suite
GNU Lesser General Public License v2.1
423 stars 311 forks source link

Managing link cache changes #261

Open cpackham opened 4 years ago

cpackham commented 4 years ago

Hi,

I'm trying to write a test application that sends traffic on network interface and expects to get them looped back (with a physical loopback installed).

I'm trying to do something along the lines of

static void test_interface_cb(struct nl_object *obj, void *p)
{
    struct rtnl_link *orig, *link, *change
    orig = (struct rtnl_link *) obj;

    // skip interfaces based on name

    // bring link up
    change = rtnl_link_alloc();
    rtnl_link_set_flags(change, IFF_PROMISC | IFF_UP);
    rtnl_link_change(nl_sock, orig, change, 0);
    rtnl_link_put(change);

   // wait for link to come up
   while (tries --)                                                                                                            
   {                                                                                                                           
        nl_cache_refill (nl_sock, nl_link_cache);                                                                               
        link = rtnl_link_get (nl_link_cache, ifindex);                                                                          
        if (rtnl_link_get_operstate (link) == IF_OPER_UP)                                                                       
                break;                                                                                                              

       rtnl_link_put(link);                                                                                                    
       usleep (1000);                                                                                                          
   } 

  if (tries < 0)
      error("link didn't come up);

  do_test(link);
}

int main()
{
    nl_sock = nl_socket_alloc();
    nl_connect (nl_sock, NETLINK_ROUTE);
    rtnl_link_alloc_cache (nl_sock, AF_UNSPEC, &nl_link_cache);
    nl_cache_foreach (nl_link_cache, test_interface_cb, NULL);
}

Naturally this segfaults because I'm blowing away the cache while iterating over it. My question is how should I be managing the cache when iterating over the links and changing state at the same time?

cpackham commented 4 years ago

I can avoid the issue by using rtnl_link_get_kernel() to get the live state.