]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-manager.c
networkd: introduce ipip tunnel
[thirdparty/systemd.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 }