]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce link_get_by_name()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 14 May 2021 07:00:52 +0000 (16:00 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 19 May 2021 07:28:53 +0000 (16:28 +0900)
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-manager.c
src/network/networkd-manager.h

index d493afda4c8458d1df88a8e77204c1f17fdf0400..b58b99d8d64e03cc20f449397a98cbb609eb1714 100644 (file)
@@ -512,14 +512,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;
 }
 
@@ -1669,6 +1683,8 @@ static void link_drop_requests(Link *link) {
 
 
 static Link *link_drop(Link *link) {
+        char **n;
+
         if (!link)
                 return NULL;
 
@@ -1694,6 +1710,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);
@@ -2164,8 +2185,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;
 
@@ -2175,12 +2221,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);
@@ -2345,7 +2389,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);
@@ -2355,14 +2398,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);
@@ -2505,10 +2546,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;
 
@@ -2518,6 +2555,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;
@@ -2835,7 +2880,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;
@@ -2865,12 +2909,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;
index fbc593f124ee0c8eb8ad8337472118e29a82ff50..54e0ae55936af12725aa7b4df81ee09683d3a98e 100644 (file)
@@ -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);
index fd576169a94cd2309af8c69f6b100dec5fab0429..fc207e4b3baa57ab8bc536a51f502807841c31cc 100644 (file)
@@ -458,6 +458,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);
index 3f8f81b865789e855367b8e16ea7eb553f10d9cc..07913516097f11b11f334e2720cdb9202a5f18ba 100644 (file)
@@ -44,6 +44,7 @@ struct Manager {
         LinkAddressState ipv6_address_state;
 
         Hashmap *links;
+        Hashmap *links_by_name;
         Hashmap *netdevs;
         OrderedHashmap *networks;
         Hashmap *dhcp6_prefixes;