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>
26 #include "conf-parser.h"
27 #include "path-util.h"
29 #include "network-internal.h"
30 #include "libudev-private.h"
31 #include "udev-util.h"
32 #include "rtnl-util.h"
38 const char* const network_dirs[] = {
39 "/etc/systemd/network",
40 "/run/systemd/network",
41 "/usr/lib/systemd/network",
43 "/lib/systemd/network",
47 static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
48 Manager *m = userdata;
52 log_received_signal(LOG_INFO, si);
54 sd_event_exit(m->event, 0);
58 static int setup_signals(Manager *m) {
64 assert_se(sigemptyset(&mask) == 0);
65 sigset_add_many(&mask, SIGINT, SIGTERM, -1);
66 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
68 r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
72 r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
79 int manager_new(Manager **ret) {
80 _cleanup_manager_free_ Manager *m = NULL;
87 m->state_file = strdup("/run/systemd/network/state");
91 r = sd_event_default(&m->event);
95 sd_event_set_watchdog(m->event, true);
97 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
102 r = sd_bus_default_system(&m->bus);
103 if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
106 r = setup_signals(m);
110 /* udev does not initialize devices inside containers,
111 * so we rely on them being already initialized before
112 * entering the container */
113 if (detect_container(NULL) <= 0) {
114 m->udev = udev_new();
118 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
119 if (!m->udev_monitor)
123 m->kmod_ctx = kmod_new(NULL, NULL);
127 m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
131 m->netdevs = hashmap_new(string_hash_func, string_compare_func);
135 LIST_HEAD_INIT(m->networks);
143 void manager_free(Manager *m) {
153 kmod_unref(m->kmod_ctx);
154 udev_monitor_unref(m->udev_monitor);
156 sd_bus_unref(m->bus);
157 sd_event_source_unref(m->udev_event_source);
158 sd_event_source_unref(m->sigterm_event_source);
159 sd_event_source_unref(m->sigint_event_source);
160 sd_event_unref(m->event);
162 while ((link = hashmap_first(m->links)))
164 hashmap_free(m->links);
166 while ((network = m->networks))
167 network_free(network);
169 while ((netdev = hashmap_first(m->netdevs)))
170 netdev_unref(netdev);
171 hashmap_free(m->netdevs);
173 sd_rtnl_unref(m->rtnl);
178 int manager_load_config(Manager *m) {
181 /* update timestamp */
182 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
195 bool manager_should_reload(Manager *m) {
196 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
199 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
206 if (!streq_ptr(udev_device_get_action(device), "add"))
209 ifindex = udev_device_get_ifindex(device);
211 log_debug("ignoring udev ADD event for device with invalid ifindex");
215 r = link_get(m, ifindex, &link);
221 r = link_initialized(link, device);
228 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
229 Manager *m = userdata;
231 NetDev *netdev = NULL;
240 r = sd_rtnl_message_get_type(message, &type);
242 log_warning("rtnl: could not get message type");
246 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
247 if (r < 0 || ifindex <= 0) {
248 log_warning("rtnl: received link message without valid ifindex");
251 link_get(m, ifindex, &link);
253 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
254 if (r < 0 || !name) {
255 log_warning("rtnl: received link message without valid ifname");
258 netdev_get(m, name, &netdev);
263 /* link is new, so add it */
264 r = link_add(m, message, &link);
266 log_debug("could not add new link");
272 /* netdev exists, so make sure the ifindex matches */
273 r = netdev_set_ifindex(netdev, message);
275 log_debug("could not set ifindex on netdev");
280 r = link_update(link, message);
293 assert_not_reached("Received invalid RTNL message type.");
299 int manager_rtnl_enumerate_links(Manager *m) {
300 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
301 sd_rtnl_message *link;
307 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
311 r = sd_rtnl_message_request_dump(req, true);
315 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
319 for (link = reply; link; link = sd_rtnl_message_next(link)) {
322 k = sd_rtnl_message_get_type(link, &type);
326 if (type != RTM_NEWLINK)
329 k = manager_rtnl_process_link(m->rtnl, link, m);
337 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
338 Manager *m = userdata;
339 struct udev_monitor *monitor = m->udev_monitor;
340 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
342 device = udev_monitor_receive_device(monitor);
346 manager_udev_process_link(m, device);
350 int manager_udev_listen(Manager *m) {
353 if (detect_container(NULL) > 0)
356 assert(m->udev_monitor);
358 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
360 log_error("Could not add udev monitor filter: %s", strerror(-r));
364 r = udev_monitor_enable_receiving(m->udev_monitor);
366 log_error("Could not enable udev monitor");
370 r = sd_event_add_io(m->event,
371 &m->udev_event_source,
372 udev_monitor_get_fd(m->udev_monitor),
373 EPOLLIN, manager_dispatch_link_udev,
381 int manager_rtnl_listen(Manager *m) {
384 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
388 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
392 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
396 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
400 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
407 int manager_bus_listen(Manager *m) {
412 if (!m->bus) /* TODO: drop when we can rely on kdbus */
415 r = sd_bus_attach_event(m->bus, m->event, 0);
422 int manager_save(Manager *m) {
425 _cleanup_free_ char *temp_path = NULL;
426 _cleanup_fclose_ FILE *f = NULL;
427 LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
428 const char *operstate_str;
432 assert(m->state_file);
434 HASHMAP_FOREACH(link, m->links, i) {
435 if (link->flags & IFF_LOOPBACK)
438 if (link->operstate > operstate)
439 operstate = link->operstate;
442 operstate_str = link_operstate_to_string(operstate);
443 assert(operstate_str);
445 r = fopen_temporary(m->state_file, &f, &temp_path);
449 fchmod(fileno(f), 0644);
452 "# This is private data. Do not parse.\n"
453 "OPER_STATE=%s\n", operstate_str);
457 if (ferror(f) || rename(temp_path, m->state_file) < 0) {
459 unlink(m->state_file);
465 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));