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