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