chiark / gitweb /
c4a325de426c119b558caac00d965a25aabc9cf1
[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 #include <libkmod.h>
25
26 #include "conf-parser.h"
27 #include "path-util.h"
28 #include "networkd.h"
29 #include "network-internal.h"
30 #include "libudev-private.h"
31 #include "udev-util.h"
32 #include "rtnl-util.h"
33 #include "mkdir.h"
34 #include "virt.h"
35
36 #include "sd-rtnl.h"
37
38 const char* const network_dirs[] = {
39         "/etc/systemd/network",
40         "/run/systemd/network",
41         "/usr/lib/systemd/network",
42 #ifdef HAVE_SPLIT_USR
43         "/lib/systemd/network",
44 #endif
45         NULL};
46
47 static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
48         Manager *m = userdata;
49
50         assert(m);
51
52         log_received_signal(LOG_INFO, si);
53
54         sd_event_exit(m->event, 0);
55         return 0;
56 }
57
58 static int setup_signals(Manager *m) {
59         sigset_t mask;
60         int r;
61
62         assert(m);
63
64         assert_se(sigemptyset(&mask) == 0);
65         sigset_add_many(&mask, SIGINT, SIGTERM, -1);
66         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
67
68         r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
69         if (r < 0)
70                 return r;
71
72         r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
73         if (r < 0)
74                 return r;
75
76         return 0;
77 }
78
79 int manager_new(Manager **ret) {
80         _cleanup_manager_free_ Manager *m = NULL;
81         int r;
82
83         m = new0(Manager, 1);
84         if (!m)
85                 return -ENOMEM;
86
87         m->state_file = strdup("/run/systemd/network/state");
88         if (!m->state_file)
89                 return -ENOMEM;
90
91         r = sd_event_default(&m->event);
92         if (r < 0)
93                 return r;
94
95         sd_event_set_watchdog(m->event, true);
96
97         r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
98                          RTNLGRP_IPV6_IFADDR);
99         if (r < 0)
100                 return r;
101
102         r = sd_bus_default_system(&m->bus);
103         if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
104                 return r;
105
106         r = setup_signals(m);
107         if (r < 0)
108                 return r;
109
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();
115                 if (!m->udev)
116                         return -ENOMEM;
117
118                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
119                 if (!m->udev_monitor)
120                         return -ENOMEM;
121         }
122
123         m->kmod_ctx = kmod_new(NULL, NULL);
124         if (!m->kmod_ctx)
125                 return -ENOMEM;
126
127         m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
128         if (!m->links)
129                 return -ENOMEM;
130
131         m->netdevs = hashmap_new(string_hash_func, string_compare_func);
132         if (!m->netdevs)
133                 return -ENOMEM;
134
135         LIST_HEAD_INIT(m->networks);
136
137         *ret = m;
138         m = NULL;
139
140         return 0;
141 }
142
143 void manager_free(Manager *m) {
144         Network *network;
145         NetDev *netdev;
146         Link *link;
147
148         if (!m)
149                 return;
150
151         free(m->state_file);
152
153         kmod_unref(m->kmod_ctx);
154         udev_monitor_unref(m->udev_monitor);
155         udev_unref(m->udev);
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);
161
162         while ((link = hashmap_first(m->links)))
163                 link_unref(link);
164         hashmap_free(m->links);
165
166         while ((network = m->networks))
167                 network_free(network);
168
169         while ((netdev = hashmap_first(m->netdevs)))
170                 netdev_unref(netdev);
171         hashmap_free(m->netdevs);
172
173         sd_rtnl_unref(m->rtnl);
174
175         free(m);
176 }
177
178 int manager_load_config(Manager *m) {
179         int r;
180
181         /* update timestamp */
182         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
183
184         r = netdev_load(m);
185         if (r < 0)
186                 return r;
187
188         r = network_load(m);
189         if (r < 0)
190                 return r;
191
192         return 0;
193 }
194
195 bool manager_should_reload(Manager *m) {
196         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
197 }
198
199 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
200         Link *link = NULL;
201         int r, ifindex;
202
203         assert(m);
204         assert(device);
205
206         if (!streq_ptr(udev_device_get_action(device), "add"))
207                 return 0;
208
209         ifindex = udev_device_get_ifindex(device);
210         if (ifindex <= 0) {
211                 log_debug("ignoring udev ADD event for device with invalid ifindex");
212                 return 0;
213         }
214
215         r = link_get(m, ifindex, &link);
216         if (r == -ENODEV)
217                 return 0;
218         else if (r < 0)
219                 return r;
220
221         r = link_initialized(link, device);
222         if (r < 0)
223                 return r;
224
225         return 0;
226 }
227
228 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
229         Manager *m = userdata;
230         Link *link = NULL;
231         NetDev *netdev = NULL;
232         uint16_t type;
233         char *name;
234         int r, ifindex;
235
236         assert(rtnl);
237         assert(message);
238         assert(m);
239
240         r = sd_rtnl_message_get_type(message, &type);
241         if (r < 0) {
242                 log_warning("rtnl: could not get message type");
243                 return 0;
244         }
245
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");
249                 return 0;
250         } else
251                 link_get(m, ifindex, &link);
252
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");
256                 return 0;
257         } else
258                 netdev_get(m, name, &netdev);
259
260         switch (type) {
261         case RTM_NEWLINK:
262                 if (!link) {
263                         /* link is new, so add it */
264                         r = link_add(m, message, &link);
265                         if (r < 0) {
266                                 log_debug("could not add new link");
267                                 return 0;
268                         }
269                 }
270
271                 if (netdev) {
272                         /* netdev exists, so make sure the ifindex matches */
273                         r = netdev_set_ifindex(netdev, message);
274                         if (r < 0) {
275                                 log_debug("could not set ifindex on netdev");
276                                 return 0;
277                         }
278                 }
279
280                 r = link_update(link, message);
281                 if (r < 0)
282                         return 0;
283
284                 break;
285
286         case RTM_DELLINK:
287                 link_drop(link);
288                 netdev_drop(netdev);
289
290                 break;
291
292         default:
293                 assert_not_reached("Received invalid RTNL message type.");
294         }
295
296         return 1;
297 }
298
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;
302         int r, k;
303
304         assert(m);
305         assert(m->rtnl);
306
307         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
308         if (r < 0)
309                 return r;
310
311         r = sd_rtnl_message_request_dump(req, true);
312         if (r < 0)
313                 return r;
314
315         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
316         if (r < 0)
317                 return r;
318
319         for (link = reply; link; link = sd_rtnl_message_next(link)) {
320                 uint16_t type;
321
322                 k = sd_rtnl_message_get_type(link, &type);
323                 if (k < 0)
324                         return k;
325
326                 if (type != RTM_NEWLINK)
327                         continue;
328
329                 k = manager_rtnl_process_link(m->rtnl, link, m);
330                 if (k < 0)
331                         r = k;
332         }
333
334         return r;
335 }
336
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;
341
342         device = udev_monitor_receive_device(monitor);
343         if (!device)
344                 return -ENOMEM;
345
346         manager_udev_process_link(m, device);
347         return 0;
348 }
349
350 int manager_udev_listen(Manager *m) {
351         int r;
352
353         if (detect_container(NULL) > 0)
354                 return 0;
355
356         assert(m->udev_monitor);
357
358         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
359         if (r < 0) {
360                 log_error("Could not add udev monitor filter: %s", strerror(-r));
361                 return r;
362         }
363
364         r = udev_monitor_enable_receiving(m->udev_monitor);
365         if (r < 0) {
366                 log_error("Could not enable udev monitor");
367                 return r;
368         }
369
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,
374                         m);
375         if (r < 0)
376                 return r;
377
378         return 0;
379 }
380
381 int manager_rtnl_listen(Manager *m) {
382         int r;
383
384         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
385         if (r < 0)
386                 return r;
387
388         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
389         if (r < 0)
390                 return r;
391
392         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
393         if (r < 0)
394                 return r;
395
396         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
397         if (r < 0)
398                 return r;
399
400         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
401         if (r < 0)
402                 return r;
403
404         return 0;
405 }
406
407 int manager_bus_listen(Manager *m) {
408         int r;
409
410         assert(m->event);
411
412         if (!m->bus) /* TODO: drop when we can rely on kdbus */
413                 return 0;
414
415         r = sd_bus_attach_event(m->bus, m->event, 0);
416         if (r < 0)
417                 return r;
418
419         return 0;
420 }
421
422 int manager_save(Manager *m) {
423         Link *link;
424         Iterator i;
425         _cleanup_free_ char *temp_path = NULL;
426         _cleanup_fclose_ FILE *f = NULL;
427         LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
428         const char *operstate_str;
429         int r;
430
431         assert(m);
432         assert(m->state_file);
433
434         HASHMAP_FOREACH(link, m->links, i) {
435                 if (link->flags & IFF_LOOPBACK)
436                         continue;
437
438                 if (link->operstate > operstate)
439                         operstate = link->operstate;
440         }
441
442         operstate_str = link_operstate_to_string(operstate);
443         assert(operstate_str);
444
445         r = fopen_temporary(m->state_file, &f, &temp_path);
446         if (r < 0)
447                 goto finish;
448
449         fchmod(fileno(f), 0644);
450
451         fprintf(f,
452                 "# This is private data. Do not parse.\n"
453                 "OPER_STATE=%s\n", operstate_str);
454
455         fflush(f);
456
457         if (ferror(f) || rename(temp_path, m->state_file) < 0) {
458                 r = -errno;
459                 unlink(m->state_file);
460                 unlink(temp_path);
461         }
462
463 finish:
464         if (r < 0)
465                 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
466
467         return r;
468 }