]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
sd-event: use event source name rather than address in debug messages
[thirdparty/systemd.git] / src / network / networkd-manager.c
CommitLineData
f579559b
TG
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
091a364c 22#include <sys/socket.h>
bbf7c048 23#include <linux/if.h>
3bef724f 24
2dcf7ec6 25#include "conf-parser.h"
f579559b
TG
26#include "path-util.h"
27#include "networkd.h"
3be1d7e0 28#include "networkd-netdev.h"
0b1831c2 29#include "networkd-link.h"
e16cb2e4 30#include "network-internal.h"
f579559b 31#include "libudev-private.h"
7b77ed8c 32#include "udev-util.h"
50add290 33#include "rtnl-util.h"
3bef724f 34#include "mkdir.h"
60ad0c85 35#include "virt.h"
f579559b 36
505f8da7
TG
37#include "sd-rtnl.h"
38
2ad8416d
ZJS
39const char* const network_dirs[] = {
40 "/etc/systemd/network",
41 "/run/systemd/network",
42 "/usr/lib/systemd/network",
eed0eee8 43#ifdef HAVE_SPLIT_USR
2ad8416d
ZJS
44 "/lib/systemd/network",
45#endif
46 NULL};
47
11bf3cce
LP
48static int setup_default_address_pool(Manager *m) {
49 AddressPool *p;
50 int r;
51
52 assert(m);
53
54 /* Add in the well-known private address ranges. */
55
56 r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
57 if (r < 0)
58 return r;
59
60 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
61 if (r < 0)
62 return r;
63
64 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
65 if (r < 0)
66 return r;
67
68 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
69 if (r < 0)
70 return r;
71
72 return 0;
73}
74
f579559b
TG
75int manager_new(Manager **ret) {
76 _cleanup_manager_free_ Manager *m = NULL;
77 int r;
78
79 m = new0(Manager, 1);
80 if (!m)
81 return -ENOMEM;
82
85b5673b 83 m->state_file = strdup("/run/systemd/netif/state");
bbf7c048
TG
84 if (!m->state_file)
85 return -ENOMEM;
86
afc6adb5 87 r = sd_event_default(&m->event);
f579559b
TG
88 if (r < 0)
89 return r;
90
cde93897
LP
91 sd_event_set_watchdog(m->event, true);
92
186fe1db
LP
93 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
94 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
95
897e184c
TG
96 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
97 RTNLGRP_IPV6_IFADDR);
f579559b
TG
98 if (r < 0)
99 return r;
100
1346b1f0 101 r = sd_bus_default_system(&m->bus);
bcbca829 102 if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
1346b1f0
TG
103 return r;
104
60ad0c85
TG
105 /* udev does not initialize devices inside containers,
106 * so we rely on them being already initialized before
107 * entering the container */
505f8da7
TG
108 if (detect_container(NULL) <= 0) {
109 m->udev = udev_new();
110 if (!m->udev)
60ad0c85 111 return -ENOMEM;
505f8da7 112
60ad0c85
TG
113 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
114 if (!m->udev_monitor)
115 return -ENOMEM;
116 }
f579559b 117
52433f6b
TG
118 m->netdevs = hashmap_new(string_hash_func, string_compare_func);
119 if (!m->netdevs)
02b59d57
TG
120 return -ENOMEM;
121
f579559b
TG
122 LIST_HEAD_INIT(m->networks);
123
11bf3cce
LP
124 r = setup_default_address_pool(m);
125 if (r < 0)
126 return r;
127
f579559b
TG
128 *ret = m;
129 m = NULL;
130
131 return 0;
132}
133
134void manager_free(Manager *m) {
0617ffab 135 Network *network;
1a436809 136 NetDev *netdev;
0617ffab 137 Link *link;
11bf3cce 138 AddressPool *pool;
0617ffab 139
624b5a63
TG
140 if (!m)
141 return;
142
bbf7c048
TG
143 free(m->state_file);
144
f579559b
TG
145 udev_monitor_unref(m->udev_monitor);
146 udev_unref(m->udev);
1346b1f0 147 sd_bus_unref(m->bus);
f579559b 148 sd_event_source_unref(m->udev_event_source);
0c2f9b84
TG
149 sd_event_source_unref(m->sigterm_event_source);
150 sd_event_source_unref(m->sigint_event_source);
f579559b 151 sd_event_unref(m->event);
0617ffab 152
0617ffab 153 while ((link = hashmap_first(m->links)))
14b746f7 154 link_unref(link);
f579559b 155 hashmap_free(m->links);
0617ffab 156
2292547a
TG
157 while ((network = m->networks))
158 network_free(network);
159
52433f6b 160 while ((netdev = hashmap_first(m->netdevs)))
14b746f7 161 netdev_unref(netdev);
52433f6b 162 hashmap_free(m->netdevs);
02b59d57 163
11bf3cce
LP
164 while ((pool = m->address_pools))
165 address_pool_free(pool);
166
f579559b
TG
167 sd_rtnl_unref(m->rtnl);
168
169 free(m);
170}
171
02b59d57
TG
172int manager_load_config(Manager *m) {
173 int r;
174
175 /* update timestamp */
2ad8416d 176 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
02b59d57 177
52433f6b 178 r = netdev_load(m);
02b59d57
TG
179 if (r < 0)
180 return r;
181
182 r = network_load(m);
183 if (r < 0)
184 return r;
185
186 return 0;
187}
188
189bool manager_should_reload(Manager *m) {
2ad8416d 190 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
02b59d57
TG
191}
192
505f8da7 193static int manager_udev_process_link(Manager *m, struct udev_device *device) {
11a7f229 194 Link *link = NULL;
667fcc6d 195 int r, ifindex;
f579559b 196
11a7f229
TG
197 assert(m);
198 assert(device);
f579559b 199
505f8da7
TG
200 if (!streq_ptr(udev_device_get_action(device), "add"))
201 return 0;
202
667fcc6d
TG
203 ifindex = udev_device_get_ifindex(device);
204 if (ifindex <= 0) {
205 log_debug("ignoring udev ADD event for device with invalid ifindex");
206 return 0;
207 }
505f8da7 208
667fcc6d
TG
209 r = link_get(m, ifindex, &link);
210 if (r == -ENODEV)
505f8da7 211 return 0;
667fcc6d
TG
212 else if (r < 0)
213 return r;
505f8da7
TG
214
215 r = link_initialized(link, device);
216 if (r < 0)
217 return r;
11a7f229 218
505f8da7
TG
219 return 0;
220}
f579559b 221
505f8da7
TG
222static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
223 Manager *m = userdata;
224 Link *link = NULL;
4d473d5d 225 NetDev *netdev = NULL;
f2236469 226 uint16_t type;
ca4e095a 227 const char *name;
505f8da7 228 int r, ifindex;
f579559b 229
505f8da7
TG
230 assert(rtnl);
231 assert(message);
f579559b
TG
232 assert(m);
233
f2236469
TG
234 r = sd_rtnl_message_get_type(message, &type);
235 if (r < 0) {
236 log_warning("rtnl: could not get message type");
237 return 0;
238 }
239
505f8da7
TG
240 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
241 if (r < 0 || ifindex <= 0) {
242 log_warning("rtnl: received link message without valid ifindex");
243 return 0;
4d473d5d
TG
244 } else
245 link_get(m, ifindex, &link);
f579559b 246
505f8da7 247 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
4d473d5d 248 if (r < 0 || !name) {
505f8da7 249 log_warning("rtnl: received link message without valid ifname");
4d473d5d
TG
250 return 0;
251 } else
f2236469 252 netdev_get(m, name, &netdev);
4d473d5d
TG
253
254 switch (type) {
255 case RTM_NEWLINK:
256 if (!link) {
257 /* link is new, so add it */
258 r = link_add(m, message, &link);
259 if (r < 0) {
1a941ac4
TG
260 log_debug("could not add new link: %s",
261 strerror(-r));
4d473d5d
TG
262 return 0;
263 }
264 }
265
266 if (netdev) {
267 /* netdev exists, so make sure the ifindex matches */
505f8da7
TG
268 r = netdev_set_ifindex(netdev, message);
269 if (r < 0) {
270 log_debug("could not set ifindex on netdev");
271 return 0;
272 }
273 }
e1202047 274
f2236469
TG
275 r = link_update(link, message);
276 if (r < 0)
277 return 0;
4d473d5d
TG
278
279 break;
280
281 case RTM_DELLINK:
282 link_drop(link);
283 netdev_drop(netdev);
284
285 break;
286
287 default:
288 assert_not_reached("Received invalid RTNL message type.");
f2236469 289 }
505f8da7
TG
290
291 return 1;
292}
293
294int manager_rtnl_enumerate_links(Manager *m) {
295 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
296 sd_rtnl_message *link;
297 int r, k;
298
299 assert(m);
300 assert(m->rtnl);
301
302 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
303 if (r < 0)
304 return r;
305
306 r = sd_rtnl_message_request_dump(req, true);
f579559b 307 if (r < 0)
bf5332d2 308 return r;
f579559b 309
505f8da7
TG
310 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
311 if (r < 0)
312 return r;
f579559b 313
505f8da7
TG
314 for (link = reply; link; link = sd_rtnl_message_next(link)) {
315 uint16_t type;
316
317 k = sd_rtnl_message_get_type(link, &type);
318 if (k < 0)
319 return k;
320
321 if (type != RTM_NEWLINK)
322 continue;
f579559b 323
505f8da7 324 k = manager_rtnl_process_link(m->rtnl, link, m);
f579559b
TG
325 if (k < 0)
326 r = k;
327 }
328
f579559b
TG
329 return r;
330}
331
332static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
333 Manager *m = userdata;
334 struct udev_monitor *monitor = m->udev_monitor;
7b77ed8c 335 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
f579559b
TG
336
337 device = udev_monitor_receive_device(monitor);
338 if (!device)
339 return -ENOMEM;
340
505f8da7 341 manager_udev_process_link(m, device);
f579559b
TG
342 return 0;
343}
344
345int manager_udev_listen(Manager *m) {
346 int r;
347
505f8da7
TG
348 if (detect_container(NULL) > 0)
349 return 0;
350
351 assert(m->udev_monitor);
352
f579559b
TG
353 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
354 if (r < 0) {
355 log_error("Could not add udev monitor filter: %s", strerror(-r));
356 return r;
357 }
358
f579559b
TG
359 r = udev_monitor_enable_receiving(m->udev_monitor);
360 if (r < 0) {
361 log_error("Could not enable udev monitor");
362 return r;
363 }
364
365 r = sd_event_add_io(m->event,
151b9b96 366 &m->udev_event_source,
f579559b
TG
367 udev_monitor_get_fd(m->udev_monitor),
368 EPOLLIN, manager_dispatch_link_udev,
151b9b96 369 m);
f579559b
TG
370 if (r < 0)
371 return r;
372
373 return 0;
374}
f882c247
TG
375
376int manager_rtnl_listen(Manager *m) {
377 int r;
378
5da8149f
TG
379 assert(m);
380
f882c247
TG
381 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
382 if (r < 0)
383 return r;
384
dd3efc09
TG
385 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
386 if (r < 0)
387 return r;
388
f2236469
TG
389 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
390 if (r < 0)
391 return r;
392
fbbeb65a 393 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
2e9f08ea
TG
394 if (r < 0)
395 return r;
396
fbbeb65a 397 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
2e9f08ea
TG
398 if (r < 0)
399 return r;
400
f882c247
TG
401 return 0;
402}
3bef724f 403
1346b1f0
TG
404int manager_bus_listen(Manager *m) {
405 int r;
406
bcbca829
TG
407 assert(m->event);
408
409 if (!m->bus) /* TODO: drop when we can rely on kdbus */
410 return 0;
411
1346b1f0
TG
412 r = sd_bus_attach_event(m->bus, m->event, 0);
413 if (r < 0)
414 return r;
415
416 return 0;
417}
418
c0c743cb
LP
419static int set_put_in_addr(Set *s, const struct in_addr *address) {
420 char *p;
421 int r;
422
423 assert(s);
424
425 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
426 if (r < 0)
427 return r;
428
429 r = set_consume(s, p);
430 if (r == -EEXIST)
431 return 0;
432
433 return r;
434}
435
436static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
437 int r, i, c = 0;
438
439 assert(s);
440 assert(n <= 0 || addresses);
441
442 for (i = 0; i < n; i++) {
443 r = set_put_in_addr(s, addresses+i);
444 if (r < 0)
445 return r;
446
447 c += r;
448 }
449
450 return c;
451}
452
8612e936
LP
453static void print_string_set(FILE *f, const char *field, Set *s) {
454 bool space = false;
455 Iterator i;
456 char *p;
457
458 if (set_isempty(s))
459 return;
460
461 fputs(field, f);
462
463 SET_FOREACH(p, s, i) {
464 if (space)
465 fputc(' ', f);
466 fputs(p, f);
467 space = true;
468 }
469 fputc('\n', f);
470}
471
bbf7c048 472int manager_save(Manager *m) {
8612e936 473 _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
bbf7c048
TG
474 Link *link;
475 Iterator i;
476 _cleanup_free_ char *temp_path = NULL;
477 _cleanup_fclose_ FILE *f = NULL;
d3df0e39 478 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
e375dcde 479 const char *operstate_str;
bbf7c048
TG
480 int r;
481
482 assert(m);
483 assert(m->state_file);
484
c0c743cb
LP
485 /* We add all NTP and DNS server to a set, to filter out duplicates */
486 dns = set_new(string_hash_func, string_compare_func);
487 if (!dns)
488 return -ENOMEM;
489
490 ntp = set_new(string_hash_func, string_compare_func);
491 if (!ntp)
492 return -ENOMEM;
493
8612e936
LP
494 domains = set_new(string_hash_func, string_compare_func);
495 if (!domains)
496 return -ENOMEM;
497
bbf7c048
TG
498 HASHMAP_FOREACH(link, m->links, i) {
499 if (link->flags & IFF_LOOPBACK)
500 continue;
501
e375dcde
TG
502 if (link->operstate > operstate)
503 operstate = link->operstate;
c0c743cb
LP
504
505 if (!link->network)
506 continue;
507
508 /* First add the static configured entries */
509 r = set_put_strdupv(dns, link->network->dns);
510 if (r < 0)
511 return r;
512
513 r = set_put_strdupv(ntp, link->network->ntp);
514 if (r < 0)
515 return r;
516
8612e936
LP
517 r = set_put_strdupv(domains, link->network->domains);
518 if (r < 0)
519 return r;
520
c0c743cb
LP
521 if (!link->dhcp_lease)
522 continue;
523
524 /* Secondly, add the entries acquired via DHCP */
525 if (link->network->dhcp_dns) {
526 const struct in_addr *addresses;
527
528 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
529 if (r > 0) {
530 r = set_put_in_addrv(dns, addresses, r);
531 if (r < 0)
532 return r;
8612e936 533 } else if (r < 0 && r != -ENOENT)
c0c743cb
LP
534 return r;
535 }
536
537 if (link->network->dhcp_ntp) {
538 const struct in_addr *addresses;
539
540 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
541 if (r > 0) {
542 r = set_put_in_addrv(ntp, addresses, r);
543 if (r < 0)
544 return r;
8612e936
LP
545 } else if (r < 0 && r != -ENOENT)
546 return r;
547 }
548
549 if (link->network->dhcp_domains) {
550 const char *domainname;
551
552 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
553 if (r >= 0) {
554 r = set_put_strdup(domains, domainname);
555 if (r < 0)
556 return r;
c0c743cb
LP
557 } else if (r != -ENOENT)
558 return r;
559 }
bbf7c048
TG
560 }
561
e375dcde
TG
562 operstate_str = link_operstate_to_string(operstate);
563 assert(operstate_str);
bbf7c048
TG
564
565 r = fopen_temporary(m->state_file, &f, &temp_path);
566 if (r < 0)
c2d6bd61 567 return r;
bbf7c048
TG
568
569 fchmod(fileno(f), 0644);
570
571 fprintf(f,
572 "# This is private data. Do not parse.\n"
e375dcde 573 "OPER_STATE=%s\n", operstate_str);
bbf7c048 574
8612e936
LP
575 print_string_set(f, "DNS=", dns);
576 print_string_set(f, "NTP=", ntp);
577 print_string_set(f, "DOMAINS=", domains);
c0c743cb 578
c2d6bd61
LP
579 r = fflush_and_check(f);
580 if (r < 0)
581 goto fail;
bbf7c048 582
c2d6bd61 583 if (rename(temp_path, m->state_file) < 0) {
bbf7c048 584 r = -errno;
c2d6bd61 585 goto fail;
bbf7c048
TG
586 }
587
c2d6bd61 588 return 0;
bbf7c048 589
c2d6bd61
LP
590fail:
591 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
592 unlink(m->state_file);
593 unlink(temp_path);
bbf7c048
TG
594 return r;
595}
11bf3cce 596
0dd25fb9 597int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
598 AddressPool *p;
599 int r;
600
601 assert(m);
602 assert(prefixlen > 0);
603 assert(found);
604
605 LIST_FOREACH(address_pools, p, m->address_pools) {
606 if (p->family != family)
607 continue;
608
609 r = address_pool_acquire(p, prefixlen, found);
610 if (r != 0)
611 return r;
612 }
613
614 return 0;
615}