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