]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
meson: sort source files
[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
5fae368b
TG
1447 *ret = m;
1448 m = NULL;
f579559b 1449
f579559b
TG
1450 return 0;
1451}
1452
5fae368b
TG
1453void manager_free(Manager *m) {
1454 Network *network;
1455 NetDev *netdev;
1456 Link *link;
1457 AddressPool *pool;
f579559b 1458
5fae368b
TG
1459 if (!m)
1460 return;
505f8da7 1461
5fae368b 1462 free(m->state_file);
505f8da7 1463
bce67bbe
SS
1464 while ((network = m->networks))
1465 network_free(network);
1466
e133b289
PF
1467 while ((link = hashmap_first(m->dhcp6_prefixes)))
1468 link_unref(link);
1469 hashmap_free(m->dhcp6_prefixes);
1470
5fae368b
TG
1471 while ((link = hashmap_first(m->links)))
1472 link_unref(link);
1473 hashmap_free(m->links);
f579559b 1474
dbffab87
TG
1475 hashmap_free(m->networks_by_name);
1476
5fae368b
TG
1477 while ((netdev = hashmap_first(m->netdevs)))
1478 netdev_unref(netdev);
1479 hashmap_free(m->netdevs);
1480
1481 while ((pool = m->address_pools))
1482 address_pool_free(pool);
1483
bce67bbe
SS
1484 set_free(m->rules);
1485 set_free(m->rules_foreign);
1486
b921fcb2 1487 set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
bce67bbe 1488
1c4baffc 1489 sd_netlink_unref(m->rtnl);
2f5b4a77 1490 sd_event_unref(m->event);
5fae368b 1491
05d0c2e3
JT
1492 sd_resolve_unref(m->resolve);
1493
7d20d375
TG
1494 sd_event_source_unref(m->udev_event_source);
1495 udev_monitor_unref(m->udev_monitor);
1496 udev_unref(m->udev);
1497
1498 sd_bus_unref(m->bus);
1499 sd_bus_slot_unref(m->prepare_for_sleep_slot);
d7afd945 1500 sd_bus_slot_unref(m->connected_slot);
7d20d375
TG
1501 sd_event_source_unref(m->bus_retry_event_source);
1502
7901cea1
MP
1503 free(m->dynamic_timezone);
1504 free(m->dynamic_hostname);
1505
5fae368b
TG
1506 free(m);
1507}
1508
b76d99d9 1509int manager_start(Manager *m) {
84de38c5
TG
1510 Link *link;
1511 Iterator i;
1512
a97dcc12
TG
1513 assert(m);
1514
84de38c5
TG
1515 /* The dirty handler will deal with future serialization, but the first one
1516 must be done explicitly. */
1517
1518 manager_save(m);
1519
1520 HASHMAP_FOREACH(link, m->links, i)
1521 link_save(link);
1522
b76d99d9 1523 return 0;
a97dcc12
TG
1524}
1525
5fae368b
TG
1526int manager_load_config(Manager *m) {
1527 int r;
1528
1529 /* update timestamp */
1530 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
1531
1532 r = netdev_load(m);
f579559b
TG
1533 if (r < 0)
1534 return r;
1535
5fae368b 1536 r = network_load(m);
9021bb9f
TG
1537 if (r < 0)
1538 return r;
1539
f579559b
TG
1540 return 0;
1541}
f882c247 1542
5fae368b
TG
1543bool manager_should_reload(Manager *m) {
1544 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
1545}
1546
1547int manager_rtnl_enumerate_links(Manager *m) {
4afd3348 1548 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1549 sd_netlink_message *link;
f882c247
TG
1550 int r;
1551
5da8149f 1552 assert(m);
5fae368b 1553 assert(m->rtnl);
5da8149f 1554
5fae368b 1555 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
f882c247
TG
1556 if (r < 0)
1557 return r;
1558
1c4baffc 1559 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
1560 if (r < 0)
1561 return r;
1562
1c4baffc 1563 r = sd_netlink_call(m->rtnl, req, 0, &reply);
f2236469
TG
1564 if (r < 0)
1565 return r;
1566
1c4baffc 1567 for (link = reply; link; link = sd_netlink_message_next(link)) {
5fae368b 1568 int k;
2e9f08ea 1569
6a24f148
TG
1570 m->enumerating = true;
1571
5fae368b
TG
1572 k = manager_rtnl_process_link(m->rtnl, link, m);
1573 if (k < 0)
1574 r = k;
6a24f148
TG
1575
1576 m->enumerating = false;
5fae368b 1577 }
2e9f08ea 1578
5fae368b 1579 return r;
f882c247 1580}
3bef724f 1581
5fae368b 1582int manager_rtnl_enumerate_addresses(Manager *m) {
4afd3348 1583 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 1584 sd_netlink_message *addr;
1346b1f0
TG
1585 int r;
1586
5fae368b
TG
1587 assert(m);
1588 assert(m->rtnl);
bcbca829 1589
5fae368b
TG
1590 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
1591 if (r < 0)
1592 return r;
bcbca829 1593
1c4baffc 1594 r = sd_netlink_message_request_dump(req, true);
1346b1f0
TG
1595 if (r < 0)
1596 return r;
1597
1c4baffc 1598 r = sd_netlink_call(m->rtnl, req, 0, &reply);
5fae368b
TG
1599 if (r < 0)
1600 return r;
1601
1c4baffc 1602 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
5fae368b
TG
1603 int k;
1604
6a24f148
TG
1605 m->enumerating = true;
1606
200a0868 1607 k = manager_rtnl_process_address(m->rtnl, addr, m);
5fae368b
TG
1608 if (k < 0)
1609 r = k;
6a24f148
TG
1610
1611 m->enumerating = false;
5fae368b
TG
1612 }
1613
1614 return r;
1346b1f0
TG
1615}
1616
1c8e710c 1617int manager_rtnl_enumerate_routes(Manager *m) {
4afd3348 1618 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c8e710c
TG
1619 sd_netlink_message *route;
1620 int r;
1621
1622 assert(m);
1623 assert(m->rtnl);
1624
1625 r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
1626 if (r < 0)
1627 return r;
1628
1629 r = sd_netlink_message_request_dump(req, true);
1630 if (r < 0)
1631 return r;
1632
1633 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1634 if (r < 0)
1635 return r;
1636
1637 for (route = reply; route; route = sd_netlink_message_next(route)) {
1638 int k;
1639
1640 m->enumerating = true;
1641
1642 k = manager_rtnl_process_route(m->rtnl, route, m);
1643 if (k < 0)
1644 r = k;
1645
1646 m->enumerating = false;
1647 }
1648
1649 return r;
1650}
1651
bce67bbe
SS
1652int manager_rtnl_enumerate_rules(Manager *m) {
1653 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1654 sd_netlink_message *rule;
1655 int r;
1656
1657 assert(m);
1658 assert(m->rtnl);
1659
1660 r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
1661 if (r < 0)
1662 return r;
1663
1664 r = sd_netlink_message_request_dump(req, true);
1665 if (r < 0)
1666 return r;
1667
1668 r = sd_netlink_call(m->rtnl, req, 0, &reply);
6acbbdd4
SS
1669 if (r < 0) {
1670 if (r == -EOPNOTSUPP) {
1671 log_debug("FIB Rules are not supported by the kernel. Ignoring.");
1672 return 0;
1673 }
1674
bce67bbe 1675 return r;
6acbbdd4 1676 }
bce67bbe
SS
1677
1678 for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
1679 int k;
1680
1681 m->enumerating = true;
1682
1683 k = manager_rtnl_process_rule(m->rtnl, rule, m);
1684 if (k < 0)
1685 r = k;
1686
1687 m->enumerating = false;
1688 }
1689
1690 return r;
1691}
1692
0dd25fb9 1693int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
1694 AddressPool *p;
1695 int r;
1696
1697 assert(m);
1698 assert(prefixlen > 0);
1699 assert(found);
1700
1701 LIST_FOREACH(address_pools, p, m->address_pools) {
1702 if (p->family != family)
1703 continue;
1704
1705 r = address_pool_acquire(p, prefixlen, found);
1706 if (r != 0)
1707 return r;
1708 }
1709
1710 return 0;
1711}
4f5f911e
LP
1712
1713Link* manager_find_uplink(Manager *m, Link *exclude) {
1714 _cleanup_free_ struct local_address *gateways = NULL;
1715 int n, i;
1716
1717 assert(m);
1718
1719 /* Looks for a suitable "uplink", via black magic: an
1720 * interface that is up and where the default route with the
1721 * highest priority points to. */
1722
1723 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
1724 if (n < 0) {
1725 log_warning_errno(n, "Failed to determine list of default gateways: %m");
1726 return NULL;
1727 }
1728
1729 for (i = 0; i < n; i++) {
1730 Link *link;
1731
1732 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
1733 if (!link) {
c2c940bd 1734 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
4f5f911e
LP
1735 continue;
1736 }
1737
1738 if (link == exclude)
1739 continue;
1740
1741 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1742 continue;
1743
1744 return link;
1745 }
1746
1747 return NULL;
1748}
84de38c5
TG
1749
1750void manager_dirty(Manager *manager) {
1751 assert(manager);
1752
1753 /* the serialized state in /run is no longer up-to-date */
1754 manager->dirty = true;
1755}
59eb33e0
MP
1756
1757static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1758 Manager *manager = userdata;
1759 const sd_bus_error *e;
1760
1761 assert(m);
1762 assert(manager);
1763
1764 e = sd_bus_message_get_error(m);
1765 if (e)
1766 log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
1767
1768 return 1;
1769}
1770
1771int manager_set_hostname(Manager *m, const char *hostname) {
1772 int r;
1773
1774 log_debug("Setting transient hostname: '%s'", strna(hostname));
d7afd945 1775
7901cea1
MP
1776 if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
1777 return log_oom();
59eb33e0 1778
d7afd945
LP
1779 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
1780 log_info("Not connected to system bus, not setting hostname.");
59eb33e0
MP
1781 return 0;
1782 }
1783
1784 r = sd_bus_call_method_async(
1785 m->bus,
1786 NULL,
1787 "org.freedesktop.hostname1",
1788 "/org/freedesktop/hostname1",
1789 "org.freedesktop.hostname1",
1790 "SetHostname",
1791 set_hostname_handler,
1792 m,
1793 "sb",
1794 hostname,
1795 false);
1796
1797 if (r < 0)
1798 return log_error_errno(r, "Could not set transient hostname: %m");
1799
1800 return 0;
1801}
1802
1803static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1804 Manager *manager = userdata;
1805 const sd_bus_error *e;
1806
1807 assert(m);
1808 assert(manager);
1809
1810 e = sd_bus_message_get_error(m);
1811 if (e)
1812 log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
1813
1814 return 1;
1815}
1816
1817int manager_set_timezone(Manager *m, const char *tz) {
1818 int r;
1819
1820 assert(m);
1821 assert(tz);
1822
1823 log_debug("Setting system timezone: '%s'", tz);
7901cea1
MP
1824 if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
1825 return log_oom();
59eb33e0 1826
d7afd945
LP
1827 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
1828 log_info("Not connected to system bus, not setting hostname.");
59eb33e0
MP
1829 return 0;
1830 }
1831
1832 r = sd_bus_call_method_async(
1833 m->bus,
1834 NULL,
1835 "org.freedesktop.timedate1",
1836 "/org/freedesktop/timedate1",
1837 "org.freedesktop.timedate1",
1838 "SetTimezone",
1839 set_timezone_handler,
1840 m,
1841 "sb",
1842 tz,
1843 false);
1844 if (r < 0)
1845 return log_error_errno(r, "Could not set timezone: %m");
1846
1847 return 0;
1848}