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