]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
wait-online: support alternative names
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 31 Oct 2022 01:19:43 +0000 (10:19 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 1 Nov 2022 13:37:59 +0000 (22:37 +0900)
src/network/wait-online/link.c
src/network/wait-online/link.h
src/network/wait-online/manager.c

index 287a91648d14da12caeff6fdebb93a94234c0f3e..a8ab7f53dee706aa2ea46a893bd15281988b3c7a 100644 (file)
@@ -8,6 +8,7 @@
 #include "link.h"
 #include "manager.h"
 #include "string-util.h"
+#include "strv.h"
 
 int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
         _cleanup_(link_freep) Link *l = NULL;
@@ -56,12 +57,16 @@ Link *link_free(Link *l) {
         if (l->manager) {
                 hashmap_remove(l->manager->links_by_index, INT_TO_PTR(l->ifindex));
                 hashmap_remove(l->manager->links_by_name, l->ifname);
+
+                STRV_FOREACH(n, l->altnames)
+                        hashmap_remove(l->manager->links_by_name, *n);
         }
 
         free(l->state);
         free(l->ifname);
+        strv_free(l->altnames);
         return mfree(l);
- }
+}
 
 static int link_update_name(Link *l, sd_netlink_message *m) {
         char ifname_from_index[IF_NAMESIZE];
@@ -107,6 +112,39 @@ static int link_update_name(Link *l, sd_netlink_message *m) {
         return 0;
 }
 
+static int link_update_altnames(Link *l, sd_netlink_message *m) {
+        _cleanup_strv_free_ char **altnames = NULL;
+        int r;
+
+        assert(l);
+        assert(l->manager);
+        assert(m);
+
+        r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &altnames);
+        if (r == -ENODATA)
+                /* The message does not have IFLA_PROP_LIST container attribute. It does not mean the
+                 * interface has no alternative name. */
+                return 0;
+        if (r < 0)
+                return r;
+
+        if (strv_equal(altnames, l->altnames))
+                return 0;
+
+        STRV_FOREACH(n, l->altnames)
+                hashmap_remove(l->manager->links_by_name, *n);
+
+        strv_free_and_replace(l->altnames, altnames);
+
+        STRV_FOREACH(n, l->altnames) {
+                r = hashmap_ensure_put(&l->manager->links_by_name, &string_hash_ops, *n, l);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
 int link_update_rtnl(Link *l, sd_netlink_message *m) {
         int r;
 
@@ -122,6 +160,10 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
         if (r < 0)
                 return r;
 
+        r = link_update_altnames(l, m);
+        if (r < 0)
+                return r;
+
         return 0;
 }
 
index 3072a91e565b21beb9f0ff5a6fb2f944830660db..5dc26d9c40ab314c2f7a875686869d08b18de160 100644 (file)
@@ -14,6 +14,7 @@ struct Link {
 
         int ifindex;
         char *ifname;
+        char **altnames;
         unsigned flags;
 
         bool required_for_online;
index 260ccce2b6dd7f9c13eb0cf5a3aaa85f6c799eaa..624029a81289576a4c1b2618a41abcd7d75832c5 100644 (file)
 #include "time-util.h"
 #include "util.h"
 
+static bool link_in_command_line_interfaces(Link *link, Manager *m) {
+        assert(link);
+        assert(m);
+
+        if (hashmap_contains(m->command_line_interfaces_by_name, link->ifname))
+                return true;
+
+        STRV_FOREACH(n, link->altnames)
+                if (hashmap_contains(m->command_line_interfaces_by_name, *n))
+                        return true;
+
+        return false;
+}
+
 static bool manager_ignore_link(Manager *m, Link *link) {
         assert(m);
         assert(link);
@@ -22,14 +36,21 @@ static bool manager_ignore_link(Manager *m, Link *link) {
 
         /* if interfaces are given on the command line, ignore all others */
         if (m->command_line_interfaces_by_name &&
-            !hashmap_contains(m->command_line_interfaces_by_name, link->ifname))
+            !link_in_command_line_interfaces(link, m))
                 return true;
 
         if (!link->required_for_online)
                 return true;
 
         /* ignore interfaces we explicitly are asked to ignore */
-        return strv_fnmatch(m->ignored_interfaces, link->ifname);
+        if (strv_fnmatch(m->ignored_interfaces, link->ifname))
+                return true;
+
+        STRV_FOREACH(n, link->altnames)
+                if (strv_fnmatch(m->ignored_interfaces, *n))
+                        return true;
+
+        return false;
 }
 
 static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange s) {
@@ -58,7 +79,7 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange
         if (streq(l->state, "unmanaged")) {
                 /* If the link is in unmanaged state, then ignore the interface unless the interface is
                  * specified in '--interface/-i' option. */
-                if (!hashmap_contains(m->command_line_interfaces_by_name, l->ifname)) {
+                if (!link_in_command_line_interfaces(l, m)) {
                         log_link_debug(l, "link is not managed by networkd (yet?).");
                         return 0;
                 }