1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
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.
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.
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/>.
22 #include <netinet/ether.h>
26 #include "libudev-private.h"
27 #include "udev-util.h"
31 #include "network-internal.h"
33 #include "network-util.h"
34 #include "dhcp-lease-internal.h"
36 static int ipv4ll_address_update(Link *link, bool deprecate);
37 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
39 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
40 _cleanup_link_unref_ Link *link = NULL;
46 assert(manager->links);
50 r = sd_rtnl_message_get_type(message, &type);
53 else if (type != RTM_NEWLINK)
56 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
59 else if (ifindex <= 0)
62 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
71 link->manager = manager;
72 link->state = LINK_STATE_INITIALIZING;
73 link->ifindex = ifindex;
74 link->ifname = strdup(ifname);
78 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
82 r = asprintf(&link->state_file, "/run/systemd/netif/links/%"PRIu64,
87 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%"PRIu64,
92 r = hashmap_put(manager->links, &link->ifindex, link);
102 static void link_free(Link *link) {
108 assert(link->manager);
110 while ((address = link->addresses)) {
111 LIST_REMOVE(addresses, link->addresses, address);
112 address_free(address);
115 sd_dhcp_client_unref(link->dhcp_client);
116 sd_dhcp_lease_unref(link->dhcp_lease);
118 unlink(link->lease_file);
119 free(link->lease_file);
121 sd_ipv4ll_unref(link->ipv4ll);
123 hashmap_remove(link->manager->links, &link->ifindex);
127 unlink(link->state_file);
128 free(link->state_file);
130 udev_device_unref(link->udev_device);
135 Link *link_unref(Link *link) {
136 if (link && (-- link->n_ref <= 0))
142 Link *link_ref(Link *link) {
144 assert_se(++ link->n_ref >= 2);
149 int link_get(Manager *m, int ifindex, Link **ret) {
158 ifindex_64 = ifindex;
159 link = hashmap_get(m->links, &ifindex_64);
168 void link_drop(Link *link) {
169 if (!link || link->state == LINK_STATE_LINGER)
172 link->state = LINK_STATE_LINGER;
174 log_debug_link(link, "link removed");
181 static void link_enter_unmanaged(Link *link) {
184 log_debug_link(link, "unmanaged");
186 link->state = LINK_STATE_UNMANAGED;
191 static int link_stop_clients(Link *link) {
195 assert(link->manager);
196 assert(link->manager->event);
201 if (link->network->dhcp) {
202 assert(link->dhcp_client);
204 k = sd_dhcp_client_stop(link->dhcp_client);
206 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
211 if (link->network->ipv4ll) {
212 assert(link->ipv4ll);
214 k = sd_ipv4ll_stop(link->ipv4ll);
216 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
221 if (link->network->dhcp_server) {
222 assert(link->dhcp_server);
224 k = sd_dhcp_server_stop(link->dhcp_server);
226 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
234 static void link_enter_failed(Link *link) {
237 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
240 log_warning_link(link, "failed");
242 link->state = LINK_STATE_FAILED;
244 link_stop_clients(link);
249 static int link_enter_configured(Link *link) {
253 assert(link->network);
254 assert(link->state == LINK_STATE_SETTING_ROUTES);
257 if (link->network->dhcp_server) {
258 log_debug_link(link, "offering DHCPv4 leases");
260 r = sd_dhcp_server_start(link->dhcp_server);
262 log_warning_link(link, "could not start DHCPv4 server "
263 "instance: %s", strerror(-r));
265 link_enter_failed(link);
271 log_info_link(link, "link configured");
273 link->state = LINK_STATE_CONFIGURED;
280 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
281 Link *link = userdata;
284 assert(link->route_messages > 0);
285 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
286 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
289 link->route_messages --;
291 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
296 r = sd_rtnl_message_get_errno(m);
297 if (r < 0 && r != -EEXIST)
298 log_struct_link(LOG_WARNING, link,
299 "MESSAGE=%-*s: could not set route: %s",
301 link->ifname, strerror(-r),
305 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
307 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
308 log_debug_link(link, "routes set");
309 link_enter_configured(link);
317 static int link_enter_set_routes(Link *link) {
322 assert(link->network);
323 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
325 link->state = LINK_STATE_SETTING_ROUTES;
327 if (!link->network->static_routes && !link->dhcp_lease &&
328 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
329 return link_enter_configured(link);
331 log_debug_link(link, "setting routes");
333 LIST_FOREACH(routes, rt, link->network->static_routes) {
334 r = route_configure(rt, link, &route_handler);
336 log_warning_link(link,
337 "could not set routes: %s", strerror(-r));
338 link_enter_failed(link);
343 link->route_messages ++;
346 if (link->ipv4ll && !link->dhcp_lease) {
347 _cleanup_route_free_ Route *route = NULL;
350 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
351 if (r < 0 && r != -ENOENT) {
352 log_warning_link(link, "IPV4LL error: no address: %s",
358 r = route_new_dynamic(&route);
360 log_error_link(link, "Could not allocate route: %s",
365 route->family = AF_INET;
366 route->scope = RT_SCOPE_LINK;
369 r = route_configure(route, link, &route_handler);
371 log_warning_link(link,
372 "could not set routes: %s", strerror(-r));
373 link_enter_failed(link);
378 link->route_messages ++;
382 if (link->dhcp_lease) {
383 _cleanup_route_free_ Route *route = NULL;
384 _cleanup_route_free_ Route *route_gw = NULL;
385 struct in_addr gateway;
387 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
388 if (r < 0 && r != -ENOENT) {
389 log_warning_link(link, "DHCP error: %s", strerror(-r));
394 r = route_new_dynamic(&route);
396 log_error_link(link, "Could not allocate route: %s",
401 r = route_new_dynamic(&route_gw);
403 log_error_link(link, "Could not allocate route: %s",
408 /* The dhcp netmask may mask out the gateway. Add an explicit
409 * route for the gw host so that we can route no matter the
410 * netmask or existing kernel route tables. */
411 route_gw->family = AF_INET;
412 route_gw->dst_addr.in = gateway;
413 route_gw->dst_prefixlen = 32;
414 route_gw->scope = RT_SCOPE_LINK;
416 r = route_configure(route_gw, link, &route_handler);
418 log_warning_link(link,
419 "could not set host route: %s", strerror(-r));
424 link->route_messages ++;
426 route->family = AF_INET;
427 route->in_addr.in = gateway;
429 r = route_configure(route, link, &route_handler);
431 log_warning_link(link,
432 "could not set routes: %s", strerror(-r));
433 link_enter_failed(link);
438 link->route_messages ++;
442 if (link->route_messages == 0) {
443 link_enter_configured(link);
449 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
450 Link *link = userdata;
455 assert(link->ifname);
457 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
462 r = sd_rtnl_message_get_errno(m);
463 if (r < 0 && r != -ESRCH)
464 log_struct_link(LOG_WARNING, link,
465 "MESSAGE=%-*s: could not drop route: %s",
467 link->ifname, strerror(-r),
476 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
477 Link *link = userdata;
482 assert(link->ifname);
483 assert(link->addr_messages > 0);
484 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
485 LINK_STATE_FAILED, LINK_STATE_LINGER));
487 link->addr_messages --;
489 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
494 r = sd_rtnl_message_get_errno(m);
495 if (r < 0 && r != -EEXIST)
496 log_struct_link(LOG_WARNING, link,
497 "MESSAGE=%-*s: could not set address: %s",
499 link->ifname, strerror(-r),
503 if (link->addr_messages == 0) {
504 log_debug_link(link, "addresses set");
505 link_enter_set_routes(link);
513 static int link_enter_set_addresses(Link *link) {
518 assert(link->network);
519 assert(link->state != _LINK_STATE_INVALID);
521 link->state = LINK_STATE_SETTING_ADDRESSES;
523 if (!link->network->static_addresses && !link->dhcp_lease &&
524 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
525 return link_enter_set_routes(link);
527 log_debug_link(link, "setting addresses");
529 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
530 r = address_configure(ad, link, &address_handler);
532 log_warning_link(link,
533 "could not set addresses: %s", strerror(-r));
534 link_enter_failed(link);
539 link->addr_messages ++;
542 if (link->ipv4ll && !link->dhcp_lease) {
543 _cleanup_address_free_ Address *ll_addr = NULL;
546 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
547 if (r < 0 && r != -ENOENT) {
548 log_warning_link(link, "IPV4LL error: no address: %s",
554 r = address_new_dynamic(&ll_addr);
556 log_error_link(link, "Could not allocate address: %s", strerror(-r));
560 ll_addr->family = AF_INET;
561 ll_addr->in_addr.in = addr;
562 ll_addr->prefixlen = 16;
563 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
564 ll_addr->scope = RT_SCOPE_LINK;
566 r = address_configure(ll_addr, link, &address_handler);
568 log_warning_link(link,
569 "could not set addresses: %s", strerror(-r));
570 link_enter_failed(link);
575 link->addr_messages ++;
579 if (link->dhcp_lease) {
580 _cleanup_address_free_ Address *address = NULL;
582 struct in_addr netmask;
585 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
587 log_warning_link(link, "DHCP error: no address: %s",
592 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
594 log_warning_link(link, "DHCP error: no netmask: %s",
599 prefixlen = net_netmask_to_prefixlen(&netmask);
601 r = address_new_dynamic(&address);
603 log_error_link(link, "Could not allocate address: %s",
608 address->family = AF_INET;
609 address->in_addr.in = addr;
610 address->prefixlen = prefixlen;
611 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
613 r = address_configure(address, link, &address_handler);
615 log_warning_link(link,
616 "could not set addresses: %s", strerror(-r));
617 link_enter_failed(link);
622 link->addr_messages ++;
628 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
629 Link *link = userdata;
634 assert(link->ifname);
636 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
641 r = sd_rtnl_message_get_errno(m);
642 if (r < 0 && r != -ENOENT)
643 log_struct_link(LOG_WARNING, link,
644 "MESSAGE=%-*s: could not update address: %s",
646 link->ifname, strerror(-r),
655 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
656 Link *link = userdata;
661 assert(link->ifname);
663 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
668 r = sd_rtnl_message_get_errno(m);
669 if (r < 0 && r != -EADDRNOTAVAIL)
670 log_struct_link(LOG_WARNING, link,
671 "MESSAGE=%-*s: could not drop address: %s",
673 link->ifname, strerror(-r),
682 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
683 Link *link = userdata;
688 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
693 r = sd_bus_message_get_errno(m);
695 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
702 static int link_set_hostname(Link *link, const char *hostname) {
703 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
707 assert(link->manager);
710 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
712 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
713 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
717 r = sd_bus_message_new_method_call(
720 "org.freedesktop.hostname1",
721 "/org/freedesktop/hostname1",
722 "org.freedesktop.hostname1",
727 r = sd_bus_message_append(m, "sb", hostname, false);
731 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
733 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
740 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
741 Link *link = userdata;
746 assert(link->ifname);
748 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
753 r = sd_rtnl_message_get_errno(m);
755 log_struct_link(LOG_WARNING, link,
756 "MESSAGE=%-*s: could not set MTU: %s",
757 IFNAMSIZ, link->ifname, strerror(-r),
766 static int link_set_mtu(Link *link, uint32_t mtu) {
767 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
771 assert(link->manager);
772 assert(link->manager->rtnl);
774 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
776 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
777 RTM_SETLINK, link->ifindex);
779 log_error_link(link, "Could not allocate RTM_SETLINK message");
783 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
785 log_error_link(link, "Could not append MTU: %s", strerror(-r));
789 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
792 "Could not send rtnetlink message: %s", strerror(-r));
801 static int dhcp_lease_lost(Link *link) {
802 _cleanup_address_free_ Address *address = NULL;
803 _cleanup_route_free_ Route *route_gw = NULL;
804 _cleanup_route_free_ Route *route = NULL;
806 struct in_addr netmask;
807 struct in_addr gateway;
812 assert(link->dhcp_lease);
814 log_warning_link(link, "DHCP lease lost");
816 r = address_new_dynamic(&address);
818 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
820 r = route_new_dynamic(&route_gw);
822 route_gw->family = AF_INET;
823 route_gw->dst_addr.in = gateway;
824 route_gw->dst_prefixlen = 32;
825 route_gw->scope = RT_SCOPE_LINK;
827 route_drop(route_gw, link, &route_drop_handler);
831 r = route_new_dynamic(&route);
833 route->family = AF_INET;
834 route->in_addr.in = gateway;
836 route_drop(route, link, &route_drop_handler);
841 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
842 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
843 prefixlen = net_netmask_to_prefixlen(&netmask);
845 address->family = AF_INET;
846 address->in_addr.in = addr;
847 address->prefixlen = prefixlen;
849 address_drop(address, link, &address_drop_handler);
853 if (link->network->dhcp_mtu) {
856 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
857 if (r >= 0 && link->original_mtu != mtu) {
858 r = link_set_mtu(link, link->original_mtu);
860 log_warning_link(link, "DHCP error: could not reset MTU");
861 link_enter_failed(link);
867 if (link->network->dhcp_hostname) {
868 const char *hostname = NULL;
870 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
871 if (r >= 0 && hostname) {
872 r = link_set_hostname(link, "");
874 log_error_link(link, "Failed to reset transient hostname");
878 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
883 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
884 sd_dhcp_lease *lease;
885 struct in_addr address;
886 struct in_addr netmask;
887 struct in_addr gateway;
894 r = sd_dhcp_client_get_lease(client, &lease);
896 log_warning_link(link, "DHCP error: no lease: %s",
901 r = sd_dhcp_lease_get_address(lease, &address);
903 log_warning_link(link, "DHCP error: no address: %s",
908 r = sd_dhcp_lease_get_netmask(lease, &netmask);
910 log_warning_link(link, "DHCP error: no netmask: %s",
915 prefixlen = net_netmask_to_prefixlen(&netmask);
917 r = sd_dhcp_lease_get_router(lease, &gateway);
918 if (r < 0 && r != -ENOENT) {
919 log_warning_link(link, "DHCP error: %s", strerror(-r));
924 log_struct_link(LOG_INFO, link,
925 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
928 ADDRESS_FMT_VAL(address),
930 ADDRESS_FMT_VAL(gateway),
931 "ADDRESS=%u.%u.%u.%u",
932 ADDRESS_FMT_VAL(address),
935 "GATEWAY=%u.%u.%u.%u",
936 ADDRESS_FMT_VAL(gateway),
939 log_struct_link(LOG_INFO, link,
940 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
943 ADDRESS_FMT_VAL(address),
945 "ADDRESS=%u.%u.%u.%u",
946 ADDRESS_FMT_VAL(address),
951 link->dhcp_lease = lease;
953 if (link->network->dhcp_mtu) {
956 r = sd_dhcp_lease_get_mtu(lease, &mtu);
958 r = link_set_mtu(link, mtu);
960 log_error_link(link, "Failed to set MTU "
965 if (link->network->dhcp_hostname) {
966 const char *hostname;
968 r = sd_dhcp_lease_get_hostname(lease, &hostname);
970 r = link_set_hostname(link, hostname);
972 log_error_link(link, "Failed to set transient hostname "
973 "to '%s'", hostname);
977 link_enter_set_addresses(link);
982 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
983 Link *link = userdata;
987 assert(link->network);
988 assert(link->manager);
990 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
994 case DHCP_EVENT_NO_LEASE:
995 log_debug_link(link, "IP address in use.");
997 case DHCP_EVENT_EXPIRED:
998 case DHCP_EVENT_STOP:
999 case DHCP_EVENT_IP_CHANGE:
1000 if (link->network->dhcp_critical) {
1001 log_error_link(link, "DHCPv4 connection considered system critical, "
1002 "ignoring request to reconfigure it.");
1006 if (link->dhcp_lease) {
1007 r = dhcp_lease_lost(link);
1009 link_enter_failed(link);
1014 if (event == DHCP_EVENT_IP_CHANGE) {
1015 r = dhcp_lease_acquired(client, link);
1017 link_enter_failed(link);
1022 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1023 if (!sd_ipv4ll_is_running(link->ipv4ll))
1024 r = sd_ipv4ll_start(link->ipv4ll);
1025 else if (ipv4ll_is_bound(link->ipv4ll))
1026 r = ipv4ll_address_update(link, false);
1028 link_enter_failed(link);
1034 case DHCP_EVENT_IP_ACQUIRE:
1035 r = dhcp_lease_acquired(client, link);
1037 link_enter_failed(link);
1041 if (ipv4ll_is_bound(link->ipv4ll))
1042 r = ipv4ll_address_update(link, true);
1044 r = sd_ipv4ll_stop(link->ipv4ll);
1046 link_enter_failed(link);
1053 log_warning_link(link, "DHCP error: %s", strerror(-event));
1055 log_warning_link(link, "DHCP unknown event: %d", event);
1062 static int ipv4ll_address_update(Link *link, bool deprecate) {
1064 struct in_addr addr;
1068 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1070 _cleanup_address_free_ Address *address = NULL;
1072 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1073 deprecate ? "deprecate" : "approve",
1074 ADDRESS_FMT_VAL(addr));
1076 r = address_new_dynamic(&address);
1078 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1082 address->family = AF_INET;
1083 address->in_addr.in = addr;
1084 address->prefixlen = 16;
1085 address->scope = RT_SCOPE_LINK;
1086 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1087 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1089 address_update(address, link, &address_update_handler);
1097 static int ipv4ll_address_lost(Link *link) {
1099 struct in_addr addr;
1103 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1105 _cleanup_address_free_ Address *address = NULL;
1106 _cleanup_route_free_ Route *route = NULL;
1108 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1109 ADDRESS_FMT_VAL(addr));
1111 r = address_new_dynamic(&address);
1113 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1117 address->family = AF_INET;
1118 address->in_addr.in = addr;
1119 address->prefixlen = 16;
1120 address->scope = RT_SCOPE_LINK;
1122 address_drop(address, link, &address_drop_handler);
1125 r = route_new_dynamic(&route);
1127 log_error_link(link, "Could not allocate route: %s",
1132 route->family = AF_INET;
1133 route->scope = RT_SCOPE_LINK;
1134 route->metrics = 99;
1136 route_drop(route, link, &route_drop_handler);
1143 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1145 struct in_addr addr;
1149 r = sd_ipv4ll_get_address(ll, &addr);
1155 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1156 struct in_addr address;
1162 r = sd_ipv4ll_get_address(ll, &address);
1166 log_struct_link(LOG_INFO, link,
1167 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1170 ADDRESS_FMT_VAL(address),
1173 link_enter_set_addresses(link);
1178 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1179 Link *link = userdata;
1183 assert(link->network);
1184 assert(link->manager);
1186 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1190 case IPV4LL_EVENT_STOP:
1191 case IPV4LL_EVENT_CONFLICT:
1192 r = ipv4ll_address_lost(link);
1194 link_enter_failed(link);
1198 case IPV4LL_EVENT_BIND:
1199 r = ipv4ll_address_claimed(ll, link);
1201 link_enter_failed(link);
1207 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1209 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1214 static int link_acquire_conf(Link *link) {
1218 assert(link->network);
1219 assert(link->manager);
1220 assert(link->manager->event);
1222 if (link->network->ipv4ll) {
1223 assert(link->ipv4ll);
1225 log_debug_link(link, "acquiring IPv4 link-local address");
1227 r = sd_ipv4ll_start(link->ipv4ll);
1229 log_warning_link(link, "could not acquire IPv4 "
1230 "link-local address");
1235 if (link->network->dhcp) {
1236 assert(link->dhcp_client);
1238 log_debug_link(link, "acquiring DHCPv4 lease");
1240 r = sd_dhcp_client_start(link->dhcp_client);
1242 log_warning_link(link, "could not acquire DHCPv4 "
1251 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1252 /* see Documentation/networking/operstates.txt in the kernel sources */
1254 if (operstate == IF_OPER_UP)
1257 if (operstate == IF_OPER_UNKNOWN)
1258 /* operstate may not be implemented, so fall back to flags */
1259 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1265 #define FLAG_STRING(string, flag, old, new) \
1266 (((old ^ new) & flag) \
1267 ? ((old & flag) ? (" -" string) : (" +" string)) \
1270 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1271 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1273 bool carrier_gained = false, carrier_lost = false;
1278 r = sd_rtnl_message_link_get_flags(m, &flags);
1280 log_warning_link(link, "Could not get link flags");
1284 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1286 /* if we got a message without operstate, take it to mean
1287 the state was unchanged */
1288 operstate = link->kernel_operstate;
1290 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1293 if (link->flags != flags) {
1294 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",
1295 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1296 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1297 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1298 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1299 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1300 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1301 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1302 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1303 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1304 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1305 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1306 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1307 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1308 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1309 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1310 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1311 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1312 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1313 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1315 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1316 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1317 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1318 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1319 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1320 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1321 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1322 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1324 /* link flags are currently at most 18 bits, let's align to printing 20 */
1325 if (unknown_flags_added)
1326 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1327 unknown_flags_added);
1329 if (unknown_flags_removed)
1330 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1331 unknown_flags_removed);
1334 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1335 link_has_carrier(flags, operstate);
1336 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1337 !link_has_carrier(flags, operstate);
1339 link->flags = flags;
1340 link->kernel_operstate = operstate;
1344 if (link->state == LINK_STATE_FAILED ||
1345 link->state == LINK_STATE_UNMANAGED)
1348 if (carrier_gained) {
1349 log_info_link(link, "gained carrier");
1351 if (link->network) {
1352 r = link_acquire_conf(link);
1354 link_enter_failed(link);
1358 } else if (carrier_lost) {
1359 log_info_link(link, "lost carrier");
1361 r = link_stop_clients(link);
1363 link_enter_failed(link);
1371 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1372 Link *link = userdata;
1377 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1382 r = sd_rtnl_message_get_errno(m);
1384 /* we warn but don't fail the link, as it may
1385 be brought up later */
1386 log_struct_link(LOG_WARNING, link,
1387 "MESSAGE=%-*s: could not bring up interface: %s",
1389 link->ifname, strerror(-r),
1399 static int link_up(Link *link) {
1400 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1404 assert(link->manager);
1405 assert(link->manager->rtnl);
1407 log_debug_link(link, "bringing link up");
1409 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1410 RTM_SETLINK, link->ifindex);
1412 log_error_link(link, "Could not allocate RTM_SETLINK message");
1416 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1418 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1422 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1424 log_error_link(link,
1425 "Could not send rtnetlink message: %s", strerror(-r));
1434 static int link_enslaved(Link *link) {
1438 assert(link->state == LINK_STATE_ENSLAVING);
1439 assert(link->network);
1441 if (!(link->flags & IFF_UP)) {
1444 link_enter_failed(link);
1449 if (!link->network->dhcp && !link->network->ipv4ll)
1450 return link_enter_set_addresses(link);
1455 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1456 Link *link = userdata;
1460 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1461 LINK_STATE_LINGER));
1462 assert(link->network);
1466 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1471 r = sd_rtnl_message_get_errno(m);
1473 log_struct_link(LOG_ERR, link,
1474 "MESSAGE=%-*s: could not enslave: %s",
1476 link->ifname, strerror(-r),
1479 link_enter_failed(link);
1484 log_debug_link(link, "enslaved");
1486 if (link->enslaving == 0)
1487 link_enslaved(link);
1494 static int link_enter_enslave(Link *link) {
1495 NetDev *vlan, *macvlan, *vxlan;
1500 assert(link->network);
1501 assert(link->state == LINK_STATE_INITIALIZING);
1503 link->state = LINK_STATE_ENSLAVING;
1507 if (!link->network->bridge &&
1508 !link->network->bond &&
1509 !link->network->tunnel &&
1510 hashmap_isempty(link->network->vlans) &&
1511 hashmap_isempty(link->network->macvlans) &&
1512 hashmap_isempty(link->network->vxlans))
1513 return link_enslaved(link);
1515 if (link->network->bond) {
1516 log_struct_link(LOG_DEBUG, link,
1517 "MESSAGE=%-*s: enslaving by '%s'",
1519 link->ifname, link->network->bond->ifname,
1520 NETDEV(link->network->bond),
1523 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1525 log_struct_link(LOG_WARNING, link,
1526 "MESSAGE=%-*s: could not enslave by '%s': %s",
1528 link->ifname, link->network->bond->ifname, strerror(-r),
1529 NETDEV(link->network->bond),
1531 link_enter_failed(link);
1539 if (link->network->bridge) {
1540 log_struct_link(LOG_DEBUG, link,
1541 "MESSAGE=%-*s: enslaving by '%s'",
1543 link->ifname, link->network->bridge->ifname,
1544 NETDEV(link->network->bridge),
1547 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1549 log_struct_link(LOG_WARNING, link,
1550 "MESSAGE=%-*s: could not enslave by '%s': %s",
1552 link->ifname, link->network->bridge->ifname, strerror(-r),
1553 NETDEV(link->network->bridge),
1555 link_enter_failed(link);
1563 if (link->network->tunnel) {
1564 log_struct_link(LOG_DEBUG, link,
1565 "MESSAGE=%-*s: enslaving by '%s'",
1567 link->ifname, link->network->tunnel->ifname,
1568 NETDEV(link->network->tunnel),
1571 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1573 log_struct_link(LOG_WARNING, link,
1574 "MESSAGE=%-*s: could not enslave by '%s': %s",
1576 link->ifname, link->network->tunnel->ifname, strerror(-r),
1577 NETDEV(link->network->tunnel),
1579 link_enter_failed(link);
1587 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1588 log_struct_link(LOG_DEBUG, link,
1589 "MESSAGE=%-*s: enslaving by '%s'",
1591 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1593 r = netdev_enslave(vlan, link, &enslave_handler);
1595 log_struct_link(LOG_WARNING, link,
1596 "MESSAGE=%-*s: could not enslave by '%s': %s",
1598 link->ifname, vlan->ifname, strerror(-r),
1599 NETDEV(vlan), NULL);
1600 link_enter_failed(link);
1608 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1609 log_struct_link(LOG_DEBUG, link,
1610 "MESSAGE=%-*s: enslaving by '%s'",
1612 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1614 r = netdev_enslave(macvlan, link, &enslave_handler);
1616 log_struct_link(LOG_WARNING, link,
1617 "MESSAGE=%-*s: could not enslave by '%s': %s",
1619 link->ifname, macvlan->ifname, strerror(-r),
1620 NETDEV(macvlan), NULL);
1621 link_enter_failed(link);
1629 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1630 log_struct_link(LOG_DEBUG, link,
1631 "MESSAGE=%*s: enslaving by '%s'",
1633 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1635 r = netdev_enslave(vxlan, link, &enslave_handler);
1637 log_struct_link(LOG_WARNING, link,
1638 "MESSAGE=%*s: could not enslave by '%s': %s",
1640 link->ifname, vxlan->ifname, strerror(-r),
1641 NETDEV(vxlan), NULL);
1642 link_enter_failed(link);
1653 static int link_configure(Link *link) {
1657 assert(link->state == LINK_STATE_INITIALIZING);
1659 if (link->network->ipv4ll) {
1662 r = sd_ipv4ll_new(&link->ipv4ll);
1666 if (link->udev_device) {
1667 r = net_get_unique_predictable_data(link->udev_device, seed);
1669 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1675 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1679 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1683 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1687 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1692 if (link->network->dhcp) {
1693 r = sd_dhcp_client_new(&link->dhcp_client);
1697 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1701 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1705 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1709 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1713 if (link->network->dhcp_mtu) {
1714 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1720 if (link->network->dhcp_server) {
1723 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1727 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1731 LIST_FOREACH(addresses, address,
1732 link->network->static_addresses) {
1733 struct in_addr pool_start;
1735 if (address->family != AF_INET)
1738 /* currently this is picked essentially at random */
1739 r = sd_dhcp_server_set_address(link->dhcp_server,
1740 &address->in_addr.in);
1744 /* offer 32 addresses starting from the address following the server address */
1745 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
1746 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
1755 r = sd_dhcp_server_set_router(link->dhcp_server,
1756 &main_address->in_addr.in);
1760 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
1761 main_address->prefixlen);
1767 if (link_has_carrier(link->flags, link->operstate)) {
1768 r = link_acquire_conf(link);
1773 return link_enter_enslave(link);
1776 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1777 Link *link = userdata;
1782 assert(link->ifname);
1783 assert(link->manager);
1785 if (link->state != LINK_STATE_INITIALIZING)
1788 log_debug_link(link, "link state is up-to-date");
1790 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1792 link_enter_unmanaged(link);
1797 r = network_apply(link->manager, network, link);
1801 r = link_configure(link);
1808 int link_initialized(Link *link, struct udev_device *device) {
1809 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1813 assert(link->manager);
1814 assert(link->manager->rtnl);
1817 if (link->state != LINK_STATE_INITIALIZING)
1820 log_debug_link(link, "udev initialized link");
1822 link->udev_device = udev_device_ref(device);
1824 /* udev has initialized the link, but we don't know if we have yet processed
1825 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1826 we know that the pending NEWLINKs have already been processed and that we
1829 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1833 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1840 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1841 Manager *m = userdata;
1844 _cleanup_address_free_ Address *address = NULL;
1846 char buf[INET6_ADDRSTRLEN];
1847 bool address_dropped = false;
1854 r = sd_rtnl_message_get_type(message, &type);
1856 log_warning("rtnl: could not get message type");
1860 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1861 if (r < 0 || ifindex <= 0) {
1862 log_warning("rtnl: received address message without valid ifindex, ignoring");
1865 r = link_get(m, ifindex, &link);
1866 if (r < 0 || !link) {
1867 log_warning("rtnl: received address for a nonexistent link, ignoring");
1872 r = address_new_dynamic(&address);
1876 r = sd_rtnl_message_addr_get_family(message, &address->family);
1877 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1878 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
1882 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1884 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
1888 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1890 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
1894 switch (address->family) {
1896 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1898 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1905 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1907 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1914 assert_not_reached("invalid address family");
1917 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
1918 log_warning_link(link, "could not print address");
1922 LIST_FOREACH(addresses, ad, link->addresses) {
1923 if (address_equal(ad, address)) {
1924 LIST_REMOVE(addresses, link->addresses, ad);
1928 address_dropped = true;
1936 if (!address_dropped)
1937 log_debug_link(link, "added address: %s/%u", buf,
1938 address->prefixlen);
1940 LIST_PREPEND(addresses, link->addresses, address);
1947 if (address_dropped) {
1948 log_debug_link(link, "removed address: %s/%u", buf,
1949 address->prefixlen);
1956 assert_not_reached("Received invalid RTNL message type");
1962 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1963 Link *link = userdata;
1970 for (; m; m = sd_rtnl_message_next(m)) {
1971 r = sd_rtnl_message_get_errno(m);
1973 log_debug_link(link, "getting address failed: %s", strerror(-r));
1977 r = link_rtnl_process_address(rtnl, m, link->manager);
1979 log_warning_link(link, "could not process address: %s", strerror(-r));
1985 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1987 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1988 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1989 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1997 r = link_new(m, message, ret);
2003 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2005 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2009 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2013 if (detect_container(NULL) <= 0) {
2014 /* not in a container, udev will be around */
2015 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2016 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2018 log_warning_link(link, "could not find udev device");
2022 if (udev_device_get_is_initialized(device) <= 0) {
2024 log_debug_link(link, "udev initializing link...");
2028 r = link_initialized(link, device);
2032 r = link_initialized_and_synced(m->rtnl, NULL, link);
2040 int link_update(Link *link, sd_rtnl_message *m) {
2041 struct ether_addr mac;
2046 assert(link->ifname);
2049 if (link->state == LINK_STATE_LINGER) {
2051 log_info_link(link, "link readded");
2052 link->state = LINK_STATE_ENSLAVING;
2055 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2056 if (r >= 0 && !streq(ifname, link->ifname)) {
2057 log_info_link(link, "renamed to %s", ifname);
2060 link->ifname = strdup(ifname);
2065 if (!link->original_mtu) {
2066 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2068 log_debug_link(link, "saved original MTU: %"
2069 PRIu16, link->original_mtu);
2072 /* The kernel may broadcast NEWLINK messages without the MAC address
2073 set, simply ignore them. */
2074 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2076 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2078 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2080 log_debug_link(link, "MAC address: "
2081 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2082 mac.ether_addr_octet[0],
2083 mac.ether_addr_octet[1],
2084 mac.ether_addr_octet[2],
2085 mac.ether_addr_octet[3],
2086 mac.ether_addr_octet[4],
2087 mac.ether_addr_octet[5]);
2090 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2092 log_warning_link(link, "Could not update MAC "
2093 "address in IPv4LL client: %s",
2099 if (link->dhcp_client) {
2100 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2102 log_warning_link(link, "Could not update MAC "
2103 "address in DHCP client: %s",
2111 return link_update_flags(link, m);
2114 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2123 fprintf(f, "%s=", key);
2125 LIST_FOREACH(addresses, ad, address) {
2126 char buf[INET6_ADDRSTRLEN];
2128 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2129 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2135 static void link_update_operstate(Link *link) {
2139 if (link->kernel_operstate == IF_OPER_DORMANT)
2140 link->operstate = LINK_OPERSTATE_DORMANT;
2141 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2143 uint8_t scope = RT_SCOPE_NOWHERE;
2145 /* if we have carrier, check what addresses we have */
2146 LIST_FOREACH(addresses, address, link->addresses) {
2147 if (address->scope < scope)
2148 scope = address->scope;
2151 if (scope < RT_SCOPE_SITE)
2152 /* universally accessible addresses found */
2153 link->operstate = LINK_OPERSTATE_ROUTABLE;
2154 else if (scope < RT_SCOPE_HOST)
2155 /* only link or site local addresses found */
2156 link->operstate = LINK_OPERSTATE_DEGRADED;
2158 /* no useful addresses found */
2159 link->operstate = LINK_OPERSTATE_CARRIER;
2161 link->operstate = LINK_OPERSTATE_UNKNOWN;
2164 int link_save(Link *link) {
2165 _cleanup_free_ char *temp_path = NULL;
2166 _cleanup_fclose_ FILE *f = NULL;
2167 const char *admin_state, *oper_state;
2171 assert(link->state_file);
2172 assert(link->lease_file);
2173 assert(link->manager);
2175 link_update_operstate(link);
2177 r = manager_save(link->manager);
2181 if (link->state == LINK_STATE_LINGER) {
2182 unlink(link->state_file);
2186 admin_state = link_state_to_string(link->state);
2187 assert(admin_state);
2189 oper_state = link_operstate_to_string(link->operstate);
2192 r = fopen_temporary(link->state_file, &f, &temp_path);
2196 fchmod(fileno(f), 0644);
2199 "# This is private data. Do not parse.\n"
2203 admin_state, oper_state, link->flags);
2205 if (link->network) {
2206 serialize_addresses(f, "DNS", link->network->dns);
2207 serialize_addresses(f, "NTP", link->network->ntp);
2210 if (link->dhcp_lease) {
2211 assert(link->network);
2213 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2220 "DHCP_USE_NTP=%s\n",
2222 yes_no(link->network->dhcp_dns),
2223 yes_no(link->network->dhcp_ntp));
2225 unlink(link->lease_file);
2229 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2231 unlink(link->state_file);
2237 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2242 static const char* const link_state_table[_LINK_STATE_MAX] = {
2243 [LINK_STATE_INITIALIZING] = "initializing",
2244 [LINK_STATE_ENSLAVING] = "configuring",
2245 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2246 [LINK_STATE_SETTING_ROUTES] = "configuring",
2247 [LINK_STATE_CONFIGURED] = "configured",
2248 [LINK_STATE_UNMANAGED] = "unmanaged",
2249 [LINK_STATE_FAILED] = "failed",
2250 [LINK_STATE_LINGER] = "linger",
2253 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2255 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2256 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2257 [LINK_OPERSTATE_DORMANT] = "dormant",
2258 [LINK_OPERSTATE_CARRIER] = "carrier",
2259 [LINK_OPERSTATE_DEGRADED] = "degraded",
2260 [LINK_OPERSTATE_ROUTABLE] = "routable",
2263 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);