chiark / gitweb /
networkd: introduce ipip tunnel
[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 <resolv.h>
23 #include <linux/if.h>
24 #include <libkmod.h>
25
26 #include "path-util.h"
27 #include "networkd.h"
28 #include "libudev-private.h"
29 #include "udev-util.h"
30 #include "rtnl-util.h"
31 #include "mkdir.h"
32 #include "virt.h"
33
34 #include "sd-rtnl.h"
35
36 const char* const network_dirs[] = {
37         "/etc/systemd/network",
38         "/run/systemd/network",
39         "/usr/lib/systemd/network",
40 #ifdef HAVE_SPLIT_USR
41         "/lib/systemd/network",
42 #endif
43         NULL};
44
45 static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
46         Manager *m = userdata;
47
48         assert(m);
49
50         log_received_signal(LOG_INFO, si);
51
52         sd_event_exit(m->event, 0);
53         return 0;
54 }
55
56 static int setup_signals(Manager *m) {
57         sigset_t mask;
58         int r;
59
60         assert(m);
61
62         assert_se(sigemptyset(&mask) == 0);
63         sigset_add_many(&mask, SIGINT, SIGTERM, -1);
64         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
65
66         r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
67         if (r < 0)
68                 return r;
69
70         r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
71         if (r < 0)
72                 return r;
73
74         return 0;
75 }
76
77 int manager_new(Manager **ret) {
78         _cleanup_manager_free_ Manager *m = NULL;
79         int r;
80
81         m = new0(Manager, 1);
82         if (!m)
83                 return -ENOMEM;
84
85         m->state_file = strdup("/run/systemd/network/state");
86         if (!m->state_file)
87                 return -ENOMEM;
88
89         r = sd_event_default(&m->event);
90         if (r < 0)
91                 return r;
92
93         sd_event_set_watchdog(m->event, true);
94
95         r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
96                          RTNLGRP_IPV6_IFADDR);
97         if (r < 0)
98                 return r;
99
100         r = sd_bus_default_system(&m->bus);
101         if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
102                 return r;
103
104         r = setup_signals(m);
105         if (r < 0)
106                 return r;
107
108         /* udev does not initialize devices inside containers,
109          * so we rely on them being already initialized before
110          * entering the container */
111         if (detect_container(NULL) <= 0) {
112                 m->udev = udev_new();
113                 if (!m->udev)
114                         return -ENOMEM;
115
116                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
117                 if (!m->udev_monitor)
118                         return -ENOMEM;
119         }
120
121         m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
122         if (!m->links)
123                 return -ENOMEM;
124
125         m->netdevs = hashmap_new(string_hash_func, string_compare_func);
126         if (!m->netdevs)
127                 return -ENOMEM;
128
129         LIST_HEAD_INIT(m->networks);
130
131         *ret = m;
132         m = NULL;
133
134         return 0;
135 }
136
137 void manager_free(Manager *m) {
138         Network *network;
139         NetDev *netdev;
140         Link *link;
141
142         if (!m)
143                 return;
144
145         free(m->state_file);
146
147         udev_monitor_unref(m->udev_monitor);
148         udev_unref(m->udev);
149         sd_bus_unref(m->bus);
150         sd_event_source_unref(m->udev_event_source);
151         sd_event_source_unref(m->sigterm_event_source);
152         sd_event_source_unref(m->sigint_event_source);
153         sd_event_unref(m->event);
154
155         while ((link = hashmap_first(m->links)))
156                 link_unref(link);
157         hashmap_free(m->links);
158
159         while ((network = m->networks))
160                 network_free(network);
161
162         while ((netdev = hashmap_first(m->netdevs)))
163                 netdev_unref(netdev);
164         hashmap_free(m->netdevs);
165
166         sd_rtnl_unref(m->rtnl);
167
168         free(m);
169 }
170
171 int manager_load_config(Manager *m) {
172         int r;
173
174         /* update timestamp */
175         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
176
177         r = netdev_load(m);
178         if (r < 0)
179                 return r;
180
181         r = network_load(m);
182         if (r < 0)
183                 return r;
184
185         return 0;
186 }
187
188 bool manager_should_reload(Manager *m) {
189         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
190 }
191
192 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
193         Link *link = NULL;
194         int r, ifindex;
195
196         assert(m);
197         assert(device);
198
199         if (!streq_ptr(udev_device_get_action(device), "add"))
200                 return 0;
201
202         ifindex = udev_device_get_ifindex(device);
203         if (ifindex <= 0) {
204                 log_debug("ignoring udev ADD event for device with invalid ifindex");
205                 return 0;
206         }
207
208         r = link_get(m, ifindex, &link);
209         if (r == -ENODEV)
210                 return 0;
211         else if (r < 0)
212                 return r;
213
214         r = link_initialized(link, device);
215         if (r < 0)
216                 return r;
217
218         return 0;
219 }
220
221 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
222         Manager *m = userdata;
223         Link *link = NULL;
224         NetDev *netdev = NULL;
225         uint16_t type;
226         char *name;
227         int r, ifindex;
228
229         assert(rtnl);
230         assert(message);
231         assert(m);
232
233         r = sd_rtnl_message_get_type(message, &type);
234         if (r < 0) {
235                 log_warning("rtnl: could not get message type");
236                 return 0;
237         }
238
239         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
240         if (r < 0 || ifindex <= 0) {
241                 log_warning("rtnl: received link message without valid ifindex");
242                 return 0;
243         } else
244                 link_get(m, ifindex, &link);
245
246         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
247         if (r < 0 || !name) {
248                 log_warning("rtnl: received link message without valid ifname");
249                 return 0;
250         } else
251                 netdev_get(m, name, &netdev);
252
253         switch (type) {
254         case RTM_NEWLINK:
255                 if (!link) {
256                         /* link is new, so add it */
257                         r = link_add(m, message, &link);
258                         if (r < 0) {
259                                 log_debug("could not add new link");
260                                 return 0;
261                         }
262                 }
263
264                 if (netdev) {
265                         /* netdev exists, so make sure the ifindex matches */
266                         r = netdev_set_ifindex(netdev, message);
267                         if (r < 0) {
268                                 log_debug("could not set ifindex on netdev");
269                                 return 0;
270                         }
271                 }
272
273                 r = link_update(link, message);
274                 if (r < 0)
275                         return 0;
276
277                 break;
278
279         case RTM_DELLINK:
280                 link_drop(link);
281                 netdev_drop(netdev);
282
283                 break;
284
285         default:
286                 assert_not_reached("Received invalid RTNL message type.");
287         }
288
289         return 1;
290 }
291
292 int manager_rtnl_enumerate_links(Manager *m) {
293         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
294         sd_rtnl_message *link;
295         int r, k;
296
297         assert(m);
298         assert(m->rtnl);
299
300         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
301         if (r < 0)
302                 return r;
303
304         r = sd_rtnl_message_request_dump(req, true);
305         if (r < 0)
306                 return r;
307
308         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
309         if (r < 0)
310                 return r;
311
312         for (link = reply; link; link = sd_rtnl_message_next(link)) {
313                 uint16_t type;
314
315                 k = sd_rtnl_message_get_type(link, &type);
316                 if (k < 0)
317                         return k;
318
319                 if (type != RTM_NEWLINK)
320                         continue;
321
322                 k = manager_rtnl_process_link(m->rtnl, link, m);
323                 if (k < 0)
324                         r = k;
325         }
326
327         return r;
328 }
329
330 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
331         Manager *m = userdata;
332         struct udev_monitor *monitor = m->udev_monitor;
333         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
334
335         device = udev_monitor_receive_device(monitor);
336         if (!device)
337                 return -ENOMEM;
338
339         manager_udev_process_link(m, device);
340         return 0;
341 }
342
343 int manager_udev_listen(Manager *m) {
344         int r;
345
346         if (detect_container(NULL) > 0)
347                 return 0;
348
349         assert(m->udev_monitor);
350
351         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
352         if (r < 0) {
353                 log_error("Could not add udev monitor filter: %s", strerror(-r));
354                 return r;
355         }
356
357         r = udev_monitor_enable_receiving(m->udev_monitor);
358         if (r < 0) {
359                 log_error("Could not enable udev monitor");
360                 return r;
361         }
362
363         r = sd_event_add_io(m->event,
364                         &m->udev_event_source,
365                         udev_monitor_get_fd(m->udev_monitor),
366                         EPOLLIN, manager_dispatch_link_udev,
367                         m);
368         if (r < 0)
369                 return r;
370
371         return 0;
372 }
373
374 int manager_rtnl_listen(Manager *m) {
375         int r;
376
377         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
378         if (r < 0)
379                 return r;
380
381         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
382         if (r < 0)
383                 return r;
384
385         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
386         if (r < 0)
387                 return r;
388
389         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
390         if (r < 0)
391                 return r;
392
393         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
394         if (r < 0)
395                 return r;
396
397         return 0;
398 }
399
400 int manager_bus_listen(Manager *m) {
401         int r;
402
403         assert(m->event);
404
405         if (!m->bus) /* TODO: drop when we can rely on kdbus */
406                 return 0;
407
408         r = sd_bus_attach_event(m->bus, m->event, 0);
409         if (r < 0)
410                 return r;
411
412         return 0;
413 }
414
415 static void append_dns(FILE *f, struct in_addr *dns, unsigned char family, unsigned *count) {
416         char buf[INET6_ADDRSTRLEN];
417         const char *address;
418
419         address = inet_ntop(family, dns, buf, INET6_ADDRSTRLEN);
420         if (!address) {
421                 log_warning("Invalid DNS address. Ignoring.");
422                 return;
423         }
424
425         if (*count == MAXNS)
426                 fputs("# Too many DNS servers configured, the following entries "
427                       "will be ignored\n", f);
428
429         fprintf(f, "nameserver %s\n", address);
430
431         (*count) ++;
432 }
433
434 int manager_update_resolv_conf(Manager *m) {
435         _cleanup_free_ char *temp_path = NULL;
436         _cleanup_fclose_ FILE *f = NULL;
437         Link *link;
438         Iterator i;
439         unsigned count = 0;
440         const char *domainname = NULL;
441         int r;
442
443         assert(m);
444
445         r = fopen_temporary("/run/systemd/network/resolv.conf", &f, &temp_path);
446         if (r < 0)
447                 return r;
448
449         fchmod(fileno(f), 0644);
450
451         fputs("# This file is managed by systemd-networkd(8). Do not edit.\n#\n"
452               "# Third party programs must not access this file directly, but\n"
453               "# only through the symlink at /etc/resolv.conf. To manage\n"
454               "# resolv.conf(5) in a different way, replace the symlink by a\n"
455               "# static file or a different symlink.\n\n", f);
456
457         HASHMAP_FOREACH(link, m->links, i) {
458                 if (link->dhcp_lease) {
459                         struct in_addr *nameservers;
460                         size_t nameservers_size;
461
462                         if (link->network->dhcp_dns) {
463                                 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &nameservers, &nameservers_size);
464                                 if (r >= 0) {
465                                         unsigned j;
466
467                                         for (j = 0; j < nameservers_size; j++)
468                                                 append_dns(f, &nameservers[j], AF_INET, &count);
469                                 }
470                         }
471
472                         if (link->network->dhcp_domainname && !domainname) {
473                                 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
474                                 if (r >= 0)
475                                        fprintf(f, "domain %s\n", domainname);
476                         }
477                 }
478         }
479
480         HASHMAP_FOREACH(link, m->links, i) {
481                 if (link->network && link->network->dns) {
482                         Address *address;
483                         Iterator j;
484
485                         SET_FOREACH(address, link->network->dns, j) {
486                                 append_dns(f, &address->in_addr.in,
487                                            address->family, &count);
488                         }
489                 }
490         }
491
492         fflush(f);
493
494         if (ferror(f) || rename(temp_path, "/run/systemd/network/resolv.conf") < 0) {
495                 r = -errno;
496                 unlink("/run/systemd/network/resolv.conf");
497                 unlink(temp_path);
498                 return r;
499         }
500
501         return 0;
502 }
503
504 int manager_save(Manager *m) {
505         Link *link;
506         Iterator i;
507         _cleanup_free_ char *temp_path = NULL;
508         _cleanup_fclose_ FILE *f = NULL;
509         const char *oper_state = "unknown";
510         bool dormant = false, carrier = false;
511         int r;
512
513         assert(m);
514         assert(m->state_file);
515
516         HASHMAP_FOREACH(link, m->links, i) {
517                 if (link->flags & IFF_LOOPBACK)
518                         continue;
519
520                 if (link_has_carrier(link->flags, link->operstate))
521                         carrier = true;
522                 else if (link->operstate == IF_OPER_DORMANT)
523                         dormant = true;
524         }
525
526         if (carrier)
527                 oper_state = "carrier";
528         else if (dormant)
529                 oper_state = "dormant";
530
531         r = fopen_temporary(m->state_file, &f, &temp_path);
532         if (r < 0)
533                 goto finish;
534
535         fchmod(fileno(f), 0644);
536
537         fprintf(f,
538                 "# This is private data. Do not parse.\n"
539                 "OPER_STATE=%s\n", oper_state);
540
541         fflush(f);
542
543         if (ferror(f) || rename(temp_path, m->state_file) < 0) {
544                 r = -errno;
545                 unlink(m->state_file);
546                 unlink(temp_path);
547         }
548
549 finish:
550         if (r < 0)
551                 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
552
553         return r;
554 }
555
556 int manager_init_kmod_ctx(Manager *m) {
557         struct kmod_ctx *ctx;
558
559         assert(m);
560
561         ctx = kmod_new(NULL, NULL);
562         if (!ctx) {
563                 return -ENOMEM;
564         }
565
566         m->kmod_ctx = ctx;
567
568         return 0;
569 }