summaryrefslogtreecommitdiff
path: root/src/network/networkd-manager.c
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-01-29 21:24:44 +0100
committerTom Gundersen <teg@jklm.no>2014-01-30 14:30:39 +0100
commit50add2909c2e4b13a04d285b058b1c2270137656 (patch)
tree6ece9c372f2d850d7df78b6137fe8e6d71741184 /src/network/networkd-manager.c
parent3815f36f05f8bc06904777b1eb7f1d22b78bcced (diff)
networkd: netdev - reduce chance of race when receiving netdev's ifindex
When creating a new link, the kernel will not inform us about the new ifindex in its ack. We have to listen for newly created devices and deduce the new ifindex by matching on the ifname. We used to do this by waiting for a new device from libudev, but that is asking for trouble, as udev will happily rename the device before handing it to us. Listen on rtnl instead, the chance of the name being changed before reaching us is much smaller (if not nil). Kernel patch in the works to make this unneccessary.
Diffstat (limited to 'src/network/networkd-manager.c')
-rw-r--r--src/network/networkd-manager.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 7b93c5b5e8..a007b0485f 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -25,6 +25,7 @@
#include "networkd.h"
#include "libudev-private.h"
#include "udev-util.h"
+#include "rtnl-util.h"
#include "mkdir.h"
const char* const network_dirs[] = {
@@ -244,15 +245,31 @@ int manager_udev_listen(Manager *m) {
static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
Manager *m = userdata;
Link *link;
+ const char *name;
uint64_t ifindex_64;
int r, ifindex;
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
- if (r < 0) {
+ if (r < 0 || ifindex <= 0) {
log_debug("received RTM_NEWLINK message without valid ifindex");
return 0;
}
+ r = rtnl_message_link_get_ifname(message, &name);
+ if (r < 0)
+ log_debug("received RTM_NEWLINK message without valid IFLA_IFNAME");
+ else {
+ Netdev *netdev;
+
+ r = netdev_get(m, name, &netdev);
+ if (r >= 0) {
+ r = netdev_set_ifindex(netdev, ifindex);
+ if (r < 0)
+ log_debug("could not set ifindex of netdev '%s' to %d: %s",
+ name, ifindex, strerror(-r));
+ }
+ }
+
ifindex_64 = ifindex;
link = hashmap_get(m->links, &ifindex_64);
if (!link) {