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