]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/wait-online/link.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / network / wait-online / link.c
index f0cb70ab4cbb20c11c04b725b058024f478051fc..529fc9f22a27fc4f4fefc8bc6b74b81c5c549bd3 100644 (file)
@@ -1,23 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-/***
-  This file is part of systemd.
-
-  Copyright 2014 Lennart Poettering
-  Copyright 2014 Tom Gundersen
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "sd-network.h"
 
@@ -29,6 +10,7 @@
 
 int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
         _cleanup_(link_freep) Link *l = NULL;
+        _cleanup_free_ char *n = NULL;
         int r;
 
         assert(m);
@@ -42,30 +24,33 @@ int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
         if (r < 0)
                 return r;
 
-        l = new0(Link, 1);
-        if (!l)
+        n = strdup(ifname);
+        if (!n)
                 return -ENOMEM;
 
-        l->manager = m;
-
-        l->ifname = strdup(ifname);
-        if (!l->ifname)
+        l = new(Link, 1);
+        if (!l)
                 return -ENOMEM;
 
+        *l = (Link) {
+                .manager = m,
+                .ifname = TAKE_PTR(n),
+                .ifindex = ifindex,
+                .required_operstate = LINK_OPERSTATE_RANGE_DEFAULT,
+        };
+
         r = hashmap_put(m->links_by_name, l->ifname, l);
         if (r < 0)
                 return r;
 
-        l->ifindex = ifindex;
-
         r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
         if (r < 0)
                 return r;
 
         if (ret)
                 *ret = l;
-        l = NULL;
 
+        TAKE_PTR(l);
         return 0;
 }
 
@@ -79,6 +64,7 @@ Link *link_free(Link *l) {
                 hashmap_remove(l->manager->links_by_name, l->ifname);
         }
 
+        free(l->state);
         free(l->ifname);
         return mfree(l);
  }
@@ -106,9 +92,8 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
                 if (!new_ifname)
                         return -ENOMEM;
 
-                hashmap_remove(l->manager->links_by_name, l->ifname);
-                free(l->ifname);
-                l->ifname = new_ifname;
+                assert_se(hashmap_remove(l->manager->links_by_name, l->ifname) == l);
+                free_and_replace(l->ifname, new_ifname);
 
                 r = hashmap_put(l->manager->links_by_name, l->ifname, l);
                 if (r < 0)
@@ -119,17 +104,50 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
 }
 
 int link_update_monitor(Link *l) {
-        assert(l);
+        _cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *state = NULL;
+        int r, ret = 0;
 
-        l->required_for_online = sd_network_link_get_required_for_online(l->ifindex) != 0;
+        assert(l);
+        assert(l->ifname);
 
-        l->operational_state = mfree(l->operational_state);
+        r = sd_network_link_get_required_for_online(l->ifindex);
+        if (r < 0)
+                ret = log_link_debug_errno(l, r, "Failed to determine whether the link is required for online or not, "
+                                           "ignoring: %m");
+        else
+                l->required_for_online = r > 0;
 
-        sd_network_link_get_operational_state(l->ifindex, &l->operational_state);
+        r = sd_network_link_get_required_operstate_for_online(l->ifindex, &required_operstate);
+        if (r < 0)
+                ret = log_link_debug_errno(l, r, "Failed to get required operational state, ignoring: %m");
+        else if (isempty(required_operstate))
+                l->required_operstate = LINK_OPERSTATE_RANGE_DEFAULT;
+        else {
+                r = parse_operational_state_range(required_operstate, &l->required_operstate);
+                if (r < 0)
+                        ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
+                                                   "Failed to parse required operational state, ignoring: %m");
+        }
 
-        l->state = mfree(l->state);
+        r = sd_network_link_get_operational_state(l->ifindex, &operstate);
+        if (r < 0)
+                ret = log_link_debug_errno(l, r, "Failed to get operational state, ignoring: %m");
+        else {
+                LinkOperationalState s;
+
+                s = link_operstate_from_string(operstate);
+                if (s < 0)
+                        ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
+                                                   "Failed to parse operational state, ignoring: %m");
+                else
+                        l->operational_state = s;
+        }
 
-        sd_network_link_get_setup_state(l->ifindex, &l->state);
+        r = sd_network_link_get_setup_state(l->ifindex, &state);
+        if (r < 0)
+                ret = log_link_debug_errno(l, r, "Failed to get setup state, ignoring: %m");
+        else
+                free_and_replace(l->state, state);
 
-        return 0;
+        return ret;
 }