]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
Fix #7704 and #7708. (#7712)
[thirdparty/systemd.git] / src / network / networkd-manager.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
f579559b
TG
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Tom Gundersen <teg@jklm.no>
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
091a364c 21#include <sys/socket.h>
bbf7c048 22#include <linux/if.h>
bce67bbe 23#include <linux/fib_rules.h>
0d536673 24#include <stdio_ext.h>
3bef724f 25
fc2f9534 26#include "sd-daemon.h"
07630cea 27#include "sd-netlink.h"
fc2f9534 28
b5efdb8a 29#include "alloc-util.h"
a97dcc12 30#include "bus-util.h"
07630cea 31#include "conf-parser.h"
a97dcc12 32#include "def.h"
482d1aeb 33#include "dns-domain.h"
3ffd4af2 34#include "fd-util.h"
0d39fa9c 35#include "fileio.h"
07630cea 36#include "libudev-private.h"
4f5f911e 37#include "local-addresses.h"
07630cea 38#include "netlink-util.h"
23f53b99 39#include "networkd-manager.h"
00616955 40#include "ordered-set.h"
07630cea
LP
41#include "path-util.h"
42#include "set.h"
43#include "udev-util.h"
44#include "virt.h"
505f8da7 45
be660c37
AR
46/* use 8 MB for receive socket kernel queue. */
47#define RCVBUF_SIZE (8*1024*1024)
48
2ad8416d
ZJS
49const char* const network_dirs[] = {
50 "/etc/systemd/network",
51 "/run/systemd/network",
52 "/usr/lib/systemd/network",
349cc4a5 53#if HAVE_SPLIT_USR
2ad8416d
ZJS
54 "/lib/systemd/network",
55#endif
56 NULL};
57
11bf3cce
LP
58static int setup_default_address_pool(Manager *m) {
59 AddressPool *p;
60 int r;
61
62 assert(m);
63
64 /* Add in the well-known private address ranges. */
65
66 r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
67 if (r < 0)
68 return r;
69
70 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
71 if (r < 0)
72 return r;
73
74 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
75 if (r < 0)
76 return r;
77
78 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
79 if (r < 0)
80 return r;
81
82 return 0;
83}
84
9c0a72f9
TG
85static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
86 Manager *m = userdata;
87
88 assert(s);
89 assert(m);
90
91 m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
92
93 manager_connect_bus(m);
94
95 return 0;
96}
97
98static int manager_reset_all(Manager *m) {
99 Link *link;
100 Iterator i;
101 int r;
102
103 assert(m);
104
105 HASHMAP_FOREACH(link, m->links, i) {
106 r = link_carrier_reset(link);
107 if (r < 0)
2f3cf1f9 108 log_link_warning_errno(link, r, "Could not reset carrier: %m");
9c0a72f9
TG
109 }
110
111 return 0;
112}
113
19070062 114static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
9c0a72f9
TG
115 Manager *m = userdata;
116 int b, r;
117
19070062 118 assert(message);
9c0a72f9
TG
119
120 r = sd_bus_message_read(message, "b", &b);
121 if (r < 0) {
122 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
123 return 0;
124 }
125
126 if (b)
127 return 0;
128
129 log_debug("Coming back from suspend, resetting all connections...");
130
131 manager_reset_all(m);
132
133 return 0;
134}
135
136int manager_connect_bus(Manager *m) {
137 int r;
138
139 assert(m);
140
141 r = sd_bus_default_system(&m->bus);
fb72b1d9 142 if (r < 0) {
9c0a72f9 143 /* We failed to connect? Yuck, we must be in early
d7ea7bb8 144 * boot. Let's try in 5s again. */
9c0a72f9
TG
145
146 log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
147
148 r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
149 if (r < 0)
150 return log_error_errno(r, "Failed to install bus reconnect time event: %m");
151
152 return 0;
7d6884b6
TA
153 }
154
9c0a72f9
TG
155 r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
156 "type='signal',"
157 "sender='org.freedesktop.login1',"
158 "interface='org.freedesktop.login1.Manager',"
159 "member='PrepareForSleep',"
160 "path='/org/freedesktop/login1'",
161 match_prepare_for_sleep,
162 m);
163 if (r < 0)
164 return log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
165
e331e246
TG
166 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m);
167 if (r < 0)
168 return log_error_errno(r, "Failed to add manager object vtable: %m");
169
170 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m);
171 if (r < 0)
172 return log_error_errno(r, "Failed to add link object vtable: %m");
173
174 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
175 if (r < 0)
176 return log_error_errno(r, "Failed to add link enumerator: %m");
3175fcde
TG
177
178 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m);
179 if (r < 0)
180 return log_error_errno(r, "Failed to add network object vtable: %m");
181
182 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m);
183 if (r < 0)
184 return log_error_errno(r, "Failed to add network enumerator: %m");
e331e246
TG
185
186 r = sd_bus_request_name(m->bus, "org.freedesktop.network1", 0);
187 if (r < 0)
188 return log_error_errno(r, "Failed to register name: %m");
189
190 r = sd_bus_attach_event(m->bus, m->event, 0);
191 if (r < 0)
192 return log_error_errno(r, "Failed to attach bus to event loop: %m");
193
7901cea1
MP
194 /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
195 if (m->dynamic_hostname) {
196 r = manager_set_hostname(m, m->dynamic_hostname);
197 if (r < 0)
198 return r;
199 }
200 if (m->dynamic_timezone) {
201 r = manager_set_timezone(m, m->dynamic_timezone);
202 if (r < 0)
203 return r;
204 }
205
9c0a72f9
TG
206 return 0;
207}
208
5fae368b
TG
209static int manager_udev_process_link(Manager *m, struct udev_device *device) {
210 Link *link = NULL;
211 int r, ifindex;
5544ee85 212
5fae368b
TG
213 assert(m);
214 assert(device);
5544ee85 215
5fae368b
TG
216 if (!streq_ptr(udev_device_get_action(device), "add"))
217 return 0;
5544ee85 218
5fae368b
TG
219 ifindex = udev_device_get_ifindex(device);
220 if (ifindex <= 0) {
2f3cf1f9 221 log_debug("Ignoring udev ADD event for device with invalid ifindex");
5fae368b 222 return 0;
5544ee85
TG
223 }
224
5fae368b
TG
225 r = link_get(m, ifindex, &link);
226 if (r == -ENODEV)
227 return 0;
228 else if (r < 0)
f579559b
TG
229 return r;
230
5fae368b 231 r = link_initialized(link, device);
44de0efc
LP
232 if (r < 0)
233 return r;
234
5fae368b
TG
235 return 0;
236}
be660c37 237
5fae368b
TG
238static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
239 Manager *m = userdata;
240 struct udev_monitor *monitor = m->udev_monitor;
241 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
f579559b 242
5fae368b
TG
243 device = udev_monitor_receive_device(monitor);
244 if (!device)
02b59d57
TG
245 return -ENOMEM;
246
5fae368b 247 manager_udev_process_link(m, device);
f579559b
TG
248 return 0;
249}
250
5fae368b
TG
251static int manager_connect_udev(Manager *m) {
252 int r;
f579559b 253
5fae368b
TG
254 /* udev does not initialize devices inside containers,
255 * so we rely on them being already initialized before
256 * entering the container */
75f86906 257 if (detect_container() > 0)
5fae368b 258 return 0;
f579559b 259
5fae368b
TG
260 m->udev = udev_new();
261 if (!m->udev)
262 return -ENOMEM;
02b59d57 263
5fae368b
TG
264 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
265 if (!m->udev_monitor)
266 return -ENOMEM;
02b59d57 267
5fae368b 268 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
02b59d57 269 if (r < 0)
5fae368b 270 return log_error_errno(r, "Could not add udev monitor filter: %m");
02b59d57 271
5fae368b
TG
272 r = udev_monitor_enable_receiving(m->udev_monitor);
273 if (r < 0) {
274 log_error("Could not enable udev monitor");
02b59d57 275 return r;
667fcc6d 276 }
505f8da7 277
5fae368b
TG
278 r = sd_event_add_io(m->event,
279 &m->udev_event_source,
280 udev_monitor_get_fd(m->udev_monitor),
281 EPOLLIN, manager_dispatch_link_udev,
282 m);
283 if (r < 0)
667fcc6d 284 return r;
505f8da7 285
5fae368b 286 r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
505f8da7
TG
287 if (r < 0)
288 return r;
11a7f229 289
505f8da7
TG
290 return 0;
291}
f579559b 292
1c8e710c
TG
293int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
294 Manager *m = userdata;
295 Link *link = NULL;
296 uint16_t type;
297 uint32_t ifindex, priority = 0;
983226f3 298 unsigned char protocol, scope, tos, table, rt_type;
1c8e710c
TG
299 int family;
300 unsigned char dst_prefixlen, src_prefixlen;
301 union in_addr_union dst = {}, gw = {}, src = {}, prefsrc = {};
302 Route *route = NULL;
303 int r;
304
305 assert(rtnl);
306 assert(message);
307 assert(m);
308
309 if (sd_netlink_message_is_error(message)) {
310 r = sd_netlink_message_get_errno(message);
311 if (r < 0)
312 log_warning_errno(r, "rtnl: failed to receive route: %m");
313
314 return 0;
315 }
316
317 r = sd_netlink_message_get_type(message, &type);
318 if (r < 0) {
319 log_warning_errno(r, "rtnl: could not get message type: %m");
320 return 0;
25a1bffc 321 } else if (!IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE)) {
1c8e710c
TG
322 log_warning("rtnl: received unexpected message type when processing route");
323 return 0;
324 }
325
326 r = sd_netlink_message_read_u32(message, RTA_OIF, &ifindex);
327 if (r == -ENODATA) {
328 log_debug("rtnl: received route without ifindex, ignoring");
329 return 0;
330 } else if (r < 0) {
331 log_warning_errno(r, "rtnl: could not get ifindex from route, ignoring: %m");
332 return 0;
333 } else if (ifindex <= 0) {
334 log_warning("rtnl: received route message with invalid ifindex, ignoring: %d", ifindex);
335 return 0;
336 } else {
337 r = link_get(m, ifindex, &link);
338 if (r < 0 || !link) {
339 /* when enumerating we might be out of sync, but we will
340 * get the route again, so just ignore it */
341 if (!m->enumerating)
342 log_warning("rtnl: received route for nonexistent link (%d), ignoring", ifindex);
343 return 0;
344 }
345 }
346
347 r = sd_rtnl_message_route_get_family(message, &family);
348 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
349 log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
350 return 0;
351 }
352
353 r = sd_rtnl_message_route_get_protocol(message, &protocol);
354 if (r < 0) {
355 log_warning_errno(r, "rtnl: could not get route protocol: %m");
356 return 0;
357 }
358
359 switch (family) {
360 case AF_INET:
361 r = sd_netlink_message_read_in_addr(message, RTA_DST, &dst.in);
362 if (r < 0 && r != -ENODATA) {
363 log_link_warning_errno(link, r, "rtnl: received route without valid destination, ignoring: %m");
364 return 0;
365 }
366
367 r = sd_netlink_message_read_in_addr(message, RTA_GATEWAY, &gw.in);
368 if (r < 0 && r != -ENODATA) {
369 log_link_warning_errno(link, r, "rtnl: received route with invalid gateway, ignoring: %m");
370 return 0;
371 }
372
373 r = sd_netlink_message_read_in_addr(message, RTA_SRC, &src.in);
374 if (r < 0 && r != -ENODATA) {
375 log_link_warning_errno(link, r, "rtnl: received route with invalid source, ignoring: %m");
376 return 0;
377 }
378
379 r = sd_netlink_message_read_in_addr(message, RTA_PREFSRC, &prefsrc.in);
380 if (r < 0 && r != -ENODATA) {
381 log_link_warning_errno(link, r, "rtnl: received route with invalid preferred source, ignoring: %m");
382 return 0;
383 }
384
385 break;
386
387 case AF_INET6:
388 r = sd_netlink_message_read_in6_addr(message, RTA_DST, &dst.in6);
389 if (r < 0 && r != -ENODATA) {
390 log_link_warning_errno(link, r, "rtnl: received route without valid destination, ignoring: %m");
391 return 0;
392 }
393
394 r = sd_netlink_message_read_in6_addr(message, RTA_GATEWAY, &gw.in6);
395 if (r < 0 && r != -ENODATA) {
396 log_link_warning_errno(link, r, "rtnl: received route with invalid gateway, ignoring: %m");
397 return 0;
398 }
399
400 r = sd_netlink_message_read_in6_addr(message, RTA_SRC, &src.in6);
401 if (r < 0 && r != -ENODATA) {
402 log_link_warning_errno(link, r, "rtnl: received route with invalid source, ignoring: %m");
403 return 0;
404 }
405
406 r = sd_netlink_message_read_in6_addr(message, RTA_PREFSRC, &prefsrc.in6);
407 if (r < 0 && r != -ENODATA) {
408 log_link_warning_errno(link, r, "rtnl: received route with invalid preferred source, ignoring: %m");
409 return 0;
410 }
411
412 break;
413
414 default:
74dead34 415 assert_not_reached("Received unsupported address family");
1c8e710c
TG
416 return 0;
417 }
418
419 r = sd_rtnl_message_route_get_dst_prefixlen(message, &dst_prefixlen);
420 if (r < 0) {
421 log_link_warning_errno(link, r, "rtnl: received route with invalid destination prefixlen, ignoring: %m");
422 return 0;
423 }
424
425 r = sd_rtnl_message_route_get_src_prefixlen(message, &src_prefixlen);
426 if (r < 0) {
427 log_link_warning_errno(link, r, "rtnl: received route with invalid source prefixlen, ignoring: %m");
428 return 0;
429 }
430
431 r = sd_rtnl_message_route_get_scope(message, &scope);
432 if (r < 0) {
433 log_link_warning_errno(link, r, "rtnl: received route with invalid scope, ignoring: %m");
434 return 0;
435 }
436
437 r = sd_rtnl_message_route_get_tos(message, &tos);
438 if (r < 0) {
439 log_link_warning_errno(link, r, "rtnl: received route with invalid tos, ignoring: %m");
440 return 0;
441 }
442
983226f3
SS
443 r = sd_rtnl_message_route_get_type(message, &rt_type);
444 if (r < 0) {
445 log_link_warning_errno(link, r, "rtnl: received route with invalid type, ignoring: %m");
446 return 0;
447 }
448
1c8e710c
TG
449 r = sd_rtnl_message_route_get_table(message, &table);
450 if (r < 0) {
451 log_link_warning_errno(link, r, "rtnl: received route with invalid table, ignoring: %m");
452 return 0;
453 }
454
455 r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &priority);
456 if (r < 0 && r != -ENODATA) {
457 log_link_warning_errno(link, r, "rtnl: received route with invalid priority, ignoring: %m");
458 return 0;
459 }
460
461 route_get(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
462
463 switch (type) {
464 case RTM_NEWROUTE:
465 if (!route) {
466 /* A route appeared that we did not request */
467 r = route_add_foreign(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
468 if (r < 0)
469 return 0;
470 }
471
bbd15900 472 route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, protocol, rt_type);
1c8e710c
TG
473
474 break;
475
476 case RTM_DELROUTE:
b9642f41 477 route_free(route);
1c8e710c 478 break;
b9642f41 479
1c8e710c
TG
480 default:
481 assert_not_reached("Received invalid RTNL message type");
482 }
483
484 return 1;
485}
486
200a0868
TG
487int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
488 Manager *m = userdata;
489 Link *link = NULL;
490 uint16_t type;
200a0868 491 unsigned char flags;
054f0db4
TG
492 int family;
493 unsigned char prefixlen;
494 unsigned char scope;
495 union in_addr_union in_addr;
496 struct ifa_cacheinfo cinfo;
497 Address *address = NULL;
200a0868
TG
498 char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
499 const char *valid_str = NULL;
500 int r, ifindex;
501
502 assert(rtnl);
503 assert(message);
504 assert(m);
505
506 if (sd_netlink_message_is_error(message)) {
507 r = sd_netlink_message_get_errno(message);
508 if (r < 0)
509 log_warning_errno(r, "rtnl: failed to receive address: %m");
510
511 return 0;
512 }
513
514 r = sd_netlink_message_get_type(message, &type);
515 if (r < 0) {
516 log_warning_errno(r, "rtnl: could not get message type: %m");
517 return 0;
25a1bffc 518 } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)) {
200a0868
TG
519 log_warning("rtnl: received unexpected message type when processing address");
520 return 0;
521 }
522
523 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
524 if (r < 0) {
525 log_warning_errno(r, "rtnl: could not get ifindex from address: %m");
526 return 0;
527 } else if (ifindex <= 0) {
528 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
529 return 0;
530 } else {
531 r = link_get(m, ifindex, &link);
532 if (r < 0 || !link) {
533 /* when enumerating we might be out of sync, but we will
534 * get the address again, so just ignore it */
535 if (!m->enumerating)
536 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
537 return 0;
538 }
539 }
540
054f0db4
TG
541 r = sd_rtnl_message_addr_get_family(message, &family);
542 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
200a0868
TG
543 log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
544 return 0;
545 }
546
054f0db4 547 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
200a0868
TG
548 if (r < 0) {
549 log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m");
550 return 0;
551 }
552
054f0db4 553 r = sd_rtnl_message_addr_get_scope(message, &scope);
200a0868
TG
554 if (r < 0) {
555 log_link_warning_errno(link, r, "rtnl: received address with invalid scope, ignoring: %m");
556 return 0;
557 }
558
559 r = sd_rtnl_message_addr_get_flags(message, &flags);
560 if (r < 0) {
561 log_link_warning_errno(link, r, "rtnl: received address with invalid flags, ignoring: %m");
562 return 0;
563 }
200a0868 564
054f0db4 565 switch (family) {
200a0868 566 case AF_INET:
054f0db4 567 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
200a0868
TG
568 if (r < 0) {
569 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
570 return 0;
571 }
572
573 break;
574
575 case AF_INET6:
054f0db4 576 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
200a0868
TG
577 if (r < 0) {
578 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
579 return 0;
580 }
581
582 break;
583
584 default:
1c8e710c 585 log_link_debug(link, "rtnl: ignoring unsupported address family: %d", family);
200a0868
TG
586 }
587
054f0db4 588 if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) {
200a0868
TG
589 log_link_warning(link, "Could not print address");
590 return 0;
591 }
592
054f0db4 593 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
200a0868 594 if (r >= 0) {
4058d339 595 if (cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
200a0868 596 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
054f0db4 597 cinfo.ifa_valid * USEC_PER_SEC,
200a0868
TG
598 USEC_PER_SEC);
599 }
600
054f0db4 601 address_get(link, family, &in_addr, prefixlen, &address);
200a0868
TG
602
603 switch (type) {
604 case RTM_NEWADDR:
36c32f61 605 if (address)
4058d339 606 log_link_debug(link, "Updating address: %s/%u (valid %s%s)", buf, prefixlen,
87e4e28d 607 valid_str ? "for " : "forever", strempty(valid_str));
36c32f61 608 else {
adda1ed9
TG
609 /* An address appeared that we did not request */
610 r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
cf1d700d 611 if (r < 0) {
054f0db4 612 log_link_warning_errno(link, r, "Failed to add address %s/%u: %m", buf, prefixlen);
cf1d700d
TG
613 return 0;
614 } else
4058d339 615 log_link_debug(link, "Adding address: %s/%u (valid %s%s)", buf, prefixlen,
87e4e28d 616 valid_str ? "for " : "forever", strempty(valid_str));
200a0868
TG
617 }
618
58fda79c 619 address_update(address, flags, scope, &cinfo);
36c32f61 620
200a0868
TG
621 break;
622
623 case RTM_DELADDR:
624
054f0db4 625 if (address) {
4058d339 626 log_link_debug(link, "Removing address: %s/%u (valid %s%s)", buf, prefixlen,
87e4e28d 627 valid_str ? "for " : "forever", strempty(valid_str));
91b5f997 628 address_drop(address);
200a0868 629 } else
4058d339 630 log_link_warning(link, "Removing non-existent address: %s/%u (valid %s%s)", buf, prefixlen,
87e4e28d 631 valid_str ? "for " : "forever", strempty(valid_str));
200a0868
TG
632
633 break;
634 default:
635 assert_not_reached("Received invalid RTNL message type");
636 }
637
638 return 1;
639}
640
1c4baffc 641static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
505f8da7
TG
642 Manager *m = userdata;
643 Link *link = NULL;
4d473d5d 644 NetDev *netdev = NULL;
f2236469 645 uint16_t type;
ca4e095a 646 const char *name;
505f8da7 647 int r, ifindex;
f579559b 648
505f8da7
TG
649 assert(rtnl);
650 assert(message);
f579559b
TG
651 assert(m);
652
1c4baffc
TG
653 if (sd_netlink_message_is_error(message)) {
654 r = sd_netlink_message_get_errno(message);
45af44d4 655 if (r < 0)
2f3cf1f9 656 log_warning_errno(r, "rtnl: Could not receive link: %m");
45af44d4
TG
657
658 return 0;
659 }
660
1c4baffc 661 r = sd_netlink_message_get_type(message, &type);
f2236469 662 if (r < 0) {
2f3cf1f9 663 log_warning_errno(r, "rtnl: Could not get message type: %m");
f2236469 664 return 0;
25a1bffc 665 } else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)) {
2f3cf1f9 666 log_warning("rtnl: Received unexpected message type when processing link");
cdfee943 667 return 0;
f2236469
TG
668 }
669
505f8da7 670 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
45af44d4 671 if (r < 0) {
2f3cf1f9 672 log_warning_errno(r, "rtnl: Could not get ifindex from link: %m");
45af44d4
TG
673 return 0;
674 } else if (ifindex <= 0) {
675 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
505f8da7 676 return 0;
a0db8e46 677 }
f579559b 678
1c4baffc 679 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
45af44d4 680 if (r < 0) {
2f3cf1f9 681 log_warning_errno(r, "rtnl: Received link message without ifname: %m");
4d473d5d 682 return 0;
a0db8e46
ZJS
683 }
684
685 (void) link_get(m, ifindex, &link);
686 (void) netdev_get(m, name, &netdev);
4d473d5d
TG
687
688 switch (type) {
689 case RTM_NEWLINK:
690 if (!link) {
691 /* link is new, so add it */
692 r = link_add(m, message, &link);
693 if (r < 0) {
2f3cf1f9 694 log_warning_errno(r, "Could not add new link: %m");
4d473d5d
TG
695 return 0;
696 }
697 }
698
699 if (netdev) {
700 /* netdev exists, so make sure the ifindex matches */
505f8da7
TG
701 r = netdev_set_ifindex(netdev, message);
702 if (r < 0) {
2f3cf1f9 703 log_warning_errno(r, "Could not set ifindex on netdev: %m");
505f8da7
TG
704 return 0;
705 }
706 }
e1202047 707
f2236469
TG
708 r = link_update(link, message);
709 if (r < 0)
710 return 0;
4d473d5d
TG
711
712 break;
713
714 case RTM_DELLINK:
715 link_drop(link);
716 netdev_drop(netdev);
717
718 break;
719
720 default:
721 assert_not_reached("Received invalid RTNL message type.");
f2236469 722 }
505f8da7
TG
723
724 return 1;
725}
726
bce67bbe
SS
727int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
728 uint8_t tos = 0, to_prefixlen = 0, from_prefixlen = 0;
36e6e28b 729 union in_addr_union to = {}, from = {};
bce67bbe 730 RoutingPolicyRule *rule = NULL;
bce67bbe 731 uint32_t fwmark = 0, table = 0;
36e6e28b 732 char *iif = NULL, *oif = NULL;
bce67bbe
SS
733 Manager *m = userdata;
734 uint16_t type;
735 int family;
736 int r;
737
738 assert(rtnl);
739 assert(message);
740 assert(m);
741
742 if (sd_netlink_message_is_error(message)) {
743 r = sd_netlink_message_get_errno(message);
744 if (r < 0)
745 log_warning_errno(r, "rtnl: failed to receive rule: %m");
746
747 return 0;
748 }
749
750 r = sd_netlink_message_get_type(message, &type);
751 if (r < 0) {
752 log_warning_errno(r, "rtnl: could not get message type: %m");
753 return 0;
754 } else if (!IN_SET(type, RTM_NEWRULE, RTM_DELRULE)) {
755 log_warning("rtnl: received unexpected message type '%u' when processing rule.", type);
756 return 0;
757 }
758
759 r = sd_rtnl_message_get_family(message, &family);
615ded62
YW
760 if (r < 0) {
761 log_warning_errno(r, "rtnl: could not get rule family: %m");
762 return 0;
763 } else if (!IN_SET(family, AF_INET, AF_INET6)) {
764 log_debug("rtnl: received address with invalid family %u, ignoring.", family);
bce67bbe
SS
765 return 0;
766 }
767
768 switch (family) {
769 case AF_INET:
770 r = sd_netlink_message_read_in_addr(message, FRA_SRC, &from.in);
771 if (r >= 0) {
772 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen);
773 if (r < 0)
774 log_warning_errno(r, "rtnl: failed to retrive rule from prefix length: %m");
775 }
776
777 r = sd_netlink_message_read_in_addr(message, FRA_DST, &to.in);
778 if (r >= 0) {
779 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen);
780 if (r < 0)
781 log_warning_errno(r, "rtnl: failed to retrive rule to prefix length: %m");
782 }
783
784 break;
785
786 case AF_INET6:
787 r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &from.in6);
788 if (r >= 0) {
789 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen);
790 if (r < 0)
791 log_warning_errno(r, "rtnl: failed to retrive rule from prefix length: %m");
792 }
793
794 r = sd_netlink_message_read_in6_addr(message, FRA_DST, &to.in6);
795 if (r >= 0) {
796 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen);
797 if (r < 0)
798 log_warning_errno(r, "rtnl: failed to retrive rule to prefix length: %m");
799 }
800
801 break;
802
803 default:
74dead34 804 assert_not_reached("Received unsupported address family");
bce67bbe
SS
805 }
806
807 if (from_prefixlen == 0 && to_prefixlen == 0)
808 return 0;
809
810 (void) sd_netlink_message_read_u32(message, FRA_FWMARK, &fwmark);
811 (void) sd_netlink_message_read_u32(message, FRA_TABLE, &table);
812 (void) sd_rtnl_message_routing_policy_rule_get_tos(message, &tos);
762e2659
SS
813 (void) sd_netlink_message_read_string(message, FRA_IIFNAME, (const char **) &iif);
814 (void) sd_netlink_message_read_string(message, FRA_OIFNAME, (const char **) &oif);
bce67bbe 815
762e2659 816 (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
bce67bbe
SS
817
818 switch (type) {
819 case RTM_NEWRULE:
508f63b4 820 if (!rule) {
762e2659 821 r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
bce67bbe
SS
822 if (r < 0) {
823 log_warning_errno(r, "Could not add rule: %m");
824 return 0;
825 }
826 }
827 break;
828 case RTM_DELRULE:
829 routing_policy_rule_free(rule);
830
831 break;
832
833 default:
834 assert_not_reached("Received invalid RTNL message type");
835 }
836
837 return 1;
838}
839
5fae368b
TG
840static int systemd_netlink_fd(void) {
841 int n, fd, rtnl_fd = -EINVAL;
842
843 n = sd_listen_fds(true);
844 if (n <= 0)
845 return -EINVAL;
846
847 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
848 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
849 if (rtnl_fd >= 0)
850 return -EINVAL;
851
852 rtnl_fd = fd;
853 }
854 }
855
856 return rtnl_fd;
857}
858
859static int manager_connect_rtnl(Manager *m) {
860 int fd, r;
505f8da7
TG
861
862 assert(m);
505f8da7 863
5fae368b
TG
864 fd = systemd_netlink_fd();
865 if (fd < 0)
1c4baffc 866 r = sd_netlink_open(&m->rtnl);
5fae368b 867 else
1c4baffc 868 r = sd_netlink_open_fd(&m->rtnl, fd);
505f8da7
TG
869 if (r < 0)
870 return r;
871
1c4baffc 872 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
f579559b 873 if (r < 0)
bf5332d2 874 return r;
f579559b 875
1c4baffc 876 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
505f8da7
TG
877 if (r < 0)
878 return r;
f579559b 879
1c4baffc 880 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
5fae368b
TG
881 if (r < 0)
882 return r;
505f8da7 883
1c4baffc 884 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
5fae368b
TG
885 if (r < 0)
886 return r;
45af44d4 887
200a0868 888 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
5fae368b
TG
889 if (r < 0)
890 return r;
891
200a0868 892 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
5fae368b
TG
893 if (r < 0)
894 return r;
895
1c8e710c
TG
896 r = sd_netlink_add_match(m->rtnl, RTM_NEWROUTE, &manager_rtnl_process_route, m);
897 if (r < 0)
898 return r;
899
900 r = sd_netlink_add_match(m->rtnl, RTM_DELROUTE, &manager_rtnl_process_route, m);
901 if (r < 0)
902 return r;
903
bce67bbe
SS
904 r = sd_netlink_add_match(m->rtnl, RTM_NEWRULE, &manager_rtnl_process_rule, m);
905 if (r < 0)
906 return r;
907
908 r = sd_netlink_add_match(m->rtnl, RTM_DELRULE, &manager_rtnl_process_rule, m);
909 if (r < 0)
910 return r;
911
5fae368b 912 return 0;
45af44d4 913}
505f8da7 914
5512a963 915static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
84de38c5
TG
916 char *p;
917 int r;
918
919 assert(s);
5512a963
LP
920 assert(address);
921
922 r = in_addr_to_string(address->family, &address->address, &p);
923 if (r < 0)
924 return r;
925
926 r = ordered_set_consume(s, p);
927 if (r == -EEXIST)
928 return 0;
929
930 return r;
931}
932
933static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
934 int r, c = 0;
935 unsigned i;
936
937 assert(s);
938 assert(addresses || n == 0);
939
940 for (i = 0; i < n; i++) {
941 r = ordered_set_put_in_addr_data(s, addresses+i);
942 if (r < 0)
943 return r;
944
945 c += r;
946 }
947
948 return c;
949}
950
951static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
952 char *p;
953 int r;
954
955 assert(s);
956 assert(address);
84de38c5
TG
957
958 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
959 if (r < 0)
960 return r;
961
00616955 962 r = ordered_set_consume(s, p);
84de38c5
TG
963 if (r == -EEXIST)
964 return 0;
965
966 return r;
967}
968
5512a963
LP
969static int ordered_set_put_in4_addrv(OrderedSet *s, const struct in_addr *addresses, unsigned n) {
970 int r, c = 0;
971 unsigned i;
84de38c5
TG
972
973 assert(s);
5512a963 974 assert(n == 0 || addresses);
84de38c5
TG
975
976 for (i = 0; i < n; i++) {
5512a963 977 r = ordered_set_put_in4_addr(s, addresses+i);
84de38c5
TG
978 if (r < 0)
979 return r;
980
981 c += r;
982 }
983
984 return c;
985}
986
00616955 987static void print_string_set(FILE *f, const char *field, OrderedSet *s) {
84de38c5
TG
988 bool space = false;
989 Iterator i;
990 char *p;
991
00616955 992 if (ordered_set_isempty(s))
84de38c5
TG
993 return;
994
0d536673 995 fputs(field, f);
84de38c5 996
d390f8ef
LP
997 ORDERED_SET_FOREACH(p, s, i)
998 fputs_with_space(f, p, NULL, &space);
999
0d536673 1000 fputc('\n', f);
84de38c5
TG
1001}
1002
1003static int manager_save(Manager *m) {
00616955 1004 _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
84de38c5
TG
1005 Link *link;
1006 Iterator i;
1007 _cleanup_free_ char *temp_path = NULL;
1008 _cleanup_fclose_ FILE *f = NULL;
1009 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
1010 const char *operstate_str;
1011 int r;
1012
1013 assert(m);
1014 assert(m->state_file);
1015
1016 /* We add all NTP and DNS server to a set, to filter out duplicates */
00616955 1017 dns = ordered_set_new(&string_hash_ops);
84de38c5
TG
1018 if (!dns)
1019 return -ENOMEM;
1020
00616955 1021 ntp = ordered_set_new(&string_hash_ops);
84de38c5
TG
1022 if (!ntp)
1023 return -ENOMEM;
1024
482d1aeb 1025 search_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5
LP
1026 if (!search_domains)
1027 return -ENOMEM;
1028
482d1aeb 1029 route_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5 1030 if (!route_domains)
84de38c5
TG
1031 return -ENOMEM;
1032
1033 HASHMAP_FOREACH(link, m->links, i) {
1034 if (link->flags & IFF_LOOPBACK)
1035 continue;
1036
1037 if (link->operstate > operstate)
1038 operstate = link->operstate;
1039
1040 if (!link->network)
1041 continue;
1042
1043 /* First add the static configured entries */
5512a963 1044 r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
84de38c5
TG
1045 if (r < 0)
1046 return r;
1047
00616955 1048 r = ordered_set_put_strdupv(ntp, link->network->ntp);
84de38c5
TG
1049 if (r < 0)
1050 return r;
1051
00616955 1052 r = ordered_set_put_strdupv(search_domains, link->network->search_domains);
3df9bec5
LP
1053 if (r < 0)
1054 return r;
1055
00616955 1056 r = ordered_set_put_strdupv(route_domains, link->network->route_domains);
84de38c5
TG
1057 if (r < 0)
1058 return r;
1059
1060 if (!link->dhcp_lease)
1061 continue;
1062
1063 /* Secondly, add the entries acquired via DHCP */
27cb34f5 1064 if (link->network->dhcp_use_dns) {
84de38c5
TG
1065 const struct in_addr *addresses;
1066
1067 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1068 if (r > 0) {
5512a963 1069 r = ordered_set_put_in4_addrv(dns, addresses, r);
84de38c5
TG
1070 if (r < 0)
1071 return r;
1072 } else if (r < 0 && r != -ENODATA)
1073 return r;
1074 }
1075
27cb34f5 1076 if (link->network->dhcp_use_ntp) {
84de38c5
TG
1077 const struct in_addr *addresses;
1078
1079 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1080 if (r > 0) {
5512a963 1081 r = ordered_set_put_in4_addrv(ntp, addresses, r);
84de38c5
TG
1082 if (r < 0)
1083 return r;
1084 } else if (r < 0 && r != -ENODATA)
1085 return r;
1086 }
1087
b2a81c0b 1088 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
84de38c5 1089 const char *domainname;
b85bc551 1090 char **domains = NULL;
84de38c5 1091
b85bc551 1092 OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
84de38c5
TG
1093 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1094 if (r >= 0) {
b85bc551
DW
1095 r = ordered_set_put_strdup(target_domains, domainname);
1096 if (r < 0)
1097 return r;
1098 } else if (r != -ENODATA)
1099 return r;
b2a81c0b 1100
b85bc551
DW
1101 r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
1102 if (r >= 0) {
1103 r = ordered_set_put_strdupv(target_domains, domains);
84de38c5
TG
1104 if (r < 0)
1105 return r;
1106 } else if (r != -ENODATA)
1107 return r;
1108 }
1109 }
1110
1111 operstate_str = link_operstate_to_string(operstate);
1112 assert(operstate_str);
1113
1114 r = fopen_temporary(m->state_file, &f, &temp_path);
1115 if (r < 0)
1116 return r;
1117
0d536673 1118 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
5512a963 1119 (void) fchmod(fileno(f), 0644);
84de38c5
TG
1120
1121 fprintf(f,
1122 "# This is private data. Do not parse.\n"
1123 "OPER_STATE=%s\n", operstate_str);
1124
1125 print_string_set(f, "DNS=", dns);
1126 print_string_set(f, "NTP=", ntp);
3df9bec5
LP
1127 print_string_set(f, "DOMAINS=", search_domains);
1128 print_string_set(f, "ROUTE_DOMAINS=", route_domains);
84de38c5 1129
458d8ae3
ZJS
1130 r = routing_policy_serialize_rules(m->rules, f);
1131 if (r < 0)
1132 goto fail;
bce67bbe 1133
84de38c5
TG
1134 r = fflush_and_check(f);
1135 if (r < 0)
1136 goto fail;
1137
1138 if (rename(temp_path, m->state_file) < 0) {
1139 r = -errno;
1140 goto fail;
1141 }
1142
1143 if (m->operational_state != operstate) {
1144 m->operational_state = operstate;
1145 r = manager_send_changed(m, "OperationalState", NULL);
1146 if (r < 0)
1147 log_error_errno(r, "Could not emit changed OperationalState: %m");
1148 }
1149
1150 m->dirty = false;
1151
1152 return 0;
1153
1154fail:
1155 (void) unlink(m->state_file);
1156 (void) unlink(temp_path);
1157
1158 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
1159}
1160
1161static int manager_dirty_handler(sd_event_source *s, void *userdata) {
1162 Manager *m = userdata;
1163 Link *link;
1164 Iterator i;
1165 int r;
1166
1167 assert(m);
1168
1169 if (m->dirty)
1170 manager_save(m);
1171
1172 SET_FOREACH(link, m->dirty_links, i) {
1173 r = link_save(link);
1174 if (r >= 0)
1175 link_clean(link);
1176 }
1177
1178 return 1;
1179}
1180
b76d99d9 1181int manager_new(Manager **ret, sd_event *event) {
5fae368b 1182 _cleanup_manager_free_ Manager *m = NULL;
45af44d4 1183 int r;
f579559b 1184
5fae368b
TG
1185 m = new0(Manager, 1);
1186 if (!m)
1187 return -ENOMEM;
45af44d4 1188
5fae368b
TG
1189 m->state_file = strdup("/run/systemd/netif/state");
1190 if (!m->state_file)
1191 return -ENOMEM;
1192
b76d99d9 1193 m->event = sd_event_ref(event);
5fae368b 1194
84de38c5
TG
1195 r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
1196 if (r < 0)
1197 return r;
1198
5fae368b 1199 r = manager_connect_rtnl(m);
45af44d4
TG
1200 if (r < 0)
1201 return r;
1202
5fae368b
TG
1203 r = manager_connect_udev(m);
1204 if (r < 0)
1205 return r;
45af44d4 1206
5fae368b
TG
1207 m->netdevs = hashmap_new(&string_hash_ops);
1208 if (!m->netdevs)
1209 return -ENOMEM;
f579559b 1210
5fae368b 1211 LIST_HEAD_INIT(m->networks);
f579559b 1212
5fae368b
TG
1213 r = setup_default_address_pool(m);
1214 if (r < 0)
1215 return r;
f579559b 1216
8341a5c3 1217 m->duid.type = DUID_TYPE_EN;
413708d1 1218
458d8ae3 1219 (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
bce67bbe 1220
5fae368b
TG
1221 *ret = m;
1222 m = NULL;
f579559b 1223
f579559b
TG
1224 return 0;
1225}
1226
5fae368b
TG
1227void manager_free(Manager *m) {
1228 Network *network;
1229 NetDev *netdev;
1230 Link *link;
1231 AddressPool *pool;
f579559b 1232
5fae368b
TG
1233 if (!m)
1234 return;
505f8da7 1235
5fae368b 1236 free(m->state_file);
505f8da7 1237
bce67bbe
SS
1238 while ((network = m->networks))
1239 network_free(network);
1240
5fae368b
TG
1241 while ((link = hashmap_first(m->links)))
1242 link_unref(link);
1243 hashmap_free(m->links);
f579559b 1244
dbffab87
TG
1245 hashmap_free(m->networks_by_name);
1246
5fae368b
TG
1247 while ((netdev = hashmap_first(m->netdevs)))
1248 netdev_unref(netdev);
1249 hashmap_free(m->netdevs);
1250
1251 while ((pool = m->address_pools))
1252 address_pool_free(pool);
1253
bce67bbe
SS
1254 set_free(m->rules);
1255 set_free(m->rules_foreign);
1256
b921fcb2 1257 set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
bce67bbe 1258
1c4baffc 1259 sd_netlink_unref(m->rtnl);
2f5b4a77 1260 sd_event_unref(m->event);
5fae368b 1261
7d20d375
TG
1262 sd_event_source_unref(m->udev_event_source);
1263 udev_monitor_unref(m->udev_monitor);
1264 udev_unref(m->udev);
1265
1266 sd_bus_unref(m->bus);
1267 sd_bus_slot_unref(m->prepare_for_sleep_slot);
1268 sd_event_source_unref(m->bus_retry_event_source);
1269
7901cea1
MP
1270 free(m->dynamic_timezone);
1271 free(m->dynamic_hostname);
1272
5fae368b
TG
1273 free(m);
1274}
1275
b76d99d9 1276int manager_start(Manager *m) {
84de38c5
TG
1277 Link *link;
1278 Iterator i;
1279
a97dcc12
TG
1280 assert(m);
1281
84de38c5
TG
1282 /* The dirty handler will deal with future serialization, but the first one
1283 must be done explicitly. */
1284
1285 manager_save(m);
1286
1287 HASHMAP_FOREACH(link, m->links, i)
1288 link_save(link);
1289
b76d99d9 1290 return 0;
a97dcc12
TG
1291}
1292
5fae368b
TG
1293int manager_load_config(Manager *m) {
1294 int r;
1295
1296 /* update timestamp */
1297 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
1298
1299 r = netdev_load(m);
f579559b
TG
1300 if (r < 0)
1301 return r;
1302
5fae368b 1303 r = network_load(m);
9021bb9f
TG
1304 if (r < 0)
1305 return r;
1306
f579559b
TG
1307 return 0;
1308}
f882c247 1309
5fae368b
TG
1310bool manager_should_reload(Manager *m) {
1311 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
1312}
1313
1314int manager_rtnl_enumerate_links(Manager *m) {
4afd3348 1315 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1316 sd_netlink_message *link;
f882c247
TG
1317 int r;
1318
5da8149f 1319 assert(m);
5fae368b 1320 assert(m->rtnl);
5da8149f 1321
5fae368b 1322 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
f882c247
TG
1323 if (r < 0)
1324 return r;
1325
1c4baffc 1326 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
1327 if (r < 0)
1328 return r;
1329
1c4baffc 1330 r = sd_netlink_call(m->rtnl, req, 0, &reply);
f2236469
TG
1331 if (r < 0)
1332 return r;
1333
1c4baffc 1334 for (link = reply; link; link = sd_netlink_message_next(link)) {
5fae368b 1335 int k;
2e9f08ea 1336
6a24f148
TG
1337 m->enumerating = true;
1338
5fae368b
TG
1339 k = manager_rtnl_process_link(m->rtnl, link, m);
1340 if (k < 0)
1341 r = k;
6a24f148
TG
1342
1343 m->enumerating = false;
5fae368b 1344 }
2e9f08ea 1345
5fae368b 1346 return r;
f882c247 1347}
3bef724f 1348
5fae368b 1349int manager_rtnl_enumerate_addresses(Manager *m) {
4afd3348 1350 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1351 sd_netlink_message *addr;
1346b1f0
TG
1352 int r;
1353
5fae368b
TG
1354 assert(m);
1355 assert(m->rtnl);
bcbca829 1356
5fae368b
TG
1357 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
1358 if (r < 0)
1359 return r;
bcbca829 1360
1c4baffc 1361 r = sd_netlink_message_request_dump(req, true);
1346b1f0
TG
1362 if (r < 0)
1363 return r;
1364
1c4baffc 1365 r = sd_netlink_call(m->rtnl, req, 0, &reply);
5fae368b
TG
1366 if (r < 0)
1367 return r;
1368
1c4baffc 1369 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
5fae368b
TG
1370 int k;
1371
6a24f148
TG
1372 m->enumerating = true;
1373
200a0868 1374 k = manager_rtnl_process_address(m->rtnl, addr, m);
5fae368b
TG
1375 if (k < 0)
1376 r = k;
6a24f148
TG
1377
1378 m->enumerating = false;
5fae368b
TG
1379 }
1380
1381 return r;
1346b1f0
TG
1382}
1383
1c8e710c 1384int manager_rtnl_enumerate_routes(Manager *m) {
4afd3348 1385 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c8e710c
TG
1386 sd_netlink_message *route;
1387 int r;
1388
1389 assert(m);
1390 assert(m->rtnl);
1391
1392 r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
1393 if (r < 0)
1394 return r;
1395
1396 r = sd_netlink_message_request_dump(req, true);
1397 if (r < 0)
1398 return r;
1399
1400 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1401 if (r < 0)
1402 return r;
1403
1404 for (route = reply; route; route = sd_netlink_message_next(route)) {
1405 int k;
1406
1407 m->enumerating = true;
1408
1409 k = manager_rtnl_process_route(m->rtnl, route, m);
1410 if (k < 0)
1411 r = k;
1412
1413 m->enumerating = false;
1414 }
1415
1416 return r;
1417}
1418
bce67bbe
SS
1419int manager_rtnl_enumerate_rules(Manager *m) {
1420 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1421 sd_netlink_message *rule;
1422 int r;
1423
1424 assert(m);
1425 assert(m->rtnl);
1426
1427 r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
1428 if (r < 0)
1429 return r;
1430
1431 r = sd_netlink_message_request_dump(req, true);
1432 if (r < 0)
1433 return r;
1434
1435 r = sd_netlink_call(m->rtnl, req, 0, &reply);
6acbbdd4
SS
1436 if (r < 0) {
1437 if (r == -EOPNOTSUPP) {
1438 log_debug("FIB Rules are not supported by the kernel. Ignoring.");
1439 return 0;
1440 }
1441
bce67bbe 1442 return r;
6acbbdd4 1443 }
bce67bbe
SS
1444
1445 for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
1446 int k;
1447
1448 m->enumerating = true;
1449
1450 k = manager_rtnl_process_rule(m->rtnl, rule, m);
1451 if (k < 0)
1452 r = k;
1453
1454 m->enumerating = false;
1455 }
1456
1457 return r;
1458}
1459
0dd25fb9 1460int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
1461 AddressPool *p;
1462 int r;
1463
1464 assert(m);
1465 assert(prefixlen > 0);
1466 assert(found);
1467
1468 LIST_FOREACH(address_pools, p, m->address_pools) {
1469 if (p->family != family)
1470 continue;
1471
1472 r = address_pool_acquire(p, prefixlen, found);
1473 if (r != 0)
1474 return r;
1475 }
1476
1477 return 0;
1478}
4f5f911e
LP
1479
1480Link* manager_find_uplink(Manager *m, Link *exclude) {
1481 _cleanup_free_ struct local_address *gateways = NULL;
1482 int n, i;
1483
1484 assert(m);
1485
1486 /* Looks for a suitable "uplink", via black magic: an
1487 * interface that is up and where the default route with the
1488 * highest priority points to. */
1489
1490 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
1491 if (n < 0) {
1492 log_warning_errno(n, "Failed to determine list of default gateways: %m");
1493 return NULL;
1494 }
1495
1496 for (i = 0; i < n; i++) {
1497 Link *link;
1498
1499 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
1500 if (!link) {
c2c940bd 1501 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
4f5f911e
LP
1502 continue;
1503 }
1504
1505 if (link == exclude)
1506 continue;
1507
1508 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1509 continue;
1510
1511 return link;
1512 }
1513
1514 return NULL;
1515}
84de38c5
TG
1516
1517void manager_dirty(Manager *manager) {
1518 assert(manager);
1519
1520 /* the serialized state in /run is no longer up-to-date */
1521 manager->dirty = true;
1522}
59eb33e0
MP
1523
1524static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1525 Manager *manager = userdata;
1526 const sd_bus_error *e;
1527
1528 assert(m);
1529 assert(manager);
1530
1531 e = sd_bus_message_get_error(m);
1532 if (e)
1533 log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
1534
1535 return 1;
1536}
1537
1538int manager_set_hostname(Manager *m, const char *hostname) {
1539 int r;
1540
1541 log_debug("Setting transient hostname: '%s'", strna(hostname));
7901cea1
MP
1542 if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
1543 return log_oom();
59eb33e0
MP
1544
1545 if (!m->bus) {
1546 /* TODO: replace by assert when we can rely on kdbus */
1547 log_info("Not connected to system bus, ignoring transient hostname.");
1548 return 0;
1549 }
1550
1551 r = sd_bus_call_method_async(
1552 m->bus,
1553 NULL,
1554 "org.freedesktop.hostname1",
1555 "/org/freedesktop/hostname1",
1556 "org.freedesktop.hostname1",
1557 "SetHostname",
1558 set_hostname_handler,
1559 m,
1560 "sb",
1561 hostname,
1562 false);
1563
1564 if (r < 0)
1565 return log_error_errno(r, "Could not set transient hostname: %m");
1566
1567 return 0;
1568}
1569
1570static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1571 Manager *manager = userdata;
1572 const sd_bus_error *e;
1573
1574 assert(m);
1575 assert(manager);
1576
1577 e = sd_bus_message_get_error(m);
1578 if (e)
1579 log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
1580
1581 return 1;
1582}
1583
1584int manager_set_timezone(Manager *m, const char *tz) {
1585 int r;
1586
1587 assert(m);
1588 assert(tz);
1589
1590 log_debug("Setting system timezone: '%s'", tz);
7901cea1
MP
1591 if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
1592 return log_oom();
59eb33e0
MP
1593
1594 if (!m->bus) {
1595 log_info("Not connected to system bus, ignoring timezone.");
1596 return 0;
1597 }
1598
1599 r = sd_bus_call_method_async(
1600 m->bus,
1601 NULL,
1602 "org.freedesktop.timedate1",
1603 "/org/freedesktop/timedate1",
1604 "org.freedesktop.timedate1",
1605 "SetTimezone",
1606 set_timezone_handler,
1607 m,
1608 "sb",
1609 tz,
1610 false);
1611 if (r < 0)
1612 return log_error_errno(r, "Could not set timezone: %m");
1613
1614 return 0;
1615}