diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-link.c | 88 | ||||
-rw-r--r-- | src/network/networkd-link.h | 1 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 1 | ||||
-rw-r--r-- | src/network/networkd-manager.h | 1 | ||||
-rw-r--r-- | src/network/networkd-route.c | 31 |
5 files changed, 89 insertions, 33 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 198425590d..55141860ae 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -552,14 +552,28 @@ int link_get(Manager *m, int ifindex, Link **ret) { assert(m); assert(ifindex > 0); - assert(ret); link = hashmap_get(m->links, INT_TO_PTR(ifindex)); if (!link) return -ENODEV; - *ret = link; + if (ret) + *ret = link; + return 0; +} + +int link_get_by_name(Manager *m, const char *ifname, Link **ret) { + Link *link; + + assert(m); + assert(ifname); + link = hashmap_get(m->links_by_name, ifname); + if (!link) + return -ENODEV; + + if (ret) + *ret = link; return 0; } @@ -1709,6 +1723,8 @@ static void link_drop_requests(Link *link) { static Link *link_drop(Link *link) { + char **n; + if (!link) return NULL; @@ -1734,6 +1750,11 @@ static Link *link_drop(Link *link) { (void) unlink(link->state_file); link_clean(link); + STRV_FOREACH(n, link->alternative_names) + hashmap_remove(link->manager->links_by_name, *n); + + hashmap_remove(link->manager->links_by_name, link->ifname); + /* The following must be called at last. */ assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link); return link_unref(link); @@ -2204,8 +2225,33 @@ static int link_get_network(Link *link, Network **ret) { return -ENOENT; } +static int link_update_alternative_names(Link *link, sd_netlink_message *message) { + _cleanup_strv_free_ char **altnames = NULL; + char **n; + int r; + + assert(link); + assert(message); + + r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &altnames); + if (r < 0 && r != -ENODATA) + return r; + + STRV_FOREACH(n, link->alternative_names) + hashmap_remove(link->manager->links_by_name, *n); + + strv_free_and_replace(link->alternative_names, altnames); + + STRV_FOREACH(n, link->alternative_names) { + r = hashmap_ensure_put(&link->manager->links_by_name, &string_hash_ops, *n, link); + if (r < 0) + return r; + } + + return 0; +} + static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) { - _cleanup_strv_free_ char **s = NULL; Network *network; int r; @@ -2215,12 +2261,10 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for if (r < 0) return r; - r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s); - if (r < 0 && r != -ENODATA) + r = link_update_alternative_names(link, m); + if (r < 0) return r; - strv_free_and_replace(link->alternative_names, s); - r = link_get_network(link, &network); if (r == -ENOENT) { link_enter_unmanaged(link); @@ -2386,7 +2430,6 @@ static int link_initialized_and_synced(Link *link) { } static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { - _cleanup_strv_free_ char **s = NULL; int r; r = sd_netlink_message_get_errno(m); @@ -2396,14 +2439,12 @@ static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin return 0; } - r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s); - if (r < 0 && r != -ENODATA) { + r = link_update_alternative_names(link, m); + if (r < 0) { link_enter_failed(link); - return 0; + return r; } - strv_free_and_replace(link->alternative_names, s); - r = link_initialized_and_synced(link); if (r < 0) link_enter_failed(link); @@ -2547,10 +2588,6 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { if (r < 0) log_link_debug_errno(link, r, "Failed to get driver, continuing without: %m"); - r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &link->alternative_names); - if (r < 0 && r != -ENODATA) - return r; - if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0) return -ENOMEM; @@ -2560,6 +2597,14 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0) return -ENOMEM; + r = hashmap_ensure_put(&manager->links_by_name, &string_hash_ops, link->ifname, link); + if (r < 0) + return r; + + r = link_update_alternative_names(link, message); + if (r < 0) + return r; + r = link_update_flags(link, message, false); if (r < 0) return r; @@ -2877,7 +2922,6 @@ static int link_admin_state_down(Link *link) { } static int link_update(Link *link, sd_netlink_message *m) { - _cleanup_strv_free_ char **s = NULL; hw_addr_data hw_addr; const char *ifname; uint32_t mtu; @@ -2907,12 +2951,12 @@ static int link_update(Link *link, sd_netlink_message *m) { r = link_add(manager, m, &link); if (r < 0) return r; + } else { + r = link_update_alternative_names(link, m); + if (r < 0) + return r; } - r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s); - if (r >= 0) - strv_free_and_replace(link->alternative_names, s); - r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu); if (r >= 0 && mtu > 0) { link->mtu = mtu; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index bc2df6b80f..ddfc32b294 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -210,6 +210,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_destroy_callback, Link, link_unref); int link_get(Manager *m, int ifindex, Link **ret); +int link_get_by_name(Manager *m, const char *ifname, Link **ret); int link_up(Link *link); int link_down(Link *link, link_netlink_message_handler_t callback); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 2b06657590..d4b4043211 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -459,6 +459,7 @@ Manager* manager_free(Manager *m) { m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref); m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref); + m->links_by_name = hashmap_free(m->links_by_name); m->links = hashmap_free_with_destructor(m->links, link_unref); m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref); diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index ef98c519d6..6b9b0697b2 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -45,6 +45,7 @@ struct Manager { LinkOnlineState online_state; Hashmap *links; + Hashmap *links_by_name; Hashmap *netdevs; OrderedHashmap *networks; Hashmap *dhcp6_prefixes; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 2f4a34eb97..60eef08074 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1565,25 +1565,23 @@ static int route_is_ready_to_configure(const Route *route, Link *link) { ORDERED_SET_FOREACH(m, route->multipath_routes) { union in_addr_union a = m->gateway.address; + Link *l = NULL; if (route->gateway_onlink <= 0 && !manager_address_is_reachable(link->manager, m->gateway.family, &a)) return false; if (m->ifname) { - Link *l; - - r = resolve_interface(&link->manager->rtnl, m->ifname); - if (r < 0) + if (link_get_by_name(link->manager, m->ifname, &l) < 0) return false; - m->ifindex = r; + m->ifindex = l->ifindex; + } else if (m->ifindex > 0) { if (link_get(link->manager, m->ifindex, &l) < 0) return false; - - if (!link_is_ready_to_configure(l, true)) - return false; } + if (l && !link_is_ready_to_configure(l, true)) + return false; } return true; @@ -2745,9 +2743,20 @@ int config_parse_multipath_route( if (dev) { *dev++ = '\0'; - m->ifname = strdup(dev); - if (!m->ifname) - return log_oom(); + r = parse_ifindex(dev); + if (r > 0) + m->ifindex = r; + else { + if (!ifname_valid_full(dev, IFNAME_VALID_ALTERNATIVE)) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid interface name '%s' in %s=, ignoring: %s", dev, lvalue, rvalue); + return 0; + } + + m->ifname = strdup(dev); + if (!m->ifname) + return log_oom(); + } } r = in_addr_from_string_auto(word, &family, &a); |