]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
util-lib: split out allocation calls into alloc-util.[ch]
[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
fc2f9534 25#include "sd-daemon.h"
07630cea 26#include "sd-netlink.h"
fc2f9534 27
b5efdb8a 28#include "alloc-util.h"
a97dcc12 29#include "bus-util.h"
07630cea 30#include "conf-parser.h"
a97dcc12 31#include "def.h"
3ffd4af2 32#include "fd-util.h"
0d39fa9c 33#include "fileio.h"
07630cea 34#include "libudev-private.h"
4f5f911e 35#include "local-addresses.h"
07630cea 36#include "netlink-util.h"
fc2f9534 37#include "networkd.h"
07630cea
LP
38#include "path-util.h"
39#include "set.h"
40#include "udev-util.h"
41#include "virt.h"
505f8da7 42
be660c37
AR
43/* use 8 MB for receive socket kernel queue. */
44#define RCVBUF_SIZE (8*1024*1024)
45
2ad8416d
ZJS
46const char* const network_dirs[] = {
47 "/etc/systemd/network",
48 "/run/systemd/network",
49 "/usr/lib/systemd/network",
eed0eee8 50#ifdef HAVE_SPLIT_USR
2ad8416d
ZJS
51 "/lib/systemd/network",
52#endif
53 NULL};
54
11bf3cce
LP
55static int setup_default_address_pool(Manager *m) {
56 AddressPool *p;
57 int r;
58
59 assert(m);
60
61 /* Add in the well-known private address ranges. */
62
63 r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
64 if (r < 0)
65 return r;
66
67 r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
68 if (r < 0)
69 return r;
70
71 r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
72 if (r < 0)
73 return r;
74
75 r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
76 if (r < 0)
77 return r;
78
79 return 0;
80}
81
9c0a72f9
TG
82static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
83 Manager *m = userdata;
84
85 assert(s);
86 assert(m);
87
88 m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
89
90 manager_connect_bus(m);
91
92 return 0;
93}
94
95static int manager_reset_all(Manager *m) {
96 Link *link;
97 Iterator i;
98 int r;
99
100 assert(m);
101
102 HASHMAP_FOREACH(link, m->links, i) {
103 r = link_carrier_reset(link);
104 if (r < 0)
2f3cf1f9 105 log_link_warning_errno(link, r, "Could not reset carrier: %m");
9c0a72f9
TG
106 }
107
108 return 0;
109}
110
19070062 111static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
9c0a72f9
TG
112 Manager *m = userdata;
113 int b, r;
114
19070062 115 assert(message);
9c0a72f9
TG
116
117 r = sd_bus_message_read(message, "b", &b);
118 if (r < 0) {
119 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
120 return 0;
121 }
122
123 if (b)
124 return 0;
125
126 log_debug("Coming back from suspend, resetting all connections...");
127
128 manager_reset_all(m);
129
130 return 0;
131}
132
133int manager_connect_bus(Manager *m) {
134 int r;
135
136 assert(m);
137
138 r = sd_bus_default_system(&m->bus);
139 if (r == -ENOENT) {
140 /* We failed to connect? Yuck, we must be in early
141 * boot. Let's try in 5s again. As soon as we have
142 * kdbus we can stop doing this... */
143
144 log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
145
146 r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
147 if (r < 0)
148 return log_error_errno(r, "Failed to install bus reconnect time event: %m");
149
150 return 0;
7d6884b6
TA
151 }
152
153 if (r < 0)
9c0a72f9
TG
154 return r;
155
9c0a72f9
TG
156 r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
157 "type='signal',"
158 "sender='org.freedesktop.login1',"
159 "interface='org.freedesktop.login1.Manager',"
160 "member='PrepareForSleep',"
161 "path='/org/freedesktop/login1'",
162 match_prepare_for_sleep,
163 m);
164 if (r < 0)
165 return log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
166
e331e246
TG
167 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m);
168 if (r < 0)
169 return log_error_errno(r, "Failed to add manager object vtable: %m");
170
171 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m);
172 if (r < 0)
173 return log_error_errno(r, "Failed to add link object vtable: %m");
174
175 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
176 if (r < 0)
177 return log_error_errno(r, "Failed to add link enumerator: %m");
3175fcde
TG
178
179 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m);
180 if (r < 0)
181 return log_error_errno(r, "Failed to add network object vtable: %m");
182
183 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m);
184 if (r < 0)
185 return log_error_errno(r, "Failed to add network enumerator: %m");
e331e246
TG
186
187 r = sd_bus_request_name(m->bus, "org.freedesktop.network1", 0);
188 if (r < 0)
189 return log_error_errno(r, "Failed to register name: %m");
190
191 r = sd_bus_attach_event(m->bus, m->event, 0);
192 if (r < 0)
193 return log_error_errno(r, "Failed to attach bus to event loop: %m");
194
9c0a72f9
TG
195 return 0;
196}
197
5fae368b
TG
198static int manager_udev_process_link(Manager *m, struct udev_device *device) {
199 Link *link = NULL;
200 int r, ifindex;
5544ee85 201
5fae368b
TG
202 assert(m);
203 assert(device);
5544ee85 204
5fae368b
TG
205 if (!streq_ptr(udev_device_get_action(device), "add"))
206 return 0;
5544ee85 207
5fae368b
TG
208 ifindex = udev_device_get_ifindex(device);
209 if (ifindex <= 0) {
2f3cf1f9 210 log_debug("Ignoring udev ADD event for device with invalid ifindex");
5fae368b 211 return 0;
5544ee85
TG
212 }
213
5fae368b
TG
214 r = link_get(m, ifindex, &link);
215 if (r == -ENODEV)
216 return 0;
217 else if (r < 0)
f579559b
TG
218 return r;
219
5fae368b 220 r = link_initialized(link, device);
44de0efc
LP
221 if (r < 0)
222 return r;
223
5fae368b
TG
224 return 0;
225}
be660c37 226
5fae368b
TG
227static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
228 Manager *m = userdata;
229 struct udev_monitor *monitor = m->udev_monitor;
230 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
f579559b 231
5fae368b
TG
232 device = udev_monitor_receive_device(monitor);
233 if (!device)
02b59d57
TG
234 return -ENOMEM;
235
5fae368b 236 manager_udev_process_link(m, device);
f579559b
TG
237 return 0;
238}
239
5fae368b
TG
240static int manager_connect_udev(Manager *m) {
241 int r;
f579559b 242
5fae368b
TG
243 /* udev does not initialize devices inside containers,
244 * so we rely on them being already initialized before
245 * entering the container */
75f86906 246 if (detect_container() > 0)
5fae368b 247 return 0;
f579559b 248
5fae368b
TG
249 m->udev = udev_new();
250 if (!m->udev)
251 return -ENOMEM;
02b59d57 252
5fae368b
TG
253 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
254 if (!m->udev_monitor)
255 return -ENOMEM;
02b59d57 256
5fae368b 257 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
02b59d57 258 if (r < 0)
5fae368b 259 return log_error_errno(r, "Could not add udev monitor filter: %m");
02b59d57 260
5fae368b
TG
261 r = udev_monitor_enable_receiving(m->udev_monitor);
262 if (r < 0) {
263 log_error("Could not enable udev monitor");
02b59d57 264 return r;
667fcc6d 265 }
505f8da7 266
5fae368b
TG
267 r = sd_event_add_io(m->event,
268 &m->udev_event_source,
269 udev_monitor_get_fd(m->udev_monitor),
270 EPOLLIN, manager_dispatch_link_udev,
271 m);
272 if (r < 0)
667fcc6d 273 return r;
505f8da7 274
5fae368b 275 r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
505f8da7
TG
276 if (r < 0)
277 return r;
11a7f229 278
505f8da7
TG
279 return 0;
280}
f579559b 281
200a0868
TG
282int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
283 Manager *m = userdata;
284 Link *link = NULL;
285 uint16_t type;
200a0868 286 unsigned char flags;
054f0db4
TG
287 int family;
288 unsigned char prefixlen;
289 unsigned char scope;
290 union in_addr_union in_addr;
291 struct ifa_cacheinfo cinfo;
292 Address *address = NULL;
200a0868
TG
293 char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
294 const char *valid_str = NULL;
295 int r, ifindex;
296
297 assert(rtnl);
298 assert(message);
299 assert(m);
300
301 if (sd_netlink_message_is_error(message)) {
302 r = sd_netlink_message_get_errno(message);
303 if (r < 0)
304 log_warning_errno(r, "rtnl: failed to receive address: %m");
305
306 return 0;
307 }
308
309 r = sd_netlink_message_get_type(message, &type);
310 if (r < 0) {
311 log_warning_errno(r, "rtnl: could not get message type: %m");
312 return 0;
313 } else if (type != RTM_NEWADDR && type != RTM_DELADDR) {
314 log_warning("rtnl: received unexpected message type when processing address");
315 return 0;
316 }
317
318 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
319 if (r < 0) {
320 log_warning_errno(r, "rtnl: could not get ifindex from address: %m");
321 return 0;
322 } else if (ifindex <= 0) {
323 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
324 return 0;
325 } else {
326 r = link_get(m, ifindex, &link);
327 if (r < 0 || !link) {
328 /* when enumerating we might be out of sync, but we will
329 * get the address again, so just ignore it */
330 if (!m->enumerating)
331 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
332 return 0;
333 }
334 }
335
054f0db4
TG
336 r = sd_rtnl_message_addr_get_family(message, &family);
337 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
200a0868
TG
338 log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
339 return 0;
340 }
341
054f0db4 342 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
200a0868
TG
343 if (r < 0) {
344 log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m");
345 return 0;
346 }
347
054f0db4 348 r = sd_rtnl_message_addr_get_scope(message, &scope);
200a0868
TG
349 if (r < 0) {
350 log_link_warning_errno(link, r, "rtnl: received address with invalid scope, ignoring: %m");
351 return 0;
352 }
353
354 r = sd_rtnl_message_addr_get_flags(message, &flags);
355 if (r < 0) {
356 log_link_warning_errno(link, r, "rtnl: received address with invalid flags, ignoring: %m");
357 return 0;
358 }
200a0868 359
054f0db4 360 switch (family) {
200a0868 361 case AF_INET:
054f0db4 362 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
200a0868
TG
363 if (r < 0) {
364 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
365 return 0;
366 }
367
368 break;
369
370 case AF_INET6:
054f0db4 371 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
200a0868
TG
372 if (r < 0) {
373 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
374 return 0;
375 }
376
377 break;
378
379 default:
380 assert_not_reached("invalid address family");
381 }
382
054f0db4 383 if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) {
200a0868
TG
384 log_link_warning(link, "Could not print address");
385 return 0;
386 }
387
054f0db4 388 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
200a0868 389 if (r >= 0) {
054f0db4 390 if (cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
200a0868
TG
391 valid_str = "ever";
392 else
393 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
054f0db4 394 cinfo.ifa_valid * USEC_PER_SEC,
200a0868
TG
395 USEC_PER_SEC);
396 }
397
054f0db4 398 address_get(link, family, &in_addr, prefixlen, &address);
200a0868
TG
399
400 switch (type) {
401 case RTM_NEWADDR:
36c32f61 402 if (address)
054f0db4 403 log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
36c32f61 404 else {
adda1ed9
TG
405 /* An address appeared that we did not request */
406 r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
cf1d700d 407 if (r < 0) {
054f0db4 408 log_link_warning_errno(link, r, "Failed to add address %s/%u: %m", buf, prefixlen);
cf1d700d
TG
409 return 0;
410 } else
054f0db4 411 log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
200a0868
TG
412 }
413
58fda79c 414 address_update(address, flags, scope, &cinfo);
36c32f61 415
200a0868
TG
416 break;
417
418 case RTM_DELADDR:
419
054f0db4
TG
420 if (address) {
421 log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
91b5f997 422 address_drop(address);
200a0868 423 } else
054f0db4 424 log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, prefixlen, valid_str);
200a0868
TG
425
426 break;
427 default:
428 assert_not_reached("Received invalid RTNL message type");
429 }
430
431 return 1;
432}
433
1c4baffc 434static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
505f8da7
TG
435 Manager *m = userdata;
436 Link *link = NULL;
4d473d5d 437 NetDev *netdev = NULL;
f2236469 438 uint16_t type;
ca4e095a 439 const char *name;
505f8da7 440 int r, ifindex;
f579559b 441
505f8da7
TG
442 assert(rtnl);
443 assert(message);
f579559b
TG
444 assert(m);
445
1c4baffc
TG
446 if (sd_netlink_message_is_error(message)) {
447 r = sd_netlink_message_get_errno(message);
45af44d4 448 if (r < 0)
2f3cf1f9 449 log_warning_errno(r, "rtnl: Could not receive link: %m");
45af44d4
TG
450
451 return 0;
452 }
453
1c4baffc 454 r = sd_netlink_message_get_type(message, &type);
f2236469 455 if (r < 0) {
2f3cf1f9 456 log_warning_errno(r, "rtnl: Could not get message type: %m");
f2236469 457 return 0;
cdfee943 458 } else if (type != RTM_NEWLINK && type != RTM_DELLINK) {
2f3cf1f9 459 log_warning("rtnl: Received unexpected message type when processing link");
cdfee943 460 return 0;
f2236469
TG
461 }
462
505f8da7 463 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
45af44d4 464 if (r < 0) {
2f3cf1f9 465 log_warning_errno(r, "rtnl: Could not get ifindex from link: %m");
45af44d4
TG
466 return 0;
467 } else if (ifindex <= 0) {
468 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
505f8da7 469 return 0;
4d473d5d
TG
470 } else
471 link_get(m, ifindex, &link);
f579559b 472
1c4baffc 473 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
45af44d4 474 if (r < 0) {
2f3cf1f9 475 log_warning_errno(r, "rtnl: Received link message without ifname: %m");
4d473d5d
TG
476 return 0;
477 } else
f2236469 478 netdev_get(m, name, &netdev);
4d473d5d
TG
479
480 switch (type) {
481 case RTM_NEWLINK:
482 if (!link) {
483 /* link is new, so add it */
484 r = link_add(m, message, &link);
485 if (r < 0) {
2f3cf1f9 486 log_warning_errno(r, "Could not add new link: %m");
4d473d5d
TG
487 return 0;
488 }
489 }
490
491 if (netdev) {
492 /* netdev exists, so make sure the ifindex matches */
505f8da7
TG
493 r = netdev_set_ifindex(netdev, message);
494 if (r < 0) {
2f3cf1f9 495 log_warning_errno(r, "Could not set ifindex on netdev: %m");
505f8da7
TG
496 return 0;
497 }
498 }
e1202047 499
f2236469
TG
500 r = link_update(link, message);
501 if (r < 0)
502 return 0;
4d473d5d
TG
503
504 break;
505
506 case RTM_DELLINK:
507 link_drop(link);
508 netdev_drop(netdev);
509
510 break;
511
512 default:
513 assert_not_reached("Received invalid RTNL message type.");
f2236469 514 }
505f8da7
TG
515
516 return 1;
517}
518
5fae368b
TG
519static int systemd_netlink_fd(void) {
520 int n, fd, rtnl_fd = -EINVAL;
521
522 n = sd_listen_fds(true);
523 if (n <= 0)
524 return -EINVAL;
525
526 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
527 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
528 if (rtnl_fd >= 0)
529 return -EINVAL;
530
531 rtnl_fd = fd;
532 }
533 }
534
535 return rtnl_fd;
536}
537
538static int manager_connect_rtnl(Manager *m) {
539 int fd, r;
505f8da7
TG
540
541 assert(m);
505f8da7 542
5fae368b
TG
543 fd = systemd_netlink_fd();
544 if (fd < 0)
1c4baffc 545 r = sd_netlink_open(&m->rtnl);
5fae368b 546 else
1c4baffc 547 r = sd_netlink_open_fd(&m->rtnl, fd);
505f8da7
TG
548 if (r < 0)
549 return r;
550
1c4baffc 551 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
f579559b 552 if (r < 0)
bf5332d2 553 return r;
f579559b 554
1c4baffc 555 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
505f8da7
TG
556 if (r < 0)
557 return r;
f579559b 558
1c4baffc 559 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
5fae368b
TG
560 if (r < 0)
561 return r;
505f8da7 562
1c4baffc 563 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
5fae368b
TG
564 if (r < 0)
565 return r;
45af44d4 566
200a0868 567 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
5fae368b
TG
568 if (r < 0)
569 return r;
570
200a0868 571 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
5fae368b
TG
572 if (r < 0)
573 return r;
574
575 return 0;
45af44d4 576}
505f8da7 577
84de38c5
TG
578static int set_put_in_addr(Set *s, const struct in_addr *address) {
579 char *p;
580 int r;
581
582 assert(s);
583
584 r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
585 if (r < 0)
586 return r;
587
588 r = set_consume(s, p);
589 if (r == -EEXIST)
590 return 0;
591
592 return r;
593}
594
595static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
596 int r, i, c = 0;
597
598 assert(s);
599 assert(n <= 0 || addresses);
600
601 for (i = 0; i < n; i++) {
602 r = set_put_in_addr(s, addresses+i);
603 if (r < 0)
604 return r;
605
606 c += r;
607 }
608
609 return c;
610}
611
612static void print_string_set(FILE *f, const char *field, Set *s) {
613 bool space = false;
614 Iterator i;
615 char *p;
616
617 if (set_isempty(s))
618 return;
619
620 fputs(field, f);
621
622 SET_FOREACH(p, s, i) {
623 if (space)
624 fputc(' ', f);
625 fputs(p, f);
626 space = true;
627 }
628 fputc('\n', f);
629}
630
631static int manager_save(Manager *m) {
632 _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
633 Link *link;
634 Iterator i;
635 _cleanup_free_ char *temp_path = NULL;
636 _cleanup_fclose_ FILE *f = NULL;
637 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
638 const char *operstate_str;
639 int r;
640
641 assert(m);
642 assert(m->state_file);
643
644 /* We add all NTP and DNS server to a set, to filter out duplicates */
645 dns = set_new(&string_hash_ops);
646 if (!dns)
647 return -ENOMEM;
648
649 ntp = set_new(&string_hash_ops);
650 if (!ntp)
651 return -ENOMEM;
652
653 domains = set_new(&string_hash_ops);
654 if (!domains)
655 return -ENOMEM;
656
657 HASHMAP_FOREACH(link, m->links, i) {
658 if (link->flags & IFF_LOOPBACK)
659 continue;
660
661 if (link->operstate > operstate)
662 operstate = link->operstate;
663
664 if (!link->network)
665 continue;
666
667 /* First add the static configured entries */
668 r = set_put_strdupv(dns, link->network->dns);
669 if (r < 0)
670 return r;
671
672 r = set_put_strdupv(ntp, link->network->ntp);
673 if (r < 0)
674 return r;
675
676 r = set_put_strdupv(domains, link->network->domains);
677 if (r < 0)
678 return r;
679
680 if (!link->dhcp_lease)
681 continue;
682
683 /* Secondly, add the entries acquired via DHCP */
684 if (link->network->dhcp_dns) {
685 const struct in_addr *addresses;
686
687 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
688 if (r > 0) {
689 r = set_put_in_addrv(dns, addresses, r);
690 if (r < 0)
691 return r;
692 } else if (r < 0 && r != -ENODATA)
693 return r;
694 }
695
696 if (link->network->dhcp_ntp) {
697 const struct in_addr *addresses;
698
699 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
700 if (r > 0) {
701 r = set_put_in_addrv(ntp, addresses, r);
702 if (r < 0)
703 return r;
704 } else if (r < 0 && r != -ENODATA)
705 return r;
706 }
707
708 if (link->network->dhcp_domains) {
709 const char *domainname;
710
711 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
712 if (r >= 0) {
713 r = set_put_strdup(domains, domainname);
714 if (r < 0)
715 return r;
716 } else if (r != -ENODATA)
717 return r;
718 }
719 }
720
721 operstate_str = link_operstate_to_string(operstate);
722 assert(operstate_str);
723
724 r = fopen_temporary(m->state_file, &f, &temp_path);
725 if (r < 0)
726 return r;
727
728 fchmod(fileno(f), 0644);
729
730 fprintf(f,
731 "# This is private data. Do not parse.\n"
732 "OPER_STATE=%s\n", operstate_str);
733
734 print_string_set(f, "DNS=", dns);
735 print_string_set(f, "NTP=", ntp);
736 print_string_set(f, "DOMAINS=", domains);
737
738 r = fflush_and_check(f);
739 if (r < 0)
740 goto fail;
741
742 if (rename(temp_path, m->state_file) < 0) {
743 r = -errno;
744 goto fail;
745 }
746
747 if (m->operational_state != operstate) {
748 m->operational_state = operstate;
749 r = manager_send_changed(m, "OperationalState", NULL);
750 if (r < 0)
751 log_error_errno(r, "Could not emit changed OperationalState: %m");
752 }
753
754 m->dirty = false;
755
756 return 0;
757
758fail:
759 (void) unlink(m->state_file);
760 (void) unlink(temp_path);
761
762 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
763}
764
765static int manager_dirty_handler(sd_event_source *s, void *userdata) {
766 Manager *m = userdata;
767 Link *link;
768 Iterator i;
769 int r;
770
771 assert(m);
772
773 if (m->dirty)
774 manager_save(m);
775
776 SET_FOREACH(link, m->dirty_links, i) {
777 r = link_save(link);
778 if (r >= 0)
779 link_clean(link);
780 }
781
782 return 1;
783}
784
5fae368b
TG
785int manager_new(Manager **ret) {
786 _cleanup_manager_free_ Manager *m = NULL;
45af44d4 787 int r;
f579559b 788
5fae368b
TG
789 m = new0(Manager, 1);
790 if (!m)
791 return -ENOMEM;
45af44d4 792
5fae368b
TG
793 m->state_file = strdup("/run/systemd/netif/state");
794 if (!m->state_file)
795 return -ENOMEM;
796
797 r = sd_event_default(&m->event);
45af44d4
TG
798 if (r < 0)
799 return r;
800
5fae368b
TG
801 sd_event_set_watchdog(m->event, true);
802
803 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
804 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
805
84de38c5
TG
806 r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
807 if (r < 0)
808 return r;
809
5fae368b 810 r = manager_connect_rtnl(m);
45af44d4
TG
811 if (r < 0)
812 return r;
813
5fae368b
TG
814 r = manager_connect_udev(m);
815 if (r < 0)
816 return r;
45af44d4 817
5fae368b
TG
818 m->netdevs = hashmap_new(&string_hash_ops);
819 if (!m->netdevs)
820 return -ENOMEM;
f579559b 821
5fae368b 822 LIST_HEAD_INIT(m->networks);
f579559b 823
5fae368b
TG
824 r = setup_default_address_pool(m);
825 if (r < 0)
826 return r;
f579559b 827
5fae368b
TG
828 *ret = m;
829 m = NULL;
f579559b 830
f579559b
TG
831 return 0;
832}
833
5fae368b
TG
834void manager_free(Manager *m) {
835 Network *network;
836 NetDev *netdev;
837 Link *link;
838 AddressPool *pool;
f579559b 839
5fae368b
TG
840 if (!m)
841 return;
505f8da7 842
5fae368b 843 free(m->state_file);
505f8da7 844
5fae368b
TG
845 while ((link = hashmap_first(m->links)))
846 link_unref(link);
847 hashmap_free(m->links);
f579559b 848
5fae368b
TG
849 while ((network = m->networks))
850 network_free(network);
851
dbffab87
TG
852 hashmap_free(m->networks_by_name);
853
5fae368b
TG
854 while ((netdev = hashmap_first(m->netdevs)))
855 netdev_unref(netdev);
856 hashmap_free(m->netdevs);
857
858 while ((pool = m->address_pools))
859 address_pool_free(pool);
860
1c4baffc 861 sd_netlink_unref(m->rtnl);
2f5b4a77 862 sd_event_unref(m->event);
5fae368b 863
7d20d375
TG
864 sd_event_source_unref(m->udev_event_source);
865 udev_monitor_unref(m->udev_monitor);
866 udev_unref(m->udev);
867
868 sd_bus_unref(m->bus);
869 sd_bus_slot_unref(m->prepare_for_sleep_slot);
870 sd_event_source_unref(m->bus_retry_event_source);
871
5fae368b
TG
872 free(m);
873}
874
a97dcc12
TG
875static bool manager_check_idle(void *userdata) {
876 Manager *m = userdata;
877 Link *link;
878 Iterator i;
879
880 assert(m);
881
882 HASHMAP_FOREACH(link, m->links, i) {
883 /* we are not woken on udev activity, so let's just wait for the
884 * pending udev event */
885 if (link->state == LINK_STATE_PENDING)
886 return false;
887
888 if (!link->network)
889 continue;
890
891 /* we are not woken on netork activity, so let's stay around */
892 if (link_lldp_enabled(link) ||
893 link_ipv4ll_enabled(link) ||
894 link_dhcp4_server_enabled(link) ||
895 link_dhcp4_enabled(link) ||
896 link_dhcp6_enabled(link))
897 return false;
898 }
899
900 return true;
901}
902
903int manager_run(Manager *m) {
84de38c5
TG
904 Link *link;
905 Iterator i;
906
a97dcc12
TG
907 assert(m);
908
84de38c5
TG
909 /* The dirty handler will deal with future serialization, but the first one
910 must be done explicitly. */
911
912 manager_save(m);
913
914 HASHMAP_FOREACH(link, m->links, i)
915 link_save(link);
916
f806f64c
TG
917 if (m->bus)
918 return bus_event_loop_with_idle(
919 m->event,
920 m->bus,
921 "org.freedesktop.network1",
922 DEFAULT_EXIT_USEC,
923 manager_check_idle,
924 m);
925 else
926 /* failed to connect to the bus, so we lose exit-on-idle logic,
927 this should not happen except if dbus is not around at all */
928 return sd_event_loop(m->event);
a97dcc12
TG
929}
930
5fae368b
TG
931int manager_load_config(Manager *m) {
932 int r;
933
934 /* update timestamp */
935 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
936
937 r = netdev_load(m);
f579559b
TG
938 if (r < 0)
939 return r;
940
5fae368b 941 r = network_load(m);
9021bb9f
TG
942 if (r < 0)
943 return r;
944
f579559b
TG
945 return 0;
946}
f882c247 947
5fae368b
TG
948bool manager_should_reload(Manager *m) {
949 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
950}
951
952int manager_rtnl_enumerate_links(Manager *m) {
1c4baffc
TG
953 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
954 sd_netlink_message *link;
f882c247
TG
955 int r;
956
5da8149f 957 assert(m);
5fae368b 958 assert(m->rtnl);
5da8149f 959
5fae368b 960 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
f882c247
TG
961 if (r < 0)
962 return r;
963
1c4baffc 964 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
965 if (r < 0)
966 return r;
967
1c4baffc 968 r = sd_netlink_call(m->rtnl, req, 0, &reply);
f2236469
TG
969 if (r < 0)
970 return r;
971
1c4baffc 972 for (link = reply; link; link = sd_netlink_message_next(link)) {
5fae368b 973 int k;
2e9f08ea 974
6a24f148
TG
975 m->enumerating = true;
976
5fae368b
TG
977 k = manager_rtnl_process_link(m->rtnl, link, m);
978 if (k < 0)
979 r = k;
6a24f148
TG
980
981 m->enumerating = false;
5fae368b 982 }
2e9f08ea 983
5fae368b 984 return r;
f882c247 985}
3bef724f 986
5fae368b 987int manager_rtnl_enumerate_addresses(Manager *m) {
1c4baffc
TG
988 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
989 sd_netlink_message *addr;
1346b1f0
TG
990 int r;
991
5fae368b
TG
992 assert(m);
993 assert(m->rtnl);
bcbca829 994
5fae368b
TG
995 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
996 if (r < 0)
997 return r;
bcbca829 998
1c4baffc 999 r = sd_netlink_message_request_dump(req, true);
1346b1f0
TG
1000 if (r < 0)
1001 return r;
1002
1c4baffc 1003 r = sd_netlink_call(m->rtnl, req, 0, &reply);
5fae368b
TG
1004 if (r < 0)
1005 return r;
1006
1c4baffc 1007 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
5fae368b
TG
1008 int k;
1009
6a24f148
TG
1010 m->enumerating = true;
1011
200a0868 1012 k = manager_rtnl_process_address(m->rtnl, addr, m);
5fae368b
TG
1013 if (k < 0)
1014 r = k;
6a24f148
TG
1015
1016 m->enumerating = false;
5fae368b
TG
1017 }
1018
1019 return r;
1346b1f0
TG
1020}
1021
0dd25fb9 1022int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
11bf3cce
LP
1023 AddressPool *p;
1024 int r;
1025
1026 assert(m);
1027 assert(prefixlen > 0);
1028 assert(found);
1029
1030 LIST_FOREACH(address_pools, p, m->address_pools) {
1031 if (p->family != family)
1032 continue;
1033
1034 r = address_pool_acquire(p, prefixlen, found);
1035 if (r != 0)
1036 return r;
1037 }
1038
1039 return 0;
1040}
4f5f911e
LP
1041
1042Link* manager_find_uplink(Manager *m, Link *exclude) {
1043 _cleanup_free_ struct local_address *gateways = NULL;
1044 int n, i;
1045
1046 assert(m);
1047
1048 /* Looks for a suitable "uplink", via black magic: an
1049 * interface that is up and where the default route with the
1050 * highest priority points to. */
1051
1052 n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
1053 if (n < 0) {
1054 log_warning_errno(n, "Failed to determine list of default gateways: %m");
1055 return NULL;
1056 }
1057
1058 for (i = 0; i < n; i++) {
1059 Link *link;
1060
1061 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
1062 if (!link) {
c2c940bd 1063 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
4f5f911e
LP
1064 continue;
1065 }
1066
1067 if (link == exclude)
1068 continue;
1069
1070 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1071 continue;
1072
1073 return link;
1074 }
1075
1076 return NULL;
1077}
84de38c5
TG
1078
1079void manager_dirty(Manager *manager) {
1080 assert(manager);
1081
1082 /* the serialized state in /run is no longer up-to-date */
1083 manager->dirty = true;
1084}