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