]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/network/networkd-link.c
networkd: link - make check for whether addresses/routes are being configured implicit
[thirdparty/systemd.git] / src / network / networkd-link.c
... / ...
CommitLineData
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 <netinet/ether.h>
23#include <linux/if.h>
24#include <unistd.h>
25
26#include "networkd-link.h"
27#include "networkd-netdev.h"
28#include "libudev-private.h"
29#include "udev-util.h"
30#include "util.h"
31#include "virt.h"
32#include "bus-util.h"
33#include "network-internal.h"
34#include "conf-parser.h"
35
36#include "dhcp-lease-internal.h"
37
38static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
39 _cleanup_link_unref_ Link *link = NULL;
40 uint16_t type;
41 const char *ifname;
42 int r, ifindex;
43
44 assert(manager);
45 assert(message);
46 assert(ret);
47
48 r = sd_rtnl_message_get_type(message, &type);
49 if (r < 0)
50 return r;
51 else if (type != RTM_NEWLINK)
52 return -EINVAL;
53
54 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
55 if (r < 0)
56 return r;
57 else if (ifindex <= 0)
58 return -EINVAL;
59
60 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
61 if (r < 0)
62 return r;
63
64 link = new0(Link, 1);
65 if (!link)
66 return -ENOMEM;
67
68 link->n_ref = 1;
69 link->manager = manager;
70 link->state = LINK_STATE_INITIALIZING;
71 link->ifindex = ifindex;
72 link->ifname = strdup(ifname);
73 if (!link->ifname)
74 return -ENOMEM;
75
76 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
77 if (r < 0)
78 log_debug_link(link, "MAC address not found for new device, continuing without");
79
80 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex);
81 if (r < 0)
82 return -ENOMEM;
83
84 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex);
85 if (r < 0)
86 return -ENOMEM;
87
88 r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
89 if (r < 0)
90 return r;
91
92 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
93 if (r < 0)
94 return r;
95
96 *ret = link;
97 link = NULL;
98
99 return 0;
100}
101
102static void link_free(Link *link) {
103 Address *address;
104
105 if (!link)
106 return;
107
108 while ((address = link->addresses)) {
109 LIST_REMOVE(addresses, link->addresses, address);
110 address_free(address);
111 }
112
113 while ((address = link->pool_addresses)) {
114 LIST_REMOVE(addresses, link->pool_addresses, address);
115 address_free(address);
116 }
117
118 sd_dhcp_client_unref(link->dhcp_client);
119 sd_dhcp_lease_unref(link->dhcp_lease);
120
121 unlink(link->lease_file);
122 free(link->lease_file);
123
124 sd_ipv4ll_unref(link->ipv4ll);
125 sd_dhcp6_client_unref(link->dhcp6_client);
126 sd_icmp6_nd_unref(link->icmp6_router_discovery);
127
128 if (link->manager)
129 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
130
131 free(link->ifname);
132
133 unlink(link->state_file);
134 free(link->state_file);
135
136 udev_device_unref(link->udev_device);
137
138 free(link);
139}
140
141Link *link_unref(Link *link) {
142 if (link && (-- link->n_ref <= 0))
143 link_free(link);
144
145 return NULL;
146}
147
148Link *link_ref(Link *link) {
149 if (link)
150 assert_se(++ link->n_ref >= 2);
151
152 return link;
153}
154
155int link_get(Manager *m, int ifindex, Link **ret) {
156 Link *link;
157
158 assert(m);
159 assert(ifindex);
160 assert(ret);
161
162 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
163 if (!link)
164 return -ENODEV;
165
166 *ret = link;
167
168 return 0;
169}
170
171void link_drop(Link *link) {
172 if (!link || link->state == LINK_STATE_LINGER)
173 return;
174
175 link->state = LINK_STATE_LINGER;
176
177 log_debug_link(link, "link removed");
178
179 link_unref(link);
180
181 return;
182}
183
184static void link_enter_unmanaged(Link *link) {
185 assert(link);
186
187 log_debug_link(link, "unmanaged");
188
189 link->state = LINK_STATE_UNMANAGED;
190
191 link_save(link);
192}
193
194static int link_stop_clients(Link *link) {
195 int r = 0, k;
196
197 assert(link);
198 assert(link->manager);
199 assert(link->manager->event);
200
201 if (!link->network)
202 return 0;
203
204 if (link->dhcp_client) {
205 k = sd_dhcp_client_stop(link->dhcp_client);
206 if (k < 0) {
207 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
208 r = k;
209 }
210 }
211
212 if (link->ipv4ll) {
213 k = sd_ipv4ll_stop(link->ipv4ll);
214 if (k < 0) {
215 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
216 r = k;
217 }
218 }
219
220 if (link->dhcp_server) {
221 k = sd_dhcp_server_stop(link->dhcp_server);
222 if (k < 0) {
223 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
224 r = k;
225 }
226 }
227
228 if(link->icmp6_router_discovery) {
229
230 if (link->dhcp6_client) {
231 k = sd_dhcp6_client_stop(link->dhcp6_client);
232 if (k < 0) {
233 log_warning_link(link, "Could not stop DHCPv6 client: %s", strerror(-r));
234 r = k;
235 }
236 }
237
238 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
239 if (k < 0) {
240 log_warning_link(link, "Could not stop ICMPv6 router discovery: %s", strerror(-r));
241 r = k;
242 }
243 }
244
245 return r;
246}
247
248static void link_enter_failed(Link *link) {
249 assert(link);
250
251 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
252 return;
253
254 log_warning_link(link, "failed");
255
256 link->state = LINK_STATE_FAILED;
257
258 link_stop_clients(link);
259
260 link_save(link);
261}
262
263static Address* link_find_dhcp_server_address(Link *link) {
264 Address *address;
265
266 assert(link);
267 assert(link->network);
268
269 /* The the first statically configured address if there is any */
270 LIST_FOREACH(addresses, address, link->network->static_addresses) {
271
272 if (address->family != AF_INET)
273 continue;
274
275 if (in_addr_is_null(address->family, &address->in_addr))
276 continue;
277
278 return address;
279 }
280
281 /* If that didn't work, find a suitable address we got from the pool */
282 LIST_FOREACH(addresses, address, link->pool_addresses) {
283 if (address->family != AF_INET)
284 continue;
285
286 return address;
287 }
288
289 return NULL;
290}
291
292static int link_enter_configured(Link *link) {
293 int r;
294
295 assert(link);
296 assert(link->network);
297 assert(link->state == LINK_STATE_SETTING_ROUTES);
298
299 if (link->network->dhcp_server &&
300 !sd_dhcp_server_is_running(link->dhcp_server)) {
301 struct in_addr pool_start;
302 Address *address;
303
304 address = link_find_dhcp_server_address(link);
305 if (!address) {
306 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
307 link_enter_failed(link);
308 return 0;
309 }
310
311 log_debug_link(link, "offering DHCPv4 leases");
312
313 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in, address->prefixlen);
314 if (r < 0)
315 return r;
316
317 /* offer 32 addresses starting from the address following the server address */
318 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
319 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
320 &pool_start, 32);
321 if (r < 0)
322 return r;
323
324 /* TODO:
325 r = sd_dhcp_server_set_router(link->dhcp_server,
326 &main_address->in_addr.in);
327 if (r < 0)
328 return r;
329
330 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
331 main_address->prefixlen);
332 if (r < 0)
333 return r;
334 */
335
336 r = sd_dhcp_server_start(link->dhcp_server);
337 if (r < 0) {
338 log_warning_link(link, "could not start DHCPv4 server "
339 "instance: %s", strerror(-r));
340
341 link_enter_failed(link);
342
343 return 0;
344 }
345 }
346
347 log_info_link(link, "link configured");
348
349 link->state = LINK_STATE_CONFIGURED;
350
351 link_save(link);
352
353 return 0;
354}
355
356static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
357 _cleanup_link_unref_ Link *link = userdata;
358 int r;
359
360 assert(link->route_messages > 0);
361 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
362 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
363 LINK_STATE_LINGER));
364
365 link->route_messages --;
366
367 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER))
368 return 1;
369
370 r = sd_rtnl_message_get_errno(m);
371 if (r < 0 && r != -EEXIST)
372 log_struct_link(LOG_WARNING, link,
373 "MESSAGE=%-*s: could not set route: %s",
374 IFNAMSIZ,
375 link->ifname, strerror(-r),
376 "ERRNO=%d", -r,
377 NULL);
378
379 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
380 * ignore it */
381 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
382 log_debug_link(link, "routes set");
383 link_enter_configured(link);
384 }
385
386 return 1;
387}
388
389static int link_set_dhcp_routes(Link *link) {
390 struct sd_dhcp_route *static_routes;
391 int r, n, i;
392
393 assert(link);
394
395 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
396 if (n < 0) {
397 if (n != -ENOENT)
398 log_warning_link(link, "DHCP error: could not get routes: %s", strerror(-n));
399 return n;
400 }
401
402 for (i = 0; i < n; i++) {
403 _cleanup_route_free_ Route *route = NULL;
404
405 r = route_new_dynamic(&route, RTPROT_DHCP);
406 if (r < 0) {
407 log_error_link(link, "Could not allocate route: %s",
408 strerror(-r));
409 return r;
410 }
411
412 route->family = AF_INET;
413 route->in_addr.in = static_routes[i].gw_addr;
414 route->dst_addr.in = static_routes[i].dst_addr;
415 route->dst_prefixlen = static_routes[i].dst_prefixlen;
416 route->metrics = DHCP_ROUTE_METRIC;
417
418 r = route_configure(route, link, &route_handler);
419 if (r < 0) {
420 log_warning_link(link,
421 "could not set host route: %s", strerror(-r));
422 return r;
423 }
424
425 link->route_messages ++;
426 }
427
428 return 0;
429}
430
431static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
432 int r;
433 struct in_addr addr;
434
435 if (!ll)
436 return false;
437
438 r = sd_ipv4ll_get_address(ll, &addr);
439 if (r < 0)
440 return false;
441
442 return true;
443}
444
445static int link_enter_set_routes(Link *link) {
446 Route *rt;
447 int r;
448
449 assert(link);
450 assert(link->network);
451 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
452
453 link->state = LINK_STATE_SETTING_ROUTES;
454
455 LIST_FOREACH(routes, rt, link->network->static_routes) {
456 r = route_configure(rt, link, &route_handler);
457 if (r < 0) {
458 log_warning_link(link,
459 "could not set routes: %s", strerror(-r));
460 link_enter_failed(link);
461 return r;
462 }
463
464 link->route_messages ++;
465 }
466
467 if (ipv4ll_is_bound(link->ipv4ll)) {
468 _cleanup_route_free_ Route *route = NULL;
469
470 r = route_new_dynamic(&route, RTPROT_STATIC);
471 if (r < 0) {
472 log_error_link(link, "Could not allocate route: %s",
473 strerror(-r));
474 return r;
475 }
476
477 route->family = AF_INET;
478 route->scope = RT_SCOPE_LINK;
479 route->metrics = IPV4LL_ROUTE_METRIC;
480
481 r = route_configure(route, link, &route_handler);
482 if (r < 0) {
483 log_warning_link(link,
484 "could not set routes: %s", strerror(-r));
485 link_enter_failed(link);
486 return r;
487 }
488
489 link->route_messages ++;
490 }
491
492 if (link->dhcp_lease) {
493 _cleanup_route_free_ Route *route = NULL;
494 _cleanup_route_free_ Route *route_gw = NULL;
495 struct in_addr gateway;
496
497 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
498 if (r < 0 && r != -ENOENT) {
499 log_warning_link(link, "DHCP error: could not get gateway: %s",
500 strerror(-r));
501 return r;
502 }
503
504 if (r >= 0) {
505 r = route_new_dynamic(&route, RTPROT_DHCP);
506 if (r < 0) {
507 log_error_link(link, "Could not allocate route: %s",
508 strerror(-r));
509 return r;
510 }
511
512 r = route_new_dynamic(&route_gw, RTPROT_DHCP);
513 if (r < 0) {
514 log_error_link(link, "Could not allocate route: %s",
515 strerror(-r));
516 return r;
517 }
518
519 /* The dhcp netmask may mask out the gateway. Add an explicit
520 * route for the gw host so that we can route no matter the
521 * netmask or existing kernel route tables. */
522 route_gw->family = AF_INET;
523 route_gw->dst_addr.in = gateway;
524 route_gw->dst_prefixlen = 32;
525 route_gw->scope = RT_SCOPE_LINK;
526 route_gw->metrics = DHCP_ROUTE_METRIC;
527
528 r = route_configure(route_gw, link, &route_handler);
529 if (r < 0) {
530 log_warning_link(link,
531 "could not set host route: %s", strerror(-r));
532 return r;
533 }
534
535 link->route_messages ++;
536
537 route->family = AF_INET;
538 route->in_addr.in = gateway;
539 route->metrics = DHCP_ROUTE_METRIC;
540
541 r = route_configure(route, link, &route_handler);
542 if (r < 0) {
543 log_warning_link(link,
544 "could not set routes: %s", strerror(-r));
545 link_enter_failed(link);
546 return r;
547 }
548
549 link->route_messages ++;
550 }
551
552 if (link->network->dhcp_routes)
553 link_set_dhcp_routes(link);
554 }
555
556 if (link->route_messages == 0) {
557 link_enter_configured(link);
558 } else
559 log_debug_link(link, "setting routes");
560
561 return 0;
562}
563
564static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
565 _cleanup_link_unref_ Link *link = userdata;
566 int r;
567
568 assert(m);
569 assert(link);
570 assert(link->ifname);
571
572 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
573 return 1;
574
575 r = sd_rtnl_message_get_errno(m);
576 if (r < 0 && r != -ESRCH)
577 log_struct_link(LOG_WARNING, link,
578 "MESSAGE=%-*s: could not drop route: %s",
579 IFNAMSIZ,
580 link->ifname, strerror(-r),
581 "ERRNO=%d", -r,
582 NULL);
583
584 return 1;
585}
586
587static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
588 _cleanup_link_unref_ Link *link = userdata;
589 int r;
590
591 assert(rtnl);
592 assert(m);
593 assert(link);
594 assert(link->manager);
595
596 for (; m; m = sd_rtnl_message_next(m)) {
597 r = sd_rtnl_message_get_errno(m);
598 if (r < 0) {
599 log_debug_link(link, "getting address failed: %s", strerror(-r));
600 continue;
601 }
602
603 r = link_rtnl_process_address(rtnl, m, link->manager);
604 if (r < 0)
605 log_warning_link(link, "could not process address: %s", strerror(-r));
606 }
607
608 return 1;
609}
610
611static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
612 _cleanup_link_unref_ Link *link = userdata;
613 int r;
614
615 assert(rtnl);
616 assert(m);
617 assert(link);
618 assert(link->ifname);
619 assert(link->addr_messages > 0);
620 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
621 LINK_STATE_FAILED, LINK_STATE_LINGER));
622
623 link->addr_messages --;
624
625 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
626 return 1;
627
628 r = sd_rtnl_message_get_errno(m);
629 if (r < 0 && r != -EEXIST)
630 log_struct_link(LOG_WARNING, link,
631 "MESSAGE=%-*s: could not set address: %s",
632 IFNAMSIZ,
633 link->ifname, strerror(-r),
634 "ERRNO=%d", -r,
635 NULL);
636 else if (r >= 0) {
637 /* calling handler directly so take a ref */
638 link_ref(link);
639 link_get_address_handler(rtnl, m, link);
640 }
641
642 if (link->addr_messages == 0) {
643 log_debug_link(link, "addresses set");
644 link_enter_set_routes(link);
645 }
646
647 return 1;
648}
649
650static int link_enter_set_addresses(Link *link) {
651 Address *ad;
652 int r;
653 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
654
655 assert(link);
656 assert(link->network);
657 assert(link->state != _LINK_STATE_INVALID);
658
659 link->state = LINK_STATE_SETTING_ADDRESSES;
660
661 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
662 r = address_configure(ad, link, &address_handler);
663 if (r < 0) {
664 log_warning_link(link,
665 "could not set addresses: %s", strerror(-r));
666 link_enter_failed(link);
667 return r;
668 }
669
670 link->addr_messages ++;
671 }
672
673 if (link->ipv4ll) {
674 _cleanup_address_free_ Address *ll_addr = NULL;
675 struct in_addr addr;
676
677 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
678 if (r < 0 && r != -ENOENT) {
679 log_warning_link(link, "IPV4LL error: no address: %s",
680 strerror(-r));
681 return r;
682 }
683
684 if (r != -ENOENT) {
685 r = address_new_dynamic(&ll_addr);
686 if (r < 0) {
687 log_error_link(link, "Could not allocate address: %s", strerror(-r));
688 return r;
689 }
690
691 ll_addr->family = AF_INET;
692 ll_addr->in_addr.in = addr;
693 ll_addr->prefixlen = 16;
694 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
695 ll_addr->scope = RT_SCOPE_LINK;
696
697 r = address_configure(ll_addr, link, &address_handler);
698 if (r < 0) {
699 log_warning_link(link,
700 "could not set addresses: %s", strerror(-r));
701 link_enter_failed(link);
702 return r;
703 }
704
705 link->addr_messages ++;
706 }
707 }
708
709 if (link->dhcp_lease) {
710 _cleanup_address_free_ Address *address = NULL;
711 struct in_addr addr;
712 struct in_addr netmask;
713 unsigned prefixlen;
714
715 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
716 if (r < 0) {
717 log_warning_link(link, "DHCP error: no address: %s",
718 strerror(-r));
719 return r;
720 }
721
722 if (!link->network->dhcp_critical) {
723 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
724 &lifetime);
725 if (r < 0) {
726 log_warning_link(link, "DHCP error: no lifetime: %s",
727 strerror(-r));
728 return r;
729 }
730 }
731
732 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
733 if (r < 0) {
734 log_warning_link(link, "DHCP error: no netmask: %s",
735 strerror(-r));
736 return r;
737 }
738
739 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
740
741 r = address_new_dynamic(&address);
742 if (r < 0) {
743 log_error_link(link, "Could not allocate address: %s",
744 strerror(-r));
745 return r;
746 }
747
748 address->family = AF_INET;
749 address->in_addr.in = addr;
750 address->cinfo.ifa_prefered = lifetime;
751 address->cinfo.ifa_valid = lifetime;
752 address->prefixlen = prefixlen;
753 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
754
755 /* use update rather than configure so that we will update the lifetime
756 of an existing address if it has already been configured */
757 r = address_update(address, link, &address_handler);
758 if (r < 0) {
759 log_warning_link(link,
760 "could not set addresses: %s", strerror(-r));
761 link_enter_failed(link);
762 return r;
763 }
764
765 link->addr_messages ++;
766 }
767
768 if (link->addr_messages == 0) {
769 link_enter_set_routes(link);
770 } else
771 log_debug_link(link, "setting addresses");
772
773 return 0;
774}
775
776static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
777 _cleanup_link_unref_ Link *link = userdata;
778 int r;
779
780 assert(m);
781 assert(link);
782 assert(link->ifname);
783
784 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
785 return 1;
786
787 r = sd_rtnl_message_get_errno(m);
788 if (r < 0 && r != -EADDRNOTAVAIL)
789 log_struct_link(LOG_WARNING, link,
790 "MESSAGE=%-*s: could not drop address: %s",
791 IFNAMSIZ,
792 link->ifname, strerror(-r),
793 "ERRNO=%d", -r,
794 NULL);
795
796 return 1;
797}
798
799static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
800 _cleanup_link_unref_ Link *link = userdata;
801 int r;
802
803 assert(link);
804
805 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
806 return 1;
807
808 r = sd_bus_message_get_errno(m);
809 if (r < 0)
810 r = -r;
811 if (r > 0)
812 log_warning_link(link, "Could not set hostname: %s", strerror(r));
813
814 return 1;
815}
816
817static int link_set_hostname(Link *link, const char *hostname) {
818 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
819 int r = 0;
820
821 assert(link);
822 assert(link->manager);
823 assert(hostname);
824
825 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
826
827 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
828 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
829 return 0;
830 }
831
832 r = sd_bus_message_new_method_call(
833 link->manager->bus,
834 &m,
835 "org.freedesktop.hostname1",
836 "/org/freedesktop/hostname1",
837 "org.freedesktop.hostname1",
838 "SetHostname");
839 if (r < 0)
840 return r;
841
842 r = sd_bus_message_append(m, "sb", hostname, false);
843 if (r < 0)
844 return r;
845
846 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
847 if (r < 0) {
848 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
849 return r;
850 }
851
852 link_ref(link);
853
854 return 0;
855}
856
857static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
858 _cleanup_link_unref_ Link *link = userdata;
859 int r;
860
861 assert(m);
862 assert(link);
863 assert(link->ifname);
864
865 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
866 return 1;
867
868 r = sd_rtnl_message_get_errno(m);
869 if (r < 0)
870 log_struct_link(LOG_WARNING, link,
871 "MESSAGE=%-*s: could not set MTU: %s",
872 IFNAMSIZ, link->ifname, strerror(-r),
873 "ERRNO=%d", -r,
874 NULL);
875
876 return 1;
877}
878
879static int link_set_mtu(Link *link, uint32_t mtu) {
880 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
881 int r;
882
883 assert(link);
884 assert(link->manager);
885 assert(link->manager->rtnl);
886
887 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
888
889 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
890 RTM_SETLINK, link->ifindex);
891 if (r < 0) {
892 log_error_link(link, "Could not allocate RTM_SETLINK message");
893 return r;
894 }
895
896 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
897 if (r < 0) {
898 log_error_link(link, "Could not append MTU: %s", strerror(-r));
899 return r;
900 }
901
902 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
903 if (r < 0) {
904 log_error_link(link,
905 "Could not send rtnetlink message: %s", strerror(-r));
906 return r;
907 }
908
909 link_ref(link);
910
911 return 0;
912}
913
914static int dhcp_lease_lost(Link *link) {
915 _cleanup_address_free_ Address *address = NULL;
916 struct in_addr addr;
917 struct in_addr netmask;
918 struct in_addr gateway;
919 unsigned prefixlen;
920 int r;
921
922 assert(link);
923 assert(link->dhcp_lease);
924
925 log_warning_link(link, "DHCP lease lost");
926
927 if (link->network->dhcp_routes) {
928 struct sd_dhcp_route *routes;
929 int n, i;
930
931 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes);
932 if (n >= 0) {
933 for (i = 0; i < n; i++) {
934 _cleanup_route_free_ Route *route = NULL;
935
936 r = route_new_dynamic(&route, RTPROT_UNSPEC);
937 if (r >= 0) {
938 route->family = AF_INET;
939 route->in_addr.in = routes[i].gw_addr;
940 route->dst_addr.in = routes[i].dst_addr;
941 route->dst_prefixlen = routes[i].dst_prefixlen;
942
943 route_drop(route, link, &route_drop_handler);
944 }
945 }
946 }
947 }
948
949 r = address_new_dynamic(&address);
950 if (r >= 0) {
951 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
952 if (r >= 0) {
953 _cleanup_route_free_ Route *route_gw = NULL;
954 _cleanup_route_free_ Route *route = NULL;
955
956 r = route_new_dynamic(&route_gw, RTPROT_UNSPEC);
957 if (r >= 0) {
958 route_gw->family = AF_INET;
959 route_gw->dst_addr.in = gateway;
960 route_gw->dst_prefixlen = 32;
961 route_gw->scope = RT_SCOPE_LINK;
962
963 route_drop(route_gw, link, &route_drop_handler);
964 }
965
966 r = route_new_dynamic(&route, RTPROT_UNSPEC);
967 if (r >= 0) {
968 route->family = AF_INET;
969 route->in_addr.in = gateway;
970
971 route_drop(route, link, &route_drop_handler);
972 }
973 }
974
975 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
976 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
977 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
978
979 address->family = AF_INET;
980 address->in_addr.in = addr;
981 address->prefixlen = prefixlen;
982
983 address_drop(address, link, &address_drop_handler);
984 }
985
986 if (link->network->dhcp_mtu) {
987 uint16_t mtu;
988
989 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
990 if (r >= 0 && link->original_mtu != mtu) {
991 r = link_set_mtu(link, link->original_mtu);
992 if (r < 0) {
993 log_warning_link(link, "DHCP error: could not reset MTU");
994 link_enter_failed(link);
995 return r;
996 }
997 }
998 }
999
1000 if (link->network->dhcp_hostname) {
1001 const char *hostname = NULL;
1002
1003 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
1004 if (r >= 0 && hostname) {
1005 r = link_set_hostname(link, "");
1006 if (r < 0)
1007 log_error_link(link, "Failed to reset transient hostname");
1008 }
1009 }
1010
1011 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
1012
1013 return 0;
1014}
1015
1016static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
1017 sd_dhcp_lease *lease;
1018 int r;
1019
1020 r = sd_dhcp_client_get_lease(client, &lease);
1021 if (r < 0) {
1022 log_warning_link(link, "DHCP error: no lease %s",
1023 strerror(-r));
1024 return r;
1025 }
1026
1027 sd_dhcp_lease_unref(link->dhcp_lease);
1028 link->dhcp_lease = lease;
1029
1030 link_enter_set_addresses(link);
1031
1032 return 0;
1033}
1034
1035static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1036 sd_dhcp_lease *lease;
1037 struct in_addr address;
1038 struct in_addr netmask;
1039 struct in_addr gateway;
1040 unsigned prefixlen;
1041 int r;
1042
1043 assert(client);
1044 assert(link);
1045
1046 r = sd_dhcp_client_get_lease(client, &lease);
1047 if (r < 0) {
1048 log_warning_link(link, "DHCP error: no lease: %s",
1049 strerror(-r));
1050 return r;
1051 }
1052
1053 r = sd_dhcp_lease_get_address(lease, &address);
1054 if (r < 0) {
1055 log_warning_link(link, "DHCP error: no address: %s",
1056 strerror(-r));
1057 return r;
1058 }
1059
1060 r = sd_dhcp_lease_get_netmask(lease, &netmask);
1061 if (r < 0) {
1062 log_warning_link(link, "DHCP error: no netmask: %s",
1063 strerror(-r));
1064 return r;
1065 }
1066
1067 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
1068
1069 r = sd_dhcp_lease_get_router(lease, &gateway);
1070 if (r < 0 && r != -ENOENT) {
1071 log_warning_link(link, "DHCP error: could not get gateway: %s",
1072 strerror(-r));
1073 return r;
1074 }
1075
1076 if (r >= 0)
1077 log_struct_link(LOG_INFO, link,
1078 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
1079 IFNAMSIZ,
1080 link->ifname,
1081 ADDRESS_FMT_VAL(address),
1082 prefixlen,
1083 ADDRESS_FMT_VAL(gateway),
1084 "ADDRESS=%u.%u.%u.%u",
1085 ADDRESS_FMT_VAL(address),
1086 "PREFIXLEN=%u",
1087 prefixlen,
1088 "GATEWAY=%u.%u.%u.%u",
1089 ADDRESS_FMT_VAL(gateway),
1090 NULL);
1091 else
1092 log_struct_link(LOG_INFO, link,
1093 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1094 IFNAMSIZ,
1095 link->ifname,
1096 ADDRESS_FMT_VAL(address),
1097 prefixlen,
1098 "ADDRESS=%u.%u.%u.%u",
1099 ADDRESS_FMT_VAL(address),
1100 "PREFIXLEN=%u",
1101 prefixlen,
1102 NULL);
1103
1104 link->dhcp_lease = lease;
1105
1106 if (link->network->dhcp_mtu) {
1107 uint16_t mtu;
1108
1109 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1110 if (r >= 0) {
1111 r = link_set_mtu(link, mtu);
1112 if (r < 0)
1113 log_error_link(link, "Failed to set MTU "
1114 "to %" PRIu16, mtu);
1115 }
1116 }
1117
1118 if (link->network->dhcp_hostname) {
1119 const char *hostname;
1120
1121 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1122 if (r >= 0) {
1123 r = link_set_hostname(link, hostname);
1124 if (r < 0)
1125 log_error_link(link, "Failed to set transient hostname "
1126 "to '%s'", hostname);
1127 }
1128 }
1129
1130 link_enter_set_addresses(link);
1131
1132 return 0;
1133}
1134
1135static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1136 Link *link = userdata;
1137 int r = 0;
1138
1139 assert(link);
1140 assert(link->network);
1141 assert(link->manager);
1142
1143 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1144 return;
1145
1146 switch (event) {
1147 case DHCP_EVENT_EXPIRED:
1148 case DHCP_EVENT_STOP:
1149 case DHCP_EVENT_IP_CHANGE:
1150 if (link->network->dhcp_critical) {
1151 log_error_link(link, "DHCPv4 connection considered system critical, "
1152 "ignoring request to reconfigure it.");
1153 return;
1154 }
1155
1156 if (link->dhcp_lease) {
1157 r = dhcp_lease_lost(link);
1158 if (r < 0) {
1159 link_enter_failed(link);
1160 return;
1161 }
1162 }
1163
1164 if (event == DHCP_EVENT_IP_CHANGE) {
1165 r = dhcp_lease_acquired(client, link);
1166 if (r < 0) {
1167 link_enter_failed(link);
1168 return;
1169 }
1170 }
1171
1172 break;
1173 case DHCP_EVENT_RENEW:
1174 r = dhcp_lease_renew(client, link);
1175 if (r < 0) {
1176 link_enter_failed(link);
1177 return;
1178 }
1179 break;
1180 case DHCP_EVENT_IP_ACQUIRE:
1181 r = dhcp_lease_acquired(client, link);
1182 if (r < 0) {
1183 link_enter_failed(link);
1184 return;
1185 }
1186 break;
1187 default:
1188 if (event < 0)
1189 log_warning_link(link, "DHCP error: client failed: %s", strerror(-event));
1190 else
1191 log_warning_link(link, "DHCP unknown event: %d", event);
1192 break;
1193 }
1194
1195 return;
1196}
1197
1198static int ipv4ll_address_lost(Link *link) {
1199 int r;
1200 struct in_addr addr;
1201
1202 assert(link);
1203
1204 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1205 if (r >= 0) {
1206 _cleanup_address_free_ Address *address = NULL;
1207 _cleanup_route_free_ Route *route = NULL;
1208
1209 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1210 ADDRESS_FMT_VAL(addr));
1211
1212 r = address_new_dynamic(&address);
1213 if (r < 0) {
1214 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1215 return r;
1216 }
1217
1218 address->family = AF_INET;
1219 address->in_addr.in = addr;
1220 address->prefixlen = 16;
1221 address->scope = RT_SCOPE_LINK;
1222
1223 address_drop(address, link, &address_drop_handler);
1224
1225 r = route_new_dynamic(&route, RTPROT_UNSPEC);
1226 if (r < 0) {
1227 log_error_link(link, "Could not allocate route: %s",
1228 strerror(-r));
1229 return r;
1230 }
1231
1232 route->family = AF_INET;
1233 route->scope = RT_SCOPE_LINK;
1234 route->metrics = 99;
1235
1236 route_drop(route, link, &route_drop_handler);
1237 }
1238
1239 return 0;
1240}
1241
1242static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1243 struct in_addr address;
1244 int r;
1245
1246 assert(ll);
1247 assert(link);
1248
1249 r = sd_ipv4ll_get_address(ll, &address);
1250 if (r < 0)
1251 return r;
1252
1253 log_struct_link(LOG_INFO, link,
1254 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1255 IFNAMSIZ,
1256 link->ifname,
1257 ADDRESS_FMT_VAL(address),
1258 NULL);
1259
1260 link_enter_set_addresses(link);
1261
1262 return 0;
1263}
1264
1265static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1266 Link *link = userdata;
1267 int r;
1268
1269 assert(link);
1270 assert(link->network);
1271 assert(link->manager);
1272
1273 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1274 return;
1275
1276 switch(event) {
1277 case IPV4LL_EVENT_STOP:
1278 case IPV4LL_EVENT_CONFLICT:
1279 r = ipv4ll_address_lost(link);
1280 if (r < 0) {
1281 link_enter_failed(link);
1282 return;
1283 }
1284 break;
1285 case IPV4LL_EVENT_BIND:
1286 r = ipv4ll_address_claimed(ll, link);
1287 if (r < 0) {
1288 link_enter_failed(link);
1289 return;
1290 }
1291 break;
1292 default:
1293 if (event < 0)
1294 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1295 else
1296 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1297 break;
1298 }
1299}
1300
1301static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1302 Link *link = userdata;
1303
1304 assert(link);
1305 assert(link->network);
1306 assert(link->manager);
1307
1308 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1309 return;
1310
1311 switch(event) {
1312 case DHCP6_EVENT_STOP:
1313 case DHCP6_EVENT_RESEND_EXPIRE:
1314 case DHCP6_EVENT_RETRANS_MAX:
1315 case DHCP6_EVENT_IP_ACQUIRE:
1316 log_debug_link(link, "DHCPv6 event %d", event);
1317
1318 break;
1319
1320 default:
1321 if (event < 0)
1322 log_warning_link(link, "DHCPv6 error: %s",
1323 strerror(-event));
1324 else
1325 log_warning_link(link, "DHCPv6 unknown event: %d",
1326 event);
1327 return;
1328 }
1329}
1330
1331static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1332 Link *link = userdata;
1333 int r;
1334
1335 assert(link);
1336 assert(link->network);
1337 assert(link->manager);
1338
1339 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1340 return;
1341
1342 switch(event) {
1343 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1344 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1345 return;
1346
1347 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1348 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1349 break;
1350
1351 default:
1352 if (event < 0)
1353 log_warning_link(link, "ICMPv6 error: %s",
1354 strerror(-event));
1355 else
1356 log_warning_link(link, "ICMPv6 unknown event: %d",
1357 event);
1358
1359 return;
1360 }
1361
1362 if (link->dhcp6_client)
1363 return;
1364
1365 r = sd_dhcp6_client_new(&link->dhcp6_client);
1366 if (r < 0)
1367 return;
1368
1369 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1370 if (r < 0) {
1371 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1372 return;
1373 }
1374
1375 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1376 if (r < 0) {
1377 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1378 return;
1379 }
1380
1381 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1382 if (r < 0) {
1383 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1384 return;
1385 }
1386
1387 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1388 link);
1389 if (r < 0) {
1390 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1391 return;
1392 }
1393
1394 r = sd_dhcp6_client_start(link->dhcp6_client);
1395 if (r < 0)
1396 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1397}
1398
1399static int link_acquire_conf(Link *link) {
1400 int r;
1401
1402 assert(link);
1403 assert(link->network);
1404 assert(link->manager);
1405 assert(link->manager->event);
1406
1407 if (link->network->ipv4ll) {
1408 assert(link->ipv4ll);
1409
1410 log_debug_link(link, "acquiring IPv4 link-local address");
1411
1412 r = sd_ipv4ll_start(link->ipv4ll);
1413 if (r < 0) {
1414 log_warning_link(link, "could not acquire IPv4 "
1415 "link-local address");
1416 return r;
1417 }
1418 }
1419
1420 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1421 assert(link->dhcp_client);
1422
1423 log_debug_link(link, "acquiring DHCPv4 lease");
1424
1425 r = sd_dhcp_client_start(link->dhcp_client);
1426 if (r < 0) {
1427 log_warning_link(link, "could not acquire DHCPv4 "
1428 "lease");
1429 return r;
1430 }
1431 }
1432
1433 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1434 assert(link->icmp6_router_discovery);
1435
1436 log_debug_link(link, "discovering IPv6 routers");
1437
1438 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1439 if (r < 0) {
1440 log_warning_link(link, "could not start IPv6 router discovery");
1441 return r;
1442 }
1443 }
1444
1445 return 0;
1446}
1447
1448bool link_has_carrier(unsigned flags, uint8_t operstate) {
1449 /* see Documentation/networking/operstates.txt in the kernel sources */
1450
1451 if (operstate == IF_OPER_UP)
1452 return true;
1453
1454 if (operstate == IF_OPER_UNKNOWN)
1455 /* operstate may not be implemented, so fall back to flags */
1456 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1457 return true;
1458
1459 return false;
1460}
1461
1462#define FLAG_STRING(string, flag, old, new) \
1463 (((old ^ new) & flag) \
1464 ? ((old & flag) ? (" -" string) : (" +" string)) \
1465 : "")
1466
1467static int link_update_flags(Link *link, sd_rtnl_message *m) {
1468 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1469 uint8_t operstate;
1470 bool carrier_gained = false, carrier_lost = false;
1471 int r;
1472
1473 assert(link);
1474
1475 r = sd_rtnl_message_link_get_flags(m, &flags);
1476 if (r < 0) {
1477 log_warning_link(link, "Could not get link flags");
1478 return r;
1479 }
1480
1481 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1482 if (r < 0)
1483 /* if we got a message without operstate, take it to mean
1484 the state was unchanged */
1485 operstate = link->kernel_operstate;
1486
1487 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1488 return 0;
1489
1490 if (link->flags != flags) {
1491 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1492 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1493 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1494 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1495 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1496 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1497 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1498 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1499 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1500 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1501 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1502 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1503 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1504 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1505 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1506 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1507 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1508 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1509 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1510 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1511
1512 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1513 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1514 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1515 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1516 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1517 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1518 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1519 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1520
1521 /* link flags are currently at most 18 bits, let's align to printing 20 */
1522 if (unknown_flags_added)
1523 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1524 unknown_flags_added);
1525
1526 if (unknown_flags_removed)
1527 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1528 unknown_flags_removed);
1529 }
1530
1531 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1532 link_has_carrier(flags, operstate);
1533 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1534 !link_has_carrier(flags, operstate);
1535
1536 link->flags = flags;
1537 link->kernel_operstate = operstate;
1538
1539 link_save(link);
1540
1541 if (link->state == LINK_STATE_FAILED ||
1542 link->state == LINK_STATE_UNMANAGED)
1543 return 0;
1544
1545 if (carrier_gained) {
1546 log_info_link(link, "gained carrier");
1547
1548 if (link->network) {
1549 r = link_acquire_conf(link);
1550 if (r < 0) {
1551 link_enter_failed(link);
1552 return r;
1553 }
1554 }
1555 } else if (carrier_lost) {
1556 log_info_link(link, "lost carrier");
1557
1558 r = link_stop_clients(link);
1559 if (r < 0) {
1560 link_enter_failed(link);
1561 return r;
1562 }
1563 }
1564
1565 return 0;
1566}
1567
1568static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1569 _cleanup_link_unref_ Link *link = userdata;
1570 int r;
1571
1572 assert(link);
1573
1574 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1575 return 1;
1576
1577 r = sd_rtnl_message_get_errno(m);
1578 if (r < 0) {
1579 /* we warn but don't fail the link, as it may
1580 be brought up later */
1581 log_struct_link(LOG_WARNING, link,
1582 "MESSAGE=%-*s: could not bring up interface: %s",
1583 IFNAMSIZ,
1584 link->ifname, strerror(-r),
1585 "ERRNO=%d", -r,
1586 NULL);
1587 }
1588
1589 return 1;
1590}
1591
1592static int link_up(Link *link) {
1593 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1594 int r;
1595
1596 assert(link);
1597 assert(link->manager);
1598 assert(link->manager->rtnl);
1599
1600 log_debug_link(link, "bringing link up");
1601
1602 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1603 RTM_SETLINK, link->ifindex);
1604 if (r < 0) {
1605 log_error_link(link, "Could not allocate RTM_SETLINK message");
1606 return r;
1607 }
1608
1609 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1610 if (r < 0) {
1611 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1612 return r;
1613 }
1614
1615 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1616 if (r < 0) {
1617 log_error_link(link,
1618 "Could not send rtnetlink message: %s", strerror(-r));
1619 return r;
1620 }
1621
1622 link_ref(link);
1623
1624 return 0;
1625}
1626
1627static int link_joined(Link *link) {
1628 int r;
1629
1630 assert(link);
1631 assert(link->state == LINK_STATE_ENSLAVING);
1632 assert(link->network);
1633
1634 if (!(link->flags & IFF_UP)) {
1635 r = link_up(link);
1636 if (r < 0) {
1637 link_enter_failed(link);
1638 return r;
1639 }
1640 }
1641
1642 return link_enter_set_addresses(link);
1643}
1644
1645static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1646 _cleanup_link_unref_ Link *link = userdata;
1647 int r;
1648
1649 assert(link);
1650 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1651 LINK_STATE_LINGER));
1652 assert(link->network);
1653
1654 link->enslaving --;
1655
1656 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1657 return 1;
1658
1659 r = sd_rtnl_message_get_errno(m);
1660 if (r < 0 && r != -EEXIST) {
1661 log_struct_link(LOG_ERR, link,
1662 "MESSAGE=%-*s: could not join netdev: %s",
1663 IFNAMSIZ,
1664 link->ifname, strerror(-r),
1665 "ERRNO=%d", -r,
1666 NULL);
1667 link_enter_failed(link);
1668 return 1;
1669 } else
1670 log_debug_link(link, "joined netdev");
1671
1672 if (link->enslaving <= 0)
1673 link_joined(link);
1674
1675 return 1;
1676}
1677
1678static int link_enter_join_netdev(Link *link) {
1679 NetDev *netdev;
1680 Iterator i;
1681 int r;
1682
1683 assert(link);
1684 assert(link->network);
1685 assert(link->state == LINK_STATE_INITIALIZING);
1686
1687 link->state = LINK_STATE_ENSLAVING;
1688
1689 link_save(link);
1690
1691 if (!link->network->bridge &&
1692 !link->network->bond &&
1693 hashmap_isempty(link->network->stacked_netdevs))
1694 return link_joined(link);
1695
1696 if (link->network->bond) {
1697 log_struct_link(LOG_DEBUG, link,
1698 "MESSAGE=%-*s: enslaving by '%s'",
1699 IFNAMSIZ,
1700 link->ifname, link->network->bond->ifname,
1701 NETDEVIF(link->network->bond),
1702 NULL);
1703
1704 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1705 if (r < 0) {
1706 log_struct_link(LOG_WARNING, link,
1707 "MESSAGE=%-*s: could not join netdev '%s': %s",
1708 IFNAMSIZ,
1709 link->ifname, link->network->bond->ifname, strerror(-r),
1710 NETDEVIF(link->network->bond),
1711 NULL);
1712 link_enter_failed(link);
1713 return r;
1714 }
1715
1716 link->enslaving ++;
1717 }
1718
1719 if (link->network->bridge) {
1720 log_struct_link(LOG_DEBUG, link,
1721 "MESSAGE=%-*s: enslaving by '%s'",
1722 IFNAMSIZ,
1723 link->ifname, link->network->bridge->ifname,
1724 NETDEVIF(link->network->bridge),
1725 NULL);
1726
1727 r = netdev_join(link->network->bridge, link, &netdev_join_handler);
1728 if (r < 0) {
1729 log_struct_link(LOG_WARNING, link,
1730 "MESSAGE=%-*s: could not join netdev '%s': %s",
1731 IFNAMSIZ,
1732 link->ifname, link->network->bridge->ifname, strerror(-r),
1733 NETDEVIF(link->network->bridge),
1734 NULL);
1735 link_enter_failed(link);
1736 return r;
1737 }
1738
1739 link->enslaving ++;
1740 }
1741
1742 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1743 log_struct_link(LOG_DEBUG, link,
1744 "MESSAGE=%-*s: enslaving by '%s'",
1745 IFNAMSIZ,
1746 link->ifname, netdev->ifname, NETDEVIF(netdev), NULL);
1747
1748 r = netdev_join(netdev, link, &netdev_join_handler);
1749 if (r < 0) {
1750 log_struct_link(LOG_WARNING, link,
1751 "MESSAGE=%-*s: could not join netdev '%s': %s",
1752 IFNAMSIZ,
1753 link->ifname, netdev->ifname, strerror(-r),
1754 NETDEVIF(netdev), NULL);
1755 link_enter_failed(link);
1756 return r;
1757 }
1758
1759 link->enslaving ++;
1760 }
1761
1762 return 0;
1763}
1764
1765static int link_configure(Link *link) {
1766 int r;
1767
1768 assert(link);
1769 assert(link->state == LINK_STATE_INITIALIZING);
1770
1771 if (link->network->ipv4ll) {
1772 uint8_t seed[8];
1773
1774 r = sd_ipv4ll_new(&link->ipv4ll);
1775 if (r < 0)
1776 return r;
1777
1778 if (link->udev_device) {
1779 r = net_get_unique_predictable_data(link->udev_device, seed);
1780 if (r >= 0) {
1781 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1782 if (r < 0)
1783 return r;
1784 }
1785 }
1786
1787 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1788 if (r < 0)
1789 return r;
1790
1791 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1792 if (r < 0)
1793 return r;
1794
1795 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1796 if (r < 0)
1797 return r;
1798
1799 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1800 if (r < 0)
1801 return r;
1802 }
1803
1804 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1805 r = sd_dhcp_client_new(&link->dhcp_client);
1806 if (r < 0)
1807 return r;
1808
1809 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1810 if (r < 0)
1811 return r;
1812
1813 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1814 if (r < 0)
1815 return r;
1816
1817 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1818 if (r < 0)
1819 return r;
1820
1821 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1822 if (r < 0)
1823 return r;
1824
1825 r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast);
1826 if (r < 0)
1827 return r;
1828
1829 if (link->mtu) {
1830 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
1831 if (r < 0)
1832 return r;
1833 }
1834
1835 if (link->network->dhcp_mtu) {
1836 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_INTERFACE_MTU);
1837 if (r < 0)
1838 return r;
1839 }
1840
1841 if (link->network->dhcp_routes) {
1842 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
1843 if (r < 0)
1844 return r;
1845 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
1846 if (r < 0)
1847 return r;
1848 }
1849
1850 if (link->network->dhcp_sendhost) {
1851 _cleanup_free_ char *hostname = gethostname_malloc();
1852 if (!hostname)
1853 return -ENOMEM;
1854
1855 if (!is_localhost(hostname)) {
1856 r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname);
1857 if (r < 0)
1858 return r;
1859 }
1860 }
1861
1862 if (link->network->dhcp_vendor_class_identifier) {
1863 r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
1864 link->network->dhcp_vendor_class_identifier);
1865 if (r < 0)
1866 return r;
1867 }
1868 }
1869
1870 if (link->network->dhcp_server) {
1871 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1872 if (r < 0)
1873 return r;
1874
1875 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1876 if (r < 0)
1877 return r;
1878 }
1879
1880 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1881 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1882 if (r < 0)
1883 return r;
1884
1885 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1886 NULL, 0);
1887 if (r < 0)
1888 return r;
1889
1890 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1891 &link->mac);
1892 if (r < 0)
1893 return r;
1894
1895 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1896 link->ifindex);
1897 if (r < 0)
1898 return r;
1899
1900 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1901 icmp6_router_handler, link);
1902 if (r < 0)
1903 return r;
1904 }
1905
1906 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1907 r = link_acquire_conf(link);
1908 if (r < 0)
1909 return r;
1910 }
1911
1912 return link_enter_join_netdev(link);
1913}
1914
1915static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1916 _cleanup_link_unref_ Link *link = userdata;
1917 Network *network;
1918 int r;
1919
1920 assert(link);
1921 assert(link->ifname);
1922 assert(link->manager);
1923
1924 if (link->state != LINK_STATE_INITIALIZING)
1925 return 1;
1926
1927 log_debug_link(link, "link state is up-to-date");
1928
1929 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1930 if (r == -ENOENT) {
1931 link_enter_unmanaged(link);
1932 return 1;
1933 } else if (r < 0)
1934 return r;
1935
1936 r = network_apply(link->manager, network, link);
1937 if (r < 0)
1938 return r;
1939
1940 r = link_configure(link);
1941 if (r < 0)
1942 return r;
1943
1944 return 1;
1945}
1946
1947int link_initialized(Link *link, struct udev_device *device) {
1948 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1949 int r;
1950
1951 assert(link);
1952 assert(link->manager);
1953 assert(link->manager->rtnl);
1954 assert(device);
1955
1956 if (link->state != LINK_STATE_INITIALIZING)
1957 return 0;
1958
1959 if (link->udev_device)
1960 return 0;
1961
1962 log_debug_link(link, "udev initialized link");
1963
1964 link->udev_device = udev_device_ref(device);
1965
1966 /* udev has initialized the link, but we don't know if we have yet processed
1967 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1968 we know that the pending NEWLINKs have already been processed and that we
1969 are up-to-date */
1970
1971 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1972 if (r < 0)
1973 return r;
1974
1975 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1976 if (r < 0)
1977 return r;
1978
1979 link_ref(link);
1980
1981 return 0;
1982}
1983
1984int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1985 Manager *m = userdata;
1986 Link *link = NULL;
1987 uint16_t type;
1988 _cleanup_address_free_ Address *address = NULL;
1989 Address *ad;
1990 char buf[INET6_ADDRSTRLEN];
1991 bool address_dropped = false;
1992 int r, ifindex;
1993
1994 assert(rtnl);
1995 assert(message);
1996 assert(m);
1997
1998 r = sd_rtnl_message_get_type(message, &type);
1999 if (r < 0) {
2000 log_warning("rtnl: could not get message type");
2001 return 0;
2002 }
2003
2004 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2005 if (r < 0 || ifindex <= 0) {
2006 log_warning("rtnl: received address message without valid ifindex, ignoring");
2007 return 0;
2008 } else {
2009 r = link_get(m, ifindex, &link);
2010 if (r < 0 || !link) {
2011 log_warning("rtnl: received address for a nonexistent link, ignoring");
2012 return 0;
2013 }
2014 }
2015
2016 r = address_new_dynamic(&address);
2017 if (r < 0)
2018 return r;
2019
2020 r = sd_rtnl_message_addr_get_family(message, &address->family);
2021 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
2022 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
2023 return 0;
2024 }
2025
2026 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2027 if (r < 0) {
2028 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2029 return 0;
2030 }
2031
2032 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2033 if (r < 0) {
2034 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
2035 return 0;
2036 }
2037
2038 switch (address->family) {
2039 case AF_INET:
2040 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2041 if (r < 0) {
2042 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2043 return 0;
2044 }
2045
2046 break;
2047
2048 case AF_INET6:
2049 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2050 if (r < 0) {
2051 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2052 return 0;
2053 }
2054
2055 break;
2056
2057 default:
2058 assert_not_reached("invalid address family");
2059 }
2060
2061 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
2062 log_warning_link(link, "could not print address");
2063 return 0;
2064 }
2065
2066 LIST_FOREACH(addresses, ad, link->addresses) {
2067 if (address_equal(ad, address)) {
2068 LIST_REMOVE(addresses, link->addresses, ad);
2069
2070 address_free(ad);
2071
2072 address_dropped = true;
2073
2074 break;
2075 }
2076 }
2077
2078 switch (type) {
2079 case RTM_NEWADDR:
2080 if (!address_dropped)
2081 log_debug_link(link, "added address: %s/%u", buf,
2082 address->prefixlen);
2083 else
2084 log_debug_link(link, "updated address: %s/%u", buf,
2085 address->prefixlen);
2086
2087 LIST_PREPEND(addresses, link->addresses, address);
2088 address = NULL;
2089
2090 link_save(link);
2091
2092 break;
2093 case RTM_DELADDR:
2094 if (address_dropped) {
2095 log_debug_link(link, "removed address: %s/%u", buf,
2096 address->prefixlen);
2097
2098 link_save(link);
2099 } else
2100 log_warning_link(link, "removing non-existent address: %s/%u",
2101 buf, address->prefixlen);
2102
2103 break;
2104 default:
2105 assert_not_reached("Received invalid RTNL message type");
2106 }
2107
2108 return 1;
2109}
2110
2111int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2112 Link *link;
2113 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2114 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2115 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2116 int r;
2117
2118 assert(m);
2119 assert(m->rtnl);
2120 assert(message);
2121 assert(ret);
2122
2123 r = link_new(m, message, ret);
2124 if (r < 0)
2125 return r;
2126
2127 link = *ret;
2128
2129 log_debug_link(link, "link %d added", link->ifindex);
2130
2131 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2132 if (r < 0)
2133 return r;
2134
2135 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2136 if (r < 0)
2137 return r;
2138
2139 link_ref(link);
2140
2141 if (detect_container(NULL) <= 0) {
2142 /* not in a container, udev will be around */
2143 sprintf(ifindex_str, "n%d", link->ifindex);
2144 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2145 if (!device) {
2146 log_warning_link(link, "could not find udev device: %m");
2147 return -errno;
2148 }
2149
2150 if (udev_device_get_is_initialized(device) <= 0) {
2151 /* not yet ready */
2152 log_debug_link(link, "udev initializing link...");
2153 return 0;
2154 }
2155
2156 r = link_initialized(link, device);
2157 if (r < 0)
2158 return r;
2159 } else {
2160 /* we are calling a callback directly, so must take a ref */
2161 link_ref(link);
2162
2163 r = link_initialized_and_synced(m->rtnl, NULL, link);
2164 if (r < 0)
2165 return r;
2166 }
2167
2168 return 0;
2169}
2170
2171int link_update(Link *link, sd_rtnl_message *m) {
2172 struct ether_addr mac;
2173 const char *ifname;
2174 uint32_t mtu;
2175 int r;
2176
2177 assert(link);
2178 assert(link->ifname);
2179 assert(m);
2180
2181 if (link->state == LINK_STATE_LINGER) {
2182 link_ref(link);
2183 log_info_link(link, "link readded");
2184 link->state = LINK_STATE_ENSLAVING;
2185 }
2186
2187 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2188 if (r >= 0 && !streq(ifname, link->ifname)) {
2189 log_info_link(link, "renamed to %s", ifname);
2190
2191 free(link->ifname);
2192 link->ifname = strdup(ifname);
2193 if (!link->ifname)
2194 return -ENOMEM;
2195 }
2196
2197 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
2198 if (r >= 0 && mtu > 0) {
2199 link->mtu = mtu;
2200 if (!link->original_mtu) {
2201 link->original_mtu = mtu;
2202 log_debug_link(link, "saved original MTU: %"
2203 PRIu32, link->original_mtu);
2204 }
2205
2206 if (link->dhcp_client) {
2207 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
2208 if (r < 0) {
2209 log_warning_link(link, "Could not update MTU in DHCP client: %s",
2210 strerror(-r));
2211 return r;
2212 }
2213 }
2214 }
2215
2216 /* The kernel may broadcast NEWLINK messages without the MAC address
2217 set, simply ignore them. */
2218 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2219 if (r >= 0) {
2220 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2221
2222 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2223
2224 log_debug_link(link, "MAC address: "
2225 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2226 mac.ether_addr_octet[0],
2227 mac.ether_addr_octet[1],
2228 mac.ether_addr_octet[2],
2229 mac.ether_addr_octet[3],
2230 mac.ether_addr_octet[4],
2231 mac.ether_addr_octet[5]);
2232
2233 if (link->ipv4ll) {
2234 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2235 if (r < 0) {
2236 log_warning_link(link, "Could not update MAC "
2237 "address in IPv4LL client: %s",
2238 strerror(-r));
2239 return r;
2240 }
2241 }
2242
2243 if (link->dhcp_client) {
2244 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2245 if (r < 0) {
2246 log_warning_link(link, "Could not update MAC "
2247 "address in DHCP client: %s",
2248 strerror(-r));
2249 return r;
2250 }
2251 }
2252
2253 if (link->dhcp6_client) {
2254 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2255 &link->mac);
2256 if (r < 0) {
2257 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2258 strerror(-r));
2259 return r;
2260 }
2261 }
2262 }
2263 }
2264
2265 return link_update_flags(link, m);
2266}
2267
2268static void link_update_operstate(Link *link) {
2269
2270 assert(link);
2271
2272 if (link->kernel_operstate == IF_OPER_DORMANT)
2273 link->operstate = LINK_OPERSTATE_DORMANT;
2274 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2275 Address *address;
2276 uint8_t scope = RT_SCOPE_NOWHERE;
2277
2278 /* if we have carrier, check what addresses we have */
2279 LIST_FOREACH(addresses, address, link->addresses) {
2280 if (address->scope < scope)
2281 scope = address->scope;
2282 }
2283
2284 if (scope < RT_SCOPE_SITE)
2285 /* universally accessible addresses found */
2286 link->operstate = LINK_OPERSTATE_ROUTABLE;
2287 else if (scope < RT_SCOPE_HOST)
2288 /* only link or site local addresses found */
2289 link->operstate = LINK_OPERSTATE_DEGRADED;
2290 else
2291 /* no useful addresses found */
2292 link->operstate = LINK_OPERSTATE_CARRIER;
2293 } else
2294 link->operstate = LINK_OPERSTATE_UNKNOWN;
2295}
2296
2297int link_save(Link *link) {
2298 _cleanup_free_ char *temp_path = NULL;
2299 _cleanup_fclose_ FILE *f = NULL;
2300 const char *admin_state, *oper_state;
2301 int r;
2302
2303 assert(link);
2304 assert(link->state_file);
2305 assert(link->lease_file);
2306 assert(link->manager);
2307
2308 link_update_operstate(link);
2309
2310 r = manager_save(link->manager);
2311 if (r < 0)
2312 return r;
2313
2314 if (link->state == LINK_STATE_LINGER) {
2315 unlink(link->state_file);
2316 return 0;
2317 }
2318
2319 admin_state = link_state_to_string(link->state);
2320 assert(admin_state);
2321
2322 oper_state = link_operstate_to_string(link->operstate);
2323 assert(oper_state);
2324
2325 r = fopen_temporary(link->state_file, &f, &temp_path);
2326 if (r < 0)
2327 return r;
2328
2329 fchmod(fileno(f), 0644);
2330
2331 fprintf(f,
2332 "# This is private data. Do not parse.\n"
2333 "ADMIN_STATE=%s\n"
2334 "OPER_STATE=%s\n",
2335 admin_state, oper_state);
2336
2337 if (link->network) {
2338 char **address;
2339
2340 fputs("DNS=", f);
2341
2342 if (link->network->dhcp_dns &&
2343 link->dhcp_lease) {
2344 const struct in_addr *addresses;
2345
2346 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2347 if (r > 0) {
2348 serialize_in_addrs(f, addresses, r);
2349 if (link->network->dns)
2350 fputs(" ", f);
2351 }
2352 }
2353
2354 STRV_FOREACH(address, link->network->dns)
2355 fprintf(f, "%s%s", *address,
2356 (address + 1 ? " " : ""));
2357
2358 fputs("\n", f);
2359
2360 fprintf(f, "NTP=");
2361
2362 if (link->network->dhcp_ntp &&
2363 link->dhcp_lease) {
2364 const struct in_addr *addresses;
2365
2366 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2367 if (r > 0) {
2368 serialize_in_addrs(f, addresses, r);
2369 if (link->network->ntp)
2370 fputs(" ", f);
2371 }
2372 }
2373
2374 STRV_FOREACH(address, link->network->ntp)
2375 fprintf(f, "%s%s", *address,
2376 (address + 1 ? " " : ""));
2377
2378 fputs("\n", f);
2379
2380 fprintf(f, "LLMNR=%s\n", llmnr_support_to_string(link->network->llmnr));
2381 }
2382
2383 if (link->dhcp_lease) {
2384 assert(link->network);
2385
2386 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2387 if (r < 0)
2388 goto fail;
2389
2390 fprintf(f,
2391 "DHCP_LEASE=%s\n",
2392 link->lease_file);
2393 } else
2394 unlink(link->lease_file);
2395
2396 r = fflush_and_check(f);
2397 if (r < 0)
2398 goto fail;
2399
2400 if (rename(temp_path, link->state_file) < 0) {
2401 r = -errno;
2402 goto fail;
2403 }
2404
2405 return 0;
2406
2407fail:
2408 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2409 unlink(link->state_file);
2410 unlink(temp_path);
2411 return r;
2412}
2413
2414static const char* const link_state_table[_LINK_STATE_MAX] = {
2415 [LINK_STATE_INITIALIZING] = "initializing",
2416 [LINK_STATE_ENSLAVING] = "configuring",
2417 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2418 [LINK_STATE_SETTING_ROUTES] = "configuring",
2419 [LINK_STATE_CONFIGURED] = "configured",
2420 [LINK_STATE_UNMANAGED] = "unmanaged",
2421 [LINK_STATE_FAILED] = "failed",
2422 [LINK_STATE_LINGER] = "linger",
2423};
2424
2425DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2426
2427static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2428 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2429 [LINK_OPERSTATE_DORMANT] = "dormant",
2430 [LINK_OPERSTATE_CARRIER] = "carrier",
2431 [LINK_OPERSTATE_DEGRADED] = "degraded",
2432 [LINK_OPERSTATE_ROUTABLE] = "routable",
2433};
2434
2435DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);