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