1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
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.
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.
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/>.
22 #include <sys/socket.h>
25 #include "conf-parser.h"
26 #include "path-util.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"
39 /* use 8 MB for receive socket kernel queue. */
40 #define RCVBUF_SIZE (8*1024*1024)
42 const char* const network_dirs[] = {
43 "/etc/systemd/network",
44 "/run/systemd/network",
45 "/usr/lib/systemd/network",
47 "/lib/systemd/network",
51 static int setup_default_address_pool(Manager *m) {
57 /* Add in the well-known private address ranges. */
59 r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
63 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
67 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
71 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
78 int manager_new(Manager **ret) {
79 _cleanup_manager_free_ Manager *m = NULL;
86 m->state_file = strdup("/run/systemd/netif/state");
90 r = sd_event_default(&m->event);
94 sd_event_set_watchdog(m->event, true);
96 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
97 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
99 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
100 RTNLGRP_IPV6_IFADDR);
104 r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
108 r = sd_bus_default_system(&m->bus);
109 if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
112 /* udev does not initialize devices inside containers,
113 * so we rely on them being already initialized before
114 * entering the container */
115 if (detect_container(NULL) <= 0) {
116 m->udev = udev_new();
120 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
121 if (!m->udev_monitor)
125 m->netdevs = hashmap_new(&string_hash_ops);
129 LIST_HEAD_INIT(m->networks);
131 r = setup_default_address_pool(m);
141 void manager_free(Manager *m) {
152 udev_monitor_unref(m->udev_monitor);
154 sd_bus_unref(m->bus);
155 sd_event_source_unref(m->udev_event_source);
156 sd_event_unref(m->event);
158 while ((link = hashmap_first(m->links)))
160 hashmap_free(m->links);
162 while ((network = m->networks))
163 network_free(network);
165 while ((netdev = hashmap_first(m->netdevs)))
166 netdev_unref(netdev);
167 hashmap_free(m->netdevs);
169 while ((pool = m->address_pools))
170 address_pool_free(pool);
172 sd_rtnl_unref(m->rtnl);
177 int manager_load_config(Manager *m) {
180 /* update timestamp */
181 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
194 bool manager_should_reload(Manager *m) {
195 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
198 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
205 if (!streq_ptr(udev_device_get_action(device), "add"))
208 ifindex = udev_device_get_ifindex(device);
210 log_debug("ignoring udev ADD event for device with invalid ifindex");
214 r = link_get(m, ifindex, &link);
220 r = link_initialized(link, device);
227 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
228 Manager *m = userdata;
230 NetDev *netdev = NULL;
239 r = sd_rtnl_message_get_type(message, &type);
241 log_warning("rtnl: could not get message type");
245 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
246 if (r < 0 || ifindex <= 0) {
247 log_warning("rtnl: received link message without valid ifindex");
250 link_get(m, ifindex, &link);
252 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
253 if (r < 0 || !name) {
254 log_warning("rtnl: received link message without valid ifname");
257 netdev_get(m, name, &netdev);
262 /* link is new, so add it */
263 r = link_add(m, message, &link);
265 log_debug_errno(r, "could not add new link: %m");
271 /* netdev exists, so make sure the ifindex matches */
272 r = netdev_set_ifindex(netdev, message);
274 log_debug("could not set ifindex on netdev");
279 r = link_update(link, message);
292 assert_not_reached("Received invalid RTNL message type.");
298 int manager_rtnl_enumerate_links(Manager *m) {
299 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
300 sd_rtnl_message *link;
306 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
310 r = sd_rtnl_message_request_dump(req, true);
314 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
318 for (link = reply; link; link = sd_rtnl_message_next(link)) {
321 k = sd_rtnl_message_get_type(link, &type);
325 if (type != RTM_NEWLINK)
328 k = manager_rtnl_process_link(m->rtnl, link, m);
336 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
337 Manager *m = userdata;
338 struct udev_monitor *monitor = m->udev_monitor;
339 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
341 device = udev_monitor_receive_device(monitor);
345 manager_udev_process_link(m, device);
349 int manager_udev_listen(Manager *m) {
352 if (detect_container(NULL) > 0)
355 assert(m->udev_monitor);
357 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
359 return log_error_errno(r, "Could not add udev monitor filter: %m");
361 r = udev_monitor_enable_receiving(m->udev_monitor);
363 log_error("Could not enable udev monitor");
367 r = sd_event_add_io(m->event,
368 &m->udev_event_source,
369 udev_monitor_get_fd(m->udev_monitor),
370 EPOLLIN, manager_dispatch_link_udev,
375 r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
382 int manager_rtnl_listen(Manager *m) {
387 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
391 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
395 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
399 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
403 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
410 int manager_bus_listen(Manager *m) {
415 if (!m->bus) /* TODO: drop when we can rely on kdbus */
418 r = sd_bus_attach_event(m->bus, m->event, 0);
425 static int set_put_in_addr(Set *s, const struct in_addr *address) {
431 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
435 r = set_consume(s, p);
442 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
446 assert(n <= 0 || addresses);
448 for (i = 0; i < n; i++) {
449 r = set_put_in_addr(s, addresses+i);
459 static void print_string_set(FILE *f, const char *field, Set *s) {
469 SET_FOREACH(p, s, i) {
478 int manager_save(Manager *m) {
479 _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
482 _cleanup_free_ char *temp_path = NULL;
483 _cleanup_fclose_ FILE *f = NULL;
484 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
485 const char *operstate_str;
489 assert(m->state_file);
491 /* We add all NTP and DNS server to a set, to filter out duplicates */
492 dns = set_new(&string_hash_ops);
496 ntp = set_new(&string_hash_ops);
500 domains = set_new(&string_hash_ops);
504 HASHMAP_FOREACH(link, m->links, i) {
505 if (link->flags & IFF_LOOPBACK)
508 if (link->operstate > operstate)
509 operstate = link->operstate;
514 /* First add the static configured entries */
515 r = set_put_strdupv(dns, link->network->dns);
519 r = set_put_strdupv(ntp, link->network->ntp);
523 r = set_put_strdupv(domains, link->network->domains);
527 if (!link->dhcp_lease)
530 /* Secondly, add the entries acquired via DHCP */
531 if (link->network->dhcp_dns) {
532 const struct in_addr *addresses;
534 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
536 r = set_put_in_addrv(dns, addresses, r);
539 } else if (r < 0 && r != -ENOENT)
543 if (link->network->dhcp_ntp) {
544 const struct in_addr *addresses;
546 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
548 r = set_put_in_addrv(ntp, addresses, r);
551 } else if (r < 0 && r != -ENOENT)
555 if (link->network->dhcp_domains) {
556 const char *domainname;
558 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
560 r = set_put_strdup(domains, domainname);
563 } else if (r != -ENOENT)
568 operstate_str = link_operstate_to_string(operstate);
569 assert(operstate_str);
571 r = fopen_temporary(m->state_file, &f, &temp_path);
575 fchmod(fileno(f), 0644);
578 "# This is private data. Do not parse.\n"
579 "OPER_STATE=%s\n", operstate_str);
581 print_string_set(f, "DNS=", dns);
582 print_string_set(f, "NTP=", ntp);
583 print_string_set(f, "DOMAINS=", domains);
585 r = fflush_and_check(f);
589 if (rename(temp_path, m->state_file) < 0) {
597 log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
598 unlink(m->state_file);
603 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
608 assert(prefixlen > 0);
611 LIST_FOREACH(address_pools, p, m->address_pools) {
612 if (p->family != family)
615 r = address_pool_acquire(p, prefixlen, found);