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