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;
}
static Link *link_drop(Link *link) {
+ char **n;
+
if (!link)
return NULL;
(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);
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;
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);
}
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);
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);
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;
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;
}
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;
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;