diff options
author | Tom Gundersen <teg@jklm.no> | 2014-01-29 21:24:44 +0100 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-01-30 14:30:39 +0100 |
commit | 50add2909c2e4b13a04d285b058b1c2270137656 (patch) | |
tree | 6ece9c372f2d850d7df78b6137fe8e6d71741184 /src/network/networkd-netdev.c | |
parent | 3815f36f05f8bc06904777b1eb7f1d22b78bcced (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-netdev.c')
-rw-r--r-- | src/network/networkd-netdev.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 1a6eebe1a7..c0f3df5b66 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -98,7 +98,7 @@ static int netdev_enslave_ready(Netdev *netdev, Link* link, sd_rtnl_message_hand return r; } - r = sd_rtnl_message_append_u32(req, IFLA_MASTER, netdev->link->ifindex); + r = sd_rtnl_message_append_u32(req, IFLA_MASTER, netdev->ifindex); if (r < 0) { log_error_netdev(netdev, "Could not append IFLA_MASTER attribute: %s", @@ -140,7 +140,7 @@ static int netdev_enter_ready(Netdev *netdev) { static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { Netdev *netdev = userdata; - int r; + int r, ifindex; assert(netdev->state != _NETDEV_STATE_INVALID); @@ -152,6 +152,14 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda return 1; } + r = sd_rtnl_message_link_get_ifindex(m, &ifindex); + if (r < 0) + log_warning_netdev(netdev, "created netdev with unknown ifindex: %s", strerror(-r)); + else { + log_info_netdev(netdev, "created netdev with ifindex %d", ifindex); + netdev_set_ifindex(netdev, ifindex); + } + return 1; } @@ -288,21 +296,18 @@ int netdev_enslave(Netdev *netdev, Link *link, sd_rtnl_message_handler_t callbac return 0; } -int netdev_set_link(Manager *m, NetdevKind kind, Link *link) { - Netdev *netdev; - int r; - - r = netdev_get(m, link->ifname, &netdev); - if (r < 0) - return r; - - if (netdev->link && netdev->link != link) - return -EEXIST; +int netdev_set_ifindex(Netdev *netdev, int ifindex) { + assert(netdev); + assert(ifindex > 0); - if (netdev->kind != kind) - return -EINVAL; + if (netdev->ifindex > 0) { + if (netdev->ifindex == ifindex) + return 0; + else + return -EEXIST; + } - netdev->link = link; + netdev->ifindex = ifindex; netdev_enter_ready(netdev); |