chiark / gitweb /
8dfe4377de4a202738fc86ad4f02e4c2e0cbe2f6
[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_request_name(m->bus, "org.freedesktop.network1", 0);
178         if (r < 0)
179                 return log_error_errno(r, "Failed to register name: %m");
180
181         r = sd_bus_attach_event(m->bus, m->event, 0);
182         if (r < 0)
183                 return log_error_errno(r, "Failed to attach bus to event loop: %m");
184
185         return 0;
186 }
187
188 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
189         Link *link = NULL;
190         int r, ifindex;
191
192         assert(m);
193         assert(device);
194
195         if (!streq_ptr(udev_device_get_action(device), "add"))
196                 return 0;
197
198         ifindex = udev_device_get_ifindex(device);
199         if (ifindex <= 0) {
200                 log_debug("ignoring udev ADD event for device with invalid ifindex");
201                 return 0;
202         }
203
204         r = link_get(m, ifindex, &link);
205         if (r == -ENODEV)
206                 return 0;
207         else if (r < 0)
208                 return r;
209
210         r = link_initialized(link, device);
211         if (r < 0)
212                 return r;
213
214         return 0;
215 }
216
217 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
218         Manager *m = userdata;
219         struct udev_monitor *monitor = m->udev_monitor;
220         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
221
222         device = udev_monitor_receive_device(monitor);
223         if (!device)
224                 return -ENOMEM;
225
226         manager_udev_process_link(m, device);
227         return 0;
228 }
229
230 static int manager_connect_udev(Manager *m) {
231         int r;
232
233         /* udev does not initialize devices inside containers,
234          * so we rely on them being already initialized before
235          * entering the container */
236         if (detect_container(NULL) > 0)
237                 return 0;
238
239         m->udev = udev_new();
240         if (!m->udev)
241                 return -ENOMEM;
242
243         m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
244         if (!m->udev_monitor)
245                 return -ENOMEM;
246
247         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
248         if (r < 0)
249                 return log_error_errno(r, "Could not add udev monitor filter: %m");
250
251         r = udev_monitor_enable_receiving(m->udev_monitor);
252         if (r < 0) {
253                 log_error("Could not enable udev monitor");
254                 return r;
255         }
256
257         r = sd_event_add_io(m->event,
258                         &m->udev_event_source,
259                         udev_monitor_get_fd(m->udev_monitor),
260                         EPOLLIN, manager_dispatch_link_udev,
261                         m);
262         if (r < 0)
263                 return r;
264
265         r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
266         if (r < 0)
267                 return r;
268
269         return 0;
270 }
271
272 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
273         Manager *m = userdata;
274         Link *link = NULL;
275         NetDev *netdev = NULL;
276         uint16_t type;
277         const char *name;
278         int r, ifindex;
279
280         assert(rtnl);
281         assert(message);
282         assert(m);
283
284         if (sd_rtnl_message_is_error(message)) {
285                 r = sd_rtnl_message_get_errno(message);
286                 if (r < 0)
287                         log_warning_errno(r, "rtnl: could not receive link: %m");
288
289                 return 0;
290         }
291
292         r = sd_rtnl_message_get_type(message, &type);
293         if (r < 0) {
294                 log_warning_errno(r, "rtnl: could not get message type: %m");
295                 return 0;
296         }
297
298         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
299         if (r < 0) {
300                 log_warning_errno(r, "rtnl: could not get ifindex: %m");
301                 return 0;
302         } else if (ifindex <= 0) {
303                 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
304                 return 0;
305         } else
306                 link_get(m, ifindex, &link);
307
308         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
309         if (r < 0) {
310                 log_warning_errno(r, "rtnl: received link message without ifname: %m");
311                 return 0;
312         } else
313                 netdev_get(m, name, &netdev);
314
315         switch (type) {
316         case RTM_NEWLINK:
317                 if (!link) {
318                         /* link is new, so add it */
319                         r = link_add(m, message, &link);
320                         if (r < 0) {
321                                 log_warning_errno(r, "could not add new link: %m");
322                                 return 0;
323                         }
324                 }
325
326                 if (netdev) {
327                         /* netdev exists, so make sure the ifindex matches */
328                         r = netdev_set_ifindex(netdev, message);
329                         if (r < 0) {
330                                 log_warning_errno(r, "could not set ifindex on netdev: %m");
331                                 return 0;
332                         }
333                 }
334
335                 r = link_update(link, message);
336                 if (r < 0)
337                         return 0;
338
339                 break;
340
341         case RTM_DELLINK:
342                 link_drop(link);
343                 netdev_drop(netdev);
344
345                 break;
346
347         default:
348                 assert_not_reached("Received invalid RTNL message type.");
349         }
350
351         return 1;
352 }
353
354 static int systemd_netlink_fd(void) {
355         int n, fd, rtnl_fd = -EINVAL;
356
357         n = sd_listen_fds(true);
358         if (n <= 0)
359                 return -EINVAL;
360
361         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
362                 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
363                         if (rtnl_fd >= 0)
364                                 return -EINVAL;
365
366                         rtnl_fd = fd;
367                 }
368         }
369
370         return rtnl_fd;
371 }
372
373 static int manager_connect_rtnl(Manager *m) {
374         int fd, r;
375
376         assert(m);
377
378         fd = systemd_netlink_fd();
379         if (fd < 0)
380                 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
381         else
382                 r = sd_rtnl_open_fd(&m->rtnl, fd, 0);
383         if (r < 0)
384                 return r;
385
386         r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
387         if (r < 0)
388                 return r;
389
390         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
391         if (r < 0)
392                 return r;
393
394         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
395         if (r < 0)
396                 return r;
397
398         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
399         if (r < 0)
400                 return r;
401
402         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
403         if (r < 0)
404                 return r;
405
406         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
407         if (r < 0)
408                 return r;
409
410         return 0;
411 }
412
413 int manager_new(Manager **ret) {
414         _cleanup_manager_free_ Manager *m = NULL;
415         int r;
416
417         m = new0(Manager, 1);
418         if (!m)
419                 return -ENOMEM;
420
421         m->state_file = strdup("/run/systemd/netif/state");
422         if (!m->state_file)
423                 return -ENOMEM;
424
425         r = sd_event_default(&m->event);
426         if (r < 0)
427                 return r;
428
429         sd_event_set_watchdog(m->event, true);
430
431         sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
432         sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
433
434         r = manager_connect_rtnl(m);
435         if (r < 0)
436                 return r;
437
438         r = manager_connect_udev(m);
439         if (r < 0)
440                 return r;
441
442         m->netdevs = hashmap_new(&string_hash_ops);
443         if (!m->netdevs)
444                 return -ENOMEM;
445
446         LIST_HEAD_INIT(m->networks);
447
448         r = setup_default_address_pool(m);
449         if (r < 0)
450                 return r;
451
452         *ret = m;
453         m = NULL;
454
455         return 0;
456 }
457
458 void manager_free(Manager *m) {
459         Network *network;
460         NetDev *netdev;
461         Link *link;
462         AddressPool *pool;
463
464         if (!m)
465                 return;
466
467         free(m->state_file);
468
469         udev_monitor_unref(m->udev_monitor);
470         udev_unref(m->udev);
471         sd_bus_unref(m->bus);
472         sd_bus_slot_unref(m->prepare_for_sleep_slot);
473         sd_event_source_unref(m->udev_event_source);
474         sd_event_source_unref(m->bus_retry_event_source);
475         sd_event_unref(m->event);
476
477         while ((link = hashmap_first(m->links)))
478                 link_unref(link);
479         hashmap_free(m->links);
480
481         while ((network = m->networks))
482                 network_free(network);
483
484         while ((netdev = hashmap_first(m->netdevs)))
485                 netdev_unref(netdev);
486         hashmap_free(m->netdevs);
487
488         while ((pool = m->address_pools))
489                 address_pool_free(pool);
490
491         sd_rtnl_unref(m->rtnl);
492
493         free(m);
494 }
495
496 static bool manager_check_idle(void *userdata) {
497         Manager *m = userdata;
498         Link *link;
499         Iterator i;
500
501         assert(m);
502
503         HASHMAP_FOREACH(link, m->links, i) {
504                 /* we are not woken on udev activity, so let's just wait for the
505                  * pending udev event */
506                 if (link->state == LINK_STATE_PENDING)
507                         return false;
508
509                 if (!link->network)
510                         continue;
511
512                 /* we are not woken on netork activity, so let's stay around */
513                 if (link_lldp_enabled(link) ||
514                     link_ipv4ll_enabled(link) ||
515                     link_dhcp4_server_enabled(link) ||
516                     link_dhcp4_enabled(link) ||
517                     link_dhcp6_enabled(link))
518                         return false;
519         }
520
521         return true;
522 }
523
524 int manager_run(Manager *m) {
525         assert(m);
526
527         return bus_event_loop_with_idle(
528                         m->event,
529                         m->bus,
530                         "org.freedesktop.network1",
531                         DEFAULT_EXIT_USEC,
532                         manager_check_idle,
533                         m);
534 }
535
536 int manager_load_config(Manager *m) {
537         int r;
538
539         /* update timestamp */
540         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
541
542         r = netdev_load(m);
543         if (r < 0)
544                 return r;
545
546         r = network_load(m);
547         if (r < 0)
548                 return r;
549
550         return 0;
551 }
552
553 bool manager_should_reload(Manager *m) {
554         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
555 }
556
557 int manager_rtnl_enumerate_links(Manager *m) {
558         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
559         sd_rtnl_message *link;
560         int r;
561
562         assert(m);
563         assert(m->rtnl);
564
565         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
566         if (r < 0)
567                 return r;
568
569         r = sd_rtnl_message_request_dump(req, true);
570         if (r < 0)
571                 return r;
572
573         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
574         if (r < 0)
575                 return r;
576
577         for (link = reply; link; link = sd_rtnl_message_next(link)) {
578                 int k;
579
580                 m->enumerating = true;
581
582                 k = manager_rtnl_process_link(m->rtnl, link, m);
583                 if (k < 0)
584                         r = k;
585
586                 m->enumerating = false;
587         }
588
589         return r;
590 }
591
592 int manager_rtnl_enumerate_addresses(Manager *m) {
593         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
594         sd_rtnl_message *addr;
595         int r;
596
597         assert(m);
598         assert(m->rtnl);
599
600         r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
601         if (r < 0)
602                 return r;
603
604         r = sd_rtnl_message_request_dump(req, true);
605         if (r < 0)
606                 return r;
607
608         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
609         if (r < 0)
610                 return r;
611
612         for (addr = reply; addr; addr = sd_rtnl_message_next(addr)) {
613                 int k;
614
615                 m->enumerating = true;
616
617                 k = link_rtnl_process_address(m->rtnl, addr, m);
618                 if (k < 0)
619                         r = k;
620
621                 m->enumerating = false;
622         }
623
624         return r;
625 }
626
627 static int set_put_in_addr(Set *s, const struct in_addr *address) {
628         char *p;
629         int r;
630
631         assert(s);
632
633         r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
634         if (r < 0)
635                 return r;
636
637         r = set_consume(s, p);
638         if (r == -EEXIST)
639                 return 0;
640
641         return r;
642 }
643
644 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
645         int r, i, c = 0;
646
647         assert(s);
648         assert(n <= 0 || addresses);
649
650         for (i = 0; i < n; i++) {
651                 r = set_put_in_addr(s, addresses+i);
652                 if (r < 0)
653                         return r;
654
655                 c += r;
656         }
657
658         return c;
659 }
660
661 static void print_string_set(FILE *f, const char *field, Set *s) {
662         bool space = false;
663         Iterator i;
664         char *p;
665
666         if (set_isempty(s))
667                 return;
668
669         fputs(field, f);
670
671         SET_FOREACH(p, s, i) {
672                 if (space)
673                         fputc(' ', f);
674                 fputs(p, f);
675                 space = true;
676         }
677         fputc('\n', f);
678 }
679
680 int manager_save(Manager *m) {
681         _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
682         Link *link;
683         Iterator i;
684         _cleanup_free_ char *temp_path = NULL;
685         _cleanup_fclose_ FILE *f = NULL;
686         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
687         const char *operstate_str;
688         int r;
689
690         assert(m);
691         assert(m->state_file);
692
693         /* We add all NTP and DNS server to a set, to filter out duplicates */
694         dns = set_new(&string_hash_ops);
695         if (!dns)
696                 return -ENOMEM;
697
698         ntp = set_new(&string_hash_ops);
699         if (!ntp)
700                 return -ENOMEM;
701
702         domains = set_new(&string_hash_ops);
703         if (!domains)
704                 return -ENOMEM;
705
706         HASHMAP_FOREACH(link, m->links, i) {
707                 if (link->flags & IFF_LOOPBACK)
708                         continue;
709
710                 if (link->operstate > operstate)
711                         operstate = link->operstate;
712
713                 if (!link->network)
714                         continue;
715
716                 /* First add the static configured entries */
717                 r = set_put_strdupv(dns, link->network->dns);
718                 if (r < 0)
719                         return r;
720
721                 r = set_put_strdupv(ntp, link->network->ntp);
722                 if (r < 0)
723                         return r;
724
725                 r = set_put_strdupv(domains, link->network->domains);
726                 if (r < 0)
727                         return r;
728
729                 if (!link->dhcp_lease)
730                         continue;
731
732                 /* Secondly, add the entries acquired via DHCP */
733                 if (link->network->dhcp_dns) {
734                         const struct in_addr *addresses;
735
736                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
737                         if (r > 0) {
738                                 r = set_put_in_addrv(dns, addresses, r);
739                                 if (r < 0)
740                                         return r;
741                         } else if (r < 0 && r != -ENOENT)
742                                 return r;
743                 }
744
745                 if (link->network->dhcp_ntp) {
746                         const struct in_addr *addresses;
747
748                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
749                         if (r > 0) {
750                                 r = set_put_in_addrv(ntp, addresses, r);
751                                 if (r < 0)
752                                         return r;
753                         } else if (r < 0 && r != -ENOENT)
754                                 return r;
755                 }
756
757                 if (link->network->dhcp_domains) {
758                         const char *domainname;
759
760                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
761                         if (r >= 0) {
762                                 r = set_put_strdup(domains, domainname);
763                                 if (r < 0)
764                                         return r;
765                         } else if (r != -ENOENT)
766                                 return r;
767                 }
768         }
769
770         operstate_str = link_operstate_to_string(operstate);
771         assert(operstate_str);
772
773         r = fopen_temporary(m->state_file, &f, &temp_path);
774         if (r < 0)
775                 return r;
776
777         fchmod(fileno(f), 0644);
778
779         fprintf(f,
780                 "# This is private data. Do not parse.\n"
781                 "OPER_STATE=%s\n", operstate_str);
782
783         print_string_set(f, "DNS=", dns);
784         print_string_set(f, "NTP=", ntp);
785         print_string_set(f, "DOMAINS=", domains);
786
787         r = fflush_and_check(f);
788         if (r < 0)
789                 goto fail;
790
791         if (rename(temp_path, m->state_file) < 0) {
792                 r = -errno;
793                 goto fail;
794         }
795
796         if (m->operational_state != operstate) {
797                 m->operational_state = operstate;
798                 r = manager_send_changed(m, "OperationalState", NULL);
799                 if (r < 0)
800                         log_error_errno(r, "Could not emit changed OperationalState: %m");
801         }
802
803         return 0;
804
805 fail:
806         log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
807         unlink(m->state_file);
808         unlink(temp_path);
809         return r;
810 }
811
812 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
813         AddressPool *p;
814         int r;
815
816         assert(m);
817         assert(prefixlen > 0);
818         assert(found);
819
820         LIST_FOREACH(address_pools, p, m->address_pools) {
821                 if (p->family != family)
822                         continue;
823
824                 r = address_pool_acquire(p, prefixlen, found);
825                 if (r != 0)
826                         return r;
827         }
828
829         return 0;
830 }
831
832 const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
833         if (b == ADDRESS_FAMILY_YES ||
834             b == ADDRESS_FAMILY_NO)
835                 return yes_no(b == ADDRESS_FAMILY_YES);
836
837         if (b == ADDRESS_FAMILY_IPV4)
838                 return "ipv4";
839         if (b == ADDRESS_FAMILY_IPV6)
840                 return "ipv6";
841
842         return NULL;
843 }
844
845 AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
846         int r;
847
848         /* Make this a true superset of a boolean */
849
850         r = parse_boolean(s);
851         if (r > 0)
852                 return ADDRESS_FAMILY_YES;
853         if (r == 0)
854                 return ADDRESS_FAMILY_NO;
855
856         if (streq(s, "ipv4"))
857                 return ADDRESS_FAMILY_IPV4;
858         if (streq(s, "ipv6"))
859                 return ADDRESS_FAMILY_IPV6;
860
861         return _ADDRESS_FAMILY_BOOLEAN_INVALID;
862 }
863
864 DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_boolean, address_family_boolean, AddressFamilyBoolean, "Failed to parse option");