]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
network: move DHCP server related functions to networkd-dhcp-server.c
[thirdparty/systemd.git] / src / network / networkd-manager.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
f579559b 2
9aa5d8ba 3#include <netinet/in.h>
091a364c 4#include <sys/socket.h>
9aa5d8ba 5#include <unistd.h>
bbf7c048 6#include <linux/if.h>
bce67bbe 7#include <linux/fib_rules.h>
3bef724f 8
fc2f9534 9#include "sd-daemon.h"
07630cea 10#include "sd-netlink.h"
fc2f9534 11
b5efdb8a 12#include "alloc-util.h"
a97dcc12 13#include "bus-util.h"
07630cea 14#include "conf-parser.h"
a97dcc12 15#include "def.h"
a7f95575 16#include "device-private.h"
21486d9e 17#include "device-util.h"
482d1aeb 18#include "dns-domain.h"
3ffd4af2 19#include "fd-util.h"
0d39fa9c 20#include "fileio.h"
4f5f911e 21#include "local-addresses.h"
07630cea 22#include "netlink-util.h"
dc0d4078 23#include "network-internal.h"
ca5ad760 24#include "networkd-dhcp6.h"
6a1af3d4 25#include "networkd-link-bus.h"
23f53b99 26#include "networkd-manager.h"
a879e1a4 27#include "networkd-speed-meter.h"
00616955 28#include "ordered-set.h"
07630cea
LP
29#include "path-util.h"
30#include "set.h"
21486d9e 31#include "strv.h"
4b600505 32#include "sysctl-util.h"
e4de7287 33#include "tmpfile-util.h"
299ad32d 34#include "udev-util.h"
07630cea 35#include "virt.h"
505f8da7 36
be660c37
AR
37/* use 8 MB for receive socket kernel queue. */
38#define RCVBUF_SIZE (8*1024*1024)
39
11bf3cce
LP
40static int setup_default_address_pool(Manager *m) {
41 AddressPool *p;
42 int r;
43
44 assert(m);
45
46 /* Add in the well-known private address ranges. */
47
f2efbeaf 48 r = address_pool_new_from_string(m, &p, AF_INET6, "fd00::", 8);
11bf3cce
LP
49 if (r < 0)
50 return r;
51
b085cd37 52 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
11bf3cce
LP
53 if (r < 0)
54 return r;
55
56 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
57 if (r < 0)
58 return r;
59
b085cd37 60 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
11bf3cce
LP
61 if (r < 0)
62 return r;
63
64 return 0;
65}
66
9c0a72f9
TG
67static int manager_reset_all(Manager *m) {
68 Link *link;
69 Iterator i;
70 int r;
71
72 assert(m);
73
74 HASHMAP_FOREACH(link, m->links, i) {
75 r = link_carrier_reset(link);
76 if (r < 0)
2f3cf1f9 77 log_link_warning_errno(link, r, "Could not reset carrier: %m");
9c0a72f9
TG
78 }
79
80 return 0;
81}
82
19070062 83static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
9c0a72f9
TG
84 Manager *m = userdata;
85 int b, r;
86
19070062 87 assert(message);
d7afd945 88 assert(m);
9c0a72f9
TG
89
90 r = sd_bus_message_read(message, "b", &b);
91 if (r < 0) {
92 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
93 return 0;
94 }
95
96 if (b)
97 return 0;
98
99 log_debug("Coming back from suspend, resetting all connections...");
100
e1694a75 101 (void) manager_reset_all(m);
9c0a72f9
TG
102
103 return 0;
104}
105
d7afd945
LP
106static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
107 Manager *m = userdata;
9c0a72f9 108
d7afd945 109 assert(message);
9c0a72f9
TG
110 assert(m);
111
d7afd945
LP
112 /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
113 if (m->dynamic_hostname)
114 (void) manager_set_hostname(m, m->dynamic_hostname);
115 if (m->dynamic_timezone)
116 (void) manager_set_timezone(m, m->dynamic_timezone);
27dfc982
YW
117 if (m->links_requesting_uuid)
118 (void) manager_request_product_uuid(m, NULL);
9c0a72f9 119
d7afd945
LP
120 return 0;
121}
9c0a72f9 122
d7afd945
LP
123int manager_connect_bus(Manager *m) {
124 int r;
125
126 assert(m);
9c0a72f9 127
d7afd945 128 if (m->bus)
9c0a72f9 129 return 0;
7d6884b6 130
621e4509 131 r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-network");
9c0a72f9 132 if (r < 0)
d7afd945 133 return log_error_errno(r, "Failed to connect to bus: %m");
9c0a72f9 134
e331e246
TG
135 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m);
136 if (r < 0)
137 return log_error_errno(r, "Failed to add manager object vtable: %m");
138
139 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m);
140 if (r < 0)
141 return log_error_errno(r, "Failed to add link object vtable: %m");
142
143 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
144 if (r < 0)
145 return log_error_errno(r, "Failed to add link enumerator: %m");
3175fcde
TG
146
147 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m);
148 if (r < 0)
149 return log_error_errno(r, "Failed to add network object vtable: %m");
150
151 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m);
152 if (r < 0)
153 return log_error_errno(r, "Failed to add network enumerator: %m");
e331e246 154
696fc836 155 r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL);
e331e246 156 if (r < 0)
0c0b9306 157 return log_error_errno(r, "Failed to request name: %m");
e331e246
TG
158
159 r = sd_bus_attach_event(m->bus, m->event, 0);
160 if (r < 0)
161 return log_error_errno(r, "Failed to attach bus to event loop: %m");
162
d7afd945
LP
163 r = sd_bus_match_signal_async(
164 m->bus,
cad43595 165 NULL,
d7afd945
LP
166 "org.freedesktop.DBus.Local",
167 NULL,
168 "org.freedesktop.DBus.Local",
169 "Connected",
170 on_connected, NULL, m);
171 if (r < 0)
172 return log_error_errno(r, "Failed to request match on Connected signal: %m");
173
174 r = sd_bus_match_signal_async(
175 m->bus,
cad43595 176 NULL,
d7afd945
LP
177 "org.freedesktop.login1",
178 "/org/freedesktop/login1",
179 "org.freedesktop.login1.Manager",
180 "PrepareForSleep",
181 match_prepare_for_sleep, NULL, m);
182 if (r < 0)
183 log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m");
7901cea1 184
9c0a72f9
TG
185 return 0;
186}
187
d2ebf952
YW
188static int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata) {
189 Manager *m = userdata;
a7f95575 190 DeviceAction action;
5fae368b
TG
191 Link *link = NULL;
192 int r, ifindex;
5544ee85 193
5fae368b
TG
194 assert(m);
195 assert(device);
5544ee85 196
a7f95575 197 r = device_get_action(device, &action);
21486d9e 198 if (r < 0) {
a7f95575 199 log_device_debug_errno(device, r, "Failed to get udev action, ignoring device: %m");
5fae368b 200 return 0;
21486d9e
YW
201 }
202
a7f95575
YW
203 if (!IN_SET(action, DEVICE_ACTION_ADD, DEVICE_ACTION_CHANGE, DEVICE_ACTION_MOVE)) {
204 log_device_debug(device, "Ignoring udev %s event for device.", device_action_to_string(action));
21486d9e
YW
205 return 0;
206 }
5544ee85 207
51517f9e 208 r = sd_device_get_ifindex(device, &ifindex);
7606377e 209 if (r < 0) {
21486d9e 210 log_device_debug_errno(device, r, "Ignoring udev ADD event for device without ifindex or with invalid ifindex: %m");
5fae368b 211 return 0;
5544ee85
TG
212 }
213
299ad32d
YW
214 r = device_is_renaming(device);
215 if (r < 0) {
a7f95575
YW
216 log_device_error_errno(device, r, "Failed to determine the device is renamed or not, ignoring '%s' uevent: %m",
217 device_action_to_string(action));
299ad32d
YW
218 return 0;
219 }
220 if (r > 0) {
221 log_device_debug(device, "Interface is under renaming, wait for the interface to be renamed: %m");
222 return 0;
223 }
224
5fae368b 225 r = link_get(m, ifindex, &link);
d2ebf952
YW
226 if (r < 0) {
227 if (r != -ENODEV)
228 log_debug_errno(r, "Failed to get link from ifindex %i, ignoring: %m", ifindex);
5fae368b 229 return 0;
d2ebf952 230 }
02b59d57 231
d2ebf952 232 (void) link_initialized(link, device);
e1694a75 233
f579559b
TG
234 return 0;
235}
236
5fae368b
TG
237static int manager_connect_udev(Manager *m) {
238 int r;
f579559b 239
5fae368b
TG
240 /* udev does not initialize devices inside containers,
241 * so we rely on them being already initialized before
242 * entering the container */
75f86906 243 if (detect_container() > 0)
5fae368b 244 return 0;
f579559b 245
d2ebf952 246 r = sd_device_monitor_new(&m->device_monitor);
02b59d57 247 if (r < 0)
d2ebf952 248 return log_error_errno(r, "Failed to initialize device monitor: %m");
02b59d57 249
d2ebf952
YW
250 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "net", NULL);
251 if (r < 0)
252 return log_error_errno(r, "Could not add device monitor filter: %m");
505f8da7 253
deb2b734 254 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
5fae368b 255 if (r < 0)
d2ebf952 256 return log_error_errno(r, "Failed to attach event to device monitor: %m");
505f8da7 257
deb2b734 258 r = sd_device_monitor_start(m->device_monitor, manager_udev_process_link, m);
505f8da7 259 if (r < 0)
d2ebf952 260 return log_error_errno(r, "Failed to start device monitor: %m");
11a7f229 261
505f8da7
TG
262 return 0;
263}
f579559b 264
1c8e710c
TG
265int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
266 Manager *m = userdata;
267 Link *link = NULL;
268 uint16_t type;
269 uint32_t ifindex, priority = 0;
983226f3 270 unsigned char protocol, scope, tos, table, rt_type;
1c8e710c
TG
271 int family;
272 unsigned char dst_prefixlen, src_prefixlen;
67a46833 273 union in_addr_union dst = IN_ADDR_NULL, gw = IN_ADDR_NULL, src = IN_ADDR_NULL, prefsrc = IN_ADDR_NULL;
1c8e710c
TG
274 Route *route = NULL;
275 int r;
276
277 assert(rtnl);
278 assert(message);
279 assert(m);
280
281 if (sd_netlink_message_is_error(message)) {
282 r = sd_netlink_message_get_errno(message);
283 if (r < 0)
7f474ed7 284 log_warning_errno(r, "rtnl: failed to receive route message, ignoring: %m");
1c8e710c
TG
285
286 return 0;
287 }
288
289 r = sd_netlink_message_get_type(message, &type);
290 if (r < 0) {
e1694a75 291 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
1c8e710c 292 return 0;
25a1bffc 293 } else if (!IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE)) {
7f474ed7 294 log_warning("rtnl: received unexpected message type %u when processing route, ignoring.", type);
1c8e710c
TG
295 return 0;
296 }
297
298 r = sd_netlink_message_read_u32(message, RTA_OIF, &ifindex);
299 if (r == -ENODATA) {
300 log_debug("rtnl: received route without ifindex, ignoring");
301 return 0;
302 } else if (r < 0) {
7f474ed7 303 log_warning_errno(r, "rtnl: could not get ifindex from route message, ignoring: %m");
1c8e710c
TG
304 return 0;
305 } else if (ifindex <= 0) {
7f474ed7
YW
306 log_warning("rtnl: received route message with invalid ifindex %d, ignoring.", ifindex);
307 return 0;
308 }
309
310 r = link_get(m, ifindex, &link);
311 if (r < 0 || !link) {
312 /* when enumerating we might be out of sync, but we will
313 * get the route again, so just ignore it */
314 if (!m->enumerating)
315 log_warning("rtnl: received route for link (%d) we do not know about, ignoring", ifindex);
316 return 0;
1c8e710c
TG
317 }
318
319 r = sd_rtnl_message_route_get_family(message, &family);
320 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
7f474ed7 321 log_link_warning(link, "rtnl: received route message with invalid family, ignoring");
1c8e710c
TG
322 return 0;
323 }
324
325 r = sd_rtnl_message_route_get_protocol(message, &protocol);
326 if (r < 0) {
7f474ed7 327 log_warning_errno(r, "rtnl: received route message with invalid route protocol: %m");
1c8e710c
TG
328 return 0;
329 }
330
331 switch (family) {
332 case AF_INET:
333 r = sd_netlink_message_read_in_addr(message, RTA_DST, &dst.in);
334 if (r < 0 && r != -ENODATA) {
7f474ed7 335 log_link_warning_errno(link, r, "rtnl: received route message without valid destination, ignoring: %m");
1c8e710c
TG
336 return 0;
337 }
338
339 r = sd_netlink_message_read_in_addr(message, RTA_GATEWAY, &gw.in);
340 if (r < 0 && r != -ENODATA) {
7f474ed7 341 log_link_warning_errno(link, r, "rtnl: received route message without valid gateway, ignoring: %m");
1c8e710c
TG
342 return 0;
343 }
344
345 r = sd_netlink_message_read_in_addr(message, RTA_SRC, &src.in);
346 if (r < 0 && r != -ENODATA) {
7f474ed7 347 log_link_warning_errno(link, r, "rtnl: received route message without valid source, ignoring: %m");
1c8e710c
TG
348 return 0;
349 }
350
351 r = sd_netlink_message_read_in_addr(message, RTA_PREFSRC, &prefsrc.in);
352 if (r < 0 && r != -ENODATA) {
7f474ed7 353 log_link_warning_errno(link, r, "rtnl: received route message without valid preferred source, ignoring: %m");
1c8e710c
TG
354 return 0;
355 }
356
357 break;
358
359 case AF_INET6:
360 r = sd_netlink_message_read_in6_addr(message, RTA_DST, &dst.in6);
361 if (r < 0 && r != -ENODATA) {
7f474ed7 362 log_link_warning_errno(link, r, "rtnl: received route message without valid destination, ignoring: %m");
1c8e710c
TG
363 return 0;
364 }
365
366 r = sd_netlink_message_read_in6_addr(message, RTA_GATEWAY, &gw.in6);
367 if (r < 0 && r != -ENODATA) {
7f474ed7 368 log_link_warning_errno(link, r, "rtnl: received route message without valid gateway, ignoring: %m");
1c8e710c
TG
369 return 0;
370 }
371
372 r = sd_netlink_message_read_in6_addr(message, RTA_SRC, &src.in6);
373 if (r < 0 && r != -ENODATA) {
7f474ed7 374 log_link_warning_errno(link, r, "rtnl: received route message without valid source, ignoring: %m");
1c8e710c
TG
375 return 0;
376 }
377
378 r = sd_netlink_message_read_in6_addr(message, RTA_PREFSRC, &prefsrc.in6);
379 if (r < 0 && r != -ENODATA) {
7f474ed7 380 log_link_warning_errno(link, r, "rtnl: received route message without valid preferred source, ignoring: %m");
1c8e710c
TG
381 return 0;
382 }
383
384 break;
385
386 default:
7f474ed7 387 assert_not_reached("Received route message with unsupported address family");
1c8e710c
TG
388 return 0;
389 }
390
391 r = sd_rtnl_message_route_get_dst_prefixlen(message, &dst_prefixlen);
392 if (r < 0) {
393 log_link_warning_errno(link, r, "rtnl: received route with invalid destination prefixlen, ignoring: %m");
394 return 0;
395 }
396
397 r = sd_rtnl_message_route_get_src_prefixlen(message, &src_prefixlen);
398 if (r < 0) {
399 log_link_warning_errno(link, r, "rtnl: received route with invalid source prefixlen, ignoring: %m");
400 return 0;
401 }
402
403 r = sd_rtnl_message_route_get_scope(message, &scope);
404 if (r < 0) {
405 log_link_warning_errno(link, r, "rtnl: received route with invalid scope, ignoring: %m");
406 return 0;
407 }
408
409 r = sd_rtnl_message_route_get_tos(message, &tos);
410 if (r < 0) {
411 log_link_warning_errno(link, r, "rtnl: received route with invalid tos, ignoring: %m");
412 return 0;
413 }
414
983226f3
SS
415 r = sd_rtnl_message_route_get_type(message, &rt_type);
416 if (r < 0) {
417 log_link_warning_errno(link, r, "rtnl: received route with invalid type, ignoring: %m");
418 return 0;
419 }
420
1c8e710c
TG
421 r = sd_rtnl_message_route_get_table(message, &table);
422 if (r < 0) {
423 log_link_warning_errno(link, r, "rtnl: received route with invalid table, ignoring: %m");
424 return 0;
425 }
426
427 r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &priority);
428 if (r < 0 && r != -ENODATA) {
429 log_link_warning_errno(link, r, "rtnl: received route with invalid priority, ignoring: %m");
430 return 0;
431 }
432
e1694a75 433 (void) route_get(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
1c8e710c 434
156ed65e
YW
435 if (DEBUG_LOGGING) {
436 _cleanup_free_ char *buf_dst = NULL, *buf_dst_prefixlen = NULL,
437 *buf_src = NULL, *buf_gw = NULL, *buf_prefsrc = NULL;
438
439 if (!in_addr_is_null(family, &dst)) {
440 (void) in_addr_to_string(family, &dst, &buf_dst);
441 (void) asprintf(&buf_dst_prefixlen, "/%u", dst_prefixlen);
442 }
443 if (!in_addr_is_null(family, &src))
444 (void) in_addr_to_string(family, &src, &buf_src);
445 if (!in_addr_is_null(family, &gw))
446 (void) in_addr_to_string(family, &gw, &buf_gw);
447 if (!in_addr_is_null(family, &prefsrc))
448 (void) in_addr_to_string(family, &prefsrc, &buf_prefsrc);
449
450 log_link_debug(link,
451 "%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s",
7f474ed7 452 type == RTM_DELROUTE ? "Forgetting" : route ? "Updating remembered" : "Remembering",
156ed65e
YW
453 strna(buf_dst), strempty(buf_dst_prefixlen),
454 strna(buf_src), strna(buf_gw), strna(buf_prefsrc));
455 }
456
1c8e710c
TG
457 switch (type) {
458 case RTM_NEWROUTE:
459 if (!route) {
460 /* A route appeared that we did not request */
461 r = route_add_foreign(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
e1694a75 462 if (r < 0) {
7f474ed7 463 log_link_warning_errno(link, r, "Failed to remember foreign route, ignoring: %m");
1c8e710c 464 return 0;
e1694a75 465 }
1c8e710c
TG
466 }
467
bbd15900 468 route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, protocol, rt_type);
1c8e710c
TG
469
470 break;
471
472 case RTM_DELROUTE:
b9642f41 473 route_free(route);
1c8e710c 474 break;
b9642f41 475
1c8e710c 476 default:
7f474ed7 477 assert_not_reached("Received route message with invalid RTNL message type");
1c8e710c
TG
478 }
479
480 return 1;
481}
482
200a0868 483int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
57e44707 484 _cleanup_free_ char *buf = NULL;
200a0868
TG
485 Manager *m = userdata;
486 Link *link = NULL;
487 uint16_t type;
57e44707 488 unsigned char flags, prefixlen, scope;
67a46833 489 union in_addr_union in_addr = IN_ADDR_NULL;
054f0db4
TG
490 struct ifa_cacheinfo cinfo;
491 Address *address = NULL;
57e44707 492 char valid_buf[FORMAT_TIMESPAN_MAX];
200a0868 493 const char *valid_str = NULL;
57e44707 494 int ifindex, family, r;
200a0868
TG
495
496 assert(rtnl);
497 assert(message);
498 assert(m);
499
500 if (sd_netlink_message_is_error(message)) {
501 r = sd_netlink_message_get_errno(message);
502 if (r < 0)
44e891bb 503 log_warning_errno(r, "rtnl: failed to receive address message, ignoring: %m");
200a0868
TG
504
505 return 0;
506 }
507
508 r = sd_netlink_message_get_type(message, &type);
509 if (r < 0) {
e1694a75 510 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
200a0868 511 return 0;
25a1bffc 512 } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)) {
7f474ed7 513 log_warning("rtnl: received unexpected message type %u when processing address, ignoring.", type);
200a0868
TG
514 return 0;
515 }
516
517 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
518 if (r < 0) {
44e891bb 519 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
200a0868
TG
520 return 0;
521 } else if (ifindex <= 0) {
7f474ed7 522 log_warning("rtnl: received address message with invalid ifindex %d, ignoring.", ifindex);
200a0868 523 return 0;
44e891bb
ZJS
524 }
525
526 r = link_get(m, ifindex, &link);
527 if (r < 0 || !link) {
528 /* when enumerating we might be out of sync, but we will get the address again, so just
529 * ignore it */
530 if (!m->enumerating)
7f474ed7 531 log_warning("rtnl: received address for link '%d' we don't know about, ignoring.", ifindex);
44e891bb 532 return 0;
200a0868
TG
533 }
534
054f0db4
TG
535 r = sd_rtnl_message_addr_get_family(message, &family);
536 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
44e891bb 537 log_link_warning(link, "rtnl: received address message with invalid family, ignoring.");
200a0868
TG
538 return 0;
539 }
540
054f0db4 541 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
200a0868 542 if (r < 0) {
44e891bb 543 log_link_warning_errno(link, r, "rtnl: received address message with invalid prefixlen, ignoring: %m");
200a0868
TG
544 return 0;
545 }
546
054f0db4 547 r = sd_rtnl_message_addr_get_scope(message, &scope);
200a0868 548 if (r < 0) {
44e891bb 549 log_link_warning_errno(link, r, "rtnl: received address message with invalid scope, ignoring: %m");
200a0868
TG
550 return 0;
551 }
552
553 r = sd_rtnl_message_addr_get_flags(message, &flags);
554 if (r < 0) {
44e891bb 555 log_link_warning_errno(link, r, "rtnl: received address message with invalid flags, ignoring: %m");
200a0868
TG
556 return 0;
557 }
200a0868 558
054f0db4 559 switch (family) {
200a0868 560 case AF_INET:
054f0db4 561 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
200a0868 562 if (r < 0) {
44e891bb 563 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
200a0868
TG
564 return 0;
565 }
566
567 break;
568
569 case AF_INET6:
054f0db4 570 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
200a0868 571 if (r < 0) {
44e891bb 572 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
200a0868
TG
573 return 0;
574 }
575
576 break;
577
578 default:
e1694a75 579 assert_not_reached("Received unsupported address family");
200a0868
TG
580 }
581
57e44707 582 r = in_addr_to_string(family, &in_addr, &buf);
44e891bb
ZJS
583 if (r < 0)
584 log_link_warning_errno(link, r, "Could not print address: %m");
200a0868 585
054f0db4 586 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
e1694a75
YW
587 if (r < 0 && r != -ENODATA) {
588 log_link_warning_errno(link, r, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m");
589 return 0;
57e44707
YW
590 } else if (r >= 0 && cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
591 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
592 cinfo.ifa_valid * USEC_PER_SEC,
593 USEC_PER_SEC);
200a0868 594
e1694a75 595 (void) address_get(link, family, &in_addr, prefixlen, &address);
200a0868
TG
596
597 switch (type) {
598 case RTM_NEWADDR:
36c32f61 599 if (address)
44e891bb
ZJS
600 log_link_debug(link, "Remembering updated address: %s/%u (valid %s%s)",
601 strnull(buf), prefixlen,
87e4e28d 602 valid_str ? "for " : "forever", strempty(valid_str));
36c32f61 603 else {
adda1ed9
TG
604 /* An address appeared that we did not request */
605 r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
cf1d700d 606 if (r < 0) {
44e891bb
ZJS
607 log_link_warning_errno(link, r, "Failed to remember foreign address %s/%u, ignoring: %m",
608 strnull(buf), prefixlen);
cf1d700d
TG
609 return 0;
610 } else
44e891bb
ZJS
611 log_link_debug(link, "Remembering foreign address: %s/%u (valid %s%s)",
612 strnull(buf), prefixlen,
87e4e28d 613 valid_str ? "for " : "forever", strempty(valid_str));
200a0868
TG
614 }
615
44e891bb
ZJS
616 /* address_update() logs internally, so we don't need to. */
617 (void) address_update(address, flags, scope, &cinfo);
36c32f61 618
200a0868
TG
619 break;
620
621 case RTM_DELADDR:
054f0db4 622 if (address) {
44e891bb
ZJS
623 log_link_debug(link, "Forgetting address: %s/%u (valid %s%s)",
624 strnull(buf), prefixlen,
87e4e28d 625 valid_str ? "for " : "forever", strempty(valid_str));
e1694a75 626 (void) address_drop(address);
200a0868 627 } else
44e891bb
ZJS
628 log_link_info(link, "Kernel removed an address we don't remember: %s/%u (valid %s%s), ignoring.",
629 strnull(buf), prefixlen,
630 valid_str ? "for " : "forever", strempty(valid_str));
200a0868
TG
631
632 break;
44e891bb 633
200a0868
TG
634 default:
635 assert_not_reached("Received invalid RTNL message type");
636 }
637
638 return 1;
639}
640
1c4baffc 641static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
505f8da7
TG
642 Manager *m = userdata;
643 Link *link = NULL;
4d473d5d 644 NetDev *netdev = NULL;
f2236469 645 uint16_t type;
ca4e095a 646 const char *name;
505f8da7 647 int r, ifindex;
f579559b 648
505f8da7
TG
649 assert(rtnl);
650 assert(message);
f579559b
TG
651 assert(m);
652
1c4baffc
TG
653 if (sd_netlink_message_is_error(message)) {
654 r = sd_netlink_message_get_errno(message);
45af44d4 655 if (r < 0)
7f474ed7 656 log_warning_errno(r, "rtnl: Could not receive link message, ignoring: %m");
45af44d4
TG
657
658 return 0;
659 }
660
1c4baffc 661 r = sd_netlink_message_get_type(message, &type);
f2236469 662 if (r < 0) {
e1694a75 663 log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m");
f2236469 664 return 0;
25a1bffc 665 } else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)) {
7f474ed7 666 log_warning("rtnl: Received unexpected message type %u when processing link, ignoring.", type);
cdfee943 667 return 0;
f2236469
TG
668 }
669
505f8da7 670 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
45af44d4 671 if (r < 0) {
7f474ed7 672 log_warning_errno(r, "rtnl: Could not get ifindex from link message, ignoring: %m");
45af44d4
TG
673 return 0;
674 } else if (ifindex <= 0) {
7f474ed7 675 log_warning("rtnl: received link message with invalid ifindex %d, ignoring.", ifindex);
505f8da7 676 return 0;
a0db8e46 677 }
f579559b 678
1c4baffc 679 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
45af44d4 680 if (r < 0) {
e1694a75 681 log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m");
4d473d5d 682 return 0;
a0db8e46
ZJS
683 }
684
685 (void) link_get(m, ifindex, &link);
686 (void) netdev_get(m, name, &netdev);
4d473d5d
TG
687
688 switch (type) {
689 case RTM_NEWLINK:
690 if (!link) {
691 /* link is new, so add it */
692 r = link_add(m, message, &link);
693 if (r < 0) {
7f474ed7 694 log_warning_errno(r, "Could not process new link message, ignoring: %m");
4d473d5d
TG
695 return 0;
696 }
697 }
698
699 if (netdev) {
700 /* netdev exists, so make sure the ifindex matches */
505f8da7
TG
701 r = netdev_set_ifindex(netdev, message);
702 if (r < 0) {
7f474ed7 703 log_warning_errno(r, "Could not process new link message for netdev, ignoring: %m");
505f8da7
TG
704 return 0;
705 }
706 }
e1202047 707
f2236469 708 r = link_update(link, message);
e1694a75 709 if (r < 0) {
7f474ed7 710 log_warning_errno(r, "Could not process link message, ignoring: %m");
f2236469 711 return 0;
e1694a75 712 }
4d473d5d
TG
713
714 break;
715
716 case RTM_DELLINK:
717 link_drop(link);
718 netdev_drop(netdev);
719
720 break;
721
722 default:
7f474ed7 723 assert_not_reached("Received link message with invalid RTNL message type.");
f2236469 724 }
505f8da7
TG
725
726 return 1;
727}
728
bce67bbe 729int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
b80a511b 730 _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
bce67bbe 731 RoutingPolicyRule *rule = NULL;
eeab051b 732 const char *iif = NULL, *oif = NULL;
bce67bbe 733 Manager *m = userdata;
b80a511b 734 unsigned flags;
bce67bbe 735 uint16_t type;
bce67bbe
SS
736 int r;
737
738 assert(rtnl);
739 assert(message);
740 assert(m);
741
742 if (sd_netlink_message_is_error(message)) {
743 r = sd_netlink_message_get_errno(message);
744 if (r < 0)
7f474ed7 745 log_warning_errno(r, "rtnl: failed to receive rule message, ignoring: %m");
bce67bbe
SS
746
747 return 0;
748 }
749
750 r = sd_netlink_message_get_type(message, &type);
751 if (r < 0) {
e1694a75 752 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
bce67bbe
SS
753 return 0;
754 } else if (!IN_SET(type, RTM_NEWRULE, RTM_DELRULE)) {
7f474ed7 755 log_warning("rtnl: received unexpected message type %u when processing rule, ignoring.", type);
bce67bbe
SS
756 return 0;
757 }
758
b80a511b
YW
759 r = routing_policy_rule_new(&tmp);
760 if (r < 0) {
761 log_oom();
762 return 0;
763 }
764
765 r = sd_rtnl_message_get_family(message, &tmp->family);
615ded62 766 if (r < 0) {
e1694a75 767 log_warning_errno(r, "rtnl: could not get rule family, ignoring: %m");
615ded62 768 return 0;
b80a511b 769 } else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) {
7f474ed7 770 log_debug("rtnl: received rule message with invalid family %d, ignoring.", tmp->family);
bce67bbe
SS
771 return 0;
772 }
773
b80a511b 774 switch (tmp->family) {
bce67bbe 775 case AF_INET:
b80a511b 776 r = sd_netlink_message_read_in_addr(message, FRA_SRC, &tmp->from.in);
e1694a75
YW
777 if (r < 0 && r != -ENODATA) {
778 log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m");
779 return 0;
780 } else if (r >= 0) {
b80a511b 781 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen);
e1694a75 782 if (r < 0) {
7f474ed7 783 log_warning_errno(r, "rtnl: received rule message without valid source prefix length, ignoring: %m");
e1694a75
YW
784 return 0;
785 }
bce67bbe
SS
786 }
787
b80a511b 788 r = sd_netlink_message_read_in_addr(message, FRA_DST, &tmp->to.in);
e1694a75
YW
789 if (r < 0 && r != -ENODATA) {
790 log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m");
791 return 0;
792 } else if (r >= 0) {
b80a511b 793 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen);
e1694a75 794 if (r < 0) {
7f474ed7 795 log_warning_errno(r, "rtnl: received rule message without valid destination prefix length, ignoring: %m");
e1694a75
YW
796 return 0;
797 }
bce67bbe
SS
798 }
799
800 break;
801
802 case AF_INET6:
b80a511b 803 r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &tmp->from.in6);
e1694a75
YW
804 if (r < 0 && r != -ENODATA) {
805 log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m");
806 return 0;
807 } else if (r >= 0) {
b80a511b 808 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen);
e1694a75 809 if (r < 0) {
7f474ed7 810 log_warning_errno(r, "rtnl: received rule message without valid source prefix length, ignoring: %m");
e1694a75
YW
811 return 0;
812 }
bce67bbe
SS
813 }
814
b80a511b 815 r = sd_netlink_message_read_in6_addr(message, FRA_DST, &tmp->to.in6);
e1694a75
YW
816 if (r < 0 && r != -ENODATA) {
817 log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m");
818 return 0;
819 } else if (r >= 0) {
b80a511b 820 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen);
e1694a75 821 if (r < 0) {
7f474ed7 822 log_warning_errno(r, "rtnl: received rule message without valid destination prefix length, ignoring: %m");
e1694a75
YW
823 return 0;
824 }
bce67bbe
SS
825 }
826
827 break;
828
829 default:
7f474ed7 830 assert_not_reached("Received rule message with unsupported address family");
bce67bbe
SS
831 }
832
b80a511b 833 if (tmp->from_prefixlen == 0 && tmp->to_prefixlen == 0)
bce67bbe
SS
834 return 0;
835
b80a511b
YW
836 r = sd_rtnl_message_routing_policy_rule_get_flags(message, &flags);
837 if (r < 0) {
7f474ed7 838 log_warning_errno(r, "rtnl: received rule message without valid flag, ignoring: %m");
b80a511b
YW
839 return 0;
840 }
841 tmp->invert_rule = flags & FIB_RULE_INVERT;
842
843 r = sd_netlink_message_read_u32(message, FRA_FWMARK, &tmp->fwmark);
e1694a75
YW
844 if (r < 0 && r != -ENODATA) {
845 log_warning_errno(r, "rtnl: could not get FRA_FWMARK attribute, ignoring: %m");
846 return 0;
847 }
848
b80a511b
YW
849 r = sd_netlink_message_read_u32(message, FRA_FWMASK, &tmp->fwmask);
850 if (r < 0 && r != -ENODATA) {
851 log_warning_errno(r, "rtnl: could not get FRA_FWMASK attribute, ignoring: %m");
852 return 0;
853 }
854
855 r = sd_netlink_message_read_u32(message, FRA_PRIORITY, &tmp->priority);
856 if (r < 0 && r != -ENODATA) {
857 log_warning_errno(r, "rtnl: could not get FRA_PRIORITY attribute, ignoring: %m");
858 return 0;
859 }
860
861 r = sd_netlink_message_read_u32(message, FRA_TABLE, &tmp->table);
e1694a75
YW
862 if (r < 0 && r != -ENODATA) {
863 log_warning_errno(r, "rtnl: could not get FRA_TABLE attribute, ignoring: %m");
864 return 0;
865 }
866
b80a511b 867 r = sd_rtnl_message_routing_policy_rule_get_tos(message, &tmp->tos);
e1694a75
YW
868 if (r < 0 && r != -ENODATA) {
869 log_warning_errno(r, "rtnl: could not get ip rule TOS, ignoring: %m");
870 return 0;
871 }
872
eeab051b 873 r = sd_netlink_message_read_string(message, FRA_IIFNAME, &iif);
e1694a75
YW
874 if (r < 0 && r != -ENODATA) {
875 log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m");
876 return 0;
877 }
b80a511b
YW
878 r = free_and_strdup(&tmp->iif, iif);
879 if (r < 0)
880 return log_oom();
e1694a75 881
eeab051b 882 r = sd_netlink_message_read_string(message, FRA_OIFNAME, &oif);
e1694a75
YW
883 if (r < 0 && r != -ENODATA) {
884 log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m");
885 return 0;
886 }
b80a511b
YW
887 r = free_and_strdup(&tmp->oif, oif);
888 if (r < 0)
889 return log_oom();
bce67bbe 890
b80a511b 891 r = sd_netlink_message_read_u8(message, FRA_IP_PROTO, &tmp->protocol);
926062f0
SS
892 if (r < 0 && r != -ENODATA) {
893 log_warning_errno(r, "rtnl: could not get FRA_IP_PROTO attribute, ignoring: %m");
894 return 0;
895 }
896
b80a511b 897 r = sd_netlink_message_read(message, FRA_SPORT_RANGE, sizeof(tmp->sport), &tmp->sport);
926062f0
SS
898 if (r < 0 && r != -ENODATA) {
899 log_warning_errno(r, "rtnl: could not get FRA_SPORT_RANGE attribute, ignoring: %m");
900 return 0;
901 }
902
b80a511b 903 r = sd_netlink_message_read(message, FRA_DPORT_RANGE, sizeof(tmp->dport), &tmp->dport);
926062f0
SS
904 if (r < 0 && r != -ENODATA) {
905 log_warning_errno(r, "rtnl: could not get FRA_DPORT_RANGE attribute, ignoring: %m");
906 return 0;
907 }
908
b80a511b 909 (void) routing_policy_rule_get(m, tmp, &rule);
bce67bbe
SS
910
911 switch (type) {
912 case RTM_NEWRULE:
508f63b4 913 if (!rule) {
b80a511b 914 r = routing_policy_rule_add_foreign(m, tmp, &rule);
bce67bbe 915 if (r < 0) {
7f474ed7 916 log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
bce67bbe
SS
917 return 0;
918 }
919 }
920 break;
921 case RTM_DELRULE:
922 routing_policy_rule_free(rule);
923
924 break;
925
926 default:
927 assert_not_reached("Received invalid RTNL message type");
928 }
929
930 return 1;
931}
932
5fae368b
TG
933static int systemd_netlink_fd(void) {
934 int n, fd, rtnl_fd = -EINVAL;
935
936 n = sd_listen_fds(true);
937 if (n <= 0)
938 return -EINVAL;
939
940 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
941 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
942 if (rtnl_fd >= 0)
943 return -EINVAL;
944
945 rtnl_fd = fd;
946 }
947 }
948
949 return rtnl_fd;
950}
951
05d0c2e3
JT
952static int manager_connect_genl(Manager *m) {
953 int r;
954
955 assert(m);
956
957 r = sd_genl_socket_open(&m->genl);
958 if (r < 0)
959 return r;
960
961 r = sd_netlink_inc_rcvbuf(m->genl, RCVBUF_SIZE);
962 if (r < 0)
963 return r;
964
965 r = sd_netlink_attach_event(m->genl, m->event, 0);
966 if (r < 0)
967 return r;
968
969 return 0;
970}
971
5fae368b
TG
972static int manager_connect_rtnl(Manager *m) {
973 int fd, r;
505f8da7
TG
974
975 assert(m);
505f8da7 976
5fae368b
TG
977 fd = systemd_netlink_fd();
978 if (fd < 0)
1c4baffc 979 r = sd_netlink_open(&m->rtnl);
5fae368b 980 else
1c4baffc 981 r = sd_netlink_open_fd(&m->rtnl, fd);
505f8da7
TG
982 if (r < 0)
983 return r;
984
1c4baffc 985 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
f579559b 986 if (r < 0)
bf5332d2 987 return r;
f579559b 988
1c4baffc 989 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
505f8da7
TG
990 if (r < 0)
991 return r;
f579559b 992
8190a388 993 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
5fae368b
TG
994 if (r < 0)
995 return r;
505f8da7 996
8190a388 997 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
5fae368b
TG
998 if (r < 0)
999 return r;
45af44d4 1000
8190a388 1001 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
5fae368b
TG
1002 if (r < 0)
1003 return r;
1004
8190a388 1005 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
5fae368b
TG
1006 if (r < 0)
1007 return r;
1008
8190a388 1009 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
1c8e710c
TG
1010 if (r < 0)
1011 return r;
1012
8190a388 1013 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
1c8e710c
TG
1014 if (r < 0)
1015 return r;
1016
8190a388 1017 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
bce67bbe
SS
1018 if (r < 0)
1019 return r;
1020
8190a388 1021 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
bce67bbe
SS
1022 if (r < 0)
1023 return r;
1024
5fae368b 1025 return 0;
45af44d4 1026}
505f8da7 1027
5512a963 1028static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
84de38c5
TG
1029 char *p;
1030 int r;
1031
1032 assert(s);
5512a963
LP
1033 assert(address);
1034
1035 r = in_addr_to_string(address->family, &address->address, &p);
1036 if (r < 0)
1037 return r;
1038
1039 r = ordered_set_consume(s, p);
1040 if (r == -EEXIST)
1041 return 0;
1042
1043 return r;
1044}
1045
1046static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
1047 int r, c = 0;
1048 unsigned i;
1049
1050 assert(s);
1051 assert(addresses || n == 0);
1052
1053 for (i = 0; i < n; i++) {
1054 r = ordered_set_put_in_addr_data(s, addresses+i);
1055 if (r < 0)
1056 return r;
1057
1058 c += r;
1059 }
1060
1061 return c;
1062}
1063
1064static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
1065 char *p;
1066 int r;
1067
1068 assert(s);
1069 assert(address);
84de38c5
TG
1070
1071 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
1072 if (r < 0)
1073 return r;
1074
00616955 1075 r = ordered_set_consume(s, p);
84de38c5
TG
1076 if (r == -EEXIST)
1077 return 0;
1078
1079 return r;
1080}
1081
072320ea
TH
1082static int ordered_set_put_in4_addrv(OrderedSet *s,
1083 const struct in_addr *addresses,
1084 size_t n,
1085 bool (*predicate)(const struct in_addr *addr)) {
5512a963 1086 int r, c = 0;
072320ea 1087 size_t i;
84de38c5
TG
1088
1089 assert(s);
5512a963 1090 assert(n == 0 || addresses);
84de38c5
TG
1091
1092 for (i = 0; i < n; i++) {
072320ea
TH
1093 if (predicate && !predicate(&addresses[i]))
1094 continue;
5512a963 1095 r = ordered_set_put_in4_addr(s, addresses+i);
84de38c5
TG
1096 if (r < 0)
1097 return r;
1098
1099 c += r;
1100 }
1101
1102 return c;
1103}
1104
84de38c5 1105static int manager_save(Manager *m) {
00616955 1106 _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
84de38c5
TG
1107 Link *link;
1108 Iterator i;
1109 _cleanup_free_ char *temp_path = NULL;
7f3c07ad 1110 _cleanup_strv_free_ char **p = NULL;
84de38c5
TG
1111 _cleanup_fclose_ FILE *f = NULL;
1112 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
7f3c07ad
YW
1113 LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
1114 LinkAddressState address_state = LINK_ADDRESS_STATE_OFF;
ac999bf0 1115 const char *operstate_str, *carrier_state_str, *address_state_str;
84de38c5
TG
1116 int r;
1117
1118 assert(m);
1119 assert(m->state_file);
1120
1121 /* We add all NTP and DNS server to a set, to filter out duplicates */
00616955 1122 dns = ordered_set_new(&string_hash_ops);
84de38c5
TG
1123 if (!dns)
1124 return -ENOMEM;
1125
00616955 1126 ntp = ordered_set_new(&string_hash_ops);
84de38c5
TG
1127 if (!ntp)
1128 return -ENOMEM;
1129
482d1aeb 1130 search_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5
LP
1131 if (!search_domains)
1132 return -ENOMEM;
1133
482d1aeb 1134 route_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5 1135 if (!route_domains)
84de38c5
TG
1136 return -ENOMEM;
1137
1138 HASHMAP_FOREACH(link, m->links, i) {
1139 if (link->flags & IFF_LOOPBACK)
1140 continue;
1141
1142 if (link->operstate > operstate)
1143 operstate = link->operstate;
1144
7f3c07ad
YW
1145 if (link->carrier_state > carrier_state)
1146 carrier_state = link->carrier_state;
1147
1148 if (link->address_state > address_state)
1149 address_state = link->address_state;
1150
84de38c5
TG
1151 if (!link->network)
1152 continue;
1153
1154 /* First add the static configured entries */
5512a963 1155 r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
84de38c5
TG
1156 if (r < 0)
1157 return r;
1158
00616955 1159 r = ordered_set_put_strdupv(ntp, link->network->ntp);
84de38c5
TG
1160 if (r < 0)
1161 return r;
1162
5e2a51d5 1163 r = ordered_set_put_string_set(search_domains, link->network->search_domains);
3df9bec5
LP
1164 if (r < 0)
1165 return r;
1166
5e2a51d5 1167 r = ordered_set_put_string_set(route_domains, link->network->route_domains);
84de38c5
TG
1168 if (r < 0)
1169 return r;
1170
1171 if (!link->dhcp_lease)
1172 continue;
1173
1174 /* Secondly, add the entries acquired via DHCP */
27cb34f5 1175 if (link->network->dhcp_use_dns) {
84de38c5
TG
1176 const struct in_addr *addresses;
1177
1178 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1179 if (r > 0) {
072320ea 1180 r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local);
84de38c5
TG
1181 if (r < 0)
1182 return r;
1183 } else if (r < 0 && r != -ENODATA)
1184 return r;
1185 }
1186
27cb34f5 1187 if (link->network->dhcp_use_ntp) {
84de38c5
TG
1188 const struct in_addr *addresses;
1189
1190 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1191 if (r > 0) {
072320ea 1192 r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local);
84de38c5
TG
1193 if (r < 0)
1194 return r;
1195 } else if (r < 0 && r != -ENODATA)
1196 return r;
1197 }
1198
b2a81c0b 1199 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
84de38c5 1200 const char *domainname;
b85bc551 1201 char **domains = NULL;
84de38c5 1202
b85bc551 1203 OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
84de38c5
TG
1204 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1205 if (r >= 0) {
b85bc551
DW
1206 r = ordered_set_put_strdup(target_domains, domainname);
1207 if (r < 0)
1208 return r;
1209 } else if (r != -ENODATA)
1210 return r;
b2a81c0b 1211
b85bc551
DW
1212 r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
1213 if (r >= 0) {
1214 r = ordered_set_put_strdupv(target_domains, domains);
84de38c5
TG
1215 if (r < 0)
1216 return r;
1217 } else if (r != -ENODATA)
1218 return r;
1219 }
1220 }
1221
7f3c07ad
YW
1222 if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED)
1223 carrier_state = LINK_CARRIER_STATE_CARRIER;
1224
84de38c5
TG
1225 operstate_str = link_operstate_to_string(operstate);
1226 assert(operstate_str);
1227
ac999bf0
YW
1228 carrier_state_str = link_carrier_state_to_string(carrier_state);
1229 assert(carrier_state_str);
1230
1231 address_state_str = link_address_state_to_string(address_state);
1232 assert(address_state_str);
1233
84de38c5
TG
1234 r = fopen_temporary(m->state_file, &f, &temp_path);
1235 if (r < 0)
1236 return r;
1237
5512a963 1238 (void) fchmod(fileno(f), 0644);
84de38c5
TG
1239
1240 fprintf(f,
1241 "# This is private data. Do not parse.\n"
ac999bf0
YW
1242 "OPER_STATE=%s\n"
1243 "CARRIER_STATE=%s\n"
1244 "ADDRESS_STATE=%s\n",
1245 operstate_str, carrier_state_str, address_state_str);
84de38c5 1246
53ae3f64
ZJS
1247 ordered_set_print(f, "DNS=", dns);
1248 ordered_set_print(f, "NTP=", ntp);
1249 ordered_set_print(f, "DOMAINS=", search_domains);
1250 ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
84de38c5 1251
458d8ae3
ZJS
1252 r = routing_policy_serialize_rules(m->rules, f);
1253 if (r < 0)
1254 goto fail;
bce67bbe 1255
84de38c5
TG
1256 r = fflush_and_check(f);
1257 if (r < 0)
1258 goto fail;
1259
1260 if (rename(temp_path, m->state_file) < 0) {
1261 r = -errno;
1262 goto fail;
1263 }
1264
1265 if (m->operational_state != operstate) {
1266 m->operational_state = operstate;
7f3c07ad
YW
1267 if (strv_extend(&p, "OperationalState") < 0)
1268 log_oom();
1269 }
1270
1271 if (m->carrier_state != carrier_state) {
1272 m->carrier_state = carrier_state;
1273 if (strv_extend(&p, "CarrierState") < 0)
1274 log_oom();
1275 }
1276
1277 if (m->address_state != address_state) {
1278 m->address_state = address_state;
1279 if (strv_extend(&p, "AddressState") < 0)
1280 log_oom();
1281 }
1282
1283 if (p) {
1284 r = manager_send_changed_strv(m, p);
84de38c5 1285 if (r < 0)
7f3c07ad 1286 log_error_errno(r, "Could not emit changed properties: %m");
84de38c5
TG
1287 }
1288
1289 m->dirty = false;
1290
1291 return 0;
1292
1293fail:
1294 (void) unlink(m->state_file);
1295 (void) unlink(temp_path);
1296
1297 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
1298}
1299
1300static int manager_dirty_handler(sd_event_source *s, void *userdata) {
1301 Manager *m = userdata;
1302 Link *link;
1303 Iterator i;
84de38c5
TG
1304
1305 assert(m);
1306
1307 if (m->dirty)
1308 manager_save(m);
1309
a0e8e4cf
YW
1310 SET_FOREACH(link, m->dirty_links, i)
1311 if (link_save(link) >= 0)
84de38c5 1312 link_clean(link);
84de38c5
TG
1313
1314 return 1;
1315}
1316
3534a043 1317int manager_new(Manager **ret) {
8e766630 1318 _cleanup_(manager_freep) Manager *m = NULL;
45af44d4 1319 int r;
f579559b 1320
a879e1a4 1321 m = new(Manager, 1);
5fae368b
TG
1322 if (!m)
1323 return -ENOMEM;
45af44d4 1324
a879e1a4
YW
1325 *m = (Manager) {
1326 .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
1327 };
1328
5fae368b
TG
1329 m->state_file = strdup("/run/systemd/netif/state");
1330 if (!m->state_file)
1331 return -ENOMEM;
1332
3534a043
YW
1333 r = sd_event_default(&m->event);
1334 if (r < 0)
1335 return r;
1336
05e21627
YW
1337 (void) sd_event_set_watchdog(m->event, true);
1338 (void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
1339 (void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
5fae368b 1340
84de38c5
TG
1341 r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
1342 if (r < 0)
1343 return r;
1344
5fae368b 1345 r = manager_connect_rtnl(m);
45af44d4
TG
1346 if (r < 0)
1347 return r;
1348
05d0c2e3
JT
1349 r = manager_connect_genl(m);
1350 if (r < 0)
1351 return r;
1352
5fae368b
TG
1353 r = manager_connect_udev(m);
1354 if (r < 0)
1355 return r;
45af44d4 1356
05d0c2e3
JT
1357 r = sd_resolve_default(&m->resolve);
1358 if (r < 0)
1359 return r;
1360
1361 r = sd_resolve_attach_event(m->resolve, m->event, 0);
1362 if (r < 0)
1363 return r;
1364
5fae368b
TG
1365 r = setup_default_address_pool(m);
1366 if (r < 0)
1367 return r;
f579559b 1368
8341a5c3 1369 m->duid.type = DUID_TYPE_EN;
413708d1 1370
458d8ae3 1371 (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
bce67bbe 1372
1cc6c93a 1373 *ret = TAKE_PTR(m);
f579559b 1374
f579559b
TG
1375 return 0;
1376}
1377
5fae368b 1378void manager_free(Manager *m) {
2c448c8a 1379 struct in6_addr *a;
c4397d94 1380 AddressPool *pool;
5fae368b 1381 Link *link;
f579559b 1382
5fae368b
TG
1383 if (!m)
1384 return;
505f8da7 1385
5fae368b 1386 free(m->state_file);
505f8da7 1387
2c448c8a 1388 while ((a = hashmap_first_key(m->dhcp6_prefixes)))
04ed9949 1389 (void) dhcp6_prefix_remove(m, a);
e133b289
PF
1390 hashmap_free(m->dhcp6_prefixes);
1391
f61365e5 1392 while ((link = hashmap_steal_first(m->links))) {
65dd5e31 1393 if (link->dhcp6_client)
f61365e5 1394 (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, link);
946f8e14 1395
95355a28 1396 (void) link_stop_clients(link, true);
946f8e14 1397
5fae368b 1398 link_unref(link);
65dd5e31 1399 }
f579559b 1400
c4397d94 1401 m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
5f707e12
YW
1402 m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
1403 m->links = hashmap_free_with_destructor(m->links, link_unref);
27dfc982 1404
5f707e12 1405 m->duids_requesting_uuid = set_free(m->duids_requesting_uuid);
715d398e 1406 m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
dbffab87 1407
c4397d94 1408 m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
5fae368b
TG
1409
1410 while ((pool = m->address_pools))
1411 address_pool_free(pool);
1412
f19ee681
YW
1413 /* routing_policy_rule_free() access m->rules and m->rules_foreign.
1414 * So, it is necessary to set NULL after the sets are freed. */
1415 m->rules = set_free_with_destructor(m->rules, routing_policy_rule_free);
1416 m->rules_foreign = set_free_with_destructor(m->rules_foreign, routing_policy_rule_free);
b921fcb2 1417 set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
bce67bbe 1418
d4df6326
SS
1419 sd_netlink_unref(m->rtnl);
1420 sd_netlink_unref(m->genl);
1421 sd_resolve_unref(m->resolve);
1422
a879e1a4 1423 sd_event_source_unref(m->speed_meter_event_source);
2f5b4a77 1424 sd_event_unref(m->event);
5fae368b 1425
d2ebf952 1426 sd_device_monitor_unref(m->device_monitor);
7d20d375 1427
92e31da1 1428 sd_bus_flush_close_unref(m->bus);
7d20d375 1429
7901cea1
MP
1430 free(m->dynamic_timezone);
1431 free(m->dynamic_hostname);
1432
5fae368b
TG
1433 free(m);
1434}
1435
b76d99d9 1436int manager_start(Manager *m) {
84de38c5
TG
1437 Link *link;
1438 Iterator i;
a879e1a4 1439 int r;
84de38c5 1440
a97dcc12
TG
1441 assert(m);
1442
a879e1a4
YW
1443 r = manager_start_speed_meter(m);
1444 if (r < 0)
1445 return log_error_errno(r, "Failed to initialize speed meter: %m");
1446
84de38c5
TG
1447 /* The dirty handler will deal with future serialization, but the first one
1448 must be done explicitly. */
1449
1450 manager_save(m);
1451
1452 HASHMAP_FOREACH(link, m->links, i)
1453 link_save(link);
1454
b76d99d9 1455 return 0;
a97dcc12
TG
1456}
1457
5fae368b
TG
1458int manager_load_config(Manager *m) {
1459 int r;
1460
1461 /* update timestamp */
dc0d4078 1462 paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, true);
5fae368b
TG
1463
1464 r = netdev_load(m);
f579559b
TG
1465 if (r < 0)
1466 return r;
1467
5fae368b 1468 r = network_load(m);
9021bb9f
TG
1469 if (r < 0)
1470 return r;
1471
f579559b
TG
1472 return 0;
1473}
f882c247 1474
5fae368b 1475bool manager_should_reload(Manager *m) {
dc0d4078 1476 return paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, false);
5fae368b
TG
1477}
1478
1479int manager_rtnl_enumerate_links(Manager *m) {
4afd3348 1480 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1481 sd_netlink_message *link;
f882c247
TG
1482 int r;
1483
5da8149f 1484 assert(m);
5fae368b 1485 assert(m->rtnl);
5da8149f 1486
5fae368b 1487 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
f882c247
TG
1488 if (r < 0)
1489 return r;
1490
1c4baffc 1491 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
1492 if (r < 0)
1493 return r;
1494
1c4baffc 1495 r = sd_netlink_call(m->rtnl, req, 0, &reply);
f2236469
TG
1496 if (r < 0)
1497 return r;
1498
1c4baffc 1499 for (link = reply; link; link = sd_netlink_message_next(link)) {
5fae368b 1500 int k;
2e9f08ea 1501
6a24f148
TG
1502 m->enumerating = true;
1503
5fae368b
TG
1504 k = manager_rtnl_process_link(m->rtnl, link, m);
1505 if (k < 0)
1506 r = k;
6a24f148
TG
1507
1508 m->enumerating = false;
5fae368b 1509 }
2e9f08ea 1510
5fae368b 1511 return r;
f882c247 1512}
3bef724f 1513
5fae368b 1514int manager_rtnl_enumerate_addresses(Manager *m) {
4afd3348 1515 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1516 sd_netlink_message *addr;
1346b1f0
TG
1517 int r;
1518
5fae368b
TG
1519 assert(m);
1520 assert(m->rtnl);
bcbca829 1521
5fae368b
TG
1522 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
1523 if (r < 0)
1524 return r;
bcbca829 1525
1c4baffc 1526 r = sd_netlink_message_request_dump(req, true);
1346b1f0
TG
1527 if (r < 0)
1528 return r;
1529
1c4baffc 1530 r = sd_netlink_call(m->rtnl, req, 0, &reply);
5fae368b
TG
1531 if (r < 0)
1532 return r;
1533
1c4baffc 1534 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
5fae368b
TG
1535 int k;
1536
6a24f148
TG
1537 m->enumerating = true;
1538
200a0868 1539 k = manager_rtnl_process_address(m->rtnl, addr, m);
5fae368b
TG
1540 if (k < 0)
1541 r = k;
6a24f148
TG
1542
1543 m->enumerating = false;
5fae368b
TG
1544 }
1545
1546 return r;
1346b1f0
TG
1547}
1548
1c8e710c 1549int manager_rtnl_enumerate_routes(Manager *m) {
4afd3348 1550 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c8e710c
TG
1551 sd_netlink_message *route;
1552 int r;
1553
1554 assert(m);
1555 assert(m->rtnl);
1556
1557 r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
1558 if (r < 0)
1559 return r;
1560
1561 r = sd_netlink_message_request_dump(req, true);
1562 if (r < 0)
1563 return r;
1564
1565 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1566 if (r < 0)
1567 return r;
1568
1569 for (route = reply; route; route = sd_netlink_message_next(route)) {
1570 int k;
1571
1572 m->enumerating = true;
1573
1574 k = manager_rtnl_process_route(m->rtnl, route, m);
1575 if (k < 0)
1576 r = k;
1577
1578 m->enumerating = false;
1579 }
1580
1581 return r;
1582}
1583
bce67bbe
SS
1584int manager_rtnl_enumerate_rules(Manager *m) {
1585 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1586 sd_netlink_message *rule;
1587 int r;
1588
1589 assert(m);
1590 assert(m->rtnl);
1591
1592 r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
1593 if (r < 0)
1594 return r;
1595
1596 r = sd_netlink_message_request_dump(req, true);
1597 if (r < 0)
1598 return r;
1599
1600 r = sd_netlink_call(m->rtnl, req, 0, &reply);
6acbbdd4
SS
1601 if (r < 0) {
1602 if (r == -EOPNOTSUPP) {
1603 log_debug("FIB Rules are not supported by the kernel. Ignoring.");
1604 return 0;
1605 }
1606
bce67bbe 1607 return r;
6acbbdd4 1608 }
bce67bbe
SS
1609
1610 for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
1611 int k;
1612
1613 m->enumerating = true;
1614
1615 k = manager_rtnl_process_rule(m->rtnl, rule, m);
1616 if (k < 0)
1617 r = k;
1618
1619 m->enumerating = false;
1620 }
1621
1622 return r;
1623}
1624
0dd25fb9 1625int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
1626 AddressPool *p;
1627 int r;
1628
1629 assert(m);
1630 assert(prefixlen > 0);
1631 assert(found);
1632
1633 LIST_FOREACH(address_pools, p, m->address_pools) {
1634 if (p->family != family)
1635 continue;
1636
1637 r = address_pool_acquire(p, prefixlen, found);
1638 if (r != 0)
1639 return r;
1640 }
1641
1642 return 0;
1643}
4f5f911e
LP
1644
1645Link* manager_find_uplink(Manager *m, Link *exclude) {
1646 _cleanup_free_ struct local_address *gateways = NULL;
1647 int n, i;
1648
1649 assert(m);
1650
1651 /* Looks for a suitable "uplink", via black magic: an
1652 * interface that is up and where the default route with the
1653 * highest priority points to. */
1654
1655 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
1656 if (n < 0) {
1657 log_warning_errno(n, "Failed to determine list of default gateways: %m");
1658 return NULL;
1659 }
1660
1661 for (i = 0; i < n; i++) {
1662 Link *link;
1663
1664 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
1665 if (!link) {
c2c940bd 1666 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
4f5f911e
LP
1667 continue;
1668 }
1669
1670 if (link == exclude)
1671 continue;
1672
1673 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1674 continue;
1675
1676 return link;
1677 }
1678
1679 return NULL;
1680}
84de38c5
TG
1681
1682void manager_dirty(Manager *manager) {
1683 assert(manager);
1684
1685 /* the serialized state in /run is no longer up-to-date */
1686 manager->dirty = true;
1687}
59eb33e0
MP
1688
1689static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1690 Manager *manager = userdata;
1691 const sd_bus_error *e;
1692
1693 assert(m);
1694 assert(manager);
1695
1696 e = sd_bus_message_get_error(m);
1697 if (e)
1698 log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
1699
1700 return 1;
1701}
1702
1703int manager_set_hostname(Manager *m, const char *hostname) {
1704 int r;
1705
1706 log_debug("Setting transient hostname: '%s'", strna(hostname));
d7afd945 1707
7901cea1
MP
1708 if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
1709 return log_oom();
59eb33e0 1710
d7afd945 1711 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
e0d95f03 1712 log_debug("Not connected to system bus, setting hostname later.");
59eb33e0
MP
1713 return 0;
1714 }
1715
1716 r = sd_bus_call_method_async(
1717 m->bus,
1718 NULL,
1719 "org.freedesktop.hostname1",
1720 "/org/freedesktop/hostname1",
1721 "org.freedesktop.hostname1",
1722 "SetHostname",
1723 set_hostname_handler,
1724 m,
1725 "sb",
1726 hostname,
1727 false);
1728
1729 if (r < 0)
1730 return log_error_errno(r, "Could not set transient hostname: %m");
1731
1732 return 0;
1733}
1734
1735static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1736 Manager *manager = userdata;
1737 const sd_bus_error *e;
1738
1739 assert(m);
1740 assert(manager);
1741
1742 e = sd_bus_message_get_error(m);
1743 if (e)
1744 log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
1745
1746 return 1;
1747}
1748
1749int manager_set_timezone(Manager *m, const char *tz) {
1750 int r;
1751
1752 assert(m);
1753 assert(tz);
1754
1755 log_debug("Setting system timezone: '%s'", tz);
7901cea1
MP
1756 if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
1757 return log_oom();
59eb33e0 1758
d7afd945 1759 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
e0d95f03 1760 log_debug("Not connected to system bus, setting timezone later.");
59eb33e0
MP
1761 return 0;
1762 }
1763
1764 r = sd_bus_call_method_async(
1765 m->bus,
1766 NULL,
1767 "org.freedesktop.timedate1",
1768 "/org/freedesktop/timedate1",
1769 "org.freedesktop.timedate1",
1770 "SetTimezone",
1771 set_timezone_handler,
1772 m,
1773 "sb",
1774 tz,
1775 false);
1776 if (r < 0)
1777 return log_error_errno(r, "Could not set timezone: %m");
1778
1779 return 0;
1780}
27dfc982
YW
1781
1782int manager_request_product_uuid(Manager *m, Link *link) {
1783 int r;
1784
1785 assert(m);
1786
1787 if (m->has_product_uuid)
1788 return 0;
1789
1790 log_debug("Requesting product UUID");
1791
1792 if (link) {
1793 DUID *duid;
1794
1795 assert_se(duid = link_get_duid(link));
1796
1797 r = set_ensure_allocated(&m->links_requesting_uuid, NULL);
1798 if (r < 0)
1799 return log_oom();
1800
1801 r = set_ensure_allocated(&m->duids_requesting_uuid, NULL);
1802 if (r < 0)
1803 return log_oom();
1804
1805 r = set_put(m->links_requesting_uuid, link);
1806 if (r < 0)
1807 return log_oom();
1808
1809 r = set_put(m->duids_requesting_uuid, duid);
1810 if (r < 0)
1811 return log_oom();
1812 }
1813
1814 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
1815 log_debug("Not connected to system bus, requesting product UUID later.");
1816 return 0;
1817 }
1818
1819 r = sd_bus_call_method_async(
1820 m->bus,
1821 NULL,
1822 "org.freedesktop.hostname1",
1823 "/org/freedesktop/hostname1",
1824 "org.freedesktop.hostname1",
1825 "GetProductUUID",
1826 get_product_uuid_handler,
1827 m,
1828 "b",
1829 false);
1830 if (r < 0)
1831 return log_warning_errno(r, "Failed to get product UUID: %m");
1832
1833 return 0;
1834}