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