]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-manager.c
networkd: make address_{establish,release}() static
[thirdparty/systemd.git] / src / network / networkd-manager.c
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
22 #include <sys/socket.h>
23 #include <linux/if.h>
24
25 #include "sd-netlink.h"
26 #include "sd-daemon.h"
27
28 #include "conf-parser.h"
29 #include "path-util.h"
30 #include "libudev-private.h"
31 #include "udev-util.h"
32 #include "netlink-util.h"
33 #include "bus-util.h"
34 #include "def.h"
35 #include "virt.h"
36 #include "set.h"
37 #include "local-addresses.h"
38
39 #include "networkd.h"
40
41 /* use 8 MB for receive socket kernel queue. */
42 #define RCVBUF_SIZE (8*1024*1024)
43
44 const char* const network_dirs[] = {
45 "/etc/systemd/network",
46 "/run/systemd/network",
47 "/usr/lib/systemd/network",
48 #ifdef HAVE_SPLIT_USR
49 "/lib/systemd/network",
50 #endif
51 NULL};
52
53 static 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
80 static 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
93 static 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)
103 log_link_warning_errno(link, r, "Could not reset carrier: %m");
104 }
105
106 return 0;
107 }
108
109 static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
110 Manager *m = userdata;
111 int b, r;
112
113 assert(message);
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
131 int 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;
149 }
150
151 if (r < 0)
152 return r;
153
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
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");
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");
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
193 return 0;
194 }
195
196 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
197 Link *link = NULL;
198 int r, ifindex;
199
200 assert(m);
201 assert(device);
202
203 if (!streq_ptr(udev_device_get_action(device), "add"))
204 return 0;
205
206 ifindex = udev_device_get_ifindex(device);
207 if (ifindex <= 0) {
208 log_debug("Ignoring udev ADD event for device with invalid ifindex");
209 return 0;
210 }
211
212 r = link_get(m, ifindex, &link);
213 if (r == -ENODEV)
214 return 0;
215 else if (r < 0)
216 return r;
217
218 r = link_initialized(link, device);
219 if (r < 0)
220 return r;
221
222 return 0;
223 }
224
225 static 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;
229
230 device = udev_monitor_receive_device(monitor);
231 if (!device)
232 return -ENOMEM;
233
234 manager_udev_process_link(m, device);
235 return 0;
236 }
237
238 static int manager_connect_udev(Manager *m) {
239 int r;
240
241 /* udev does not initialize devices inside containers,
242 * so we rely on them being already initialized before
243 * entering the container */
244 if (detect_container() > 0)
245 return 0;
246
247 m->udev = udev_new();
248 if (!m->udev)
249 return -ENOMEM;
250
251 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
252 if (!m->udev_monitor)
253 return -ENOMEM;
254
255 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
256 if (r < 0)
257 return log_error_errno(r, "Could not add udev monitor filter: %m");
258
259 r = udev_monitor_enable_receiving(m->udev_monitor);
260 if (r < 0) {
261 log_error("Could not enable udev monitor");
262 return r;
263 }
264
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)
271 return r;
272
273 r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
274 if (r < 0)
275 return r;
276
277 return 0;
278 }
279
280 int 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;
284 unsigned char flags;
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;
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
334 r = sd_rtnl_message_addr_get_family(message, &family);
335 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
336 log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
337 return 0;
338 }
339
340 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
341 if (r < 0) {
342 log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m");
343 return 0;
344 }
345
346 r = sd_rtnl_message_addr_get_scope(message, &scope);
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 }
357
358 switch (family) {
359 case AF_INET:
360 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
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:
369 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
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
381 if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) {
382 log_link_warning(link, "Could not print address");
383 return 0;
384 }
385
386 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
387 if (r >= 0) {
388 if (cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
389 valid_str = "ever";
390 else
391 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
392 cinfo.ifa_valid * USEC_PER_SEC,
393 USEC_PER_SEC);
394 }
395
396 address_get(link, family, &in_addr, prefixlen, &address);
397
398 switch (type) {
399 case RTM_NEWADDR:
400 if (address) {
401 log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
402
403 address->scope = scope;
404 address->flags = flags;
405 address->cinfo = cinfo;
406
407 } else {
408 r = address_add(link, family, &in_addr, prefixlen, &address);
409 if (r < 0) {
410 log_link_warning_errno(link, r, "Failed to add address %s/%u: %m", buf, prefixlen);
411 return 0;
412 } else
413 log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
414
415 address->scope = scope;
416 address->flags = flags;
417 address->cinfo = cinfo;
418
419 link_save(link);
420 }
421
422 break;
423
424 case RTM_DELADDR:
425
426 if (address) {
427 log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
428 address_drop(address);
429 } else
430 log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
431
432 break;
433 default:
434 assert_not_reached("Received invalid RTNL message type");
435 }
436
437 return 1;
438 }
439
440 static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
441 Manager *m = userdata;
442 Link *link = NULL;
443 NetDev *netdev = NULL;
444 uint16_t type;
445 const char *name;
446 int r, ifindex;
447
448 assert(rtnl);
449 assert(message);
450 assert(m);
451
452 if (sd_netlink_message_is_error(message)) {
453 r = sd_netlink_message_get_errno(message);
454 if (r < 0)
455 log_warning_errno(r, "rtnl: Could not receive link: %m");
456
457 return 0;
458 }
459
460 r = sd_netlink_message_get_type(message, &type);
461 if (r < 0) {
462 log_warning_errno(r, "rtnl: Could not get message type: %m");
463 return 0;
464 } else if (type != RTM_NEWLINK && type != RTM_DELLINK) {
465 log_warning("rtnl: Received unexpected message type when processing link");
466 return 0;
467 }
468
469 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
470 if (r < 0) {
471 log_warning_errno(r, "rtnl: Could not get ifindex from link: %m");
472 return 0;
473 } else if (ifindex <= 0) {
474 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
475 return 0;
476 } else
477 link_get(m, ifindex, &link);
478
479 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
480 if (r < 0) {
481 log_warning_errno(r, "rtnl: Received link message without ifname: %m");
482 return 0;
483 } else
484 netdev_get(m, name, &netdev);
485
486 switch (type) {
487 case RTM_NEWLINK:
488 if (!link) {
489 /* link is new, so add it */
490 r = link_add(m, message, &link);
491 if (r < 0) {
492 log_warning_errno(r, "Could not add new link: %m");
493 return 0;
494 }
495 }
496
497 if (netdev) {
498 /* netdev exists, so make sure the ifindex matches */
499 r = netdev_set_ifindex(netdev, message);
500 if (r < 0) {
501 log_warning_errno(r, "Could not set ifindex on netdev: %m");
502 return 0;
503 }
504 }
505
506 r = link_update(link, message);
507 if (r < 0)
508 return 0;
509
510 break;
511
512 case RTM_DELLINK:
513 link_drop(link);
514 netdev_drop(netdev);
515
516 break;
517
518 default:
519 assert_not_reached("Received invalid RTNL message type.");
520 }
521
522 return 1;
523 }
524
525 static int systemd_netlink_fd(void) {
526 int n, fd, rtnl_fd = -EINVAL;
527
528 n = sd_listen_fds(true);
529 if (n <= 0)
530 return -EINVAL;
531
532 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
533 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
534 if (rtnl_fd >= 0)
535 return -EINVAL;
536
537 rtnl_fd = fd;
538 }
539 }
540
541 return rtnl_fd;
542 }
543
544 static int manager_connect_rtnl(Manager *m) {
545 int fd, r;
546
547 assert(m);
548
549 fd = systemd_netlink_fd();
550 if (fd < 0)
551 r = sd_netlink_open(&m->rtnl);
552 else
553 r = sd_netlink_open_fd(&m->rtnl, fd);
554 if (r < 0)
555 return r;
556
557 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
558 if (r < 0)
559 return r;
560
561 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
562 if (r < 0)
563 return r;
564
565 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
566 if (r < 0)
567 return r;
568
569 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
570 if (r < 0)
571 return r;
572
573 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
574 if (r < 0)
575 return r;
576
577 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
578 if (r < 0)
579 return r;
580
581 return 0;
582 }
583
584 int manager_new(Manager **ret) {
585 _cleanup_manager_free_ Manager *m = NULL;
586 int r;
587
588 m = new0(Manager, 1);
589 if (!m)
590 return -ENOMEM;
591
592 m->state_file = strdup("/run/systemd/netif/state");
593 if (!m->state_file)
594 return -ENOMEM;
595
596 r = sd_event_default(&m->event);
597 if (r < 0)
598 return r;
599
600 sd_event_set_watchdog(m->event, true);
601
602 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
603 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
604
605 r = manager_connect_rtnl(m);
606 if (r < 0)
607 return r;
608
609 r = manager_connect_udev(m);
610 if (r < 0)
611 return r;
612
613 m->netdevs = hashmap_new(&string_hash_ops);
614 if (!m->netdevs)
615 return -ENOMEM;
616
617 LIST_HEAD_INIT(m->networks);
618
619 r = setup_default_address_pool(m);
620 if (r < 0)
621 return r;
622
623 *ret = m;
624 m = NULL;
625
626 return 0;
627 }
628
629 void manager_free(Manager *m) {
630 Network *network;
631 NetDev *netdev;
632 Link *link;
633 AddressPool *pool;
634
635 if (!m)
636 return;
637
638 free(m->state_file);
639
640 while ((link = hashmap_first(m->links)))
641 link_unref(link);
642 hashmap_free(m->links);
643
644 while ((network = m->networks))
645 network_free(network);
646
647 hashmap_free(m->networks_by_name);
648
649 while ((netdev = hashmap_first(m->netdevs)))
650 netdev_unref(netdev);
651 hashmap_free(m->netdevs);
652
653 while ((pool = m->address_pools))
654 address_pool_free(pool);
655
656 sd_netlink_unref(m->rtnl);
657 sd_event_unref(m->event);
658
659 sd_event_source_unref(m->udev_event_source);
660 udev_monitor_unref(m->udev_monitor);
661 udev_unref(m->udev);
662
663 sd_bus_unref(m->bus);
664 sd_bus_slot_unref(m->prepare_for_sleep_slot);
665 sd_event_source_unref(m->bus_retry_event_source);
666
667 free(m);
668 }
669
670 static bool manager_check_idle(void *userdata) {
671 Manager *m = userdata;
672 Link *link;
673 Iterator i;
674
675 assert(m);
676
677 HASHMAP_FOREACH(link, m->links, i) {
678 /* we are not woken on udev activity, so let's just wait for the
679 * pending udev event */
680 if (link->state == LINK_STATE_PENDING)
681 return false;
682
683 if (!link->network)
684 continue;
685
686 /* we are not woken on netork activity, so let's stay around */
687 if (link_lldp_enabled(link) ||
688 link_ipv4ll_enabled(link) ||
689 link_dhcp4_server_enabled(link) ||
690 link_dhcp4_enabled(link) ||
691 link_dhcp6_enabled(link))
692 return false;
693 }
694
695 return true;
696 }
697
698 int manager_run(Manager *m) {
699 assert(m);
700
701 if (m->bus)
702 return bus_event_loop_with_idle(
703 m->event,
704 m->bus,
705 "org.freedesktop.network1",
706 DEFAULT_EXIT_USEC,
707 manager_check_idle,
708 m);
709 else
710 /* failed to connect to the bus, so we lose exit-on-idle logic,
711 this should not happen except if dbus is not around at all */
712 return sd_event_loop(m->event);
713 }
714
715 int manager_load_config(Manager *m) {
716 int r;
717
718 /* update timestamp */
719 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
720
721 r = netdev_load(m);
722 if (r < 0)
723 return r;
724
725 r = network_load(m);
726 if (r < 0)
727 return r;
728
729 return 0;
730 }
731
732 bool manager_should_reload(Manager *m) {
733 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
734 }
735
736 int manager_rtnl_enumerate_links(Manager *m) {
737 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
738 sd_netlink_message *link;
739 int r;
740
741 assert(m);
742 assert(m->rtnl);
743
744 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
745 if (r < 0)
746 return r;
747
748 r = sd_netlink_message_request_dump(req, true);
749 if (r < 0)
750 return r;
751
752 r = sd_netlink_call(m->rtnl, req, 0, &reply);
753 if (r < 0)
754 return r;
755
756 for (link = reply; link; link = sd_netlink_message_next(link)) {
757 int k;
758
759 m->enumerating = true;
760
761 k = manager_rtnl_process_link(m->rtnl, link, m);
762 if (k < 0)
763 r = k;
764
765 m->enumerating = false;
766 }
767
768 return r;
769 }
770
771 int manager_rtnl_enumerate_addresses(Manager *m) {
772 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
773 sd_netlink_message *addr;
774 int r;
775
776 assert(m);
777 assert(m->rtnl);
778
779 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
780 if (r < 0)
781 return r;
782
783 r = sd_netlink_message_request_dump(req, true);
784 if (r < 0)
785 return r;
786
787 r = sd_netlink_call(m->rtnl, req, 0, &reply);
788 if (r < 0)
789 return r;
790
791 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
792 int k;
793
794 m->enumerating = true;
795
796 k = manager_rtnl_process_address(m->rtnl, addr, m);
797 if (k < 0)
798 r = k;
799
800 m->enumerating = false;
801 }
802
803 return r;
804 }
805
806 static int set_put_in_addr(Set *s, const struct in_addr *address) {
807 char *p;
808 int r;
809
810 assert(s);
811
812 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
813 if (r < 0)
814 return r;
815
816 r = set_consume(s, p);
817 if (r == -EEXIST)
818 return 0;
819
820 return r;
821 }
822
823 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
824 int r, i, c = 0;
825
826 assert(s);
827 assert(n <= 0 || addresses);
828
829 for (i = 0; i < n; i++) {
830 r = set_put_in_addr(s, addresses+i);
831 if (r < 0)
832 return r;
833
834 c += r;
835 }
836
837 return c;
838 }
839
840 static void print_string_set(FILE *f, const char *field, Set *s) {
841 bool space = false;
842 Iterator i;
843 char *p;
844
845 if (set_isempty(s))
846 return;
847
848 fputs(field, f);
849
850 SET_FOREACH(p, s, i) {
851 if (space)
852 fputc(' ', f);
853 fputs(p, f);
854 space = true;
855 }
856 fputc('\n', f);
857 }
858
859 int manager_save(Manager *m) {
860 _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
861 Link *link;
862 Iterator i;
863 _cleanup_free_ char *temp_path = NULL;
864 _cleanup_fclose_ FILE *f = NULL;
865 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
866 const char *operstate_str;
867 int r;
868
869 assert(m);
870 assert(m->state_file);
871
872 /* We add all NTP and DNS server to a set, to filter out duplicates */
873 dns = set_new(&string_hash_ops);
874 if (!dns)
875 return -ENOMEM;
876
877 ntp = set_new(&string_hash_ops);
878 if (!ntp)
879 return -ENOMEM;
880
881 domains = set_new(&string_hash_ops);
882 if (!domains)
883 return -ENOMEM;
884
885 HASHMAP_FOREACH(link, m->links, i) {
886 if (link->flags & IFF_LOOPBACK)
887 continue;
888
889 if (link->operstate > operstate)
890 operstate = link->operstate;
891
892 if (!link->network)
893 continue;
894
895 /* First add the static configured entries */
896 r = set_put_strdupv(dns, link->network->dns);
897 if (r < 0)
898 return r;
899
900 r = set_put_strdupv(ntp, link->network->ntp);
901 if (r < 0)
902 return r;
903
904 r = set_put_strdupv(domains, link->network->domains);
905 if (r < 0)
906 return r;
907
908 if (!link->dhcp_lease)
909 continue;
910
911 /* Secondly, add the entries acquired via DHCP */
912 if (link->network->dhcp_dns) {
913 const struct in_addr *addresses;
914
915 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
916 if (r > 0) {
917 r = set_put_in_addrv(dns, addresses, r);
918 if (r < 0)
919 return r;
920 } else if (r < 0 && r != -ENODATA)
921 return r;
922 }
923
924 if (link->network->dhcp_ntp) {
925 const struct in_addr *addresses;
926
927 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
928 if (r > 0) {
929 r = set_put_in_addrv(ntp, addresses, r);
930 if (r < 0)
931 return r;
932 } else if (r < 0 && r != -ENODATA)
933 return r;
934 }
935
936 if (link->network->dhcp_domains) {
937 const char *domainname;
938
939 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
940 if (r >= 0) {
941 r = set_put_strdup(domains, domainname);
942 if (r < 0)
943 return r;
944 } else if (r != -ENODATA)
945 return r;
946 }
947 }
948
949 operstate_str = link_operstate_to_string(operstate);
950 assert(operstate_str);
951
952 r = fopen_temporary(m->state_file, &f, &temp_path);
953 if (r < 0)
954 return r;
955
956 fchmod(fileno(f), 0644);
957
958 fprintf(f,
959 "# This is private data. Do not parse.\n"
960 "OPER_STATE=%s\n", operstate_str);
961
962 print_string_set(f, "DNS=", dns);
963 print_string_set(f, "NTP=", ntp);
964 print_string_set(f, "DOMAINS=", domains);
965
966 r = fflush_and_check(f);
967 if (r < 0)
968 goto fail;
969
970 if (rename(temp_path, m->state_file) < 0) {
971 r = -errno;
972 goto fail;
973 }
974
975 if (m->operational_state != operstate) {
976 m->operational_state = operstate;
977 r = manager_send_changed(m, "OperationalState", NULL);
978 if (r < 0)
979 log_error_errno(r, "Could not emit changed OperationalState: %m");
980 }
981
982 return 0;
983
984 fail:
985 (void) unlink(m->state_file);
986 (void) unlink(temp_path);
987
988 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
989 }
990
991 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
992 AddressPool *p;
993 int r;
994
995 assert(m);
996 assert(prefixlen > 0);
997 assert(found);
998
999 LIST_FOREACH(address_pools, p, m->address_pools) {
1000 if (p->family != family)
1001 continue;
1002
1003 r = address_pool_acquire(p, prefixlen, found);
1004 if (r != 0)
1005 return r;
1006 }
1007
1008 return 0;
1009 }
1010
1011 Link* manager_find_uplink(Manager *m, Link *exclude) {
1012 _cleanup_free_ struct local_address *gateways = NULL;
1013 int n, i;
1014
1015 assert(m);
1016
1017 /* Looks for a suitable "uplink", via black magic: an
1018 * interface that is up and where the default route with the
1019 * highest priority points to. */
1020
1021 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
1022 if (n < 0) {
1023 log_warning_errno(n, "Failed to determine list of default gateways: %m");
1024 return NULL;
1025 }
1026
1027 for (i = 0; i < n; i++) {
1028 Link *link;
1029
1030 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
1031 if (!link) {
1032 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
1033 continue;
1034 }
1035
1036 if (link == exclude)
1037 continue;
1038
1039 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1040 continue;
1041
1042 return link;
1043 }
1044
1045 return NULL;
1046 }