]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/wait-online/link.c
Merge pull request #18863 from keszybz/cmdline-escaping
[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);
ee9ead76 18 assert(ifname);
7de12ae7 19
f023184e
YW
20 n = strdup(ifname);
21 if (!n)
7de12ae7
TG
22 return -ENOMEM;
23
f023184e
YW
24 l = new(Link, 1);
25 if (!l)
7de12ae7
TG
26 return -ENOMEM;
27
f023184e
YW
28 *l = (Link) {
29 .manager = m,
30 .ifname = TAKE_PTR(n),
31 .ifindex = ifindex,
75cd4a5d 32 .required_operstate = LINK_OPERSTATE_RANGE_DEFAULT,
f023184e
YW
33 };
34
3f70f938 35 r = hashmap_ensure_put(&m->links, NULL, INT_TO_PTR(ifindex), l);
7de12ae7
TG
36 if (r < 0)
37 return r;
38
3f70f938 39 r = hashmap_ensure_put(&m->links_by_name, &string_hash_ops, l->ifname, l);
7de12ae7
TG
40 if (r < 0)
41 return r;
42
43 if (ret)
44 *ret = l;
7de12ae7 45
f023184e 46 TAKE_PTR(l);
7de12ae7
TG
47 return 0;
48}
49
50Link *link_free(Link *l) {
51
52 if (!l)
53 return NULL;
54
55 if (l->manager) {
56 hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
57 hashmap_remove(l->manager->links_by_name, l->ifname);
58 }
59
f023184e 60 free(l->state);
7de12ae7 61 free(l->ifname);
6b430fdb 62 return mfree(l);
7de12ae7
TG
63 }
64
1c4baffc 65int link_update_rtnl(Link *l, sd_netlink_message *m) {
d2437732 66 const char *ifname;
7de12ae7
TG
67 int r;
68
69 assert(l);
70 assert(l->manager);
71 assert(m);
72
73 r = sd_rtnl_message_link_get_flags(m, &l->flags);
74 if (r < 0)
75 return r;
76
1c4baffc 77 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
7de12ae7
TG
78 if (r < 0)
79 return r;
80
81 if (!streq(l->ifname, ifname)) {
82 char *new_ifname;
83
84 new_ifname = strdup(ifname);
85 if (!new_ifname)
86 return -ENOMEM;
87
f023184e
YW
88 assert_se(hashmap_remove(l->manager->links_by_name, l->ifname) == l);
89 free_and_replace(l->ifname, new_ifname);
7de12ae7
TG
90
91 r = hashmap_put(l->manager->links_by_name, l->ifname, l);
92 if (r < 0)
93 return r;
94 }
95
96 return 0;
97}
98
99int link_update_monitor(Link *l) {
6dc4531d
L
100 _cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *required_family = NULL,
101 *ipv4_address_state = NULL, *ipv6_address_state = NULL, *state = NULL;
f023184e 102 int r, ret = 0;
7de12ae7 103
f023184e
YW
104 assert(l);
105 assert(l->ifname);
c1a38904 106
f023184e
YW
107 r = sd_network_link_get_required_for_online(l->ifindex);
108 if (r < 0)
07e1ffe4
YW
109 ret = log_link_debug_errno(l, r, "Failed to determine whether the link is required for online or not, "
110 "ignoring: %m");
f023184e
YW
111 else
112 l->required_for_online = r > 0;
7de12ae7 113
f023184e
YW
114 r = sd_network_link_get_required_operstate_for_online(l->ifindex, &required_operstate);
115 if (r < 0)
07e1ffe4 116 ret = log_link_debug_errno(l, r, "Failed to get required operational state, ignoring: %m");
75cd4a5d
DDM
117 else if (isempty(required_operstate))
118 l->required_operstate = LINK_OPERSTATE_RANGE_DEFAULT;
f023184e 119 else {
75cd4a5d
DDM
120 r = parse_operational_state_range(required_operstate, &l->required_operstate);
121 if (r < 0)
07e1ffe4
YW
122 ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
123 "Failed to parse required operational state, ignoring: %m");
f023184e 124 }
7de12ae7 125
f023184e
YW
126 r = sd_network_link_get_operational_state(l->ifindex, &operstate);
127 if (r < 0)
07e1ffe4 128 ret = log_link_debug_errno(l, r, "Failed to get operational state, ignoring: %m");
f023184e 129 else {
75cd4a5d
DDM
130 LinkOperationalState s;
131
f023184e
YW
132 s = link_operstate_from_string(operstate);
133 if (s < 0)
7211c853 134 ret = log_link_debug_errno(l, s, "Failed to parse operational state, ignoring: %m");
f023184e
YW
135 else
136 l->operational_state = s;
137 }
7de12ae7 138
6dc4531d
L
139 r = sd_network_link_get_required_family_for_online(l->ifindex, &required_family);
140 if (r < 0)
141 ret = log_link_debug_errno(l, r, "Failed to get required address family, ignoring: %m");
142 else if (isempty(required_family))
143 l->required_family = ADDRESS_FAMILY_NO;
144 else {
145 AddressFamily f;
146
147 f = link_required_address_family_from_string(required_family);
148 if (f < 0)
149 ret = log_link_debug_errno(l, f, "Failed to parse required address family, ignoring: %m");
150 else
151 l->required_family = f;
152 }
153
154 r = sd_network_link_get_ipv4_address_state(l->ifindex, &ipv4_address_state);
155 if (r < 0)
156 ret = log_link_debug_errno(l, r, "Failed to get IPv4 address state, ignoring: %m");
157 else {
158 LinkAddressState s;
159
160 s = link_address_state_from_string(ipv4_address_state);
161 if (s < 0)
162 ret = log_link_debug_errno(l, s, "Failed to parse IPv4 address state, ignoring: %m");
163 else
164 l->ipv4_address_state = s;
165 }
166
167 r = sd_network_link_get_ipv6_address_state(l->ifindex, &ipv6_address_state);
168 if (r < 0)
169 ret = log_link_debug_errno(l, r, "Failed to get IPv6 address state, ignoring: %m");
170 else {
171 LinkAddressState s;
172
173 s = link_address_state_from_string(ipv6_address_state);
174 if (s < 0)
175 ret = log_link_debug_errno(l, s, "Failed to parse IPv6 address state, ignoring: %m");
176 else
177 l->ipv6_address_state = s;
178 }
179
f023184e
YW
180 r = sd_network_link_get_setup_state(l->ifindex, &state);
181 if (r < 0)
07e1ffe4 182 ret = log_link_debug_errno(l, r, "Failed to get setup state, ignoring: %m");
f023184e
YW
183 else
184 free_and_replace(l->state, state);
7de12ae7 185
f023184e 186 return ret;
7de12ae7 187}