]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
networkd: address - rework firewall rules lifetime
[thirdparty/systemd.git] / src / network / networkd-manager.c
CommitLineData
f579559b
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
091a364c 22#include <sys/socket.h>
bbf7c048 23#include <linux/if.h>
3bef724f 24
fc2f9534
LP
25#include "sd-netlink.h"
26#include "sd-daemon.h"
27
2dcf7ec6 28#include "conf-parser.h"
f579559b 29#include "path-util.h"
f579559b 30#include "libudev-private.h"
7b77ed8c 31#include "udev-util.h"
1c4baffc 32#include "netlink-util.h"
a97dcc12
TG
33#include "bus-util.h"
34#include "def.h"
60ad0c85 35#include "virt.h"
fc2f9534 36#include "set.h"
4f5f911e 37#include "local-addresses.h"
f579559b 38
fc2f9534 39#include "networkd.h"
505f8da7 40
be660c37
AR
41/* use 8 MB for receive socket kernel queue. */
42#define RCVBUF_SIZE (8*1024*1024)
43
2ad8416d
ZJS
44const char* const network_dirs[] = {
45 "/etc/systemd/network",
46 "/run/systemd/network",
47 "/usr/lib/systemd/network",
eed0eee8 48#ifdef HAVE_SPLIT_USR
2ad8416d
ZJS
49 "/lib/systemd/network",
50#endif
51 NULL};
52
11bf3cce
LP
53static int setup_default_address_pool(Manager *m) {
54 AddressPool *p;
55 int r;
56
57 assert(m);
58
59 /* Add in the well-known private address ranges. */
60
61 r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
62 if (r < 0)
63 return r;
64
65 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
66 if (r < 0)
67 return r;
68
69 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
70 if (r < 0)
71 return r;
72
73 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
74 if (r < 0)
75 return r;
76
77 return 0;
78}
79
9c0a72f9
TG
80static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
81 Manager *m = userdata;
82
83 assert(s);
84 assert(m);
85
86 m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
87
88 manager_connect_bus(m);
89
90 return 0;
91}
92
93static int manager_reset_all(Manager *m) {
94 Link *link;
95 Iterator i;
96 int r;
97
98 assert(m);
99
100 HASHMAP_FOREACH(link, m->links, i) {
101 r = link_carrier_reset(link);
102 if (r < 0)
2f3cf1f9 103 log_link_warning_errno(link, r, "Could not reset carrier: %m");
9c0a72f9
TG
104 }
105
106 return 0;
107}
108
19070062 109static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
9c0a72f9
TG
110 Manager *m = userdata;
111 int b, r;
112
19070062 113 assert(message);
9c0a72f9
TG
114
115 r = sd_bus_message_read(message, "b", &b);
116 if (r < 0) {
117 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
118 return 0;
119 }
120
121 if (b)
122 return 0;
123
124 log_debug("Coming back from suspend, resetting all connections...");
125
126 manager_reset_all(m);
127
128 return 0;
129}
130
131int manager_connect_bus(Manager *m) {
132 int r;
133
134 assert(m);
135
136 r = sd_bus_default_system(&m->bus);
137 if (r == -ENOENT) {
138 /* We failed to connect? Yuck, we must be in early
139 * boot. Let's try in 5s again. As soon as we have
140 * kdbus we can stop doing this... */
141
142 log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
143
144 r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
145 if (r < 0)
146 return log_error_errno(r, "Failed to install bus reconnect time event: %m");
147
148 return 0;
7d6884b6
TA
149 }
150
151 if (r < 0)
9c0a72f9
TG
152 return r;
153
9c0a72f9
TG
154 r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
155 "type='signal',"
156 "sender='org.freedesktop.login1',"
157 "interface='org.freedesktop.login1.Manager',"
158 "member='PrepareForSleep',"
159 "path='/org/freedesktop/login1'",
160 match_prepare_for_sleep,
161 m);
162 if (r < 0)
163 return log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
164
e331e246
TG
165 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m);
166 if (r < 0)
167 return log_error_errno(r, "Failed to add manager object vtable: %m");
168
169 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m);
170 if (r < 0)
171 return log_error_errno(r, "Failed to add link object vtable: %m");
172
173 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
174 if (r < 0)
175 return log_error_errno(r, "Failed to add link enumerator: %m");
3175fcde
TG
176
177 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m);
178 if (r < 0)
179 return log_error_errno(r, "Failed to add network object vtable: %m");
180
181 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m);
182 if (r < 0)
183 return log_error_errno(r, "Failed to add network enumerator: %m");
e331e246
TG
184
185 r = sd_bus_request_name(m->bus, "org.freedesktop.network1", 0);
186 if (r < 0)
187 return log_error_errno(r, "Failed to register name: %m");
188
189 r = sd_bus_attach_event(m->bus, m->event, 0);
190 if (r < 0)
191 return log_error_errno(r, "Failed to attach bus to event loop: %m");
192
9c0a72f9
TG
193 return 0;
194}
195
5fae368b
TG
196static int manager_udev_process_link(Manager *m, struct udev_device *device) {
197 Link *link = NULL;
198 int r, ifindex;
5544ee85 199
5fae368b
TG
200 assert(m);
201 assert(device);
5544ee85 202
5fae368b
TG
203 if (!streq_ptr(udev_device_get_action(device), "add"))
204 return 0;
5544ee85 205
5fae368b
TG
206 ifindex = udev_device_get_ifindex(device);
207 if (ifindex <= 0) {
2f3cf1f9 208 log_debug("Ignoring udev ADD event for device with invalid ifindex");
5fae368b 209 return 0;
5544ee85
TG
210 }
211
5fae368b
TG
212 r = link_get(m, ifindex, &link);
213 if (r == -ENODEV)
214 return 0;
215 else if (r < 0)
f579559b
TG
216 return r;
217
5fae368b 218 r = link_initialized(link, device);
44de0efc
LP
219 if (r < 0)
220 return r;
221
5fae368b
TG
222 return 0;
223}
be660c37 224
5fae368b
TG
225static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
226 Manager *m = userdata;
227 struct udev_monitor *monitor = m->udev_monitor;
228 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
f579559b 229
5fae368b
TG
230 device = udev_monitor_receive_device(monitor);
231 if (!device)
02b59d57
TG
232 return -ENOMEM;
233
5fae368b 234 manager_udev_process_link(m, device);
f579559b
TG
235 return 0;
236}
237
5fae368b
TG
238static int manager_connect_udev(Manager *m) {
239 int r;
f579559b 240
5fae368b
TG
241 /* udev does not initialize devices inside containers,
242 * so we rely on them being already initialized before
243 * entering the container */
75f86906 244 if (detect_container() > 0)
5fae368b 245 return 0;
f579559b 246
5fae368b
TG
247 m->udev = udev_new();
248 if (!m->udev)
249 return -ENOMEM;
02b59d57 250
5fae368b
TG
251 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
252 if (!m->udev_monitor)
253 return -ENOMEM;
02b59d57 254
5fae368b 255 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
02b59d57 256 if (r < 0)
5fae368b 257 return log_error_errno(r, "Could not add udev monitor filter: %m");
02b59d57 258
5fae368b
TG
259 r = udev_monitor_enable_receiving(m->udev_monitor);
260 if (r < 0) {
261 log_error("Could not enable udev monitor");
02b59d57 262 return r;
667fcc6d 263 }
505f8da7 264
5fae368b
TG
265 r = sd_event_add_io(m->event,
266 &m->udev_event_source,
267 udev_monitor_get_fd(m->udev_monitor),
268 EPOLLIN, manager_dispatch_link_udev,
269 m);
270 if (r < 0)
667fcc6d 271 return r;
505f8da7 272
5fae368b 273 r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
505f8da7
TG
274 if (r < 0)
275 return r;
11a7f229 276
505f8da7
TG
277 return 0;
278}
f579559b 279
200a0868
TG
280int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
281 Manager *m = userdata;
282 Link *link = NULL;
283 uint16_t type;
200a0868 284 unsigned char flags;
054f0db4
TG
285 int family;
286 unsigned char prefixlen;
287 unsigned char scope;
288 union in_addr_union in_addr;
289 struct ifa_cacheinfo cinfo;
290 Address *address = NULL;
200a0868
TG
291 char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
292 const char *valid_str = NULL;
293 int r, ifindex;
294
295 assert(rtnl);
296 assert(message);
297 assert(m);
298
299 if (sd_netlink_message_is_error(message)) {
300 r = sd_netlink_message_get_errno(message);
301 if (r < 0)
302 log_warning_errno(r, "rtnl: failed to receive address: %m");
303
304 return 0;
305 }
306
307 r = sd_netlink_message_get_type(message, &type);
308 if (r < 0) {
309 log_warning_errno(r, "rtnl: could not get message type: %m");
310 return 0;
311 } else if (type != RTM_NEWADDR && type != RTM_DELADDR) {
312 log_warning("rtnl: received unexpected message type when processing address");
313 return 0;
314 }
315
316 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
317 if (r < 0) {
318 log_warning_errno(r, "rtnl: could not get ifindex from address: %m");
319 return 0;
320 } else if (ifindex <= 0) {
321 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
322 return 0;
323 } else {
324 r = link_get(m, ifindex, &link);
325 if (r < 0 || !link) {
326 /* when enumerating we might be out of sync, but we will
327 * get the address again, so just ignore it */
328 if (!m->enumerating)
329 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
330 return 0;
331 }
332 }
333
054f0db4
TG
334 r = sd_rtnl_message_addr_get_family(message, &family);
335 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
200a0868
TG
336 log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
337 return 0;
338 }
339
054f0db4 340 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
200a0868
TG
341 if (r < 0) {
342 log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m");
343 return 0;
344 }
345
054f0db4 346 r = sd_rtnl_message_addr_get_scope(message, &scope);
200a0868
TG
347 if (r < 0) {
348 log_link_warning_errno(link, r, "rtnl: received address with invalid scope, ignoring: %m");
349 return 0;
350 }
351
352 r = sd_rtnl_message_addr_get_flags(message, &flags);
353 if (r < 0) {
354 log_link_warning_errno(link, r, "rtnl: received address with invalid flags, ignoring: %m");
355 return 0;
356 }
200a0868 357
054f0db4 358 switch (family) {
200a0868 359 case AF_INET:
054f0db4 360 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
200a0868
TG
361 if (r < 0) {
362 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
363 return 0;
364 }
365
366 break;
367
368 case AF_INET6:
054f0db4 369 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
200a0868
TG
370 if (r < 0) {
371 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
372 return 0;
373 }
374
375 break;
376
377 default:
378 assert_not_reached("invalid address family");
379 }
380
054f0db4 381 if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) {
200a0868
TG
382 log_link_warning(link, "Could not print address");
383 return 0;
384 }
385
054f0db4 386 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
200a0868 387 if (r >= 0) {
054f0db4 388 if (cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
200a0868
TG
389 valid_str = "ever";
390 else
391 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
054f0db4 392 cinfo.ifa_valid * USEC_PER_SEC,
200a0868
TG
393 USEC_PER_SEC);
394 }
395
054f0db4 396 address_get(link, family, &in_addr, prefixlen, &address);
200a0868
TG
397
398 switch (type) {
399 case RTM_NEWADDR:
36c32f61 400 if (address)
054f0db4 401 log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
36c32f61 402 else {
054f0db4 403 r = address_add(link, family, &in_addr, prefixlen, &address);
cf1d700d 404 if (r < 0) {
054f0db4 405 log_link_warning_errno(link, r, "Failed to add address %s/%u: %m", buf, prefixlen);
cf1d700d
TG
406 return 0;
407 } else
054f0db4 408 log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
200a0868
TG
409 }
410
36c32f61
TG
411 address_update(address, scope, flags, &cinfo);
412
200a0868
TG
413 break;
414
415 case RTM_DELADDR:
416
054f0db4
TG
417 if (address) {
418 log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
91b5f997 419 address_drop(address);
200a0868 420 } else
054f0db4 421 log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
200a0868
TG
422
423 break;
424 default:
425 assert_not_reached("Received invalid RTNL message type");
426 }
427
428 return 1;
429}
430
1c4baffc 431static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
505f8da7
TG
432 Manager *m = userdata;
433 Link *link = NULL;
4d473d5d 434 NetDev *netdev = NULL;
f2236469 435 uint16_t type;
ca4e095a 436 const char *name;
505f8da7 437 int r, ifindex;
f579559b 438
505f8da7
TG
439 assert(rtnl);
440 assert(message);
f579559b
TG
441 assert(m);
442
1c4baffc
TG
443 if (sd_netlink_message_is_error(message)) {
444 r = sd_netlink_message_get_errno(message);
45af44d4 445 if (r < 0)
2f3cf1f9 446 log_warning_errno(r, "rtnl: Could not receive link: %m");
45af44d4
TG
447
448 return 0;
449 }
450
1c4baffc 451 r = sd_netlink_message_get_type(message, &type);
f2236469 452 if (r < 0) {
2f3cf1f9 453 log_warning_errno(r, "rtnl: Could not get message type: %m");
f2236469 454 return 0;
cdfee943 455 } else if (type != RTM_NEWLINK && type != RTM_DELLINK) {
2f3cf1f9 456 log_warning("rtnl: Received unexpected message type when processing link");
cdfee943 457 return 0;
f2236469
TG
458 }
459
505f8da7 460 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
45af44d4 461 if (r < 0) {
2f3cf1f9 462 log_warning_errno(r, "rtnl: Could not get ifindex from link: %m");
45af44d4
TG
463 return 0;
464 } else if (ifindex <= 0) {
465 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
505f8da7 466 return 0;
4d473d5d
TG
467 } else
468 link_get(m, ifindex, &link);
f579559b 469
1c4baffc 470 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
45af44d4 471 if (r < 0) {
2f3cf1f9 472 log_warning_errno(r, "rtnl: Received link message without ifname: %m");
4d473d5d
TG
473 return 0;
474 } else
f2236469 475 netdev_get(m, name, &netdev);
4d473d5d
TG
476
477 switch (type) {
478 case RTM_NEWLINK:
479 if (!link) {
480 /* link is new, so add it */
481 r = link_add(m, message, &link);
482 if (r < 0) {
2f3cf1f9 483 log_warning_errno(r, "Could not add new link: %m");
4d473d5d
TG
484 return 0;
485 }
486 }
487
488 if (netdev) {
489 /* netdev exists, so make sure the ifindex matches */
505f8da7
TG
490 r = netdev_set_ifindex(netdev, message);
491 if (r < 0) {
2f3cf1f9 492 log_warning_errno(r, "Could not set ifindex on netdev: %m");
505f8da7
TG
493 return 0;
494 }
495 }
e1202047 496
f2236469
TG
497 r = link_update(link, message);
498 if (r < 0)
499 return 0;
4d473d5d
TG
500
501 break;
502
503 case RTM_DELLINK:
504 link_drop(link);
505 netdev_drop(netdev);
506
507 break;
508
509 default:
510 assert_not_reached("Received invalid RTNL message type.");
f2236469 511 }
505f8da7
TG
512
513 return 1;
514}
515
5fae368b
TG
516static int systemd_netlink_fd(void) {
517 int n, fd, rtnl_fd = -EINVAL;
518
519 n = sd_listen_fds(true);
520 if (n <= 0)
521 return -EINVAL;
522
523 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
524 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
525 if (rtnl_fd >= 0)
526 return -EINVAL;
527
528 rtnl_fd = fd;
529 }
530 }
531
532 return rtnl_fd;
533}
534
535static int manager_connect_rtnl(Manager *m) {
536 int fd, r;
505f8da7
TG
537
538 assert(m);
505f8da7 539
5fae368b
TG
540 fd = systemd_netlink_fd();
541 if (fd < 0)
1c4baffc 542 r = sd_netlink_open(&m->rtnl);
5fae368b 543 else
1c4baffc 544 r = sd_netlink_open_fd(&m->rtnl, fd);
505f8da7
TG
545 if (r < 0)
546 return r;
547
1c4baffc 548 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
f579559b 549 if (r < 0)
bf5332d2 550 return r;
f579559b 551
1c4baffc 552 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
505f8da7
TG
553 if (r < 0)
554 return r;
f579559b 555
1c4baffc 556 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
5fae368b
TG
557 if (r < 0)
558 return r;
505f8da7 559
1c4baffc 560 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
5fae368b
TG
561 if (r < 0)
562 return r;
45af44d4 563
200a0868 564 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
5fae368b
TG
565 if (r < 0)
566 return r;
567
200a0868 568 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
5fae368b
TG
569 if (r < 0)
570 return r;
571
572 return 0;
45af44d4 573}
505f8da7 574
5fae368b
TG
575int manager_new(Manager **ret) {
576 _cleanup_manager_free_ Manager *m = NULL;
45af44d4 577 int r;
f579559b 578
5fae368b
TG
579 m = new0(Manager, 1);
580 if (!m)
581 return -ENOMEM;
45af44d4 582
5fae368b
TG
583 m->state_file = strdup("/run/systemd/netif/state");
584 if (!m->state_file)
585 return -ENOMEM;
586
587 r = sd_event_default(&m->event);
45af44d4
TG
588 if (r < 0)
589 return r;
590
5fae368b
TG
591 sd_event_set_watchdog(m->event, true);
592
593 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
594 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
595
596 r = manager_connect_rtnl(m);
45af44d4
TG
597 if (r < 0)
598 return r;
599
5fae368b
TG
600 r = manager_connect_udev(m);
601 if (r < 0)
602 return r;
45af44d4 603
5fae368b
TG
604 m->netdevs = hashmap_new(&string_hash_ops);
605 if (!m->netdevs)
606 return -ENOMEM;
f579559b 607
5fae368b 608 LIST_HEAD_INIT(m->networks);
f579559b 609
5fae368b
TG
610 r = setup_default_address_pool(m);
611 if (r < 0)
612 return r;
f579559b 613
5fae368b
TG
614 *ret = m;
615 m = NULL;
f579559b 616
f579559b
TG
617 return 0;
618}
619
5fae368b
TG
620void manager_free(Manager *m) {
621 Network *network;
622 NetDev *netdev;
623 Link *link;
624 AddressPool *pool;
f579559b 625
5fae368b
TG
626 if (!m)
627 return;
505f8da7 628
5fae368b 629 free(m->state_file);
505f8da7 630
5fae368b
TG
631 while ((link = hashmap_first(m->links)))
632 link_unref(link);
633 hashmap_free(m->links);
f579559b 634
5fae368b
TG
635 while ((network = m->networks))
636 network_free(network);
637
dbffab87
TG
638 hashmap_free(m->networks_by_name);
639
5fae368b
TG
640 while ((netdev = hashmap_first(m->netdevs)))
641 netdev_unref(netdev);
642 hashmap_free(m->netdevs);
643
644 while ((pool = m->address_pools))
645 address_pool_free(pool);
646
1c4baffc 647 sd_netlink_unref(m->rtnl);
2f5b4a77 648 sd_event_unref(m->event);
5fae368b 649
7d20d375
TG
650 sd_event_source_unref(m->udev_event_source);
651 udev_monitor_unref(m->udev_monitor);
652 udev_unref(m->udev);
653
654 sd_bus_unref(m->bus);
655 sd_bus_slot_unref(m->prepare_for_sleep_slot);
656 sd_event_source_unref(m->bus_retry_event_source);
657
5fae368b
TG
658 free(m);
659}
660
a97dcc12
TG
661static bool manager_check_idle(void *userdata) {
662 Manager *m = userdata;
663 Link *link;
664 Iterator i;
665
666 assert(m);
667
668 HASHMAP_FOREACH(link, m->links, i) {
669 /* we are not woken on udev activity, so let's just wait for the
670 * pending udev event */
671 if (link->state == LINK_STATE_PENDING)
672 return false;
673
674 if (!link->network)
675 continue;
676
677 /* we are not woken on netork activity, so let's stay around */
678 if (link_lldp_enabled(link) ||
679 link_ipv4ll_enabled(link) ||
680 link_dhcp4_server_enabled(link) ||
681 link_dhcp4_enabled(link) ||
682 link_dhcp6_enabled(link))
683 return false;
684 }
685
686 return true;
687}
688
689int manager_run(Manager *m) {
690 assert(m);
691
f806f64c
TG
692 if (m->bus)
693 return bus_event_loop_with_idle(
694 m->event,
695 m->bus,
696 "org.freedesktop.network1",
697 DEFAULT_EXIT_USEC,
698 manager_check_idle,
699 m);
700 else
701 /* failed to connect to the bus, so we lose exit-on-idle logic,
702 this should not happen except if dbus is not around at all */
703 return sd_event_loop(m->event);
a97dcc12
TG
704}
705
5fae368b
TG
706int manager_load_config(Manager *m) {
707 int r;
708
709 /* update timestamp */
710 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
711
712 r = netdev_load(m);
f579559b
TG
713 if (r < 0)
714 return r;
715
5fae368b 716 r = network_load(m);
9021bb9f
TG
717 if (r < 0)
718 return r;
719
f579559b
TG
720 return 0;
721}
f882c247 722
5fae368b
TG
723bool manager_should_reload(Manager *m) {
724 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
725}
726
727int manager_rtnl_enumerate_links(Manager *m) {
1c4baffc
TG
728 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
729 sd_netlink_message *link;
f882c247
TG
730 int r;
731
5da8149f 732 assert(m);
5fae368b 733 assert(m->rtnl);
5da8149f 734
5fae368b 735 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
f882c247
TG
736 if (r < 0)
737 return r;
738
1c4baffc 739 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
740 if (r < 0)
741 return r;
742
1c4baffc 743 r = sd_netlink_call(m->rtnl, req, 0, &reply);
f2236469
TG
744 if (r < 0)
745 return r;
746
1c4baffc 747 for (link = reply; link; link = sd_netlink_message_next(link)) {
5fae368b 748 int k;
2e9f08ea 749
6a24f148
TG
750 m->enumerating = true;
751
5fae368b
TG
752 k = manager_rtnl_process_link(m->rtnl, link, m);
753 if (k < 0)
754 r = k;
6a24f148
TG
755
756 m->enumerating = false;
5fae368b 757 }
2e9f08ea 758
5fae368b 759 return r;
f882c247 760}
3bef724f 761
5fae368b 762int manager_rtnl_enumerate_addresses(Manager *m) {
1c4baffc
TG
763 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
764 sd_netlink_message *addr;
1346b1f0
TG
765 int r;
766
5fae368b
TG
767 assert(m);
768 assert(m->rtnl);
bcbca829 769
5fae368b
TG
770 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
771 if (r < 0)
772 return r;
bcbca829 773
1c4baffc 774 r = sd_netlink_message_request_dump(req, true);
1346b1f0
TG
775 if (r < 0)
776 return r;
777
1c4baffc 778 r = sd_netlink_call(m->rtnl, req, 0, &reply);
5fae368b
TG
779 if (r < 0)
780 return r;
781
1c4baffc 782 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
5fae368b
TG
783 int k;
784
6a24f148
TG
785 m->enumerating = true;
786
200a0868 787 k = manager_rtnl_process_address(m->rtnl, addr, m);
5fae368b
TG
788 if (k < 0)
789 r = k;
6a24f148
TG
790
791 m->enumerating = false;
5fae368b
TG
792 }
793
794 return r;
1346b1f0
TG
795}
796
c0c743cb
LP
797static int set_put_in_addr(Set *s, const struct in_addr *address) {
798 char *p;
799 int r;
800
801 assert(s);
802
803 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
804 if (r < 0)
805 return r;
806
807 r = set_consume(s, p);
808 if (r == -EEXIST)
809 return 0;
810
811 return r;
812}
813
814static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
815 int r, i, c = 0;
816
817 assert(s);
818 assert(n <= 0 || addresses);
819
820 for (i = 0; i < n; i++) {
821 r = set_put_in_addr(s, addresses+i);
822 if (r < 0)
823 return r;
824
825 c += r;
826 }
827
828 return c;
829}
830
8612e936
LP
831static void print_string_set(FILE *f, const char *field, Set *s) {
832 bool space = false;
833 Iterator i;
834 char *p;
835
836 if (set_isempty(s))
837 return;
838
839 fputs(field, f);
840
841 SET_FOREACH(p, s, i) {
842 if (space)
843 fputc(' ', f);
844 fputs(p, f);
845 space = true;
846 }
847 fputc('\n', f);
848}
849
bbf7c048 850int manager_save(Manager *m) {
8612e936 851 _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
bbf7c048
TG
852 Link *link;
853 Iterator i;
854 _cleanup_free_ char *temp_path = NULL;
855 _cleanup_fclose_ FILE *f = NULL;
d3df0e39 856 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
e375dcde 857 const char *operstate_str;
bbf7c048
TG
858 int r;
859
860 assert(m);
861 assert(m->state_file);
862
c0c743cb 863 /* We add all NTP and DNS server to a set, to filter out duplicates */
d5099efc 864 dns = set_new(&string_hash_ops);
c0c743cb
LP
865 if (!dns)
866 return -ENOMEM;
867
d5099efc 868 ntp = set_new(&string_hash_ops);
c0c743cb
LP
869 if (!ntp)
870 return -ENOMEM;
871
d5099efc 872 domains = set_new(&string_hash_ops);
8612e936
LP
873 if (!domains)
874 return -ENOMEM;
875
bbf7c048
TG
876 HASHMAP_FOREACH(link, m->links, i) {
877 if (link->flags & IFF_LOOPBACK)
878 continue;
879
e375dcde
TG
880 if (link->operstate > operstate)
881 operstate = link->operstate;
c0c743cb
LP
882
883 if (!link->network)
884 continue;
885
886 /* First add the static configured entries */
887 r = set_put_strdupv(dns, link->network->dns);
888 if (r < 0)
889 return r;
890
891 r = set_put_strdupv(ntp, link->network->ntp);
892 if (r < 0)
893 return r;
894
8612e936
LP
895 r = set_put_strdupv(domains, link->network->domains);
896 if (r < 0)
897 return r;
898
c0c743cb
LP
899 if (!link->dhcp_lease)
900 continue;
901
902 /* Secondly, add the entries acquired via DHCP */
903 if (link->network->dhcp_dns) {
904 const struct in_addr *addresses;
905
906 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
907 if (r > 0) {
908 r = set_put_in_addrv(dns, addresses, r);
909 if (r < 0)
910 return r;
397d15fd 911 } else if (r < 0 && r != -ENODATA)
c0c743cb
LP
912 return r;
913 }
914
915 if (link->network->dhcp_ntp) {
916 const struct in_addr *addresses;
917
918 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
919 if (r > 0) {
920 r = set_put_in_addrv(ntp, addresses, r);
921 if (r < 0)
922 return r;
397d15fd 923 } else if (r < 0 && r != -ENODATA)
8612e936
LP
924 return r;
925 }
926
927 if (link->network->dhcp_domains) {
928 const char *domainname;
929
930 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
931 if (r >= 0) {
932 r = set_put_strdup(domains, domainname);
933 if (r < 0)
934 return r;
397d15fd 935 } else if (r != -ENODATA)
c0c743cb
LP
936 return r;
937 }
bbf7c048
TG
938 }
939
e375dcde
TG
940 operstate_str = link_operstate_to_string(operstate);
941 assert(operstate_str);
bbf7c048
TG
942
943 r = fopen_temporary(m->state_file, &f, &temp_path);
944 if (r < 0)
c2d6bd61 945 return r;
bbf7c048
TG
946
947 fchmod(fileno(f), 0644);
948
949 fprintf(f,
950 "# This is private data. Do not parse.\n"
e375dcde 951 "OPER_STATE=%s\n", operstate_str);
bbf7c048 952
8612e936
LP
953 print_string_set(f, "DNS=", dns);
954 print_string_set(f, "NTP=", ntp);
955 print_string_set(f, "DOMAINS=", domains);
c0c743cb 956
c2d6bd61
LP
957 r = fflush_and_check(f);
958 if (r < 0)
959 goto fail;
bbf7c048 960
c2d6bd61 961 if (rename(temp_path, m->state_file) < 0) {
bbf7c048 962 r = -errno;
c2d6bd61 963 goto fail;
bbf7c048
TG
964 }
965
e331e246
TG
966 if (m->operational_state != operstate) {
967 m->operational_state = operstate;
968 r = manager_send_changed(m, "OperationalState", NULL);
969 if (r < 0)
970 log_error_errno(r, "Could not emit changed OperationalState: %m");
971 }
972
c2d6bd61 973 return 0;
bbf7c048 974
c2d6bd61 975fail:
dacd6cee
LP
976 (void) unlink(m->state_file);
977 (void) unlink(temp_path);
978
979 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
bbf7c048 980}
11bf3cce 981
0dd25fb9 982int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
983 AddressPool *p;
984 int r;
985
986 assert(m);
987 assert(prefixlen > 0);
988 assert(found);
989
990 LIST_FOREACH(address_pools, p, m->address_pools) {
991 if (p->family != family)
992 continue;
993
994 r = address_pool_acquire(p, prefixlen, found);
995 if (r != 0)
996 return r;
997 }
998
999 return 0;
1000}
4f5f911e
LP
1001
1002Link* manager_find_uplink(Manager *m, Link *exclude) {
1003 _cleanup_free_ struct local_address *gateways = NULL;
1004 int n, i;
1005
1006 assert(m);
1007
1008 /* Looks for a suitable "uplink", via black magic: an
1009 * interface that is up and where the default route with the
1010 * highest priority points to. */
1011
1012 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
1013 if (n < 0) {
1014 log_warning_errno(n, "Failed to determine list of default gateways: %m");
1015 return NULL;
1016 }
1017
1018 for (i = 0; i < n; i++) {
1019 Link *link;
1020
1021 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
1022 if (!link) {
c2c940bd 1023 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
4f5f911e
LP
1024 continue;
1025 }
1026
1027 if (link == exclude)
1028 continue;
1029
1030 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1031 continue;
1032
1033 return link;
1034 }
1035
1036 return NULL;
1037}