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 "network-internal.h"
29 #include "libudev-private.h"
30 #include "udev-util.h"
31 #include "rtnl-util.h"
37 const char* const network_dirs[] = {
38 "/etc/systemd/network",
39 "/run/systemd/network",
40 "/usr/lib/systemd/network",
42 "/lib/systemd/network",
46 static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
47 Manager *m = userdata;
51 log_received_signal(LOG_INFO, si);
53 sd_event_exit(m->event, 0);
57 static int setup_signals(Manager *m) {
63 assert_se(sigemptyset(&mask) == 0);
64 sigset_add_many(&mask, SIGINT, SIGTERM, -1);
65 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
67 r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
71 r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
78 static int setup_default_address_pool(Manager *m) {
84 /* Add in the well-known private address ranges. */
86 r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
90 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
94 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
98 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
105 int manager_new(Manager **ret) {
106 _cleanup_manager_free_ Manager *m = NULL;
109 m = new0(Manager, 1);
113 m->state_file = strdup("/run/systemd/netif/state");
117 r = sd_event_default(&m->event);
121 sd_event_set_watchdog(m->event, true);
123 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
124 RTNLGRP_IPV6_IFADDR);
128 r = sd_bus_default_system(&m->bus);
129 if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
132 r = setup_signals(m);
136 /* udev does not initialize devices inside containers,
137 * so we rely on them being already initialized before
138 * entering the container */
139 if (detect_container(NULL) <= 0) {
140 m->udev = udev_new();
144 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
145 if (!m->udev_monitor)
149 m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
153 m->netdevs = hashmap_new(string_hash_func, string_compare_func);
157 LIST_HEAD_INIT(m->networks);
159 r = setup_default_address_pool(m);
169 void manager_free(Manager *m) {
180 udev_monitor_unref(m->udev_monitor);
182 sd_bus_unref(m->bus);
183 sd_event_source_unref(m->udev_event_source);
184 sd_event_source_unref(m->sigterm_event_source);
185 sd_event_source_unref(m->sigint_event_source);
186 sd_event_unref(m->event);
188 while ((link = hashmap_first(m->links)))
190 hashmap_free(m->links);
192 while ((network = m->networks))
193 network_free(network);
195 while ((netdev = hashmap_first(m->netdevs)))
196 netdev_unref(netdev);
197 hashmap_free(m->netdevs);
199 while ((pool = m->address_pools))
200 address_pool_free(pool);
202 sd_rtnl_unref(m->rtnl);
207 int manager_load_config(Manager *m) {
210 /* update timestamp */
211 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
224 bool manager_should_reload(Manager *m) {
225 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
228 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
235 if (!streq_ptr(udev_device_get_action(device), "add"))
238 ifindex = udev_device_get_ifindex(device);
240 log_debug("ignoring udev ADD event for device with invalid ifindex");
244 r = link_get(m, ifindex, &link);
250 r = link_initialized(link, device);
257 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
258 Manager *m = userdata;
260 NetDev *netdev = NULL;
269 r = sd_rtnl_message_get_type(message, &type);
271 log_warning("rtnl: could not get message type");
275 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
276 if (r < 0 || ifindex <= 0) {
277 log_warning("rtnl: received link message without valid ifindex");
280 link_get(m, ifindex, &link);
282 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
283 if (r < 0 || !name) {
284 log_warning("rtnl: received link message without valid ifname");
287 netdev_get(m, name, &netdev);
292 /* link is new, so add it */
293 r = link_add(m, message, &link);
295 log_debug("could not add new link: %s",
302 /* netdev exists, so make sure the ifindex matches */
303 r = netdev_set_ifindex(netdev, message);
305 log_debug("could not set ifindex on netdev");
310 r = link_update(link, message);
323 assert_not_reached("Received invalid RTNL message type.");
329 int manager_rtnl_enumerate_links(Manager *m) {
330 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
331 sd_rtnl_message *link;
337 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
341 r = sd_rtnl_message_request_dump(req, true);
345 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
349 for (link = reply; link; link = sd_rtnl_message_next(link)) {
352 k = sd_rtnl_message_get_type(link, &type);
356 if (type != RTM_NEWLINK)
359 k = manager_rtnl_process_link(m->rtnl, link, m);
367 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
368 Manager *m = userdata;
369 struct udev_monitor *monitor = m->udev_monitor;
370 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
372 device = udev_monitor_receive_device(monitor);
376 manager_udev_process_link(m, device);
380 int manager_udev_listen(Manager *m) {
383 if (detect_container(NULL) > 0)
386 assert(m->udev_monitor);
388 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
390 log_error("Could not add udev monitor filter: %s", strerror(-r));
394 r = udev_monitor_enable_receiving(m->udev_monitor);
396 log_error("Could not enable udev monitor");
400 r = sd_event_add_io(m->event,
401 &m->udev_event_source,
402 udev_monitor_get_fd(m->udev_monitor),
403 EPOLLIN, manager_dispatch_link_udev,
411 int manager_rtnl_listen(Manager *m) {
416 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
420 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
424 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
428 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
432 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
439 int manager_bus_listen(Manager *m) {
444 if (!m->bus) /* TODO: drop when we can rely on kdbus */
447 r = sd_bus_attach_event(m->bus, m->event, 0);
454 int manager_save(Manager *m) {
457 _cleanup_free_ char *temp_path = NULL;
458 _cleanup_fclose_ FILE *f = NULL;
459 LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
460 const char *operstate_str;
464 assert(m->state_file);
466 HASHMAP_FOREACH(link, m->links, i) {
467 if (link->flags & IFF_LOOPBACK)
470 if (link->operstate > operstate)
471 operstate = link->operstate;
474 operstate_str = link_operstate_to_string(operstate);
475 assert(operstate_str);
477 r = fopen_temporary(m->state_file, &f, &temp_path);
481 fchmod(fileno(f), 0644);
484 "# This is private data. Do not parse.\n"
485 "OPER_STATE=%s\n", operstate_str);
489 if (ferror(f) || rename(temp_path, m->state_file) < 0) {
491 unlink(m->state_file);
497 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
502 int manager_address_pool_acquire(Manager *m, unsigned family, unsigned prefixlen, union in_addr_union *found) {
507 assert(prefixlen > 0);
510 LIST_FOREACH(address_pools, p, m->address_pools) {
511 if (p->family != family)
514 r = address_pool_acquire(p, prefixlen, found);