]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/wait-online/link.c
Merge pull request #17549 from yuwata/tiny-fixes
[thirdparty/systemd.git] / src / network / wait-online / link.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
7de12ae7 2
7de12ae7 3#include "sd-network.h"
7de12ae7 4
b5efdb8a 5#include "alloc-util.h"
c5fcf6e4
TG
6#include "hashmap.h"
7#include "link.h"
8#include "manager.h"
07630cea 9#include "string-util.h"
7de12ae7
TG
10
11int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
12 _cleanup_(link_freep) Link *l = NULL;
f023184e 13 _cleanup_free_ char *n = NULL;
7de12ae7
TG
14 int r;
15
16 assert(m);
17 assert(ifindex > 0);
18
d5099efc 19 r = hashmap_ensure_allocated(&m->links, NULL);
7de12ae7
TG
20 if (r < 0)
21 return r;
22
d5099efc 23 r = hashmap_ensure_allocated(&m->links_by_name, &string_hash_ops);
7de12ae7
TG
24 if (r < 0)
25 return r;
26
f023184e
YW
27 n = strdup(ifname);
28 if (!n)
7de12ae7
TG
29 return -ENOMEM;
30
f023184e
YW
31 l = new(Link, 1);
32 if (!l)
7de12ae7
TG
33 return -ENOMEM;
34
f023184e
YW
35 *l = (Link) {
36 .manager = m,
37 .ifname = TAKE_PTR(n),
38 .ifindex = ifindex,
75cd4a5d 39 .required_operstate = LINK_OPERSTATE_RANGE_DEFAULT,
f023184e
YW
40 };
41
7de12ae7
TG
42 r = hashmap_put(m->links_by_name, l->ifname, l);
43 if (r < 0)
44 return r;
45
7de12ae7
TG
46 r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
47 if (r < 0)
48 return r;
49
50 if (ret)
51 *ret = l;
7de12ae7 52
f023184e 53 TAKE_PTR(l);
7de12ae7
TG
54 return 0;
55}
56
57Link *link_free(Link *l) {
58
59 if (!l)
60 return NULL;
61
62 if (l->manager) {
63 hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
64 hashmap_remove(l->manager->links_by_name, l->ifname);
65 }
66
f023184e 67 free(l->state);
7de12ae7 68 free(l->ifname);
6b430fdb 69 return mfree(l);
7de12ae7
TG
70 }
71
1c4baffc 72int link_update_rtnl(Link *l, sd_netlink_message *m) {
d2437732 73 const char *ifname;
7de12ae7
TG
74 int r;
75
76 assert(l);
77 assert(l->manager);
78 assert(m);
79
80 r = sd_rtnl_message_link_get_flags(m, &l->flags);
81 if (r < 0)
82 return r;
83
1c4baffc 84 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
7de12ae7
TG
85 if (r < 0)
86 return r;
87
88 if (!streq(l->ifname, ifname)) {
89 char *new_ifname;
90
91 new_ifname = strdup(ifname);
92 if (!new_ifname)
93 return -ENOMEM;
94
f023184e
YW
95 assert_se(hashmap_remove(l->manager->links_by_name, l->ifname) == l);
96 free_and_replace(l->ifname, new_ifname);
7de12ae7
TG
97
98 r = hashmap_put(l->manager->links_by_name, l->ifname, l);
99 if (r < 0)
100 return r;
101 }
102
103 return 0;
104}
105
106int link_update_monitor(Link *l) {
f023184e 107 _cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *state = NULL;
f023184e 108 int r, ret = 0;
7de12ae7 109
f023184e
YW
110 assert(l);
111 assert(l->ifname);
c1a38904 112
f023184e
YW
113 r = sd_network_link_get_required_for_online(l->ifindex);
114 if (r < 0)
07e1ffe4
YW
115 ret = log_link_debug_errno(l, r, "Failed to determine whether the link is required for online or not, "
116 "ignoring: %m");
f023184e
YW
117 else
118 l->required_for_online = r > 0;
7de12ae7 119
f023184e
YW
120 r = sd_network_link_get_required_operstate_for_online(l->ifindex, &required_operstate);
121 if (r < 0)
07e1ffe4 122 ret = log_link_debug_errno(l, r, "Failed to get required operational state, ignoring: %m");
75cd4a5d
DDM
123 else if (isempty(required_operstate))
124 l->required_operstate = LINK_OPERSTATE_RANGE_DEFAULT;
f023184e 125 else {
75cd4a5d
DDM
126 r = parse_operational_state_range(required_operstate, &l->required_operstate);
127 if (r < 0)
07e1ffe4
YW
128 ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
129 "Failed to parse required operational state, ignoring: %m");
f023184e 130 }
7de12ae7 131
f023184e
YW
132 r = sd_network_link_get_operational_state(l->ifindex, &operstate);
133 if (r < 0)
07e1ffe4 134 ret = log_link_debug_errno(l, r, "Failed to get operational state, ignoring: %m");
f023184e 135 else {
75cd4a5d
DDM
136 LinkOperationalState s;
137
f023184e
YW
138 s = link_operstate_from_string(operstate);
139 if (s < 0)
07e1ffe4
YW
140 ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
141 "Failed to parse operational state, ignoring: %m");
f023184e
YW
142 else
143 l->operational_state = s;
144 }
7de12ae7 145
f023184e
YW
146 r = sd_network_link_get_setup_state(l->ifindex, &state);
147 if (r < 0)
07e1ffe4 148 ret = log_link_debug_errno(l, r, "Failed to get setup state, ignoring: %m");
f023184e
YW
149 else
150 free_and_replace(l->state, state);
7de12ae7 151
f023184e 152 return ret;
7de12ae7 153}