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/>.
25 #include "path-util.h"
27 #include "libudev-private.h"
28 #include "udev-util.h"
29 #include "rtnl-util.h"
35 const char* const network_dirs[] = {
36 "/etc/systemd/network",
37 "/run/systemd/network",
38 "/usr/lib/systemd/network",
40 "/lib/systemd/network",
44 static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
45 Manager *m = userdata;
49 log_received_signal(LOG_INFO, si);
51 sd_event_exit(m->event, 0);
55 static int setup_signals(Manager *m) {
61 assert_se(sigemptyset(&mask) == 0);
62 sigset_add_many(&mask, SIGINT, SIGTERM, -1);
63 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
65 r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
69 r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
76 int manager_new(Manager **ret) {
77 _cleanup_manager_free_ Manager *m = NULL;
84 m->state_file = strdup("/run/systemd/network/state");
88 r = sd_event_default(&m->event);
92 sd_event_set_watchdog(m->event, true);
94 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
99 r = sd_bus_default_system(&m->bus);
100 if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
103 r = setup_signals(m);
107 /* udev does not initialize devices inside containers,
108 * so we rely on them being already initialized before
109 * entering the container */
110 if (detect_container(NULL) <= 0) {
111 m->udev = udev_new();
115 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
116 if (!m->udev_monitor)
120 m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
124 m->netdevs = hashmap_new(string_hash_func, string_compare_func);
128 LIST_HEAD_INIT(m->networks);
136 void manager_free(Manager *m) {
146 udev_monitor_unref(m->udev_monitor);
148 sd_bus_unref(m->bus);
149 sd_event_source_unref(m->udev_event_source);
150 sd_event_source_unref(m->sigterm_event_source);
151 sd_event_source_unref(m->sigint_event_source);
152 sd_event_unref(m->event);
154 while ((link = hashmap_first(m->links)))
156 hashmap_free(m->links);
158 while ((network = m->networks))
159 network_free(network);
161 while ((netdev = hashmap_first(m->netdevs)))
162 netdev_unref(netdev);
163 hashmap_free(m->netdevs);
165 sd_rtnl_unref(m->rtnl);
170 int manager_load_config(Manager *m) {
173 /* update timestamp */
174 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
187 bool manager_should_reload(Manager *m) {
188 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
191 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
198 if (!streq_ptr(udev_device_get_action(device), "add"))
201 ifindex = udev_device_get_ifindex(device);
203 log_debug("ignoring udev ADD event for device with invalid ifindex");
207 r = link_get(m, ifindex, &link);
213 r = link_initialized(link, device);
220 static int manager_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
221 Manager *m = userdata;
224 _cleanup_address_free_ Address *address = NULL;
225 char buf[INET6_ADDRSTRLEN];
232 r = sd_rtnl_message_get_type(message, &type);
234 log_warning("rtnl: could not get message type");
238 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
239 if (r < 0 || ifindex <= 0) {
240 log_warning("rtnl: received address message without valid ifindix, ignoring");
243 r = link_get(m, ifindex, &link);
244 if (r < 0 || !link) {
245 log_warning("rtnl: received address for non-existing link, ignoring");
250 r = address_new_dynamic(&address);
254 r = sd_rtnl_message_addr_get_family(message, &address->family);
255 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
256 log_warning("rtnl: received address with invalid family, ignoring");
260 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
262 log_warning("rtnl: recevied address with invalid prefixlen, ignoring");
266 switch (address->family) {
268 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
270 log_warning("rtnl: received address without valid address, ignoring");
277 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
279 log_warning("rtnl: received address without valid address, ignoring");
286 assert_not_reached("invalid address family");
289 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
290 log_warning("could not print address");
296 log_info("added address: %s/%u to ifindex %d", buf,
297 address->prefixlen, ifindex);
301 log_info("removed address: %s/%u from ifindex %d", buf,
302 address->prefixlen, ifindex);
305 assert_not_reached("Received invalid RTNL message type");
311 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
312 Manager *m = userdata;
314 NetDev *netdev = NULL;
323 r = sd_rtnl_message_get_type(message, &type);
325 log_warning("rtnl: could not get message type");
329 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
330 if (r < 0 || ifindex <= 0) {
331 log_warning("rtnl: received link message without valid ifindex");
334 link_get(m, ifindex, &link);
336 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
337 if (r < 0 || !name) {
338 log_warning("rtnl: received link message without valid ifname");
341 netdev_get(m, name, &netdev);
346 /* link is new, so add it */
347 r = link_add(m, message, &link);
349 log_debug("could not add new link");
355 /* netdev exists, so make sure the ifindex matches */
356 r = netdev_set_ifindex(netdev, message);
358 log_debug("could not set ifindex on netdev");
363 r = link_update(link, message);
376 assert_not_reached("Received invalid RTNL message type.");
382 int manager_rtnl_enumerate_links(Manager *m) {
383 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
384 sd_rtnl_message *link;
390 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
394 r = sd_rtnl_message_request_dump(req, true);
398 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
402 for (link = reply; link; link = sd_rtnl_message_next(link)) {
405 k = sd_rtnl_message_get_type(link, &type);
409 if (type != RTM_NEWLINK)
412 k = manager_rtnl_process_link(m->rtnl, link, m);
420 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
421 Manager *m = userdata;
422 struct udev_monitor *monitor = m->udev_monitor;
423 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
425 device = udev_monitor_receive_device(monitor);
429 manager_udev_process_link(m, device);
433 int manager_udev_listen(Manager *m) {
436 if (detect_container(NULL) > 0)
439 assert(m->udev_monitor);
441 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
443 log_error("Could not add udev monitor filter: %s", strerror(-r));
447 r = udev_monitor_enable_receiving(m->udev_monitor);
449 log_error("Could not enable udev monitor");
453 r = sd_event_add_io(m->event,
454 &m->udev_event_source,
455 udev_monitor_get_fd(m->udev_monitor),
456 EPOLLIN, manager_dispatch_link_udev,
464 int manager_rtnl_listen(Manager *m) {
467 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
471 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
475 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
479 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
483 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
490 int manager_bus_listen(Manager *m) {
495 if (!m->bus) /* TODO: drop when we can rely on kdbus */
498 r = sd_bus_attach_event(m->bus, m->event, 0);
505 static void append_dns(FILE *f, struct in_addr *dns, unsigned char family, unsigned *count) {
506 char buf[INET6_ADDRSTRLEN];
509 address = inet_ntop(family, dns, buf, INET6_ADDRSTRLEN);
511 log_warning("Invalid DNS address. Ignoring.");
516 fputs("# Too many DNS servers configured, the following entries "
517 "will be ignored\n", f);
519 fprintf(f, "nameserver %s\n", address);
524 int manager_update_resolv_conf(Manager *m) {
525 _cleanup_free_ char *temp_path = NULL;
526 _cleanup_fclose_ FILE *f = NULL;
530 const char *domainname = NULL;
535 r = fopen_temporary("/run/systemd/network/resolv.conf", &f, &temp_path);
539 fchmod(fileno(f), 0644);
541 fputs("# This file is managed by systemd-networkd(8). Do not edit.\n#\n"
542 "# Third party programs must not access this file directly, but\n"
543 "# only through the symlink at /etc/resolv.conf. To manage\n"
544 "# resolv.conf(5) in a different way, replace the symlink by a\n"
545 "# static file or a different symlink.\n\n", f);
547 HASHMAP_FOREACH(link, m->links, i) {
548 if (link->dhcp_lease) {
549 struct in_addr *nameservers;
550 size_t nameservers_size;
552 if (link->network->dhcp_dns) {
553 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &nameservers, &nameservers_size);
557 for (j = 0; j < nameservers_size; j++)
558 append_dns(f, &nameservers[j], AF_INET, &count);
562 if (link->network->dhcp_domainname && !domainname) {
563 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
565 fprintf(f, "domain %s\n", domainname);
570 HASHMAP_FOREACH(link, m->links, i) {
571 if (link->network && link->network->dns) {
575 SET_FOREACH(address, link->network->dns, j) {
576 append_dns(f, &address->in_addr.in,
577 address->family, &count);
584 if (ferror(f) || rename(temp_path, "/run/systemd/network/resolv.conf") < 0) {
586 unlink("/run/systemd/network/resolv.conf");
594 int manager_save(Manager *m) {
597 _cleanup_free_ char *temp_path = NULL;
598 _cleanup_fclose_ FILE *f = NULL;
599 const char *oper_state = "unknown";
600 bool dormant = false, carrier = false;
604 assert(m->state_file);
606 HASHMAP_FOREACH(link, m->links, i) {
607 if (link->flags & IFF_LOOPBACK)
610 if (link_has_carrier(link->flags, link->operstate))
612 else if (link->operstate == IF_OPER_DORMANT)
617 oper_state = "carrier";
619 oper_state = "dormant";
621 r = fopen_temporary(m->state_file, &f, &temp_path);
625 fchmod(fileno(f), 0644);
628 "# This is private data. Do not parse.\n"
629 "OPER_STATE=%s\n", oper_state);
633 if (ferror(f) || rename(temp_path, m->state_file) < 0) {
635 unlink(m->state_file);
641 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));