]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
Add SPDX license identifiers to source files under the LGPL
[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
TG
608 log_link_debug(link, "Updating address: %s/%u (valid %s%s)", buf, prefixlen,
609 valid_str ? "for " : "forever", 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
TG
617 log_link_debug(link, "Adding address: %s/%u (valid %s%s)", buf, prefixlen,
618 valid_str ? "for " : "forever", 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
TG
628 log_link_debug(link, "Removing address: %s/%u (valid %s%s)", buf, prefixlen,
629 valid_str ? "for " : "forever", valid_str ?: "");
91b5f997 630 address_drop(address);
200a0868 631 } else
4058d339
TG
632 log_link_warning(link, "Removing non-existent address: %s/%u (valid %s%s)", buf, prefixlen,
633 valid_str ? "for " : "forever", 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;
735 uint16_t type;
736 int family;
737 int r;
738
739 assert(rtnl);
740 assert(message);
741 assert(m);
742
743 if (sd_netlink_message_is_error(message)) {
744 r = sd_netlink_message_get_errno(message);
745 if (r < 0)
746 log_warning_errno(r, "rtnl: failed to receive rule: %m");
747
748 return 0;
749 }
750
751 r = sd_netlink_message_get_type(message, &type);
752 if (r < 0) {
753 log_warning_errno(r, "rtnl: could not get message type: %m");
754 return 0;
755 } else if (!IN_SET(type, RTM_NEWRULE, RTM_DELRULE)) {
756 log_warning("rtnl: received unexpected message type '%u' when processing rule.", type);
757 return 0;
758 }
759
760 r = sd_rtnl_message_get_family(message, &family);
615ded62
YW
761 if (r < 0) {
762 log_warning_errno(r, "rtnl: could not get rule family: %m");
763 return 0;
764 } else if (!IN_SET(family, AF_INET, AF_INET6)) {
765 log_debug("rtnl: received address with invalid family %u, ignoring.", family);
bce67bbe
SS
766 return 0;
767 }
768
769 switch (family) {
770 case AF_INET:
771 r = sd_netlink_message_read_in_addr(message, FRA_SRC, &from.in);
772 if (r >= 0) {
773 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen);
774 if (r < 0)
775 log_warning_errno(r, "rtnl: failed to retrive rule from prefix length: %m");
776 }
777
778 r = sd_netlink_message_read_in_addr(message, FRA_DST, &to.in);
779 if (r >= 0) {
780 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen);
781 if (r < 0)
782 log_warning_errno(r, "rtnl: failed to retrive rule to prefix length: %m");
783 }
784
785 break;
786
787 case AF_INET6:
788 r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &from.in6);
789 if (r >= 0) {
790 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen);
791 if (r < 0)
792 log_warning_errno(r, "rtnl: failed to retrive rule from prefix length: %m");
793 }
794
795 r = sd_netlink_message_read_in6_addr(message, FRA_DST, &to.in6);
796 if (r >= 0) {
797 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen);
798 if (r < 0)
799 log_warning_errno(r, "rtnl: failed to retrive rule to prefix length: %m");
800 }
801
802 break;
803
804 default:
74dead34 805 assert_not_reached("Received unsupported address family");
bce67bbe
SS
806 }
807
808 if (from_prefixlen == 0 && to_prefixlen == 0)
809 return 0;
810
811 (void) sd_netlink_message_read_u32(message, FRA_FWMARK, &fwmark);
812 (void) sd_netlink_message_read_u32(message, FRA_TABLE, &table);
813 (void) sd_rtnl_message_routing_policy_rule_get_tos(message, &tos);
814
815 (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, &rule);
816
817 switch (type) {
818 case RTM_NEWRULE:
819 if(!rule) {
820 r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, &rule);
821 if (r < 0) {
822 log_warning_errno(r, "Could not add rule: %m");
823 return 0;
824 }
825 }
826 break;
827 case RTM_DELRULE:
828 routing_policy_rule_free(rule);
829
830 break;
831
832 default:
833 assert_not_reached("Received invalid RTNL message type");
834 }
835
836 return 1;
837}
838
5fae368b
TG
839static int systemd_netlink_fd(void) {
840 int n, fd, rtnl_fd = -EINVAL;
841
842 n = sd_listen_fds(true);
843 if (n <= 0)
844 return -EINVAL;
845
846 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
847 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
848 if (rtnl_fd >= 0)
849 return -EINVAL;
850
851 rtnl_fd = fd;
852 }
853 }
854
855 return rtnl_fd;
856}
857
858static int manager_connect_rtnl(Manager *m) {
859 int fd, r;
505f8da7
TG
860
861 assert(m);
505f8da7 862
5fae368b
TG
863 fd = systemd_netlink_fd();
864 if (fd < 0)
1c4baffc 865 r = sd_netlink_open(&m->rtnl);
5fae368b 866 else
1c4baffc 867 r = sd_netlink_open_fd(&m->rtnl, fd);
505f8da7
TG
868 if (r < 0)
869 return r;
870
1c4baffc 871 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
f579559b 872 if (r < 0)
bf5332d2 873 return r;
f579559b 874
1c4baffc 875 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
505f8da7
TG
876 if (r < 0)
877 return r;
f579559b 878
1c4baffc 879 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
5fae368b
TG
880 if (r < 0)
881 return r;
505f8da7 882
1c4baffc 883 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
5fae368b
TG
884 if (r < 0)
885 return r;
45af44d4 886
200a0868 887 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
5fae368b
TG
888 if (r < 0)
889 return r;
890
200a0868 891 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
5fae368b
TG
892 if (r < 0)
893 return r;
894
1c8e710c
TG
895 r = sd_netlink_add_match(m->rtnl, RTM_NEWROUTE, &manager_rtnl_process_route, m);
896 if (r < 0)
897 return r;
898
899 r = sd_netlink_add_match(m->rtnl, RTM_DELROUTE, &manager_rtnl_process_route, m);
900 if (r < 0)
901 return r;
902
bce67bbe
SS
903 r = sd_netlink_add_match(m->rtnl, RTM_NEWRULE, &manager_rtnl_process_rule, m);
904 if (r < 0)
905 return r;
906
907 r = sd_netlink_add_match(m->rtnl, RTM_DELRULE, &manager_rtnl_process_rule, m);
908 if (r < 0)
909 return r;
910
5fae368b 911 return 0;
45af44d4 912}
505f8da7 913
5512a963 914static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
84de38c5
TG
915 char *p;
916 int r;
917
918 assert(s);
5512a963
LP
919 assert(address);
920
921 r = in_addr_to_string(address->family, &address->address, &p);
922 if (r < 0)
923 return r;
924
925 r = ordered_set_consume(s, p);
926 if (r == -EEXIST)
927 return 0;
928
929 return r;
930}
931
932static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
933 int r, c = 0;
934 unsigned i;
935
936 assert(s);
937 assert(addresses || n == 0);
938
939 for (i = 0; i < n; i++) {
940 r = ordered_set_put_in_addr_data(s, addresses+i);
941 if (r < 0)
942 return r;
943
944 c += r;
945 }
946
947 return c;
948}
949
950static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
951 char *p;
952 int r;
953
954 assert(s);
955 assert(address);
84de38c5
TG
956
957 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
958 if (r < 0)
959 return r;
960
00616955 961 r = ordered_set_consume(s, p);
84de38c5
TG
962 if (r == -EEXIST)
963 return 0;
964
965 return r;
966}
967
5512a963
LP
968static int ordered_set_put_in4_addrv(OrderedSet *s, const struct in_addr *addresses, unsigned n) {
969 int r, c = 0;
970 unsigned i;
84de38c5
TG
971
972 assert(s);
5512a963 973 assert(n == 0 || addresses);
84de38c5
TG
974
975 for (i = 0; i < n; i++) {
5512a963 976 r = ordered_set_put_in4_addr(s, addresses+i);
84de38c5
TG
977 if (r < 0)
978 return r;
979
980 c += r;
981 }
982
983 return c;
984}
985
00616955 986static void print_string_set(FILE *f, const char *field, OrderedSet *s) {
84de38c5
TG
987 bool space = false;
988 Iterator i;
989 char *p;
990
00616955 991 if (ordered_set_isempty(s))
84de38c5
TG
992 return;
993
4b61c875 994 fputs_unlocked(field, f);
84de38c5 995
d390f8ef
LP
996 ORDERED_SET_FOREACH(p, s, i)
997 fputs_with_space(f, p, NULL, &space);
998
4b61c875 999 fputc_unlocked('\n', f);
84de38c5
TG
1000}
1001
1002static int manager_save(Manager *m) {
00616955 1003 _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
bce67bbe
SS
1004 RoutingPolicyRule *rule = NULL;
1005 bool space = false;
84de38c5
TG
1006 Link *link;
1007 Iterator i;
1008 _cleanup_free_ char *temp_path = NULL;
1009 _cleanup_fclose_ FILE *f = NULL;
1010 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
1011 const char *operstate_str;
1012 int r;
1013
1014 assert(m);
1015 assert(m->state_file);
1016
1017 /* We add all NTP and DNS server to a set, to filter out duplicates */
00616955 1018 dns = ordered_set_new(&string_hash_ops);
84de38c5
TG
1019 if (!dns)
1020 return -ENOMEM;
1021
00616955 1022 ntp = ordered_set_new(&string_hash_ops);
84de38c5
TG
1023 if (!ntp)
1024 return -ENOMEM;
1025
482d1aeb 1026 search_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5
LP
1027 if (!search_domains)
1028 return -ENOMEM;
1029
482d1aeb 1030 route_domains = ordered_set_new(&dns_name_hash_ops);
3df9bec5 1031 if (!route_domains)
84de38c5
TG
1032 return -ENOMEM;
1033
1034 HASHMAP_FOREACH(link, m->links, i) {
1035 if (link->flags & IFF_LOOPBACK)
1036 continue;
1037
1038 if (link->operstate > operstate)
1039 operstate = link->operstate;
1040
1041 if (!link->network)
1042 continue;
1043
1044 /* First add the static configured entries */
5512a963 1045 r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
84de38c5
TG
1046 if (r < 0)
1047 return r;
1048
00616955 1049 r = ordered_set_put_strdupv(ntp, link->network->ntp);
84de38c5
TG
1050 if (r < 0)
1051 return r;
1052
00616955 1053 r = ordered_set_put_strdupv(search_domains, link->network->search_domains);
3df9bec5
LP
1054 if (r < 0)
1055 return r;
1056
00616955 1057 r = ordered_set_put_strdupv(route_domains, link->network->route_domains);
84de38c5
TG
1058 if (r < 0)
1059 return r;
1060
1061 if (!link->dhcp_lease)
1062 continue;
1063
1064 /* Secondly, add the entries acquired via DHCP */
27cb34f5 1065 if (link->network->dhcp_use_dns) {
84de38c5
TG
1066 const struct in_addr *addresses;
1067
1068 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1069 if (r > 0) {
5512a963 1070 r = ordered_set_put_in4_addrv(dns, addresses, r);
84de38c5
TG
1071 if (r < 0)
1072 return r;
1073 } else if (r < 0 && r != -ENODATA)
1074 return r;
1075 }
1076
27cb34f5 1077 if (link->network->dhcp_use_ntp) {
84de38c5
TG
1078 const struct in_addr *addresses;
1079
1080 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1081 if (r > 0) {
5512a963 1082 r = ordered_set_put_in4_addrv(ntp, addresses, r);
84de38c5
TG
1083 if (r < 0)
1084 return r;
1085 } else if (r < 0 && r != -ENODATA)
1086 return r;
1087 }
1088
b2a81c0b 1089 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
84de38c5 1090 const char *domainname;
b85bc551 1091 char **domains = NULL;
84de38c5 1092
b85bc551 1093 OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
84de38c5
TG
1094 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1095 if (r >= 0) {
b85bc551
DW
1096 r = ordered_set_put_strdup(target_domains, domainname);
1097 if (r < 0)
1098 return r;
1099 } else if (r != -ENODATA)
1100 return r;
b2a81c0b 1101
b85bc551
DW
1102 r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
1103 if (r >= 0) {
1104 r = ordered_set_put_strdupv(target_domains, domains);
84de38c5
TG
1105 if (r < 0)
1106 return r;
1107 } else if (r != -ENODATA)
1108 return r;
1109 }
1110 }
1111
1112 operstate_str = link_operstate_to_string(operstate);
1113 assert(operstate_str);
1114
1115 r = fopen_temporary(m->state_file, &f, &temp_path);
1116 if (r < 0)
1117 return r;
1118
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
bce67bbe
SS
1130 SET_FOREACH(rule, m->rules, i) {
1131 _cleanup_free_ char *from_str = NULL, *to_str = NULL;
1132 fputs("RULE=", f);
1133
1134 if (!in_addr_is_null(rule->family, &rule->from)) {
1135 r = in_addr_to_string(rule->family, &rule->from, &from_str);
1136 if (r < 0)
1137 goto fail;
1138 }
1139
1140 if (!in_addr_is_null(rule->family, &rule->to)) {
1141 r = in_addr_to_string(rule->family, &rule->to, &to_str);
1142 if (r < 0)
1143 goto fail;
1144 }
1145
ecc3f340
ZJS
1146 fprintf(f, "from=%s%s/%hhu to=%s%s/%hhu tos=%hhu fwmark=%"PRIu32"/%"PRIu32" table=%"PRIu32,
1147 space ? " " : "", from_str, rule->from_prefixlen,
1148 space ? " " : "", to_str, rule->to_prefixlen,
1149 rule->tos,
1150 rule->fwmark, rule->fwmask,
1151 rule->table);
bce67bbe
SS
1152
1153 fputc('\n', f);
1154 }
1155
84de38c5
TG
1156 r = fflush_and_check(f);
1157 if (r < 0)
1158 goto fail;
1159
1160 if (rename(temp_path, m->state_file) < 0) {
1161 r = -errno;
1162 goto fail;
1163 }
1164
1165 if (m->operational_state != operstate) {
1166 m->operational_state = operstate;
1167 r = manager_send_changed(m, "OperationalState", NULL);
1168 if (r < 0)
1169 log_error_errno(r, "Could not emit changed OperationalState: %m");
1170 }
1171
1172 m->dirty = false;
1173
1174 return 0;
1175
1176fail:
1177 (void) unlink(m->state_file);
1178 (void) unlink(temp_path);
1179
1180 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
1181}
1182
1183static int manager_dirty_handler(sd_event_source *s, void *userdata) {
1184 Manager *m = userdata;
1185 Link *link;
1186 Iterator i;
1187 int r;
1188
1189 assert(m);
1190
1191 if (m->dirty)
1192 manager_save(m);
1193
1194 SET_FOREACH(link, m->dirty_links, i) {
1195 r = link_save(link);
1196 if (r >= 0)
1197 link_clean(link);
1198 }
1199
1200 return 1;
1201}
1202
b76d99d9 1203int manager_new(Manager **ret, sd_event *event) {
5fae368b 1204 _cleanup_manager_free_ Manager *m = NULL;
45af44d4 1205 int r;
f579559b 1206
5fae368b
TG
1207 m = new0(Manager, 1);
1208 if (!m)
1209 return -ENOMEM;
45af44d4 1210
5fae368b
TG
1211 m->state_file = strdup("/run/systemd/netif/state");
1212 if (!m->state_file)
1213 return -ENOMEM;
1214
b76d99d9 1215 m->event = sd_event_ref(event);
5fae368b 1216
84de38c5
TG
1217 r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
1218 if (r < 0)
1219 return r;
1220
5fae368b 1221 r = manager_connect_rtnl(m);
45af44d4
TG
1222 if (r < 0)
1223 return r;
1224
5fae368b
TG
1225 r = manager_connect_udev(m);
1226 if (r < 0)
1227 return r;
45af44d4 1228
5fae368b
TG
1229 m->netdevs = hashmap_new(&string_hash_ops);
1230 if (!m->netdevs)
1231 return -ENOMEM;
f579559b 1232
5fae368b 1233 LIST_HEAD_INIT(m->networks);
f579559b 1234
5fae368b
TG
1235 r = setup_default_address_pool(m);
1236 if (r < 0)
1237 return r;
f579559b 1238
8341a5c3 1239 m->duid.type = DUID_TYPE_EN;
413708d1 1240
bce67bbe
SS
1241 (void) routing_policy_rule_load(m);
1242
5fae368b
TG
1243 *ret = m;
1244 m = NULL;
f579559b 1245
f579559b
TG
1246 return 0;
1247}
1248
5fae368b 1249void manager_free(Manager *m) {
bce67bbe 1250 RoutingPolicyRule *rule;
5fae368b
TG
1251 Network *network;
1252 NetDev *netdev;
1253 Link *link;
1254 AddressPool *pool;
f579559b 1255
5fae368b
TG
1256 if (!m)
1257 return;
505f8da7 1258
5fae368b 1259 free(m->state_file);
505f8da7 1260
bce67bbe
SS
1261 while ((network = m->networks))
1262 network_free(network);
1263
5fae368b
TG
1264 while ((link = hashmap_first(m->links)))
1265 link_unref(link);
1266 hashmap_free(m->links);
f579559b 1267
dbffab87
TG
1268 hashmap_free(m->networks_by_name);
1269
5fae368b
TG
1270 while ((netdev = hashmap_first(m->netdevs)))
1271 netdev_unref(netdev);
1272 hashmap_free(m->netdevs);
1273
1274 while ((pool = m->address_pools))
1275 address_pool_free(pool);
1276
bce67bbe
SS
1277 set_free(m->rules);
1278 set_free(m->rules_foreign);
1279
1280 while ((rule = set_steal_first(m->rules_saved)))
1281 free(rule);
1282
1283 set_free(m->rules_saved);
1284
1c4baffc 1285 sd_netlink_unref(m->rtnl);
2f5b4a77 1286 sd_event_unref(m->event);
5fae368b 1287
7d20d375
TG
1288 sd_event_source_unref(m->udev_event_source);
1289 udev_monitor_unref(m->udev_monitor);
1290 udev_unref(m->udev);
1291
1292 sd_bus_unref(m->bus);
1293 sd_bus_slot_unref(m->prepare_for_sleep_slot);
1294 sd_event_source_unref(m->bus_retry_event_source);
1295
7901cea1
MP
1296 free(m->dynamic_timezone);
1297 free(m->dynamic_hostname);
1298
5fae368b
TG
1299 free(m);
1300}
1301
b76d99d9 1302int manager_start(Manager *m) {
84de38c5
TG
1303 Link *link;
1304 Iterator i;
1305
a97dcc12
TG
1306 assert(m);
1307
84de38c5
TG
1308 /* The dirty handler will deal with future serialization, but the first one
1309 must be done explicitly. */
1310
1311 manager_save(m);
1312
1313 HASHMAP_FOREACH(link, m->links, i)
1314 link_save(link);
1315
b76d99d9 1316 return 0;
a97dcc12
TG
1317}
1318
5fae368b
TG
1319int manager_load_config(Manager *m) {
1320 int r;
1321
1322 /* update timestamp */
1323 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
1324
1325 r = netdev_load(m);
f579559b
TG
1326 if (r < 0)
1327 return r;
1328
5fae368b 1329 r = network_load(m);
9021bb9f
TG
1330 if (r < 0)
1331 return r;
1332
f579559b
TG
1333 return 0;
1334}
f882c247 1335
5fae368b
TG
1336bool manager_should_reload(Manager *m) {
1337 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
1338}
1339
1340int manager_rtnl_enumerate_links(Manager *m) {
4afd3348 1341 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1342 sd_netlink_message *link;
f882c247
TG
1343 int r;
1344
5da8149f 1345 assert(m);
5fae368b 1346 assert(m->rtnl);
5da8149f 1347
5fae368b 1348 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
f882c247
TG
1349 if (r < 0)
1350 return r;
1351
1c4baffc 1352 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
1353 if (r < 0)
1354 return r;
1355
1c4baffc 1356 r = sd_netlink_call(m->rtnl, req, 0, &reply);
f2236469
TG
1357 if (r < 0)
1358 return r;
1359
1c4baffc 1360 for (link = reply; link; link = sd_netlink_message_next(link)) {
5fae368b 1361 int k;
2e9f08ea 1362
6a24f148
TG
1363 m->enumerating = true;
1364
5fae368b
TG
1365 k = manager_rtnl_process_link(m->rtnl, link, m);
1366 if (k < 0)
1367 r = k;
6a24f148
TG
1368
1369 m->enumerating = false;
5fae368b 1370 }
2e9f08ea 1371
5fae368b 1372 return r;
f882c247 1373}
3bef724f 1374
5fae368b 1375int manager_rtnl_enumerate_addresses(Manager *m) {
4afd3348 1376 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1377 sd_netlink_message *addr;
1346b1f0
TG
1378 int r;
1379
5fae368b
TG
1380 assert(m);
1381 assert(m->rtnl);
bcbca829 1382
5fae368b
TG
1383 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
1384 if (r < 0)
1385 return r;
bcbca829 1386
1c4baffc 1387 r = sd_netlink_message_request_dump(req, true);
1346b1f0
TG
1388 if (r < 0)
1389 return r;
1390
1c4baffc 1391 r = sd_netlink_call(m->rtnl, req, 0, &reply);
5fae368b
TG
1392 if (r < 0)
1393 return r;
1394
1c4baffc 1395 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
5fae368b
TG
1396 int k;
1397
6a24f148
TG
1398 m->enumerating = true;
1399
200a0868 1400 k = manager_rtnl_process_address(m->rtnl, addr, m);
5fae368b
TG
1401 if (k < 0)
1402 r = k;
6a24f148
TG
1403
1404 m->enumerating = false;
5fae368b
TG
1405 }
1406
1407 return r;
1346b1f0
TG
1408}
1409
1c8e710c 1410int manager_rtnl_enumerate_routes(Manager *m) {
4afd3348 1411 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c8e710c
TG
1412 sd_netlink_message *route;
1413 int r;
1414
1415 assert(m);
1416 assert(m->rtnl);
1417
1418 r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
1419 if (r < 0)
1420 return r;
1421
1422 r = sd_netlink_message_request_dump(req, true);
1423 if (r < 0)
1424 return r;
1425
1426 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1427 if (r < 0)
1428 return r;
1429
1430 for (route = reply; route; route = sd_netlink_message_next(route)) {
1431 int k;
1432
1433 m->enumerating = true;
1434
1435 k = manager_rtnl_process_route(m->rtnl, route, m);
1436 if (k < 0)
1437 r = k;
1438
1439 m->enumerating = false;
1440 }
1441
1442 return r;
1443}
1444
bce67bbe
SS
1445int manager_rtnl_enumerate_rules(Manager *m) {
1446 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1447 sd_netlink_message *rule;
1448 int r;
1449
1450 assert(m);
1451 assert(m->rtnl);
1452
1453 r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
1454 if (r < 0)
1455 return r;
1456
1457 r = sd_netlink_message_request_dump(req, true);
1458 if (r < 0)
1459 return r;
1460
1461 r = sd_netlink_call(m->rtnl, req, 0, &reply);
6acbbdd4
SS
1462 if (r < 0) {
1463 if (r == -EOPNOTSUPP) {
1464 log_debug("FIB Rules are not supported by the kernel. Ignoring.");
1465 return 0;
1466 }
1467
bce67bbe 1468 return r;
6acbbdd4 1469 }
bce67bbe
SS
1470
1471 for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
1472 int k;
1473
1474 m->enumerating = true;
1475
1476 k = manager_rtnl_process_rule(m->rtnl, rule, m);
1477 if (k < 0)
1478 r = k;
1479
1480 m->enumerating = false;
1481 }
1482
1483 return r;
1484}
1485
0dd25fb9 1486int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
1487 AddressPool *p;
1488 int r;
1489
1490 assert(m);
1491 assert(prefixlen > 0);
1492 assert(found);
1493
1494 LIST_FOREACH(address_pools, p, m->address_pools) {
1495 if (p->family != family)
1496 continue;
1497
1498 r = address_pool_acquire(p, prefixlen, found);
1499 if (r != 0)
1500 return r;
1501 }
1502
1503 return 0;
1504}
4f5f911e
LP
1505
1506Link* manager_find_uplink(Manager *m, Link *exclude) {
1507 _cleanup_free_ struct local_address *gateways = NULL;
1508 int n, i;
1509
1510 assert(m);
1511
1512 /* Looks for a suitable "uplink", via black magic: an
1513 * interface that is up and where the default route with the
1514 * highest priority points to. */
1515
1516 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
1517 if (n < 0) {
1518 log_warning_errno(n, "Failed to determine list of default gateways: %m");
1519 return NULL;
1520 }
1521
1522 for (i = 0; i < n; i++) {
1523 Link *link;
1524
1525 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
1526 if (!link) {
c2c940bd 1527 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
4f5f911e
LP
1528 continue;
1529 }
1530
1531 if (link == exclude)
1532 continue;
1533
1534 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1535 continue;
1536
1537 return link;
1538 }
1539
1540 return NULL;
1541}
84de38c5
TG
1542
1543void manager_dirty(Manager *manager) {
1544 assert(manager);
1545
1546 /* the serialized state in /run is no longer up-to-date */
1547 manager->dirty = true;
1548}
59eb33e0
MP
1549
1550static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1551 Manager *manager = userdata;
1552 const sd_bus_error *e;
1553
1554 assert(m);
1555 assert(manager);
1556
1557 e = sd_bus_message_get_error(m);
1558 if (e)
1559 log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
1560
1561 return 1;
1562}
1563
1564int manager_set_hostname(Manager *m, const char *hostname) {
1565 int r;
1566
1567 log_debug("Setting transient hostname: '%s'", strna(hostname));
7901cea1
MP
1568 if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
1569 return log_oom();
59eb33e0
MP
1570
1571 if (!m->bus) {
1572 /* TODO: replace by assert when we can rely on kdbus */
1573 log_info("Not connected to system bus, ignoring transient hostname.");
1574 return 0;
1575 }
1576
1577 r = sd_bus_call_method_async(
1578 m->bus,
1579 NULL,
1580 "org.freedesktop.hostname1",
1581 "/org/freedesktop/hostname1",
1582 "org.freedesktop.hostname1",
1583 "SetHostname",
1584 set_hostname_handler,
1585 m,
1586 "sb",
1587 hostname,
1588 false);
1589
1590 if (r < 0)
1591 return log_error_errno(r, "Could not set transient hostname: %m");
1592
1593 return 0;
1594}
1595
1596static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1597 Manager *manager = userdata;
1598 const sd_bus_error *e;
1599
1600 assert(m);
1601 assert(manager);
1602
1603 e = sd_bus_message_get_error(m);
1604 if (e)
1605 log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
1606
1607 return 1;
1608}
1609
1610int manager_set_timezone(Manager *m, const char *tz) {
1611 int r;
1612
1613 assert(m);
1614 assert(tz);
1615
1616 log_debug("Setting system timezone: '%s'", tz);
7901cea1
MP
1617 if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
1618 return log_oom();
59eb33e0
MP
1619
1620 if (!m->bus) {
1621 log_info("Not connected to system bus, ignoring timezone.");
1622 return 0;
1623 }
1624
1625 r = sd_bus_call_method_async(
1626 m->bus,
1627 NULL,
1628 "org.freedesktop.timedate1",
1629 "/org/freedesktop/timedate1",
1630 "org.freedesktop.timedate1",
1631 "SetTimezone",
1632 set_timezone_handler,
1633 m,
1634 "sb",
1635 tz,
1636 false);
1637 if (r < 0)
1638 return log_error_errno(r, "Could not set timezone: %m");
1639
1640 return 0;
1641}