]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
tree-wide: Mark as _unused_ variables that are only used in assert()
[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>
c16c7808 8#include <linux/nexthop.h>
3bef724f 9
fc2f9534 10#include "sd-daemon.h"
07630cea 11#include "sd-netlink.h"
fc2f9534 12
b5efdb8a 13#include "alloc-util.h"
ac9f55ed 14#include "bus-log-control-api.h"
269e4d2d 15#include "bus-polkit.h"
a97dcc12 16#include "bus-util.h"
07630cea 17#include "conf-parser.h"
a97dcc12 18#include "def.h"
a7f95575 19#include "device-private.h"
21486d9e 20#include "device-util.h"
482d1aeb 21#include "dns-domain.h"
3ffd4af2 22#include "fd-util.h"
0d39fa9c 23#include "fileio.h"
4f5f911e 24#include "local-addresses.h"
07630cea 25#include "netlink-util.h"
dc0d4078 26#include "network-internal.h"
ca5ad760 27#include "networkd-dhcp6.h"
6a1af3d4 28#include "networkd-link-bus.h"
79a59fa5 29#include "networkd-manager-bus.h"
23f53b99 30#include "networkd-manager.h"
ceac2c2b 31#include "networkd-network-bus.h"
a879e1a4 32#include "networkd-speed-meter.h"
00616955 33#include "ordered-set.h"
b0c82192 34#include "path-lookup.h"
07630cea
LP
35#include "path-util.h"
36#include "set.h"
ab76be55 37#include "signal-util.h"
21486d9e 38#include "strv.h"
4b600505 39#include "sysctl-util.h"
e4de7287 40#include "tmpfile-util.h"
299ad32d 41#include "udev-util.h"
07630cea 42#include "virt.h"
505f8da7 43
48d0248e
YW
44/* use 128 MB for receive socket kernel queue. */
45#define RCVBUF_SIZE (128*1024*1024)
be660c37 46
5ecb131d
YW
47static int log_message_warning_errno(sd_netlink_message *m, int err, const char *msg) {
48 const char *err_msg = NULL;
49
50 (void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
51 return log_warning_errno(err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : "");
52}
53
11bf3cce
LP
54static int setup_default_address_pool(Manager *m) {
55 AddressPool *p;
56 int r;
57
58 assert(m);
59
60 /* Add in the well-known private address ranges. */
61
f2efbeaf 62 r = address_pool_new_from_string(m, &p, AF_INET6, "fd00::", 8);
11bf3cce
LP
63 if (r < 0)
64 return r;
65
b085cd37 66 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
11bf3cce
LP
67 if (r < 0)
68 return r;
69
70 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
71 if (r < 0)
72 return r;
73
b085cd37 74 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
11bf3cce
LP
75 if (r < 0)
76 return r;
77
78 return 0;
79}
80
9c0a72f9
TG
81static int manager_reset_all(Manager *m) {
82 Link *link;
83 Iterator i;
84 int r;
85
86 assert(m);
87
88 HASHMAP_FOREACH(link, m->links, i) {
89 r = link_carrier_reset(link);
90 if (r < 0)
2f3cf1f9 91 log_link_warning_errno(link, r, "Could not reset carrier: %m");
9c0a72f9
TG
92 }
93
94 return 0;
95}
96
19070062 97static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
9c0a72f9
TG
98 Manager *m = userdata;
99 int b, r;
100
19070062 101 assert(message);
d7afd945 102 assert(m);
9c0a72f9
TG
103
104 r = sd_bus_message_read(message, "b", &b);
105 if (r < 0) {
106 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
107 return 0;
108 }
109
110 if (b)
111 return 0;
112
113 log_debug("Coming back from suspend, resetting all connections...");
114
e1694a75 115 (void) manager_reset_all(m);
9c0a72f9
TG
116
117 return 0;
118}
119
d7afd945
LP
120static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
121 Manager *m = userdata;
9c0a72f9 122
d7afd945 123 assert(message);
9c0a72f9
TG
124 assert(m);
125
d7afd945
LP
126 /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
127 if (m->dynamic_hostname)
128 (void) manager_set_hostname(m, m->dynamic_hostname);
129 if (m->dynamic_timezone)
130 (void) manager_set_timezone(m, m->dynamic_timezone);
27dfc982
YW
131 if (m->links_requesting_uuid)
132 (void) manager_request_product_uuid(m, NULL);
9c0a72f9 133
d7afd945
LP
134 return 0;
135}
9c0a72f9 136
d7afd945
LP
137int manager_connect_bus(Manager *m) {
138 int r;
139
140 assert(m);
9c0a72f9 141
d7afd945 142 if (m->bus)
9c0a72f9 143 return 0;
7d6884b6 144
621e4509 145 r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-network");
9c0a72f9 146 if (r < 0)
d7afd945 147 return log_error_errno(r, "Failed to connect to bus: %m");
9c0a72f9 148
e331e246
TG
149 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m);
150 if (r < 0)
151 return log_error_errno(r, "Failed to add manager object vtable: %m");
152
153 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m);
154 if (r < 0)
155 return log_error_errno(r, "Failed to add link object vtable: %m");
156
157 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
158 if (r < 0)
159 return log_error_errno(r, "Failed to add link enumerator: %m");
3175fcde
TG
160
161 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m);
162 if (r < 0)
163 return log_error_errno(r, "Failed to add network object vtable: %m");
164
165 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m);
166 if (r < 0)
167 return log_error_errno(r, "Failed to add network enumerator: %m");
e331e246 168
ac9f55ed
LP
169 r = bus_log_control_api_register(m->bus);
170 if (r < 0)
171 return r;
172
696fc836 173 r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL);
e331e246 174 if (r < 0)
0c0b9306 175 return log_error_errno(r, "Failed to request name: %m");
e331e246
TG
176
177 r = sd_bus_attach_event(m->bus, m->event, 0);
178 if (r < 0)
179 return log_error_errno(r, "Failed to attach bus to event loop: %m");
180
d7afd945
LP
181 r = sd_bus_match_signal_async(
182 m->bus,
cad43595 183 NULL,
d7afd945
LP
184 "org.freedesktop.DBus.Local",
185 NULL,
186 "org.freedesktop.DBus.Local",
187 "Connected",
188 on_connected, NULL, m);
189 if (r < 0)
190 return log_error_errno(r, "Failed to request match on Connected signal: %m");
191
192 r = sd_bus_match_signal_async(
193 m->bus,
cad43595 194 NULL,
d7afd945
LP
195 "org.freedesktop.login1",
196 "/org/freedesktop/login1",
197 "org.freedesktop.login1.Manager",
198 "PrepareForSleep",
199 match_prepare_for_sleep, NULL, m);
200 if (r < 0)
201 log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m");
7901cea1 202
9c0a72f9
TG
203 return 0;
204}
205
d2ebf952
YW
206static int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata) {
207 Manager *m = userdata;
a7f95575 208 DeviceAction action;
5fae368b
TG
209 Link *link = NULL;
210 int r, ifindex;
5544ee85 211
5fae368b
TG
212 assert(m);
213 assert(device);
5544ee85 214
a7f95575 215 r = device_get_action(device, &action);
21486d9e 216 if (r < 0) {
a7f95575 217 log_device_debug_errno(device, r, "Failed to get udev action, ignoring device: %m");
5fae368b 218 return 0;
21486d9e
YW
219 }
220
a7f95575
YW
221 if (!IN_SET(action, DEVICE_ACTION_ADD, DEVICE_ACTION_CHANGE, DEVICE_ACTION_MOVE)) {
222 log_device_debug(device, "Ignoring udev %s event for device.", device_action_to_string(action));
21486d9e
YW
223 return 0;
224 }
5544ee85 225
51517f9e 226 r = sd_device_get_ifindex(device, &ifindex);
7606377e 227 if (r < 0) {
21486d9e 228 log_device_debug_errno(device, r, "Ignoring udev ADD event for device without ifindex or with invalid ifindex: %m");
5fae368b 229 return 0;
5544ee85
TG
230 }
231
299ad32d
YW
232 r = device_is_renaming(device);
233 if (r < 0) {
a7f95575
YW
234 log_device_error_errno(device, r, "Failed to determine the device is renamed or not, ignoring '%s' uevent: %m",
235 device_action_to_string(action));
299ad32d
YW
236 return 0;
237 }
238 if (r > 0) {
239 log_device_debug(device, "Interface is under renaming, wait for the interface to be renamed: %m");
240 return 0;
241 }
242
5fae368b 243 r = link_get(m, ifindex, &link);
d2ebf952
YW
244 if (r < 0) {
245 if (r != -ENODEV)
246 log_debug_errno(r, "Failed to get link from ifindex %i, ignoring: %m", ifindex);
5fae368b 247 return 0;
d2ebf952 248 }
02b59d57 249
d2ebf952 250 (void) link_initialized(link, device);
e1694a75 251
f579559b
TG
252 return 0;
253}
254
5fae368b
TG
255static int manager_connect_udev(Manager *m) {
256 int r;
f579559b 257
5fae368b
TG
258 /* udev does not initialize devices inside containers,
259 * so we rely on them being already initialized before
260 * entering the container */
75f86906 261 if (detect_container() > 0)
5fae368b 262 return 0;
f579559b 263
d2ebf952 264 r = sd_device_monitor_new(&m->device_monitor);
02b59d57 265 if (r < 0)
d2ebf952 266 return log_error_errno(r, "Failed to initialize device monitor: %m");
02b59d57 267
d2ebf952
YW
268 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "net", NULL);
269 if (r < 0)
270 return log_error_errno(r, "Could not add device monitor filter: %m");
505f8da7 271
deb2b734 272 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
5fae368b 273 if (r < 0)
d2ebf952 274 return log_error_errno(r, "Failed to attach event to device monitor: %m");
505f8da7 275
deb2b734 276 r = sd_device_monitor_start(m->device_monitor, manager_udev_process_link, m);
505f8da7 277 if (r < 0)
d2ebf952 278 return log_error_errno(r, "Failed to start device monitor: %m");
11a7f229 279
505f8da7
TG
280 return 0;
281}
f579559b 282
1c8e710c 283int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
f1368755
YW
284 _cleanup_(route_freep) Route *tmp = NULL;
285 Route *route = NULL;
1c8e710c
TG
286 Manager *m = userdata;
287 Link *link = NULL;
f1368755 288 uint32_t ifindex;
1c8e710c 289 uint16_t type;
f1368755 290 unsigned char table;
1c8e710c
TG
291 int r;
292
293 assert(rtnl);
294 assert(message);
295 assert(m);
296
297 if (sd_netlink_message_is_error(message)) {
298 r = sd_netlink_message_get_errno(message);
299 if (r < 0)
5ecb131d 300 log_message_warning_errno(message, r, "rtnl: failed to receive route message, ignoring");
1c8e710c
TG
301
302 return 0;
303 }
304
305 r = sd_netlink_message_get_type(message, &type);
306 if (r < 0) {
e1694a75 307 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
1c8e710c 308 return 0;
25a1bffc 309 } else if (!IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE)) {
7f474ed7 310 log_warning("rtnl: received unexpected message type %u when processing route, ignoring.", type);
1c8e710c
TG
311 return 0;
312 }
313
314 r = sd_netlink_message_read_u32(message, RTA_OIF, &ifindex);
315 if (r == -ENODATA) {
39f26098 316 log_debug("rtnl: received route message without ifindex, ignoring");
1c8e710c
TG
317 return 0;
318 } else if (r < 0) {
7f474ed7 319 log_warning_errno(r, "rtnl: could not get ifindex from route message, ignoring: %m");
1c8e710c
TG
320 return 0;
321 } else if (ifindex <= 0) {
7f474ed7
YW
322 log_warning("rtnl: received route message with invalid ifindex %d, ignoring.", ifindex);
323 return 0;
324 }
325
326 r = link_get(m, ifindex, &link);
327 if (r < 0 || !link) {
328 /* when enumerating we might be out of sync, but we will
329 * get the route again, so just ignore it */
330 if (!m->enumerating)
39f26098 331 log_warning("rtnl: received route message for link (%d) we do not know about, ignoring", ifindex);
7f474ed7 332 return 0;
1c8e710c
TG
333 }
334
f1368755
YW
335 r = route_new(&tmp);
336 if (r < 0)
337 return log_oom();
338
339 r = sd_rtnl_message_route_get_family(message, &tmp->family);
509b06ff
YW
340 if (r < 0) {
341 log_link_warning(link, "rtnl: received route message without family, ignoring");
342 return 0;
343 } else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) {
344 log_link_debug(link, "rtnl: received route message with invalid family '%i', ignoring", tmp->family);
1c8e710c
TG
345 return 0;
346 }
347
f1368755 348 r = sd_rtnl_message_route_get_protocol(message, &tmp->protocol);
1c8e710c 349 if (r < 0) {
509b06ff 350 log_warning_errno(r, "rtnl: received route message without route protocol: %m");
1c8e710c
TG
351 return 0;
352 }
353
f1368755 354 switch (tmp->family) {
1c8e710c 355 case AF_INET:
f1368755 356 r = sd_netlink_message_read_in_addr(message, RTA_DST, &tmp->dst.in);
1c8e710c 357 if (r < 0 && r != -ENODATA) {
7f474ed7 358 log_link_warning_errno(link, r, "rtnl: received route message without valid destination, ignoring: %m");
1c8e710c
TG
359 return 0;
360 }
361
f1368755 362 r = sd_netlink_message_read_in_addr(message, RTA_GATEWAY, &tmp->gw.in);
1c8e710c 363 if (r < 0 && r != -ENODATA) {
7f474ed7 364 log_link_warning_errno(link, r, "rtnl: received route message without valid gateway, ignoring: %m");
1c8e710c
TG
365 return 0;
366 }
367
f1368755 368 r = sd_netlink_message_read_in_addr(message, RTA_SRC, &tmp->src.in);
1c8e710c 369 if (r < 0 && r != -ENODATA) {
7f474ed7 370 log_link_warning_errno(link, r, "rtnl: received route message without valid source, ignoring: %m");
1c8e710c
TG
371 return 0;
372 }
373
f1368755 374 r = sd_netlink_message_read_in_addr(message, RTA_PREFSRC, &tmp->prefsrc.in);
1c8e710c 375 if (r < 0 && r != -ENODATA) {
7f474ed7 376 log_link_warning_errno(link, r, "rtnl: received route message without valid preferred source, ignoring: %m");
1c8e710c
TG
377 return 0;
378 }
379
380 break;
381
382 case AF_INET6:
f1368755 383 r = sd_netlink_message_read_in6_addr(message, RTA_DST, &tmp->dst.in6);
1c8e710c 384 if (r < 0 && r != -ENODATA) {
7f474ed7 385 log_link_warning_errno(link, r, "rtnl: received route message without valid destination, ignoring: %m");
1c8e710c
TG
386 return 0;
387 }
388
f1368755 389 r = sd_netlink_message_read_in6_addr(message, RTA_GATEWAY, &tmp->gw.in6);
1c8e710c 390 if (r < 0 && r != -ENODATA) {
7f474ed7 391 log_link_warning_errno(link, r, "rtnl: received route message without valid gateway, ignoring: %m");
1c8e710c
TG
392 return 0;
393 }
394
f1368755 395 r = sd_netlink_message_read_in6_addr(message, RTA_SRC, &tmp->src.in6);
1c8e710c 396 if (r < 0 && r != -ENODATA) {
7f474ed7 397 log_link_warning_errno(link, r, "rtnl: received route message without valid source, ignoring: %m");
1c8e710c
TG
398 return 0;
399 }
400
f1368755 401 r = sd_netlink_message_read_in6_addr(message, RTA_PREFSRC, &tmp->prefsrc.in6);
1c8e710c 402 if (r < 0 && r != -ENODATA) {
7f474ed7 403 log_link_warning_errno(link, r, "rtnl: received route message without valid preferred source, ignoring: %m");
1c8e710c
TG
404 return 0;
405 }
406
407 break;
408
409 default:
7f474ed7 410 assert_not_reached("Received route message with unsupported address family");
1c8e710c
TG
411 return 0;
412 }
413
f1368755 414 r = sd_rtnl_message_route_get_dst_prefixlen(message, &tmp->dst_prefixlen);
1c8e710c 415 if (r < 0) {
39f26098 416 log_link_warning_errno(link, r, "rtnl: received route message with invalid destination prefixlen, ignoring: %m");
1c8e710c
TG
417 return 0;
418 }
419
f1368755 420 r = sd_rtnl_message_route_get_src_prefixlen(message, &tmp->src_prefixlen);
1c8e710c 421 if (r < 0) {
39f26098 422 log_link_warning_errno(link, r, "rtnl: received route message with invalid source prefixlen, ignoring: %m");
1c8e710c
TG
423 return 0;
424 }
425
f1368755 426 r = sd_rtnl_message_route_get_scope(message, &tmp->scope);
1c8e710c 427 if (r < 0) {
39f26098 428 log_link_warning_errno(link, r, "rtnl: received route message with invalid scope, ignoring: %m");
1c8e710c
TG
429 return 0;
430 }
431
f1368755 432 r = sd_rtnl_message_route_get_tos(message, &tmp->tos);
1c8e710c 433 if (r < 0) {
39f26098 434 log_link_warning_errno(link, r, "rtnl: received route message with invalid tos, ignoring: %m");
1c8e710c
TG
435 return 0;
436 }
437
f1368755 438 r = sd_rtnl_message_route_get_type(message, &tmp->type);
983226f3 439 if (r < 0) {
39f26098 440 log_link_warning_errno(link, r, "rtnl: received route message with invalid type, ignoring: %m");
983226f3
SS
441 return 0;
442 }
443
1c8e710c
TG
444 r = sd_rtnl_message_route_get_table(message, &table);
445 if (r < 0) {
39f26098 446 log_link_warning_errno(link, r, "rtnl: received route message with invalid table, ignoring: %m");
1c8e710c
TG
447 return 0;
448 }
f1368755 449 tmp->table = table;
1c8e710c 450
f1368755 451 r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &tmp->priority);
1c8e710c 452 if (r < 0 && r != -ENODATA) {
39f26098 453 log_link_warning_errno(link, r, "rtnl: received route message with invalid priority, ignoring: %m");
1c8e710c
TG
454 return 0;
455 }
456
fa3e401a
YW
457 r = sd_netlink_message_enter_container(message, RTA_METRICS);
458 if (r < 0 && r != -ENODATA) {
459 log_link_error_errno(link, r, "rtnl: Could not enter RTA_METRICS container: %m");
460 return 0;
461 }
462 if (r >= 0) {
463 r = sd_netlink_message_read_u32(message, RTAX_INITCWND, &tmp->initcwnd);
464 if (r < 0 && r != -ENODATA) {
465 log_link_warning_errno(link, r, "rtnl: received route message with invalid initcwnd, ignoring: %m");
466 return 0;
467 }
468
469 r = sd_netlink_message_read_u32(message, RTAX_INITRWND, &tmp->initrwnd);
470 if (r < 0 && r != -ENODATA) {
471 log_link_warning_errno(link, r, "rtnl: received route message with invalid initrwnd, ignoring: %m");
472 return 0;
473 }
474
475 r = sd_netlink_message_exit_container(message);
476 if (r < 0) {
477 log_link_error_errno(link, r, "rtnl: Could not exit from RTA_METRICS container: %m");
478 return 0;
479 }
480 }
481
f1368755 482 (void) route_get(link, tmp, &route);
1c8e710c 483
156ed65e
YW
484 if (DEBUG_LOGGING) {
485 _cleanup_free_ char *buf_dst = NULL, *buf_dst_prefixlen = NULL,
486 *buf_src = NULL, *buf_gw = NULL, *buf_prefsrc = NULL;
d3e291fd
YW
487 char buf_scope[ROUTE_SCOPE_STR_MAX], buf_table[ROUTE_TABLE_STR_MAX],
488 buf_protocol[ROUTE_PROTOCOL_STR_MAX];
156ed65e 489
f1368755
YW
490 if (!in_addr_is_null(tmp->family, &tmp->dst)) {
491 (void) in_addr_to_string(tmp->family, &tmp->dst, &buf_dst);
492 (void) asprintf(&buf_dst_prefixlen, "/%u", tmp->dst_prefixlen);
156ed65e 493 }
f1368755
YW
494 if (!in_addr_is_null(tmp->family, &tmp->src))
495 (void) in_addr_to_string(tmp->family, &tmp->src, &buf_src);
496 if (!in_addr_is_null(tmp->family, &tmp->gw))
497 (void) in_addr_to_string(tmp->family, &tmp->gw, &buf_gw);
498 if (!in_addr_is_null(tmp->family, &tmp->prefsrc))
499 (void) in_addr_to_string(tmp->family, &tmp->prefsrc, &buf_prefsrc);
156ed65e
YW
500
501 log_link_debug(link,
d3e291fd 502 "%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s",
5d3b8017
SS
503 (!route && !link->manager->manage_foreign_routes) || type == RTM_DELROUTE ? "Forgetting" :
504 route ? "Received remembered" : "Remembering",
156ed65e 505 strna(buf_dst), strempty(buf_dst_prefixlen),
b297e0a7 506 strna(buf_src), strna(buf_gw), strna(buf_prefsrc),
f1368755
YW
507 format_route_scope(tmp->scope, buf_scope, sizeof buf_scope),
508 format_route_table(tmp->table, buf_table, sizeof buf_table),
509 format_route_protocol(tmp->protocol, buf_protocol, sizeof buf_protocol),
510 strna(route_type_to_string(tmp->type)));
156ed65e
YW
511 }
512
1c8e710c
TG
513 switch (type) {
514 case RTM_NEWROUTE:
5d3b8017 515 if (!route && link->manager->manage_foreign_routes) {
1c8e710c 516 /* A route appeared that we did not request */
f1368755 517 r = route_add_foreign(link, tmp, &route);
e1694a75 518 if (r < 0) {
7f474ed7 519 log_link_warning_errno(link, r, "Failed to remember foreign route, ignoring: %m");
1c8e710c 520 return 0;
e1694a75 521 }
1c8e710c
TG
522 }
523
1c8e710c
TG
524 break;
525
526 case RTM_DELROUTE:
b9642f41 527 route_free(route);
1c8e710c 528 break;
b9642f41 529
1c8e710c 530 default:
7f474ed7 531 assert_not_reached("Received route message with invalid RTNL message type");
1c8e710c
TG
532 }
533
534 return 1;
535}
536
d1bdafd2
WKI
537static int manager_rtnl_process_neighbor_lladdr(sd_netlink_message *message, union lladdr_union *lladdr, size_t *size, char **str) {
538 int r;
539
540 assert(message);
541 assert(lladdr);
542 assert(size);
543 assert(str);
544
545 *str = NULL;
546
547 r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in6), &lladdr->ip.in6);
548 if (r >= 0) {
549 *size = sizeof(lladdr->ip.in6);
550 if (in_addr_to_string(AF_INET6, &lladdr->ip, str) < 0)
551 log_warning_errno(r, "Could not print lower address: %m");
552 return r;
553 }
554
555 r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->mac), &lladdr->mac);
556 if (r >= 0) {
557 *size = sizeof(lladdr->mac);
558 *str = new(char, ETHER_ADDR_TO_STRING_MAX);
559 if (!*str) {
560 log_oom();
561 return r;
562 }
563 ether_addr_to_string(&lladdr->mac, *str);
564 return r;
565 }
566
567 r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in), &lladdr->ip.in);
568 if (r >= 0) {
569 *size = sizeof(lladdr->ip.in);
570 if (in_addr_to_string(AF_INET, &lladdr->ip, str) < 0)
571 log_warning_errno(r, "Could not print lower address: %m");
572 return r;
573 }
574
575 return r;
576}
577
578int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
579 Manager *m = userdata;
580 Link *link = NULL;
581 Neighbor *neighbor = NULL;
582 int ifindex, family, r;
583 uint16_t type, state;
584 union in_addr_union in_addr = IN_ADDR_NULL;
585 _cleanup_free_ char *addr_str = NULL;
586 union lladdr_union lladdr;
587 size_t lladdr_size = 0;
588 _cleanup_free_ char *lladdr_str = NULL;
589
590 assert(rtnl);
591 assert(message);
592 assert(m);
593
594 if (sd_netlink_message_is_error(message)) {
595 r = sd_netlink_message_get_errno(message);
596 if (r < 0)
5ecb131d 597 log_message_warning_errno(message, r, "rtnl: failed to receive neighbor message, ignoring");
d1bdafd2
WKI
598
599 return 0;
600 }
601
602 r = sd_netlink_message_get_type(message, &type);
603 if (r < 0) {
604 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
605 return 0;
606 } else if (!IN_SET(type, RTM_NEWNEIGH, RTM_DELNEIGH)) {
607 log_warning("rtnl: received unexpected message type %u when processing neighbor, ignoring.", type);
608 return 0;
609 }
610
611 r = sd_rtnl_message_neigh_get_state(message, &state);
612 if (r < 0) {
613 log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid state, ignoring: %m");
614 return 0;
615 } else if (!FLAGS_SET(state, NUD_PERMANENT)) {
616 log_debug("rtnl: received non-static neighbor, ignoring.");
617 return 0;
618 }
619
620 r = sd_rtnl_message_neigh_get_ifindex(message, &ifindex);
621 if (r < 0) {
622 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
623 return 0;
624 } else if (ifindex <= 0) {
625 log_warning("rtnl: received neighbor message with invalid ifindex %d, ignoring.", ifindex);
626 return 0;
627 }
628
629 r = link_get(m, ifindex, &link);
630 if (r < 0 || !link) {
631 /* when enumerating we might be out of sync, but we will get the neighbor again, so just
632 * ignore it */
633 if (!m->enumerating)
634 log_warning("rtnl: received neighbor for link '%d' we don't know about, ignoring.", ifindex);
635 return 0;
636 }
637
638 r = sd_rtnl_message_neigh_get_family(message, &family);
509b06ff 639 if (r < 0) {
7c6d95ea 640 log_link_warning(link, "rtnl: received neighbor message without family, ignoring.");
509b06ff
YW
641 return 0;
642 } else if (!IN_SET(family, AF_INET, AF_INET6)) {
643 log_link_debug(link, "rtnl: received neighbor message with invalid family '%i', ignoring.", family);
d1bdafd2
WKI
644 return 0;
645 }
646
647 switch (family) {
648 case AF_INET:
649 r = sd_netlink_message_read_in_addr(message, NDA_DST, &in_addr.in);
650 if (r < 0) {
651 log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m");
652 return 0;
653 }
654
655 break;
656
657 case AF_INET6:
658 r = sd_netlink_message_read_in6_addr(message, NDA_DST, &in_addr.in6);
659 if (r < 0) {
660 log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m");
661 return 0;
662 }
663
664 break;
665
666 default:
667 assert_not_reached("Received unsupported address family");
668 }
669
670 if (in_addr_to_string(family, &in_addr, &addr_str) < 0)
671 log_link_warning_errno(link, r, "Could not print address: %m");
672
673 r = manager_rtnl_process_neighbor_lladdr(message, &lladdr, &lladdr_size, &lladdr_str);
674 if (r < 0) {
675 log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid lladdr, ignoring: %m");
676 return 0;
677 }
678
679 (void) neighbor_get(link, family, &in_addr, &lladdr, lladdr_size, &neighbor);
680
681 switch (type) {
682 case RTM_NEWNEIGH:
683 if (neighbor)
684 log_link_debug(link, "Remembering neighbor: %s->%s",
685 strnull(addr_str), strnull(lladdr_str));
686 else {
687 /* A neighbor appeared that we did not request */
688 r = neighbor_add_foreign(link, family, &in_addr, &lladdr, lladdr_size, &neighbor);
689 if (r < 0) {
690 log_link_warning_errno(link, r, "Failed to remember foreign neighbor %s->%s, ignoring: %m",
691 strnull(addr_str), strnull(lladdr_str));
692 return 0;
693 } else
694 log_link_debug(link, "Remembering foreign neighbor: %s->%s",
695 strnull(addr_str), strnull(lladdr_str));
696 }
697
698 break;
699
700 case RTM_DELNEIGH:
701 if (neighbor) {
702 log_link_debug(link, "Forgetting neighbor: %s->%s",
703 strnull(addr_str), strnull(lladdr_str));
704 (void) neighbor_free(neighbor);
705 } else
d6246fd4
YW
706 log_link_debug(link, "Kernel removed a neighbor we don't remember: %s->%s, ignoring.",
707 strnull(addr_str), strnull(lladdr_str));
d1bdafd2
WKI
708
709 break;
710
711 default:
712 assert_not_reached("Received invalid RTNL message type");
713 }
714
715 return 1;
716}
717
200a0868 718int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
57e44707 719 _cleanup_free_ char *buf = NULL;
200a0868
TG
720 Manager *m = userdata;
721 Link *link = NULL;
722 uint16_t type;
57e44707 723 unsigned char flags, prefixlen, scope;
67a46833 724 union in_addr_union in_addr = IN_ADDR_NULL;
054f0db4
TG
725 struct ifa_cacheinfo cinfo;
726 Address *address = NULL;
57e44707 727 char valid_buf[FORMAT_TIMESPAN_MAX];
200a0868 728 const char *valid_str = NULL;
57e44707 729 int ifindex, family, r;
200a0868
TG
730
731 assert(rtnl);
732 assert(message);
733 assert(m);
734
735 if (sd_netlink_message_is_error(message)) {
736 r = sd_netlink_message_get_errno(message);
737 if (r < 0)
5ecb131d 738 log_message_warning_errno(message, r, "rtnl: failed to receive address message, ignoring");
200a0868
TG
739
740 return 0;
741 }
742
743 r = sd_netlink_message_get_type(message, &type);
744 if (r < 0) {
e1694a75 745 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
200a0868 746 return 0;
25a1bffc 747 } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)) {
7f474ed7 748 log_warning("rtnl: received unexpected message type %u when processing address, ignoring.", type);
200a0868
TG
749 return 0;
750 }
751
752 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
753 if (r < 0) {
44e891bb 754 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
200a0868
TG
755 return 0;
756 } else if (ifindex <= 0) {
7f474ed7 757 log_warning("rtnl: received address message with invalid ifindex %d, ignoring.", ifindex);
200a0868 758 return 0;
44e891bb
ZJS
759 }
760
761 r = link_get(m, ifindex, &link);
762 if (r < 0 || !link) {
763 /* when enumerating we might be out of sync, but we will get the address again, so just
764 * ignore it */
765 if (!m->enumerating)
7f474ed7 766 log_warning("rtnl: received address for link '%d' we don't know about, ignoring.", ifindex);
44e891bb 767 return 0;
200a0868
TG
768 }
769
054f0db4 770 r = sd_rtnl_message_addr_get_family(message, &family);
509b06ff
YW
771 if (r < 0) {
772 log_link_warning(link, "rtnl: received address message without family, ignoring.");
773 return 0;
774 } else if (!IN_SET(family, AF_INET, AF_INET6)) {
775 log_link_debug(link, "rtnl: received address message with invalid family '%i', ignoring.", family);
200a0868
TG
776 return 0;
777 }
778
054f0db4 779 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
200a0868 780 if (r < 0) {
44e891bb 781 log_link_warning_errno(link, r, "rtnl: received address message with invalid prefixlen, ignoring: %m");
200a0868
TG
782 return 0;
783 }
784
054f0db4 785 r = sd_rtnl_message_addr_get_scope(message, &scope);
200a0868 786 if (r < 0) {
44e891bb 787 log_link_warning_errno(link, r, "rtnl: received address message with invalid scope, ignoring: %m");
200a0868
TG
788 return 0;
789 }
790
791 r = sd_rtnl_message_addr_get_flags(message, &flags);
792 if (r < 0) {
44e891bb 793 log_link_warning_errno(link, r, "rtnl: received address message with invalid flags, ignoring: %m");
200a0868
TG
794 return 0;
795 }
200a0868 796
054f0db4 797 switch (family) {
200a0868 798 case AF_INET:
054f0db4 799 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
200a0868 800 if (r < 0) {
44e891bb 801 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
200a0868
TG
802 return 0;
803 }
804
805 break;
806
807 case AF_INET6:
054f0db4 808 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
200a0868 809 if (r < 0) {
44e891bb 810 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
200a0868
TG
811 return 0;
812 }
813
814 break;
815
816 default:
e1694a75 817 assert_not_reached("Received unsupported address family");
200a0868
TG
818 }
819
57e44707 820 r = in_addr_to_string(family, &in_addr, &buf);
44e891bb
ZJS
821 if (r < 0)
822 log_link_warning_errno(link, r, "Could not print address: %m");
200a0868 823
054f0db4 824 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
e1694a75
YW
825 if (r < 0 && r != -ENODATA) {
826 log_link_warning_errno(link, r, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m");
827 return 0;
57e44707
YW
828 } else if (r >= 0 && cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
829 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
830 cinfo.ifa_valid * USEC_PER_SEC,
831 USEC_PER_SEC);
200a0868 832
e1694a75 833 (void) address_get(link, family, &in_addr, prefixlen, &address);
200a0868
TG
834
835 switch (type) {
836 case RTM_NEWADDR:
36c32f61 837 if (address)
44e891bb
ZJS
838 log_link_debug(link, "Remembering updated address: %s/%u (valid %s%s)",
839 strnull(buf), prefixlen,
87e4e28d 840 valid_str ? "for " : "forever", strempty(valid_str));
36c32f61 841 else {
adda1ed9
TG
842 /* An address appeared that we did not request */
843 r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
cf1d700d 844 if (r < 0) {
44e891bb
ZJS
845 log_link_warning_errno(link, r, "Failed to remember foreign address %s/%u, ignoring: %m",
846 strnull(buf), prefixlen);
cf1d700d
TG
847 return 0;
848 } else
44e891bb
ZJS
849 log_link_debug(link, "Remembering foreign address: %s/%u (valid %s%s)",
850 strnull(buf), prefixlen,
87e4e28d 851 valid_str ? "for " : "forever", strempty(valid_str));
200a0868
TG
852 }
853
44e891bb
ZJS
854 /* address_update() logs internally, so we don't need to. */
855 (void) address_update(address, flags, scope, &cinfo);
36c32f61 856
200a0868
TG
857 break;
858
859 case RTM_DELADDR:
054f0db4 860 if (address) {
44e891bb
ZJS
861 log_link_debug(link, "Forgetting address: %s/%u (valid %s%s)",
862 strnull(buf), prefixlen,
87e4e28d 863 valid_str ? "for " : "forever", strempty(valid_str));
e1694a75 864 (void) address_drop(address);
200a0868 865 } else
d6246fd4
YW
866 log_link_debug(link, "Kernel removed an address we don't remember: %s/%u (valid %s%s), ignoring.",
867 strnull(buf), prefixlen,
868 valid_str ? "for " : "forever", strempty(valid_str));
200a0868
TG
869
870 break;
44e891bb 871
200a0868
TG
872 default:
873 assert_not_reached("Received invalid RTNL message type");
874 }
875
876 return 1;
877}
878
1c4baffc 879static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
505f8da7
TG
880 Manager *m = userdata;
881 Link *link = NULL;
4d473d5d 882 NetDev *netdev = NULL;
f2236469 883 uint16_t type;
ca4e095a 884 const char *name;
505f8da7 885 int r, ifindex;
f579559b 886
505f8da7
TG
887 assert(rtnl);
888 assert(message);
f579559b
TG
889 assert(m);
890
1c4baffc
TG
891 if (sd_netlink_message_is_error(message)) {
892 r = sd_netlink_message_get_errno(message);
45af44d4 893 if (r < 0)
5ecb131d 894 log_message_warning_errno(message, r, "rtnl: Could not receive link message, ignoring");
45af44d4
TG
895
896 return 0;
897 }
898
1c4baffc 899 r = sd_netlink_message_get_type(message, &type);
f2236469 900 if (r < 0) {
e1694a75 901 log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m");
f2236469 902 return 0;
25a1bffc 903 } else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)) {
7f474ed7 904 log_warning("rtnl: Received unexpected message type %u when processing link, ignoring.", type);
cdfee943 905 return 0;
f2236469
TG
906 }
907
505f8da7 908 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
45af44d4 909 if (r < 0) {
7f474ed7 910 log_warning_errno(r, "rtnl: Could not get ifindex from link message, ignoring: %m");
45af44d4
TG
911 return 0;
912 } else if (ifindex <= 0) {
7f474ed7 913 log_warning("rtnl: received link message with invalid ifindex %d, ignoring.", ifindex);
505f8da7 914 return 0;
a0db8e46 915 }
f579559b 916
1c4baffc 917 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
45af44d4 918 if (r < 0) {
e1694a75 919 log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m");
4d473d5d 920 return 0;
a0db8e46
ZJS
921 }
922
923 (void) link_get(m, ifindex, &link);
924 (void) netdev_get(m, name, &netdev);
4d473d5d
TG
925
926 switch (type) {
927 case RTM_NEWLINK:
928 if (!link) {
929 /* link is new, so add it */
930 r = link_add(m, message, &link);
931 if (r < 0) {
7f474ed7 932 log_warning_errno(r, "Could not process new link message, ignoring: %m");
4d473d5d
TG
933 return 0;
934 }
935 }
936
937 if (netdev) {
938 /* netdev exists, so make sure the ifindex matches */
505f8da7
TG
939 r = netdev_set_ifindex(netdev, message);
940 if (r < 0) {
7f474ed7 941 log_warning_errno(r, "Could not process new link message for netdev, ignoring: %m");
505f8da7
TG
942 return 0;
943 }
944 }
e1202047 945
f2236469 946 r = link_update(link, message);
e1694a75 947 if (r < 0) {
7f474ed7 948 log_warning_errno(r, "Could not process link message, ignoring: %m");
f2236469 949 return 0;
e1694a75 950 }
4d473d5d
TG
951
952 break;
953
954 case RTM_DELLINK:
955 link_drop(link);
956 netdev_drop(netdev);
957
958 break;
959
960 default:
7f474ed7 961 assert_not_reached("Received link message with invalid RTNL message type.");
f2236469 962 }
505f8da7
TG
963
964 return 1;
965}
966
bce67bbe 967int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
b80a511b 968 _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
15201512 969 _cleanup_free_ char *from = NULL, *to = NULL;
bce67bbe 970 RoutingPolicyRule *rule = NULL;
eeab051b 971 const char *iif = NULL, *oif = NULL;
53e1ba28 972 uint32_t suppress_prefixlen;
bce67bbe 973 Manager *m = userdata;
b80a511b 974 unsigned flags;
bce67bbe 975 uint16_t type;
bce67bbe
SS
976 int r;
977
978 assert(rtnl);
979 assert(message);
980 assert(m);
981
982 if (sd_netlink_message_is_error(message)) {
983 r = sd_netlink_message_get_errno(message);
984 if (r < 0)
5ecb131d 985 log_message_warning_errno(message, r, "rtnl: failed to receive rule message, ignoring");
bce67bbe
SS
986
987 return 0;
988 }
989
990 r = sd_netlink_message_get_type(message, &type);
991 if (r < 0) {
e1694a75 992 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
bce67bbe
SS
993 return 0;
994 } else if (!IN_SET(type, RTM_NEWRULE, RTM_DELRULE)) {
7f474ed7 995 log_warning("rtnl: received unexpected message type %u when processing rule, ignoring.", type);
bce67bbe
SS
996 return 0;
997 }
998
b80a511b
YW
999 r = routing_policy_rule_new(&tmp);
1000 if (r < 0) {
1001 log_oom();
1002 return 0;
1003 }
1004
1005 r = sd_rtnl_message_get_family(message, &tmp->family);
615ded62 1006 if (r < 0) {
e1694a75 1007 log_warning_errno(r, "rtnl: could not get rule family, ignoring: %m");
615ded62 1008 return 0;
b80a511b 1009 } else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) {
7f474ed7 1010 log_debug("rtnl: received rule message with invalid family %d, ignoring.", tmp->family);
bce67bbe
SS
1011 return 0;
1012 }
1013
b80a511b 1014 switch (tmp->family) {
bce67bbe 1015 case AF_INET:
b80a511b 1016 r = sd_netlink_message_read_in_addr(message, FRA_SRC, &tmp->from.in);
e1694a75
YW
1017 if (r < 0 && r != -ENODATA) {
1018 log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m");
1019 return 0;
1020 } else if (r >= 0) {
b80a511b 1021 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen);
e1694a75 1022 if (r < 0) {
7f474ed7 1023 log_warning_errno(r, "rtnl: received rule message without valid source prefix length, ignoring: %m");
e1694a75
YW
1024 return 0;
1025 }
bce67bbe
SS
1026 }
1027
b80a511b 1028 r = sd_netlink_message_read_in_addr(message, FRA_DST, &tmp->to.in);
e1694a75
YW
1029 if (r < 0 && r != -ENODATA) {
1030 log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m");
1031 return 0;
1032 } else if (r >= 0) {
b80a511b 1033 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen);
e1694a75 1034 if (r < 0) {
7f474ed7 1035 log_warning_errno(r, "rtnl: received rule message without valid destination prefix length, ignoring: %m");
e1694a75
YW
1036 return 0;
1037 }
bce67bbe
SS
1038 }
1039
1040 break;
1041
1042 case AF_INET6:
b80a511b 1043 r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &tmp->from.in6);
e1694a75
YW
1044 if (r < 0 && r != -ENODATA) {
1045 log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m");
1046 return 0;
1047 } else if (r >= 0) {
b80a511b 1048 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen);
e1694a75 1049 if (r < 0) {
7f474ed7 1050 log_warning_errno(r, "rtnl: received rule message without valid source prefix length, ignoring: %m");
e1694a75
YW
1051 return 0;
1052 }
bce67bbe
SS
1053 }
1054
b80a511b 1055 r = sd_netlink_message_read_in6_addr(message, FRA_DST, &tmp->to.in6);
e1694a75
YW
1056 if (r < 0 && r != -ENODATA) {
1057 log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m");
1058 return 0;
1059 } else if (r >= 0) {
b80a511b 1060 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen);
e1694a75 1061 if (r < 0) {
7f474ed7 1062 log_warning_errno(r, "rtnl: received rule message without valid destination prefix length, ignoring: %m");
e1694a75
YW
1063 return 0;
1064 }
bce67bbe
SS
1065 }
1066
1067 break;
1068
1069 default:
7f474ed7 1070 assert_not_reached("Received rule message with unsupported address family");
bce67bbe
SS
1071 }
1072
b80a511b 1073 if (tmp->from_prefixlen == 0 && tmp->to_prefixlen == 0)
bce67bbe
SS
1074 return 0;
1075
b80a511b
YW
1076 r = sd_rtnl_message_routing_policy_rule_get_flags(message, &flags);
1077 if (r < 0) {
7f474ed7 1078 log_warning_errno(r, "rtnl: received rule message without valid flag, ignoring: %m");
b80a511b
YW
1079 return 0;
1080 }
1081 tmp->invert_rule = flags & FIB_RULE_INVERT;
1082
1083 r = sd_netlink_message_read_u32(message, FRA_FWMARK, &tmp->fwmark);
e1694a75
YW
1084 if (r < 0 && r != -ENODATA) {
1085 log_warning_errno(r, "rtnl: could not get FRA_FWMARK attribute, ignoring: %m");
1086 return 0;
1087 }
1088
b80a511b
YW
1089 r = sd_netlink_message_read_u32(message, FRA_FWMASK, &tmp->fwmask);
1090 if (r < 0 && r != -ENODATA) {
1091 log_warning_errno(r, "rtnl: could not get FRA_FWMASK attribute, ignoring: %m");
1092 return 0;
1093 }
1094
1095 r = sd_netlink_message_read_u32(message, FRA_PRIORITY, &tmp->priority);
1096 if (r < 0 && r != -ENODATA) {
1097 log_warning_errno(r, "rtnl: could not get FRA_PRIORITY attribute, ignoring: %m");
1098 return 0;
1099 }
1100
1101 r = sd_netlink_message_read_u32(message, FRA_TABLE, &tmp->table);
e1694a75
YW
1102 if (r < 0 && r != -ENODATA) {
1103 log_warning_errno(r, "rtnl: could not get FRA_TABLE attribute, ignoring: %m");
1104 return 0;
1105 }
1106
b80a511b 1107 r = sd_rtnl_message_routing_policy_rule_get_tos(message, &tmp->tos);
e1694a75
YW
1108 if (r < 0 && r != -ENODATA) {
1109 log_warning_errno(r, "rtnl: could not get ip rule TOS, ignoring: %m");
1110 return 0;
1111 }
1112
eeab051b 1113 r = sd_netlink_message_read_string(message, FRA_IIFNAME, &iif);
e1694a75
YW
1114 if (r < 0 && r != -ENODATA) {
1115 log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m");
1116 return 0;
1117 }
b80a511b
YW
1118 r = free_and_strdup(&tmp->iif, iif);
1119 if (r < 0)
1120 return log_oom();
e1694a75 1121
eeab051b 1122 r = sd_netlink_message_read_string(message, FRA_OIFNAME, &oif);
e1694a75
YW
1123 if (r < 0 && r != -ENODATA) {
1124 log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m");
1125 return 0;
1126 }
b80a511b
YW
1127 r = free_and_strdup(&tmp->oif, oif);
1128 if (r < 0)
1129 return log_oom();
bce67bbe 1130
b80a511b 1131 r = sd_netlink_message_read_u8(message, FRA_IP_PROTO, &tmp->protocol);
926062f0
SS
1132 if (r < 0 && r != -ENODATA) {
1133 log_warning_errno(r, "rtnl: could not get FRA_IP_PROTO attribute, ignoring: %m");
1134 return 0;
1135 }
1136
b80a511b 1137 r = sd_netlink_message_read(message, FRA_SPORT_RANGE, sizeof(tmp->sport), &tmp->sport);
926062f0
SS
1138 if (r < 0 && r != -ENODATA) {
1139 log_warning_errno(r, "rtnl: could not get FRA_SPORT_RANGE attribute, ignoring: %m");
1140 return 0;
1141 }
1142
b80a511b 1143 r = sd_netlink_message_read(message, FRA_DPORT_RANGE, sizeof(tmp->dport), &tmp->dport);
926062f0
SS
1144 if (r < 0 && r != -ENODATA) {
1145 log_warning_errno(r, "rtnl: could not get FRA_DPORT_RANGE attribute, ignoring: %m");
1146 return 0;
1147 }
1148
ea471a46
YW
1149 r = sd_netlink_message_read(message, FRA_UID_RANGE, sizeof(tmp->uid_range), &tmp->uid_range);
1150 if (r < 0 && r != -ENODATA) {
1151 log_warning_errno(r, "rtnl: could not get FRA_UID_RANGE attribute, ignoring: %m");
1152 return 0;
1153 }
1154
53e1ba28
NF
1155 r = sd_netlink_message_read_u32(message, FRA_SUPPRESS_PREFIXLEN, &suppress_prefixlen);
1156 if (r < 0 && r != -ENODATA) {
1157 log_warning_errno(r, "rtnl: could not get FRA_SUPPRESS_PREFIXLEN attribute, ignoring: %m");
1158 return 0;
1159 }
1160 if (r >= 0)
1161 tmp->suppress_prefixlen = (int) suppress_prefixlen;
1162
b80a511b 1163 (void) routing_policy_rule_get(m, tmp, &rule);
bce67bbe 1164
15201512
YW
1165 if (DEBUG_LOGGING) {
1166 (void) in_addr_to_string(tmp->family, &tmp->from, &from);
1167 (void) in_addr_to_string(tmp->family, &tmp->to, &to);
1168 }
1169
bce67bbe
SS
1170 switch (type) {
1171 case RTM_NEWRULE:
508f63b4 1172 if (!rule) {
15201512
YW
1173 log_debug("Remembering foreign routing policy rule: %s/%u -> %s/%u, iif: %s, oif: %s, table: %u",
1174 from, tmp->from_prefixlen, to, tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
b80a511b 1175 r = routing_policy_rule_add_foreign(m, tmp, &rule);
bce67bbe 1176 if (r < 0) {
7f474ed7 1177 log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
bce67bbe
SS
1178 return 0;
1179 }
1180 }
1181 break;
1182 case RTM_DELRULE:
15201512
YW
1183 log_debug("Forgetting routing policy rule: %s/%u -> %s/%u, iif: %s, oif: %s, table: %u",
1184 from, tmp->from_prefixlen, to, tmp->to_prefixlen, strna(tmp->iif), strna(tmp->oif), tmp->table);
bce67bbe
SS
1185 routing_policy_rule_free(rule);
1186
1187 break;
1188
1189 default:
1190 assert_not_reached("Received invalid RTNL message type");
1191 }
1192
1193 return 1;
1194}
1195
c16c7808
SS
1196int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
1197 _cleanup_(nexthop_freep) NextHop *tmp = NULL;
1198 _cleanup_free_ char *gateway = NULL;
1199 NextHop *nexthop = NULL;
1200 Manager *m = userdata;
1201 Link *link = NULL;
1202 uint16_t type;
1203 int r;
1204
1205 assert(rtnl);
1206 assert(message);
1207 assert(m);
1208
1209 if (sd_netlink_message_is_error(message)) {
1210 r = sd_netlink_message_get_errno(message);
1211 if (r < 0)
5ecb131d 1212 log_message_warning_errno(message, r, "rtnl: failed to receive rule message, ignoring");
c16c7808
SS
1213
1214 return 0;
1215 }
1216
1217 r = sd_netlink_message_get_type(message, &type);
1218 if (r < 0) {
1219 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
1220 return 0;
1221 } else if (!IN_SET(type, RTM_NEWNEXTHOP, RTM_DELNEXTHOP)) {
1222 log_warning("rtnl: received unexpected message type %u when processing nexthop, ignoring.", type);
1223 return 0;
1224 }
1225
1226 r = nexthop_new(&tmp);
1227 if (r < 0)
1228 return log_oom();
1229
1230 r = sd_rtnl_message_get_family(message, &tmp->family);
1231 if (r < 0) {
1232 log_warning_errno(r, "rtnl: could not get nexthop family, ignoring: %m");
1233 return 0;
1234 } else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) {
1235 log_debug("rtnl: received nexthop message with invalid family %d, ignoring.", tmp->family);
1236 return 0;
1237 }
1238
1239 switch (tmp->family) {
1240 case AF_INET:
1241 r = sd_netlink_message_read_in_addr(message, NHA_GATEWAY, &tmp->gw.in);
1242 if (r < 0 && r != -ENODATA) {
1243 log_warning_errno(r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m");
1244 return 0;
1245 }
1246 break;
1247
1248 case AF_INET6:
1249 r = sd_netlink_message_read_in6_addr(message, NHA_GATEWAY, &tmp->gw.in6);
1250 if (r < 0 && r != -ENODATA) {
1251 log_warning_errno(r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m");
1252 return 0;
1253 }
1254 break;
1255
1256 default:
1257 assert_not_reached("Received rule message with unsupported address family");
1258 }
1259
1260 r = sd_netlink_message_read_u32(message, NHA_ID, &tmp->id);
1261 if (r < 0 && r != -ENODATA) {
1262 log_warning_errno(r, "rtnl: could not get NHA_ID attribute, ignoring: %m");
1263 return 0;
1264 }
1265
1266 r = sd_netlink_message_read_u32(message, NHA_OIF, &tmp->oif);
1267 if (r < 0 && r != -ENODATA) {
1268 log_warning_errno(r, "rtnl: could not get NHA_OIF attribute, ignoring: %m");
1269 return 0;
1270 }
1271
1272 r = link_get(m, tmp->oif, &link);
1273 if (r < 0 || !link) {
1274 if (!m->enumerating)
1275 log_warning("rtnl: received nexthop message for link (%d) we do not know about, ignoring", tmp->oif);
1276 return 0;
1277 }
1278
1279 (void) nexthop_get(link, tmp, &nexthop);
1280
1281 if (DEBUG_LOGGING)
1282 (void) in_addr_to_string(tmp->family, &tmp->gw, &gateway);
1283
1284 switch (type) {
1285 case RTM_NEWNEXTHOP:
1286 if (!nexthop) {
1287 log_debug("Remembering foreign nexthop: %s, oif: %d, id: %d", gateway, tmp->oif, tmp->id);
1288 r = nexthop_add_foreign(link, tmp, &nexthop);
1289 if (r < 0) {
1290 log_warning_errno(r, "Could not remember foreign nexthop, ignoring: %m");
1291 return 0;
1292 }
1293 }
1294 break;
1295 case RTM_DELNEXTHOP:
1296 log_debug("Forgetting foreign nexthop: %s, oif: %d, id: %d", gateway, tmp->oif, tmp->id);
1297 nexthop_free(nexthop);
1298
1299 break;
1300
1301 default:
1302 assert_not_reached("Received invalid RTNL message type");
1303 }
1304
1305 return 1;
1306}
1307
5fae368b
TG
1308static int systemd_netlink_fd(void) {
1309 int n, fd, rtnl_fd = -EINVAL;
1310
1311 n = sd_listen_fds(true);
1312 if (n <= 0)
1313 return -EINVAL;
1314
1315 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
1316 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
1317 if (rtnl_fd >= 0)
1318 return -EINVAL;
1319
1320 rtnl_fd = fd;
1321 }
1322 }
1323
1324 return rtnl_fd;
1325}
1326
05d0c2e3
JT
1327static int manager_connect_genl(Manager *m) {
1328 int r;
1329
1330 assert(m);
1331
1332 r = sd_genl_socket_open(&m->genl);
1333 if (r < 0)
1334 return r;
1335
1336 r = sd_netlink_inc_rcvbuf(m->genl, RCVBUF_SIZE);
1337 if (r < 0)
1338 return r;
1339
1340 r = sd_netlink_attach_event(m->genl, m->event, 0);
1341 if (r < 0)
1342 return r;
1343
1344 return 0;
1345}
1346
5fae368b
TG
1347static int manager_connect_rtnl(Manager *m) {
1348 int fd, r;
505f8da7
TG
1349
1350 assert(m);
505f8da7 1351
5fae368b
TG
1352 fd = systemd_netlink_fd();
1353 if (fd < 0)
1c4baffc 1354 r = sd_netlink_open(&m->rtnl);
5fae368b 1355 else
1c4baffc 1356 r = sd_netlink_open_fd(&m->rtnl, fd);
505f8da7
TG
1357 if (r < 0)
1358 return r;
1359
1c4baffc 1360 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
f579559b 1361 if (r < 0)
bf5332d2 1362 return r;
f579559b 1363
1c4baffc 1364 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
505f8da7
TG
1365 if (r < 0)
1366 return r;
f579559b 1367
8190a388 1368 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
5fae368b
TG
1369 if (r < 0)
1370 return r;
505f8da7 1371
8190a388 1372 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
5fae368b
TG
1373 if (r < 0)
1374 return r;
45af44d4 1375
8190a388 1376 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
5fae368b
TG
1377 if (r < 0)
1378 return r;
1379
8190a388 1380 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
5fae368b
TG
1381 if (r < 0)
1382 return r;
1383
d1bdafd2
WKI
1384 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
1385 if (r < 0)
1386 return r;
1387
1388 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
1389 if (r < 0)
1390 return r;
1391
8190a388 1392 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
1c8e710c
TG
1393 if (r < 0)
1394 return r;
1395
8190a388 1396 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
1c8e710c
TG
1397 if (r < 0)
1398 return r;
1399
8190a388 1400 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
bce67bbe
SS
1401 if (r < 0)
1402 return r;
1403
8190a388 1404 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
bce67bbe
SS
1405 if (r < 0)
1406 return r;
1407
c16c7808
SS
1408 r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
1409 if (r < 0)
1410 return r;
1411
1412 r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
1413 if (r < 0)
1414 return r;
1415
5fae368b 1416 return 0;
45af44d4 1417}
505f8da7 1418
5512a963 1419static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
84de38c5
TG
1420 char *p;
1421 int r;
1422
1423 assert(s);
5512a963
LP
1424 assert(address);
1425
1426 r = in_addr_to_string(address->family, &address->address, &p);
1427 if (r < 0)
1428 return r;
1429
1430 r = ordered_set_consume(s, p);
1431 if (r == -EEXIST)
1432 return 0;
1433
1434 return r;
1435}
1436
1437static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
1438 int r, c = 0;
1439 unsigned i;
1440
1441 assert(s);
1442 assert(addresses || n == 0);
1443
1444 for (i = 0; i < n; i++) {
1445 r = ordered_set_put_in_addr_data(s, addresses+i);
1446 if (r < 0)
1447 return r;
1448
1449 c += r;
1450 }
1451
1452 return c;
1453}
1454
1455static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
1456 char *p;
1457 int r;
1458
1459 assert(s);
1460 assert(address);
84de38c5
TG
1461
1462 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
1463 if (r < 0)
1464 return r;
1465
00616955 1466 r = ordered_set_consume(s, p);
84de38c5
TG
1467 if (r == -EEXIST)
1468 return 0;
1469
1470 return r;
1471}
1472
072320ea
TH
1473static int ordered_set_put_in4_addrv(OrderedSet *s,
1474 const struct in_addr *addresses,
1475 size_t n,
1476 bool (*predicate)(const struct in_addr *addr)) {
5512a963 1477 int r, c = 0;
072320ea 1478 size_t i;
84de38c5
TG
1479
1480 assert(s);
5512a963 1481 assert(n == 0 || addresses);
84de38c5
TG
1482
1483 for (i = 0; i < n; i++) {
072320ea
TH
1484 if (predicate && !predicate(&addresses[i]))
1485 continue;
5512a963 1486 r = ordered_set_put_in4_addr(s, addresses+i);
84de38c5
TG
1487 if (r < 0)
1488 return r;
1489
1490 c += r;
1491 }
1492
1493 return c;
1494}
1495
84de38c5 1496static int manager_save(Manager *m) {
284e8fd0 1497 _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL,
d361b373 1498 *smtp = NULL, *lpr = NULL, *search_domains = NULL, *route_domains = NULL;
299d578f 1499 const char *operstate_str, *carrier_state_str, *address_state_str;
84de38c5 1500 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
7f3c07ad
YW
1501 LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
1502 LinkAddressState address_state = LINK_ADDRESS_STATE_OFF;
299d578f
SS
1503 _cleanup_free_ char *temp_path = NULL;
1504 _cleanup_strv_free_ char **p = NULL;
1505 _cleanup_fclose_ FILE *f = NULL;
284e8fd0 1506 const struct in_addr *addresses;
299d578f
SS
1507 Link *link;
1508 Iterator i;
84de38c5
TG
1509 int r;
1510
1511 assert(m);
1512 assert(m->state_file);
1513
1514 /* We add all NTP and DNS server to a set, to filter out duplicates */
00616955 1515 dns = ordered_set_new(&string_hash_ops);
84de38c5
TG
1516 if (!dns)
1517 return -ENOMEM;
1518
00616955 1519 ntp = ordered_set_new(&string_hash_ops);
84de38c5
TG
1520 if (!ntp)
1521 return -ENOMEM;
1522
284e8fd0
SS
1523 sip = ordered_set_new(&string_hash_ops);
1524 if (!sip)
299d578f
SS
1525 return -ENOMEM;
1526
284e8fd0
SS
1527 pop3 = ordered_set_new(&string_hash_ops);
1528 if (!pop3)
f6269fe7
SS
1529 return -ENOMEM;
1530
1531 smtp = ordered_set_new(&string_hash_ops);
d361b373
SS
1532 if (!smtp)
1533 return -ENOMEM;
1534
1535 lpr = ordered_set_new(&string_hash_ops);
1536 if (!lpr)
1537 return -ENOMEM;
284e8fd0 1538
482d1aeb 1539 search_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5
LP
1540 if (!search_domains)
1541 return -ENOMEM;
1542
482d1aeb 1543 route_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5 1544 if (!route_domains)
84de38c5
TG
1545 return -ENOMEM;
1546
1547 HASHMAP_FOREACH(link, m->links, i) {
1548 if (link->flags & IFF_LOOPBACK)
1549 continue;
1550
1551 if (link->operstate > operstate)
1552 operstate = link->operstate;
1553
7f3c07ad
YW
1554 if (link->carrier_state > carrier_state)
1555 carrier_state = link->carrier_state;
1556
1557 if (link->address_state > address_state)
1558 address_state = link->address_state;
1559
84de38c5
TG
1560 if (!link->network)
1561 continue;
1562
1563 /* First add the static configured entries */
5512a963 1564 r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
84de38c5
TG
1565 if (r < 0)
1566 return r;
1567
15761549 1568 r = ordered_set_put_strdupv(ntp, link->ntp ?: link->network->ntp);
84de38c5
TG
1569 if (r < 0)
1570 return r;
1571
15761549 1572 r = ordered_set_put_string_set(search_domains, link->search_domains ?: link->network->search_domains);
3df9bec5
LP
1573 if (r < 0)
1574 return r;
1575
15761549 1576 r = ordered_set_put_string_set(route_domains, link->route_domains ?: link->network->route_domains);
84de38c5
TG
1577 if (r < 0)
1578 return r;
1579
1580 if (!link->dhcp_lease)
1581 continue;
1582
1583 /* Secondly, add the entries acquired via DHCP */
27cb34f5 1584 if (link->network->dhcp_use_dns) {
84de38c5
TG
1585 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1586 if (r > 0) {
072320ea 1587 r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local);
84de38c5
TG
1588 if (r < 0)
1589 return r;
1590 } else if (r < 0 && r != -ENODATA)
1591 return r;
1592 }
1593
27cb34f5 1594 if (link->network->dhcp_use_ntp) {
84de38c5
TG
1595 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1596 if (r > 0) {
072320ea 1597 r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local);
84de38c5
TG
1598 if (r < 0)
1599 return r;
1600 } else if (r < 0 && r != -ENODATA)
1601 return r;
1602 }
1603
299d578f 1604 if (link->network->dhcp_use_sip) {
299d578f
SS
1605 r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses);
1606 if (r > 0) {
1607 r = ordered_set_put_in4_addrv(sip, addresses, r, in4_addr_is_non_local);
1608 if (r < 0)
1609 return r;
1610 } else if (r < 0 && r != -ENODATA)
1611 return r;
1612 }
1613
284e8fd0
SS
1614 r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses);
1615 if (r > 0) {
1616 r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local);
1617 if (r < 0)
1618 return r;
1619 } else if (r < 0 && r != -ENODATA)
1620 return r;
1621
f6269fe7
SS
1622 r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses);
1623 if (r > 0) {
1624 r = ordered_set_put_in4_addrv(smtp, addresses, r, in4_addr_is_non_local);
1625 if (r < 0)
1626 return r;
1627 } else if (r < 0 && r != -ENODATA)
1628 return r;
1629
d361b373
SS
1630 r = sd_dhcp_lease_get_lpr_servers(link->dhcp_lease, &addresses);
1631 if (r > 0) {
1632 r = ordered_set_put_in4_addrv(lpr, addresses, r, in4_addr_is_non_local);
1633 if (r < 0)
1634 return r;
1635 } else if (r < 0 && r != -ENODATA)
1636 return r;
1637
b2a81c0b 1638 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
84de38c5 1639 const char *domainname;
b85bc551 1640 char **domains = NULL;
84de38c5 1641
b85bc551 1642 OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
84de38c5
TG
1643 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1644 if (r >= 0) {
b85bc551
DW
1645 r = ordered_set_put_strdup(target_domains, domainname);
1646 if (r < 0)
1647 return r;
1648 } else if (r != -ENODATA)
1649 return r;
b2a81c0b 1650
b85bc551
DW
1651 r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
1652 if (r >= 0) {
1653 r = ordered_set_put_strdupv(target_domains, domains);
84de38c5
TG
1654 if (r < 0)
1655 return r;
1656 } else if (r != -ENODATA)
1657 return r;
1658 }
1659 }
1660
7f3c07ad
YW
1661 if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED)
1662 carrier_state = LINK_CARRIER_STATE_CARRIER;
1663
84de38c5
TG
1664 operstate_str = link_operstate_to_string(operstate);
1665 assert(operstate_str);
1666
ac999bf0
YW
1667 carrier_state_str = link_carrier_state_to_string(carrier_state);
1668 assert(carrier_state_str);
1669
1670 address_state_str = link_address_state_to_string(address_state);
1671 assert(address_state_str);
1672
84de38c5
TG
1673 r = fopen_temporary(m->state_file, &f, &temp_path);
1674 if (r < 0)
1675 return r;
1676
5512a963 1677 (void) fchmod(fileno(f), 0644);
84de38c5
TG
1678
1679 fprintf(f,
1680 "# This is private data. Do not parse.\n"
ac999bf0
YW
1681 "OPER_STATE=%s\n"
1682 "CARRIER_STATE=%s\n"
1683 "ADDRESS_STATE=%s\n",
1684 operstate_str, carrier_state_str, address_state_str);
84de38c5 1685
53ae3f64
ZJS
1686 ordered_set_print(f, "DNS=", dns);
1687 ordered_set_print(f, "NTP=", ntp);
299d578f 1688 ordered_set_print(f, "SIP=", sip);
284e8fd0 1689 ordered_set_print(f, "POP3_SERVERS=", pop3);
f6269fe7 1690 ordered_set_print(f, "SMTP_SERVERS=", smtp);
d361b373 1691 ordered_set_print(f, "LPR_SERVERS=", lpr);
53ae3f64
ZJS
1692 ordered_set_print(f, "DOMAINS=", search_domains);
1693 ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
84de38c5 1694
458d8ae3
ZJS
1695 r = routing_policy_serialize_rules(m->rules, f);
1696 if (r < 0)
1697 goto fail;
bce67bbe 1698
84de38c5
TG
1699 r = fflush_and_check(f);
1700 if (r < 0)
1701 goto fail;
1702
1703 if (rename(temp_path, m->state_file) < 0) {
1704 r = -errno;
1705 goto fail;
1706 }
1707
1708 if (m->operational_state != operstate) {
1709 m->operational_state = operstate;
7f3c07ad
YW
1710 if (strv_extend(&p, "OperationalState") < 0)
1711 log_oom();
1712 }
1713
1714 if (m->carrier_state != carrier_state) {
1715 m->carrier_state = carrier_state;
1716 if (strv_extend(&p, "CarrierState") < 0)
1717 log_oom();
1718 }
1719
1720 if (m->address_state != address_state) {
1721 m->address_state = address_state;
1722 if (strv_extend(&p, "AddressState") < 0)
1723 log_oom();
1724 }
1725
1726 if (p) {
1727 r = manager_send_changed_strv(m, p);
84de38c5 1728 if (r < 0)
7f3c07ad 1729 log_error_errno(r, "Could not emit changed properties: %m");
84de38c5
TG
1730 }
1731
1732 m->dirty = false;
1733
1734 return 0;
1735
1736fail:
1737 (void) unlink(m->state_file);
1738 (void) unlink(temp_path);
1739
1740 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
1741}
1742
1743static int manager_dirty_handler(sd_event_source *s, void *userdata) {
1744 Manager *m = userdata;
1745 Link *link;
1746 Iterator i;
84de38c5
TG
1747
1748 assert(m);
1749
1750 if (m->dirty)
1751 manager_save(m);
1752
a0e8e4cf
YW
1753 SET_FOREACH(link, m->dirty_links, i)
1754 if (link_save(link) >= 0)
84de38c5 1755 link_clean(link);
84de38c5
TG
1756
1757 return 1;
1758}
1759
ab76be55
ZJS
1760static int signal_terminate_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1761 Manager *m = userdata;
1762
1763 assert(m);
1764 m->restarting = false;
1765
1766 log_debug("Terminate operation initiated.");
1767
1768 return sd_event_exit(sd_event_source_get_event(s), 0);
1769}
1770
1771static int signal_restart_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1772 Manager *m = userdata;
1773
1774 assert(m);
1775 m->restarting = true;
1776
1777 log_debug("Restart operation initiated.");
1778
1779 return sd_event_exit(sd_event_source_get_event(s), 0);
1780}
1781
3534a043 1782int manager_new(Manager **ret) {
8e766630 1783 _cleanup_(manager_freep) Manager *m = NULL;
45af44d4 1784 int r;
f579559b 1785
a879e1a4 1786 m = new(Manager, 1);
5fae368b
TG
1787 if (!m)
1788 return -ENOMEM;
45af44d4 1789
a879e1a4
YW
1790 *m = (Manager) {
1791 .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
5d3b8017 1792 .manage_foreign_routes = true,
a879e1a4
YW
1793 };
1794
5fae368b
TG
1795 m->state_file = strdup("/run/systemd/netif/state");
1796 if (!m->state_file)
1797 return -ENOMEM;
1798
3534a043
YW
1799 r = sd_event_default(&m->event);
1800 if (r < 0)
1801 return r;
1802
ab76be55
ZJS
1803 assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR2, -1) >= 0);
1804
05e21627 1805 (void) sd_event_set_watchdog(m->event, true);
ab76be55
ZJS
1806 (void) sd_event_add_signal(m->event, NULL, SIGTERM, signal_terminate_callback, m);
1807 (void) sd_event_add_signal(m->event, NULL, SIGINT, signal_terminate_callback, m);
1808 (void) sd_event_add_signal(m->event, NULL, SIGUSR2, signal_restart_callback, m);
5fae368b 1809
84de38c5
TG
1810 r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
1811 if (r < 0)
1812 return r;
1813
5fae368b 1814 r = manager_connect_rtnl(m);
45af44d4
TG
1815 if (r < 0)
1816 return r;
1817
05d0c2e3
JT
1818 r = manager_connect_genl(m);
1819 if (r < 0)
1820 return r;
1821
5fae368b
TG
1822 r = manager_connect_udev(m);
1823 if (r < 0)
1824 return r;
45af44d4 1825
05d0c2e3
JT
1826 r = sd_resolve_default(&m->resolve);
1827 if (r < 0)
1828 return r;
1829
1830 r = sd_resolve_attach_event(m->resolve, m->event, 0);
1831 if (r < 0)
1832 return r;
1833
5fae368b
TG
1834 r = setup_default_address_pool(m);
1835 if (r < 0)
1836 return r;
f579559b 1837
8341a5c3 1838 m->duid.type = DUID_TYPE_EN;
413708d1 1839
458d8ae3 1840 (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
bce67bbe 1841
1cc6c93a 1842 *ret = TAKE_PTR(m);
f579559b 1843
f579559b
TG
1844 return 0;
1845}
1846
5fae368b 1847void manager_free(Manager *m) {
2c448c8a 1848 struct in6_addr *a;
c4397d94 1849 AddressPool *pool;
5fae368b 1850 Link *link;
f579559b 1851
5fae368b
TG
1852 if (!m)
1853 return;
505f8da7 1854
5fae368b 1855 free(m->state_file);
505f8da7 1856
2c448c8a 1857 while ((a = hashmap_first_key(m->dhcp6_prefixes)))
04ed9949 1858 (void) dhcp6_prefix_remove(m, a);
26a65470 1859 m->dhcp6_prefixes = hashmap_free(m->dhcp6_prefixes);
e133b289 1860
f61365e5 1861 while ((link = hashmap_steal_first(m->links))) {
65dd5e31 1862 if (link->dhcp6_client)
f61365e5 1863 (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, link);
946f8e14 1864
95355a28 1865 (void) link_stop_clients(link, true);
946f8e14 1866
5fae368b 1867 link_unref(link);
65dd5e31 1868 }
f579559b 1869
c4397d94 1870 m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
5f707e12
YW
1871 m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
1872 m->links = hashmap_free_with_destructor(m->links, link_unref);
27dfc982 1873
5f707e12 1874 m->duids_requesting_uuid = set_free(m->duids_requesting_uuid);
715d398e 1875 m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
dbffab87 1876
c4397d94 1877 m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
5fae368b
TG
1878
1879 while ((pool = m->address_pools))
1880 address_pool_free(pool);
1881
f19ee681
YW
1882 /* routing_policy_rule_free() access m->rules and m->rules_foreign.
1883 * So, it is necessary to set NULL after the sets are freed. */
1884 m->rules = set_free_with_destructor(m->rules, routing_policy_rule_free);
1885 m->rules_foreign = set_free_with_destructor(m->rules_foreign, routing_policy_rule_free);
b921fcb2 1886 set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
bce67bbe 1887
d4df6326
SS
1888 sd_netlink_unref(m->rtnl);
1889 sd_netlink_unref(m->genl);
1890 sd_resolve_unref(m->resolve);
1891
a879e1a4 1892 sd_event_source_unref(m->speed_meter_event_source);
2f5b4a77 1893 sd_event_unref(m->event);
5fae368b 1894
d2ebf952 1895 sd_device_monitor_unref(m->device_monitor);
7d20d375 1896
15761549 1897 bus_verify_polkit_async_registry_free(m->polkit_registry);
92e31da1 1898 sd_bus_flush_close_unref(m->bus);
7d20d375 1899
7901cea1
MP
1900 free(m->dynamic_timezone);
1901 free(m->dynamic_hostname);
1902
5fae368b
TG
1903 free(m);
1904}
1905
b76d99d9 1906int manager_start(Manager *m) {
84de38c5
TG
1907 Link *link;
1908 Iterator i;
a879e1a4 1909 int r;
84de38c5 1910
a97dcc12
TG
1911 assert(m);
1912
a879e1a4
YW
1913 r = manager_start_speed_meter(m);
1914 if (r < 0)
1915 return log_error_errno(r, "Failed to initialize speed meter: %m");
1916
84de38c5
TG
1917 /* The dirty handler will deal with future serialization, but the first one
1918 must be done explicitly. */
1919
1920 manager_save(m);
1921
1922 HASHMAP_FOREACH(link, m->links, i)
1923 link_save(link);
1924
b76d99d9 1925 return 0;
a97dcc12
TG
1926}
1927
5fae368b
TG
1928int manager_load_config(Manager *m) {
1929 int r;
1930
1931 /* update timestamp */
dc0d4078 1932 paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, true);
5fae368b 1933
e272b621 1934 r = netdev_load(m, false);
f579559b
TG
1935 if (r < 0)
1936 return r;
1937
7f06b3e1 1938 r = network_load(m, &m->networks);
9021bb9f
TG
1939 if (r < 0)
1940 return r;
1941
f579559b
TG
1942 return 0;
1943}
f882c247 1944
5fae368b 1945bool manager_should_reload(Manager *m) {
dc0d4078 1946 return paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, false);
5fae368b
TG
1947}
1948
1949int manager_rtnl_enumerate_links(Manager *m) {
4afd3348 1950 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1951 sd_netlink_message *link;
f882c247
TG
1952 int r;
1953
5da8149f 1954 assert(m);
5fae368b 1955 assert(m->rtnl);
5da8149f 1956
5fae368b 1957 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
f882c247
TG
1958 if (r < 0)
1959 return r;
1960
1c4baffc 1961 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
1962 if (r < 0)
1963 return r;
1964
1c4baffc 1965 r = sd_netlink_call(m->rtnl, req, 0, &reply);
f2236469
TG
1966 if (r < 0)
1967 return r;
1968
1c4baffc 1969 for (link = reply; link; link = sd_netlink_message_next(link)) {
5fae368b 1970 int k;
2e9f08ea 1971
6a24f148
TG
1972 m->enumerating = true;
1973
5fae368b
TG
1974 k = manager_rtnl_process_link(m->rtnl, link, m);
1975 if (k < 0)
1976 r = k;
6a24f148
TG
1977
1978 m->enumerating = false;
5fae368b 1979 }
2e9f08ea 1980
5fae368b 1981 return r;
f882c247 1982}
3bef724f 1983
5fae368b 1984int manager_rtnl_enumerate_addresses(Manager *m) {
4afd3348 1985 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1986 sd_netlink_message *addr;
1346b1f0
TG
1987 int r;
1988
5fae368b
TG
1989 assert(m);
1990 assert(m->rtnl);
bcbca829 1991
5fae368b
TG
1992 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
1993 if (r < 0)
1994 return r;
bcbca829 1995
1c4baffc 1996 r = sd_netlink_message_request_dump(req, true);
1346b1f0
TG
1997 if (r < 0)
1998 return r;
1999
1c4baffc 2000 r = sd_netlink_call(m->rtnl, req, 0, &reply);
5fae368b
TG
2001 if (r < 0)
2002 return r;
2003
1c4baffc 2004 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
5fae368b
TG
2005 int k;
2006
6a24f148
TG
2007 m->enumerating = true;
2008
200a0868 2009 k = manager_rtnl_process_address(m->rtnl, addr, m);
5fae368b
TG
2010 if (k < 0)
2011 r = k;
6a24f148
TG
2012
2013 m->enumerating = false;
5fae368b
TG
2014 }
2015
2016 return r;
1346b1f0 2017}
d1bdafd2
WKI
2018
2019int manager_rtnl_enumerate_neighbors(Manager *m) {
2020 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
2021 sd_netlink_message *neigh;
2022 int r;
2023
2024 assert(m);
2025 assert(m->rtnl);
2026
2027 r = sd_rtnl_message_new_neigh(m->rtnl, &req, RTM_GETNEIGH, 0, AF_UNSPEC);
2028 if (r < 0)
2029 return r;
2030
2031 r = sd_netlink_message_request_dump(req, true);
2032 if (r < 0)
2033 return r;
2034
2035 r = sd_netlink_call(m->rtnl, req, 0, &reply);
2036 if (r < 0)
2037 return r;
2038
2039 for (neigh = reply; neigh; neigh = sd_netlink_message_next(neigh)) {
2040 int k;
2041
2042 m->enumerating = true;
2043
2044 k = manager_rtnl_process_neighbor(m->rtnl, neigh, m);
2045 if (k < 0)
2046 r = k;
2047
2048 m->enumerating = false;
2049 }
2050
2051 return r;
2052}
1346b1f0 2053
1c8e710c 2054int manager_rtnl_enumerate_routes(Manager *m) {
4afd3348 2055 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c8e710c
TG
2056 sd_netlink_message *route;
2057 int r;
2058
2059 assert(m);
2060 assert(m->rtnl);
2061
2062 r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
2063 if (r < 0)
2064 return r;
2065
2066 r = sd_netlink_message_request_dump(req, true);
2067 if (r < 0)
2068 return r;
2069
2070 r = sd_netlink_call(m->rtnl, req, 0, &reply);
2071 if (r < 0)
2072 return r;
2073
2074 for (route = reply; route; route = sd_netlink_message_next(route)) {
2075 int k;
2076
2077 m->enumerating = true;
2078
2079 k = manager_rtnl_process_route(m->rtnl, route, m);
2080 if (k < 0)
2081 r = k;
2082
2083 m->enumerating = false;
2084 }
2085
2086 return r;
2087}
2088
bce67bbe
SS
2089int manager_rtnl_enumerate_rules(Manager *m) {
2090 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
2091 sd_netlink_message *rule;
2092 int r;
2093
2094 assert(m);
2095 assert(m->rtnl);
2096
2097 r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
2098 if (r < 0)
2099 return r;
2100
2101 r = sd_netlink_message_request_dump(req, true);
2102 if (r < 0)
2103 return r;
2104
2105 r = sd_netlink_call(m->rtnl, req, 0, &reply);
6acbbdd4
SS
2106 if (r < 0) {
2107 if (r == -EOPNOTSUPP) {
2108 log_debug("FIB Rules are not supported by the kernel. Ignoring.");
2109 return 0;
2110 }
2111
bce67bbe 2112 return r;
6acbbdd4 2113 }
bce67bbe
SS
2114
2115 for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
2116 int k;
2117
2118 m->enumerating = true;
2119
2120 k = manager_rtnl_process_rule(m->rtnl, rule, m);
2121 if (k < 0)
2122 r = k;
2123
2124 m->enumerating = false;
2125 }
2126
2127 return r;
2128}
2129
c16c7808
SS
2130int manager_rtnl_enumerate_nexthop(Manager *m) {
2131 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
2132 sd_netlink_message *nexthop;
2133 int r;
2134
2135 assert(m);
2136 assert(m->rtnl);
2137
2138 r = sd_rtnl_message_new_nexthop(m->rtnl, &req, RTM_GETNEXTHOP, 0, 0);
2139 if (r < 0)
2140 return r;
2141
2142 r = sd_netlink_message_request_dump(req, true);
2143 if (r < 0)
2144 return r;
2145
2146 r = sd_netlink_call(m->rtnl, req, 0, &reply);
2147 if (r < 0) {
2148 if (r == -EOPNOTSUPP) {
2149 log_debug("Nexthop are not supported by the kernel. Ignoring.");
2150 return 0;
2151 }
2152
2153 return r;
2154 }
2155
2156 for (nexthop = reply; nexthop; nexthop = sd_netlink_message_next(nexthop)) {
2157 int k;
2158
2159 m->enumerating = true;
2160
2161 k = manager_rtnl_process_nexthop(m->rtnl, nexthop, m);
2162 if (k < 0)
2163 r = k;
2164
2165 m->enumerating = false;
2166 }
2167
2168 return r;
2169}
2170
0dd25fb9 2171int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
2172 AddressPool *p;
2173 int r;
2174
2175 assert(m);
2176 assert(prefixlen > 0);
2177 assert(found);
2178
2179 LIST_FOREACH(address_pools, p, m->address_pools) {
2180 if (p->family != family)
2181 continue;
2182
2183 r = address_pool_acquire(p, prefixlen, found);
2184 if (r != 0)
2185 return r;
2186 }
2187
2188 return 0;
2189}
4f5f911e
LP
2190
2191Link* manager_find_uplink(Manager *m, Link *exclude) {
2192 _cleanup_free_ struct local_address *gateways = NULL;
2193 int n, i;
2194
2195 assert(m);
2196
2197 /* Looks for a suitable "uplink", via black magic: an
2198 * interface that is up and where the default route with the
2199 * highest priority points to. */
2200
2201 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
2202 if (n < 0) {
2203 log_warning_errno(n, "Failed to determine list of default gateways: %m");
2204 return NULL;
2205 }
2206
2207 for (i = 0; i < n; i++) {
2208 Link *link;
2209
2210 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
2211 if (!link) {
c2c940bd 2212 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
4f5f911e
LP
2213 continue;
2214 }
2215
2216 if (link == exclude)
2217 continue;
2218
2219 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
2220 continue;
2221
2222 return link;
2223 }
2224
2225 return NULL;
2226}
84de38c5
TG
2227
2228void manager_dirty(Manager *manager) {
2229 assert(manager);
2230
2231 /* the serialized state in /run is no longer up-to-date */
2232 manager->dirty = true;
2233}
59eb33e0
MP
2234
2235static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
0a0e594a 2236 _unused_ Manager *manager = userdata;
59eb33e0
MP
2237 const sd_bus_error *e;
2238
2239 assert(m);
2240 assert(manager);
2241
2242 e = sd_bus_message_get_error(m);
2243 if (e)
2244 log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
2245
2246 return 1;
2247}
2248
2249int manager_set_hostname(Manager *m, const char *hostname) {
2250 int r;
2251
2252 log_debug("Setting transient hostname: '%s'", strna(hostname));
d7afd945 2253
7901cea1
MP
2254 if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
2255 return log_oom();
59eb33e0 2256
d7afd945 2257 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
e0d95f03 2258 log_debug("Not connected to system bus, setting hostname later.");
59eb33e0
MP
2259 return 0;
2260 }
2261
2262 r = sd_bus_call_method_async(
2263 m->bus,
2264 NULL,
2265 "org.freedesktop.hostname1",
2266 "/org/freedesktop/hostname1",
2267 "org.freedesktop.hostname1",
2268 "SetHostname",
2269 set_hostname_handler,
2270 m,
2271 "sb",
2272 hostname,
2273 false);
2274
2275 if (r < 0)
2276 return log_error_errno(r, "Could not set transient hostname: %m");
2277
2278 return 0;
2279}
2280
2281static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
0a0e594a 2282 _unused_ Manager *manager = userdata;
59eb33e0
MP
2283 const sd_bus_error *e;
2284
2285 assert(m);
2286 assert(manager);
2287
2288 e = sd_bus_message_get_error(m);
2289 if (e)
2290 log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
2291
2292 return 1;
2293}
2294
2295int manager_set_timezone(Manager *m, const char *tz) {
2296 int r;
2297
2298 assert(m);
2299 assert(tz);
2300
2301 log_debug("Setting system timezone: '%s'", tz);
7901cea1
MP
2302 if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
2303 return log_oom();
59eb33e0 2304
d7afd945 2305 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
e0d95f03 2306 log_debug("Not connected to system bus, setting timezone later.");
59eb33e0
MP
2307 return 0;
2308 }
2309
2310 r = sd_bus_call_method_async(
2311 m->bus,
2312 NULL,
2313 "org.freedesktop.timedate1",
2314 "/org/freedesktop/timedate1",
2315 "org.freedesktop.timedate1",
2316 "SetTimezone",
2317 set_timezone_handler,
2318 m,
2319 "sb",
2320 tz,
2321 false);
2322 if (r < 0)
2323 return log_error_errno(r, "Could not set timezone: %m");
2324
2325 return 0;
2326}
27dfc982
YW
2327
2328int manager_request_product_uuid(Manager *m, Link *link) {
2329 int r;
2330
2331 assert(m);
2332
2333 if (m->has_product_uuid)
2334 return 0;
2335
2336 log_debug("Requesting product UUID");
2337
2338 if (link) {
2339 DUID *duid;
2340
2341 assert_se(duid = link_get_duid(link));
2342
2343 r = set_ensure_allocated(&m->links_requesting_uuid, NULL);
2344 if (r < 0)
2345 return log_oom();
2346
2347 r = set_ensure_allocated(&m->duids_requesting_uuid, NULL);
2348 if (r < 0)
2349 return log_oom();
2350
2351 r = set_put(m->links_requesting_uuid, link);
2352 if (r < 0)
2353 return log_oom();
2354
2355 r = set_put(m->duids_requesting_uuid, duid);
2356 if (r < 0)
2357 return log_oom();
3dc2e7af
YW
2358
2359 link_ref(link);
27dfc982
YW
2360 }
2361
2362 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
2363 log_debug("Not connected to system bus, requesting product UUID later.");
2364 return 0;
2365 }
2366
2367 r = sd_bus_call_method_async(
2368 m->bus,
2369 NULL,
2370 "org.freedesktop.hostname1",
2371 "/org/freedesktop/hostname1",
2372 "org.freedesktop.hostname1",
2373 "GetProductUUID",
2374 get_product_uuid_handler,
2375 m,
2376 "b",
2377 false);
2378 if (r < 0)
2379 return log_warning_errno(r, "Failed to get product UUID: %m");
2380
2381 return 0;
2382}