diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index f021918311..363602e962 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -96,7 +96,6 @@ int link_add(Manager *m, struct udev_device *device, Link **ret) { Network *network; int r; uint64_t ifindex; - NetdevKind kind; assert(m); assert(device); @@ -114,13 +113,6 @@ int link_add(Manager *m, struct udev_device *device, Link **ret) { *ret = link; - kind = netdev_kind_from_string(udev_device_get_devtype(device)); - if (kind != _NETDEV_KIND_INVALID) { - r = netdev_set_link(m, kind, link); - if (r < 0 && r != -ENOENT) - return r; - } - r = network_get(m, device, &network); if (r < 0) return r == -ENOENT ? 0 : r; 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) { 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; +int netdev_set_ifindex(Netdev *netdev, int ifindex) { + assert(netdev); + assert(ifindex > 0); - r = netdev_get(m, link->ifname, &netdev); - if (r < 0) - return r; + if (netdev->ifindex > 0) { + if (netdev->ifindex == ifindex) + return 0; + else + return -EEXIST; + } - if (netdev->link && netdev->link != link) - return -EEXIST; - - if (netdev->kind != kind) - return -EINVAL; - - netdev->link = link; + netdev->ifindex = ifindex; netdev_enter_ready(netdev); diff --git a/src/network/networkd.h b/src/network/networkd.h index 01a8a7f681..831a9cbdd9 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -77,7 +77,7 @@ struct Netdev { int vlanid; - Link *link; + int ifindex; NetdevState state; LIST_HEAD(netdev_enslave_callback, callbacks); @@ -234,7 +234,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Netdev*, netdev_free); #define _cleanup_netdev_free_ _cleanup_(netdev_freep) int netdev_get(Manager *manager, const char *name, Netdev **ret); -int netdev_set_link(Manager *m, NetdevKind kind, Link *link); +int netdev_set_ifindex(Netdev *netdev, int ifindex); int netdev_enslave(Netdev *netdev, Link *link, sd_rtnl_message_handler_t cb); const char *netdev_kind_to_string(NetdevKind d) _const_;