]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
resolve: reject empty TXT records
[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
d5099efc 118 m->netdevs = hashmap_new(&string_hash_ops);
52433f6b 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
TG
148 sd_event_source_unref(m->udev_event_source);
149 sd_event_unref(m->event);
0617ffab 150
0617ffab 151 while ((link = hashmap_first(m->links)))
14b746f7 152 link_unref(link);
f579559b 153 hashmap_free(m->links);
0617ffab 154
2292547a
TG
155 while ((network = m->networks))
156 network_free(network);
157
52433f6b 158 while ((netdev = hashmap_first(m->netdevs)))
14b746f7 159 netdev_unref(netdev);
52433f6b 160 hashmap_free(m->netdevs);
02b59d57 161
11bf3cce
LP
162 while ((pool = m->address_pools))
163 address_pool_free(pool);
164
f579559b
TG
165 sd_rtnl_unref(m->rtnl);
166
167 free(m);
168}
169
02b59d57
TG
170int manager_load_config(Manager *m) {
171 int r;
172
173 /* update timestamp */
2ad8416d 174 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
02b59d57 175
52433f6b 176 r = netdev_load(m);
02b59d57
TG
177 if (r < 0)
178 return r;
179
180 r = network_load(m);
181 if (r < 0)
182 return r;
183
184 return 0;
185}
186
187bool manager_should_reload(Manager *m) {
2ad8416d 188 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
02b59d57
TG
189}
190
505f8da7 191static int manager_udev_process_link(Manager *m, struct udev_device *device) {
11a7f229 192 Link *link = NULL;
667fcc6d 193 int r, ifindex;
f579559b 194
11a7f229
TG
195 assert(m);
196 assert(device);
f579559b 197
505f8da7
TG
198 if (!streq_ptr(udev_device_get_action(device), "add"))
199 return 0;
200
667fcc6d
TG
201 ifindex = udev_device_get_ifindex(device);
202 if (ifindex <= 0) {
203 log_debug("ignoring udev ADD event for device with invalid ifindex");
204 return 0;
205 }
505f8da7 206
667fcc6d
TG
207 r = link_get(m, ifindex, &link);
208 if (r == -ENODEV)
505f8da7 209 return 0;
667fcc6d
TG
210 else if (r < 0)
211 return r;
505f8da7
TG
212
213 r = link_initialized(link, device);
214 if (r < 0)
215 return r;
11a7f229 216
505f8da7
TG
217 return 0;
218}
f579559b 219
505f8da7
TG
220static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
221 Manager *m = userdata;
222 Link *link = NULL;
4d473d5d 223 NetDev *netdev = NULL;
f2236469 224 uint16_t type;
ca4e095a 225 const char *name;
505f8da7 226 int r, ifindex;
f579559b 227
505f8da7
TG
228 assert(rtnl);
229 assert(message);
f579559b
TG
230 assert(m);
231
f2236469
TG
232 r = sd_rtnl_message_get_type(message, &type);
233 if (r < 0) {
234 log_warning("rtnl: could not get message type");
235 return 0;
236 }
237
505f8da7
TG
238 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
239 if (r < 0 || ifindex <= 0) {
240 log_warning("rtnl: received link message without valid ifindex");
241 return 0;
4d473d5d
TG
242 } else
243 link_get(m, ifindex, &link);
f579559b 244
505f8da7 245 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
4d473d5d 246 if (r < 0 || !name) {
505f8da7 247 log_warning("rtnl: received link message without valid ifname");
4d473d5d
TG
248 return 0;
249 } else
f2236469 250 netdev_get(m, name, &netdev);
4d473d5d
TG
251
252 switch (type) {
253 case RTM_NEWLINK:
254 if (!link) {
255 /* link is new, so add it */
256 r = link_add(m, message, &link);
257 if (r < 0) {
1a941ac4
TG
258 log_debug("could not add new link: %s",
259 strerror(-r));
4d473d5d
TG
260 return 0;
261 }
262 }
263
264 if (netdev) {
265 /* netdev exists, so make sure the ifindex matches */
505f8da7
TG
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 }
e1202047 272
f2236469
TG
273 r = link_update(link, message);
274 if (r < 0)
275 return 0;
4d473d5d
TG
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.");
f2236469 287 }
505f8da7
TG
288
289 return 1;
290}
291
292int 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);
f579559b 305 if (r < 0)
bf5332d2 306 return r;
f579559b 307
505f8da7
TG
308 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
309 if (r < 0)
310 return r;
f579559b 311
505f8da7
TG
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;
f579559b 321
505f8da7 322 k = manager_rtnl_process_link(m->rtnl, link, m);
f579559b
TG
323 if (k < 0)
324 r = k;
325 }
326
f579559b
TG
327 return r;
328}
329
330static 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;
7b77ed8c 333 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
f579559b
TG
334
335 device = udev_monitor_receive_device(monitor);
336 if (!device)
337 return -ENOMEM;
338
505f8da7 339 manager_udev_process_link(m, device);
f579559b
TG
340 return 0;
341}
342
343int manager_udev_listen(Manager *m) {
344 int r;
345
505f8da7
TG
346 if (detect_container(NULL) > 0)
347 return 0;
348
349 assert(m->udev_monitor);
350
f579559b
TG
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
f579559b
TG
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,
151b9b96 364 &m->udev_event_source,
f579559b
TG
365 udev_monitor_get_fd(m->udev_monitor),
366 EPOLLIN, manager_dispatch_link_udev,
151b9b96 367 m);
f579559b
TG
368 if (r < 0)
369 return r;
370
356779df 371 r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
9021bb9f
TG
372 if (r < 0)
373 return r;
374
f579559b
TG
375 return 0;
376}
f882c247
TG
377
378int manager_rtnl_listen(Manager *m) {
379 int r;
380
5da8149f
TG
381 assert(m);
382
f882c247
TG
383 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
384 if (r < 0)
385 return r;
386
dd3efc09
TG
387 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
388 if (r < 0)
389 return r;
390
f2236469
TG
391 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
392 if (r < 0)
393 return r;
394
fbbeb65a 395 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
2e9f08ea
TG
396 if (r < 0)
397 return r;
398
fbbeb65a 399 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
2e9f08ea
TG
400 if (r < 0)
401 return r;
402
f882c247
TG
403 return 0;
404}
3bef724f 405
1346b1f0
TG
406int manager_bus_listen(Manager *m) {
407 int r;
408
bcbca829
TG
409 assert(m->event);
410
411 if (!m->bus) /* TODO: drop when we can rely on kdbus */
412 return 0;
413
1346b1f0
TG
414 r = sd_bus_attach_event(m->bus, m->event, 0);
415 if (r < 0)
416 return r;
417
418 return 0;
419}
420
c0c743cb
LP
421static int set_put_in_addr(Set *s, const struct in_addr *address) {
422 char *p;
423 int r;
424
425 assert(s);
426
427 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
428 if (r < 0)
429 return r;
430
431 r = set_consume(s, p);
432 if (r == -EEXIST)
433 return 0;
434
435 return r;
436}
437
438static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
439 int r, i, c = 0;
440
441 assert(s);
442 assert(n <= 0 || addresses);
443
444 for (i = 0; i < n; i++) {
445 r = set_put_in_addr(s, addresses+i);
446 if (r < 0)
447 return r;
448
449 c += r;
450 }
451
452 return c;
453}
454
8612e936
LP
455static void print_string_set(FILE *f, const char *field, Set *s) {
456 bool space = false;
457 Iterator i;
458 char *p;
459
460 if (set_isempty(s))
461 return;
462
463 fputs(field, f);
464
465 SET_FOREACH(p, s, i) {
466 if (space)
467 fputc(' ', f);
468 fputs(p, f);
469 space = true;
470 }
471 fputc('\n', f);
472}
473
bbf7c048 474int manager_save(Manager *m) {
8612e936 475 _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
bbf7c048
TG
476 Link *link;
477 Iterator i;
478 _cleanup_free_ char *temp_path = NULL;
479 _cleanup_fclose_ FILE *f = NULL;
d3df0e39 480 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
e375dcde 481 const char *operstate_str;
bbf7c048
TG
482 int r;
483
484 assert(m);
485 assert(m->state_file);
486
c0c743cb 487 /* We add all NTP and DNS server to a set, to filter out duplicates */
d5099efc 488 dns = set_new(&string_hash_ops);
c0c743cb
LP
489 if (!dns)
490 return -ENOMEM;
491
d5099efc 492 ntp = set_new(&string_hash_ops);
c0c743cb
LP
493 if (!ntp)
494 return -ENOMEM;
495
d5099efc 496 domains = set_new(&string_hash_ops);
8612e936
LP
497 if (!domains)
498 return -ENOMEM;
499
bbf7c048
TG
500 HASHMAP_FOREACH(link, m->links, i) {
501 if (link->flags & IFF_LOOPBACK)
502 continue;
503
e375dcde
TG
504 if (link->operstate > operstate)
505 operstate = link->operstate;
c0c743cb
LP
506
507 if (!link->network)
508 continue;
509
510 /* First add the static configured entries */
511 r = set_put_strdupv(dns, link->network->dns);
512 if (r < 0)
513 return r;
514
515 r = set_put_strdupv(ntp, link->network->ntp);
516 if (r < 0)
517 return r;
518
8612e936
LP
519 r = set_put_strdupv(domains, link->network->domains);
520 if (r < 0)
521 return r;
522
c0c743cb
LP
523 if (!link->dhcp_lease)
524 continue;
525
526 /* Secondly, add the entries acquired via DHCP */
527 if (link->network->dhcp_dns) {
528 const struct in_addr *addresses;
529
530 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
531 if (r > 0) {
532 r = set_put_in_addrv(dns, addresses, r);
533 if (r < 0)
534 return r;
8612e936 535 } else if (r < 0 && r != -ENOENT)
c0c743cb
LP
536 return r;
537 }
538
539 if (link->network->dhcp_ntp) {
540 const struct in_addr *addresses;
541
542 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
543 if (r > 0) {
544 r = set_put_in_addrv(ntp, addresses, r);
545 if (r < 0)
546 return r;
8612e936
LP
547 } else if (r < 0 && r != -ENOENT)
548 return r;
549 }
550
551 if (link->network->dhcp_domains) {
552 const char *domainname;
553
554 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
555 if (r >= 0) {
556 r = set_put_strdup(domains, domainname);
557 if (r < 0)
558 return r;
c0c743cb
LP
559 } else if (r != -ENOENT)
560 return r;
561 }
bbf7c048
TG
562 }
563
e375dcde
TG
564 operstate_str = link_operstate_to_string(operstate);
565 assert(operstate_str);
bbf7c048
TG
566
567 r = fopen_temporary(m->state_file, &f, &temp_path);
568 if (r < 0)
c2d6bd61 569 return r;
bbf7c048
TG
570
571 fchmod(fileno(f), 0644);
572
573 fprintf(f,
574 "# This is private data. Do not parse.\n"
e375dcde 575 "OPER_STATE=%s\n", operstate_str);
bbf7c048 576
8612e936
LP
577 print_string_set(f, "DNS=", dns);
578 print_string_set(f, "NTP=", ntp);
579 print_string_set(f, "DOMAINS=", domains);
c0c743cb 580
c2d6bd61
LP
581 r = fflush_and_check(f);
582 if (r < 0)
583 goto fail;
bbf7c048 584
c2d6bd61 585 if (rename(temp_path, m->state_file) < 0) {
bbf7c048 586 r = -errno;
c2d6bd61 587 goto fail;
bbf7c048
TG
588 }
589
c2d6bd61 590 return 0;
bbf7c048 591
c2d6bd61
LP
592fail:
593 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
594 unlink(m->state_file);
595 unlink(temp_path);
bbf7c048
TG
596 return r;
597}
11bf3cce 598
0dd25fb9 599int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
600 AddressPool *p;
601 int r;
602
603 assert(m);
604 assert(prefixlen > 0);
605 assert(found);
606
607 LIST_FOREACH(address_pools, p, m->address_pools) {
608 if (p->family != family)
609 continue;
610
611 r = address_pool_acquire(p, prefixlen, found);
612 if (r != 0)
613 return r;
614 }
615
616 return 0;
617}