chiark / gitweb /
tmpfiles: Fix parse_acl error message
[elogind.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 "conf-parser.h"
26 #include "path-util.h"
27 #include "networkd.h"
28 #include "networkd-netdev.h"
29 #include "networkd-link.h"
30 #include "network-internal.h"
31 #include "libudev-private.h"
32 #include "udev-util.h"
33 #include "rtnl-util.h"
34 #include "bus-util.h"
35 #include "def.h"
36 #include "mkdir.h"
37 #include "virt.h"
38
39 #include "sd-rtnl.h"
40 #include "sd-daemon.h"
41
42 /* use 8 MB for receive socket kernel queue. */
43 #define RCVBUF_SIZE    (8*1024*1024)
44
45 const char* const network_dirs[] = {
46         "/etc/systemd/network",
47         "/run/systemd/network",
48         "/usr/lib/systemd/network",
49 #ifdef HAVE_SPLIT_USR
50         "/lib/systemd/network",
51 #endif
52         NULL};
53
54 static int setup_default_address_pool(Manager *m) {
55         AddressPool *p;
56         int r;
57
58         assert(m);
59
60         /* Add in the well-known private address ranges. */
61
62         r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
63         if (r < 0)
64                 return r;
65
66         r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
67         if (r < 0)
68                 return r;
69
70         r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
71         if (r < 0)
72                 return r;
73
74         r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
75         if (r < 0)
76                 return r;
77
78         return 0;
79 }
80
81 static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
82         Manager *m = userdata;
83
84         assert(s);
85         assert(m);
86
87         m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
88
89         manager_connect_bus(m);
90
91         return 0;
92 }
93
94 static int manager_reset_all(Manager *m) {
95         Link *link;
96         Iterator i;
97         int r;
98
99         assert(m);
100
101         HASHMAP_FOREACH(link, m->links, i) {
102                 r = link_carrier_reset(link);
103                 if (r < 0)
104                         log_link_warning_errno(link, r, "could not reset carrier: %m");
105         }
106
107         return 0;
108 }
109
110 static int match_prepare_for_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
111         Manager *m = userdata;
112         int b, r;
113
114         assert(bus);
115         assert(bus);
116
117         r = sd_bus_message_read(message, "b", &b);
118         if (r < 0) {
119                 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
120                 return 0;
121         }
122
123         if (b)
124                 return 0;
125
126         log_debug("Coming back from suspend, resetting all connections...");
127
128         manager_reset_all(m);
129
130         return 0;
131 }
132
133 int manager_connect_bus(Manager *m) {
134         int r;
135
136         assert(m);
137
138         r = sd_bus_default_system(&m->bus);
139         if (r == -ENOENT) {
140                 /* We failed to connect? Yuck, we must be in early
141                  * boot. Let's try in 5s again. As soon as we have
142                  * kdbus we can stop doing this... */
143
144                 log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
145
146                 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);
147                 if (r < 0)
148                         return log_error_errno(r, "Failed to install bus reconnect time event: %m");
149
150                 return 0;
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(NULL) > 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 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
281         Manager *m = userdata;
282         Link *link = NULL;
283         NetDev *netdev = NULL;
284         uint16_t type;
285         const char *name;
286         int r, ifindex;
287
288         assert(rtnl);
289         assert(message);
290         assert(m);
291
292         if (sd_rtnl_message_is_error(message)) {
293                 r = sd_rtnl_message_get_errno(message);
294                 if (r < 0)
295                         log_warning_errno(r, "rtnl: could not receive link: %m");
296
297                 return 0;
298         }
299
300         r = sd_rtnl_message_get_type(message, &type);
301         if (r < 0) {
302                 log_warning_errno(r, "rtnl: could not get message type: %m");
303                 return 0;
304         }
305
306         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
307         if (r < 0) {
308                 log_warning_errno(r, "rtnl: could not get ifindex: %m");
309                 return 0;
310         } else if (ifindex <= 0) {
311                 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
312                 return 0;
313         } else
314                 link_get(m, ifindex, &link);
315
316         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
317         if (r < 0) {
318                 log_warning_errno(r, "rtnl: received link message without ifname: %m");
319                 return 0;
320         } else
321                 netdev_get(m, name, &netdev);
322
323         switch (type) {
324         case RTM_NEWLINK:
325                 if (!link) {
326                         /* link is new, so add it */
327                         r = link_add(m, message, &link);
328                         if (r < 0) {
329                                 log_warning_errno(r, "could not add new link: %m");
330                                 return 0;
331                         }
332                 }
333
334                 if (netdev) {
335                         /* netdev exists, so make sure the ifindex matches */
336                         r = netdev_set_ifindex(netdev, message);
337                         if (r < 0) {
338                                 log_warning_errno(r, "could not set ifindex on netdev: %m");
339                                 return 0;
340                         }
341                 }
342
343                 r = link_update(link, message);
344                 if (r < 0)
345                         return 0;
346
347                 break;
348
349         case RTM_DELLINK:
350                 link_drop(link);
351                 netdev_drop(netdev);
352
353                 break;
354
355         default:
356                 assert_not_reached("Received invalid RTNL message type.");
357         }
358
359         return 1;
360 }
361
362 static int systemd_netlink_fd(void) {
363         int n, fd, rtnl_fd = -EINVAL;
364
365         n = sd_listen_fds(true);
366         if (n <= 0)
367                 return -EINVAL;
368
369         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
370                 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
371                         if (rtnl_fd >= 0)
372                                 return -EINVAL;
373
374                         rtnl_fd = fd;
375                 }
376         }
377
378         return rtnl_fd;
379 }
380
381 static int manager_connect_rtnl(Manager *m) {
382         int fd, r;
383
384         assert(m);
385
386         fd = systemd_netlink_fd();
387         if (fd < 0)
388                 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
389         else
390                 r = sd_rtnl_open_fd(&m->rtnl, fd, 0);
391         if (r < 0)
392                 return r;
393
394         r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
395         if (r < 0)
396                 return r;
397
398         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
399         if (r < 0)
400                 return r;
401
402         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
403         if (r < 0)
404                 return r;
405
406         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
407         if (r < 0)
408                 return r;
409
410         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
411         if (r < 0)
412                 return r;
413
414         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
415         if (r < 0)
416                 return r;
417
418         return 0;
419 }
420
421 int manager_new(Manager **ret) {
422         _cleanup_manager_free_ Manager *m = NULL;
423         int r;
424
425         m = new0(Manager, 1);
426         if (!m)
427                 return -ENOMEM;
428
429         m->state_file = strdup("/run/systemd/netif/state");
430         if (!m->state_file)
431                 return -ENOMEM;
432
433         r = sd_event_default(&m->event);
434         if (r < 0)
435                 return r;
436
437         sd_event_set_watchdog(m->event, true);
438
439         sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
440         sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
441
442         r = manager_connect_rtnl(m);
443         if (r < 0)
444                 return r;
445
446         r = manager_connect_udev(m);
447         if (r < 0)
448                 return r;
449
450         m->netdevs = hashmap_new(&string_hash_ops);
451         if (!m->netdevs)
452                 return -ENOMEM;
453
454         LIST_HEAD_INIT(m->networks);
455
456         r = setup_default_address_pool(m);
457         if (r < 0)
458                 return r;
459
460         *ret = m;
461         m = NULL;
462
463         return 0;
464 }
465
466 void manager_free(Manager *m) {
467         Network *network;
468         NetDev *netdev;
469         Link *link;
470         AddressPool *pool;
471
472         if (!m)
473                 return;
474
475         free(m->state_file);
476
477         udev_monitor_unref(m->udev_monitor);
478         udev_unref(m->udev);
479         sd_bus_unref(m->bus);
480         sd_bus_slot_unref(m->prepare_for_sleep_slot);
481         sd_event_source_unref(m->udev_event_source);
482         sd_event_source_unref(m->bus_retry_event_source);
483         sd_event_unref(m->event);
484
485         while ((link = hashmap_first(m->links)))
486                 link_unref(link);
487         hashmap_free(m->links);
488
489         while ((network = m->networks))
490                 network_free(network);
491
492         hashmap_free(m->networks_by_name);
493
494         while ((netdev = hashmap_first(m->netdevs)))
495                 netdev_unref(netdev);
496         hashmap_free(m->netdevs);
497
498         while ((pool = m->address_pools))
499                 address_pool_free(pool);
500
501         sd_rtnl_unref(m->rtnl);
502
503         free(m);
504 }
505
506 static bool manager_check_idle(void *userdata) {
507         Manager *m = userdata;
508         Link *link;
509         Iterator i;
510
511         assert(m);
512
513         HASHMAP_FOREACH(link, m->links, i) {
514                 /* we are not woken on udev activity, so let's just wait for the
515                  * pending udev event */
516                 if (link->state == LINK_STATE_PENDING)
517                         return false;
518
519                 if (!link->network)
520                         continue;
521
522                 /* we are not woken on netork activity, so let's stay around */
523                 if (link_lldp_enabled(link) ||
524                     link_ipv4ll_enabled(link) ||
525                     link_dhcp4_server_enabled(link) ||
526                     link_dhcp4_enabled(link) ||
527                     link_dhcp6_enabled(link))
528                         return false;
529         }
530
531         return true;
532 }
533
534 int manager_run(Manager *m) {
535         assert(m);
536
537         if (m->bus)
538                 return bus_event_loop_with_idle(
539                                 m->event,
540                                 m->bus,
541                                 "org.freedesktop.network1",
542                                 DEFAULT_EXIT_USEC,
543                                 manager_check_idle,
544                                 m);
545         else
546                 /* failed to connect to the bus, so we lose exit-on-idle logic,
547                    this should not happen except if dbus is not around at all */
548                 return sd_event_loop(m->event);
549 }
550
551 int manager_load_config(Manager *m) {
552         int r;
553
554         /* update timestamp */
555         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
556
557         r = netdev_load(m);
558         if (r < 0)
559                 return r;
560
561         r = network_load(m);
562         if (r < 0)
563                 return r;
564
565         return 0;
566 }
567
568 bool manager_should_reload(Manager *m) {
569         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
570 }
571
572 int manager_rtnl_enumerate_links(Manager *m) {
573         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
574         sd_rtnl_message *link;
575         int r;
576
577         assert(m);
578         assert(m->rtnl);
579
580         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
581         if (r < 0)
582                 return r;
583
584         r = sd_rtnl_message_request_dump(req, true);
585         if (r < 0)
586                 return r;
587
588         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
589         if (r < 0)
590                 return r;
591
592         for (link = reply; link; link = sd_rtnl_message_next(link)) {
593                 int k;
594
595                 m->enumerating = true;
596
597                 k = manager_rtnl_process_link(m->rtnl, link, m);
598                 if (k < 0)
599                         r = k;
600
601                 m->enumerating = false;
602         }
603
604         return r;
605 }
606
607 int manager_rtnl_enumerate_addresses(Manager *m) {
608         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
609         sd_rtnl_message *addr;
610         int r;
611
612         assert(m);
613         assert(m->rtnl);
614
615         r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
616         if (r < 0)
617                 return r;
618
619         r = sd_rtnl_message_request_dump(req, true);
620         if (r < 0)
621                 return r;
622
623         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
624         if (r < 0)
625                 return r;
626
627         for (addr = reply; addr; addr = sd_rtnl_message_next(addr)) {
628                 int k;
629
630                 m->enumerating = true;
631
632                 k = link_rtnl_process_address(m->rtnl, addr, m);
633                 if (k < 0)
634                         r = k;
635
636                 m->enumerating = false;
637         }
638
639         return r;
640 }
641
642 static int set_put_in_addr(Set *s, const struct in_addr *address) {
643         char *p;
644         int r;
645
646         assert(s);
647
648         r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
649         if (r < 0)
650                 return r;
651
652         r = set_consume(s, p);
653         if (r == -EEXIST)
654                 return 0;
655
656         return r;
657 }
658
659 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
660         int r, i, c = 0;
661
662         assert(s);
663         assert(n <= 0 || addresses);
664
665         for (i = 0; i < n; i++) {
666                 r = set_put_in_addr(s, addresses+i);
667                 if (r < 0)
668                         return r;
669
670                 c += r;
671         }
672
673         return c;
674 }
675
676 static void print_string_set(FILE *f, const char *field, Set *s) {
677         bool space = false;
678         Iterator i;
679         char *p;
680
681         if (set_isempty(s))
682                 return;
683
684         fputs(field, f);
685
686         SET_FOREACH(p, s, i) {
687                 if (space)
688                         fputc(' ', f);
689                 fputs(p, f);
690                 space = true;
691         }
692         fputc('\n', f);
693 }
694
695 int manager_save(Manager *m) {
696         _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
697         Link *link;
698         Iterator i;
699         _cleanup_free_ char *temp_path = NULL;
700         _cleanup_fclose_ FILE *f = NULL;
701         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
702         const char *operstate_str;
703         int r;
704
705         assert(m);
706         assert(m->state_file);
707
708         /* We add all NTP and DNS server to a set, to filter out duplicates */
709         dns = set_new(&string_hash_ops);
710         if (!dns)
711                 return -ENOMEM;
712
713         ntp = set_new(&string_hash_ops);
714         if (!ntp)
715                 return -ENOMEM;
716
717         domains = set_new(&string_hash_ops);
718         if (!domains)
719                 return -ENOMEM;
720
721         HASHMAP_FOREACH(link, m->links, i) {
722                 if (link->flags & IFF_LOOPBACK)
723                         continue;
724
725                 if (link->operstate > operstate)
726                         operstate = link->operstate;
727
728                 if (!link->network)
729                         continue;
730
731                 /* First add the static configured entries */
732                 r = set_put_strdupv(dns, link->network->dns);
733                 if (r < 0)
734                         return r;
735
736                 r = set_put_strdupv(ntp, link->network->ntp);
737                 if (r < 0)
738                         return r;
739
740                 r = set_put_strdupv(domains, link->network->domains);
741                 if (r < 0)
742                         return r;
743
744                 if (!link->dhcp_lease)
745                         continue;
746
747                 /* Secondly, add the entries acquired via DHCP */
748                 if (link->network->dhcp_dns) {
749                         const struct in_addr *addresses;
750
751                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
752                         if (r > 0) {
753                                 r = set_put_in_addrv(dns, addresses, r);
754                                 if (r < 0)
755                                         return r;
756                         } else if (r < 0 && r != -ENOENT)
757                                 return r;
758                 }
759
760                 if (link->network->dhcp_ntp) {
761                         const struct in_addr *addresses;
762
763                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
764                         if (r > 0) {
765                                 r = set_put_in_addrv(ntp, addresses, r);
766                                 if (r < 0)
767                                         return r;
768                         } else if (r < 0 && r != -ENOENT)
769                                 return r;
770                 }
771
772                 if (link->network->dhcp_domains) {
773                         const char *domainname;
774
775                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
776                         if (r >= 0) {
777                                 r = set_put_strdup(domains, domainname);
778                                 if (r < 0)
779                                         return r;
780                         } else if (r != -ENOENT)
781                                 return r;
782                 }
783         }
784
785         operstate_str = link_operstate_to_string(operstate);
786         assert(operstate_str);
787
788         r = fopen_temporary(m->state_file, &f, &temp_path);
789         if (r < 0)
790                 return r;
791
792         fchmod(fileno(f), 0644);
793
794         fprintf(f,
795                 "# This is private data. Do not parse.\n"
796                 "OPER_STATE=%s\n", operstate_str);
797
798         print_string_set(f, "DNS=", dns);
799         print_string_set(f, "NTP=", ntp);
800         print_string_set(f, "DOMAINS=", domains);
801
802         r = fflush_and_check(f);
803         if (r < 0)
804                 goto fail;
805
806         if (rename(temp_path, m->state_file) < 0) {
807                 r = -errno;
808                 goto fail;
809         }
810
811         if (m->operational_state != operstate) {
812                 m->operational_state = operstate;
813                 r = manager_send_changed(m, "OperationalState", NULL);
814                 if (r < 0)
815                         log_error_errno(r, "Could not emit changed OperationalState: %m");
816         }
817
818         return 0;
819
820 fail:
821         log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
822         unlink(m->state_file);
823         unlink(temp_path);
824         return r;
825 }
826
827 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
828         AddressPool *p;
829         int r;
830
831         assert(m);
832         assert(prefixlen > 0);
833         assert(found);
834
835         LIST_FOREACH(address_pools, p, m->address_pools) {
836                 if (p->family != family)
837                         continue;
838
839                 r = address_pool_acquire(p, prefixlen, found);
840                 if (r != 0)
841                         return r;
842         }
843
844         return 0;
845 }
846
847 const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
848         if (b == ADDRESS_FAMILY_YES ||
849             b == ADDRESS_FAMILY_NO)
850                 return yes_no(b == ADDRESS_FAMILY_YES);
851
852         if (b == ADDRESS_FAMILY_IPV4)
853                 return "ipv4";
854         if (b == ADDRESS_FAMILY_IPV6)
855                 return "ipv6";
856
857         return NULL;
858 }
859
860 AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
861         int r;
862
863         /* Make this a true superset of a boolean */
864
865         r = parse_boolean(s);
866         if (r > 0)
867                 return ADDRESS_FAMILY_YES;
868         if (r == 0)
869                 return ADDRESS_FAMILY_NO;
870
871         if (streq(s, "ipv4"))
872                 return ADDRESS_FAMILY_IPV4;
873         if (streq(s, "ipv6"))
874                 return ADDRESS_FAMILY_IPV6;
875
876         return _ADDRESS_FAMILY_BOOLEAN_INVALID;
877 }
878
879 DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_boolean, address_family_boolean, AddressFamilyBoolean, "Failed to parse option");