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 while ((address = link->pool_addresses)) {
116 LIST_REMOVE(addresses, link->pool_addresses, address);
117 address_free(address);
120 sd_dhcp_client_unref(link->dhcp_client);
121 sd_dhcp_lease_unref(link->dhcp_lease);
123 unlink(link->lease_file);
124 free(link->lease_file);
126 sd_ipv4ll_unref(link->ipv4ll);
128 hashmap_remove(link->manager->links, &link->ifindex);
132 unlink(link->state_file);
133 free(link->state_file);
135 udev_device_unref(link->udev_device);
140 Link *link_unref(Link *link) {
141 if (link && (-- link->n_ref <= 0))
147 Link *link_ref(Link *link) {
149 assert_se(++ link->n_ref >= 2);
154 int link_get(Manager *m, int ifindex, Link **ret) {
163 ifindex_64 = ifindex;
164 link = hashmap_get(m->links, &ifindex_64);
173 void link_drop(Link *link) {
174 if (!link || link->state == LINK_STATE_LINGER)
177 link->state = LINK_STATE_LINGER;
179 log_debug_link(link, "link removed");
186 static void link_enter_unmanaged(Link *link) {
189 log_debug_link(link, "unmanaged");
191 link->state = LINK_STATE_UNMANAGED;
196 static int link_stop_clients(Link *link) {
200 assert(link->manager);
201 assert(link->manager->event);
206 if (link->network->dhcp) {
207 assert(link->dhcp_client);
209 k = sd_dhcp_client_stop(link->dhcp_client);
211 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
216 if (link->network->ipv4ll) {
217 assert(link->ipv4ll);
219 k = sd_ipv4ll_stop(link->ipv4ll);
221 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
226 if (link->network->dhcp_server) {
227 assert(link->dhcp_server);
229 k = sd_dhcp_server_stop(link->dhcp_server);
231 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
239 static void link_enter_failed(Link *link) {
242 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
245 log_warning_link(link, "failed");
247 link->state = LINK_STATE_FAILED;
249 link_stop_clients(link);
254 static int link_enter_configured(Link *link) {
258 assert(link->network);
259 assert(link->state == LINK_STATE_SETTING_ROUTES);
262 if (link->network->dhcp_server) {
263 log_debug_link(link, "offering DHCPv4 leases");
265 r = sd_dhcp_server_start(link->dhcp_server);
267 log_warning_link(link, "could not start DHCPv4 server "
268 "instance: %s", strerror(-r));
270 link_enter_failed(link);
276 log_info_link(link, "link configured");
278 link->state = LINK_STATE_CONFIGURED;
285 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
286 Link *link = userdata;
289 assert(link->route_messages > 0);
290 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
291 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
294 link->route_messages --;
296 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
301 r = sd_rtnl_message_get_errno(m);
302 if (r < 0 && r != -EEXIST)
303 log_struct_link(LOG_WARNING, link,
304 "MESSAGE=%-*s: could not set route: %s",
306 link->ifname, strerror(-r),
310 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
312 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
313 log_debug_link(link, "routes set");
314 link_enter_configured(link);
322 static int link_enter_set_routes(Link *link) {
327 assert(link->network);
328 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
330 link->state = LINK_STATE_SETTING_ROUTES;
332 if (!link->network->static_routes && !link->dhcp_lease &&
333 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
334 return link_enter_configured(link);
336 log_debug_link(link, "setting routes");
338 LIST_FOREACH(routes, rt, link->network->static_routes) {
339 r = route_configure(rt, link, &route_handler);
341 log_warning_link(link,
342 "could not set routes: %s", strerror(-r));
343 link_enter_failed(link);
348 link->route_messages ++;
351 if (link->ipv4ll && !link->dhcp_lease) {
352 _cleanup_route_free_ Route *route = NULL;
355 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
356 if (r < 0 && r != -ENOENT) {
357 log_warning_link(link, "IPV4LL error: no address: %s",
363 r = route_new_dynamic(&route);
365 log_error_link(link, "Could not allocate route: %s",
370 route->family = AF_INET;
371 route->scope = RT_SCOPE_LINK;
374 r = route_configure(route, link, &route_handler);
376 log_warning_link(link,
377 "could not set routes: %s", strerror(-r));
378 link_enter_failed(link);
383 link->route_messages ++;
387 if (link->dhcp_lease) {
388 _cleanup_route_free_ Route *route = NULL;
389 _cleanup_route_free_ Route *route_gw = NULL;
390 struct in_addr gateway;
392 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
393 if (r < 0 && r != -ENOENT) {
394 log_warning_link(link, "DHCP error: %s", strerror(-r));
399 r = route_new_dynamic(&route);
401 log_error_link(link, "Could not allocate route: %s",
406 r = route_new_dynamic(&route_gw);
408 log_error_link(link, "Could not allocate route: %s",
413 /* The dhcp netmask may mask out the gateway. Add an explicit
414 * route for the gw host so that we can route no matter the
415 * netmask or existing kernel route tables. */
416 route_gw->family = AF_INET;
417 route_gw->dst_addr.in = gateway;
418 route_gw->dst_prefixlen = 32;
419 route_gw->scope = RT_SCOPE_LINK;
421 r = route_configure(route_gw, link, &route_handler);
423 log_warning_link(link,
424 "could not set host route: %s", strerror(-r));
429 link->route_messages ++;
431 route->family = AF_INET;
432 route->in_addr.in = gateway;
434 r = route_configure(route, link, &route_handler);
436 log_warning_link(link,
437 "could not set routes: %s", strerror(-r));
438 link_enter_failed(link);
443 link->route_messages ++;
447 if (link->route_messages == 0) {
448 link_enter_configured(link);
454 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
455 Link *link = userdata;
460 assert(link->ifname);
462 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
467 r = sd_rtnl_message_get_errno(m);
468 if (r < 0 && r != -ESRCH)
469 log_struct_link(LOG_WARNING, link,
470 "MESSAGE=%-*s: could not drop route: %s",
472 link->ifname, strerror(-r),
481 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
482 Link *link = userdata;
487 assert(link->ifname);
488 assert(link->addr_messages > 0);
489 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
490 LINK_STATE_FAILED, LINK_STATE_LINGER));
492 link->addr_messages --;
494 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
499 r = sd_rtnl_message_get_errno(m);
500 if (r < 0 && r != -EEXIST)
501 log_struct_link(LOG_WARNING, link,
502 "MESSAGE=%-*s: could not set address: %s",
504 link->ifname, strerror(-r),
508 if (link->addr_messages == 0) {
509 log_debug_link(link, "addresses set");
510 link_enter_set_routes(link);
518 static int link_enter_set_addresses(Link *link) {
523 assert(link->network);
524 assert(link->state != _LINK_STATE_INVALID);
526 link->state = LINK_STATE_SETTING_ADDRESSES;
528 if (!link->network->static_addresses && !link->dhcp_lease &&
529 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
530 return link_enter_set_routes(link);
532 log_debug_link(link, "setting addresses");
534 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
535 r = address_configure(ad, link, &address_handler);
537 log_warning_link(link,
538 "could not set addresses: %s", strerror(-r));
539 link_enter_failed(link);
544 link->addr_messages ++;
547 if (link->ipv4ll && !link->dhcp_lease) {
548 _cleanup_address_free_ Address *ll_addr = NULL;
551 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
552 if (r < 0 && r != -ENOENT) {
553 log_warning_link(link, "IPV4LL error: no address: %s",
559 r = address_new_dynamic(&ll_addr);
561 log_error_link(link, "Could not allocate address: %s", strerror(-r));
565 ll_addr->family = AF_INET;
566 ll_addr->in_addr.in = addr;
567 ll_addr->prefixlen = 16;
568 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
569 ll_addr->scope = RT_SCOPE_LINK;
571 r = address_configure(ll_addr, link, &address_handler);
573 log_warning_link(link,
574 "could not set addresses: %s", strerror(-r));
575 link_enter_failed(link);
580 link->addr_messages ++;
584 if (link->dhcp_lease) {
585 _cleanup_address_free_ Address *address = NULL;
587 struct in_addr netmask;
590 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
592 log_warning_link(link, "DHCP error: no address: %s",
597 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
599 log_warning_link(link, "DHCP error: no netmask: %s",
604 prefixlen = net_netmask_to_prefixlen(&netmask);
606 r = address_new_dynamic(&address);
608 log_error_link(link, "Could not allocate address: %s",
613 address->family = AF_INET;
614 address->in_addr.in = addr;
615 address->prefixlen = prefixlen;
616 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
618 r = address_configure(address, link, &address_handler);
620 log_warning_link(link,
621 "could not set addresses: %s", strerror(-r));
622 link_enter_failed(link);
627 link->addr_messages ++;
633 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
634 Link *link = userdata;
639 assert(link->ifname);
641 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
646 r = sd_rtnl_message_get_errno(m);
647 if (r < 0 && r != -ENOENT)
648 log_struct_link(LOG_WARNING, link,
649 "MESSAGE=%-*s: could not update address: %s",
651 link->ifname, strerror(-r),
660 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
661 Link *link = userdata;
666 assert(link->ifname);
668 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
673 r = sd_rtnl_message_get_errno(m);
674 if (r < 0 && r != -EADDRNOTAVAIL)
675 log_struct_link(LOG_WARNING, link,
676 "MESSAGE=%-*s: could not drop address: %s",
678 link->ifname, strerror(-r),
687 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
688 Link *link = userdata;
693 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
698 r = sd_bus_message_get_errno(m);
700 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
707 static int link_set_hostname(Link *link, const char *hostname) {
708 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
712 assert(link->manager);
715 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
717 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
718 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
722 r = sd_bus_message_new_method_call(
725 "org.freedesktop.hostname1",
726 "/org/freedesktop/hostname1",
727 "org.freedesktop.hostname1",
732 r = sd_bus_message_append(m, "sb", hostname, false);
736 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
738 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
745 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
746 Link *link = userdata;
751 assert(link->ifname);
753 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
758 r = sd_rtnl_message_get_errno(m);
760 log_struct_link(LOG_WARNING, link,
761 "MESSAGE=%-*s: could not set MTU: %s",
762 IFNAMSIZ, link->ifname, strerror(-r),
771 static int link_set_mtu(Link *link, uint32_t mtu) {
772 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
776 assert(link->manager);
777 assert(link->manager->rtnl);
779 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
781 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
782 RTM_SETLINK, link->ifindex);
784 log_error_link(link, "Could not allocate RTM_SETLINK message");
788 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
790 log_error_link(link, "Could not append MTU: %s", strerror(-r));
794 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
797 "Could not send rtnetlink message: %s", strerror(-r));
806 static int dhcp_lease_lost(Link *link) {
807 _cleanup_address_free_ Address *address = NULL;
808 _cleanup_route_free_ Route *route_gw = NULL;
809 _cleanup_route_free_ Route *route = NULL;
811 struct in_addr netmask;
812 struct in_addr gateway;
817 assert(link->dhcp_lease);
819 log_warning_link(link, "DHCP lease lost");
821 r = address_new_dynamic(&address);
823 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
825 r = route_new_dynamic(&route_gw);
827 route_gw->family = AF_INET;
828 route_gw->dst_addr.in = gateway;
829 route_gw->dst_prefixlen = 32;
830 route_gw->scope = RT_SCOPE_LINK;
832 route_drop(route_gw, link, &route_drop_handler);
836 r = route_new_dynamic(&route);
838 route->family = AF_INET;
839 route->in_addr.in = gateway;
841 route_drop(route, link, &route_drop_handler);
846 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
847 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
848 prefixlen = net_netmask_to_prefixlen(&netmask);
850 address->family = AF_INET;
851 address->in_addr.in = addr;
852 address->prefixlen = prefixlen;
854 address_drop(address, link, &address_drop_handler);
858 if (link->network->dhcp_mtu) {
861 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
862 if (r >= 0 && link->original_mtu != mtu) {
863 r = link_set_mtu(link, link->original_mtu);
865 log_warning_link(link, "DHCP error: could not reset MTU");
866 link_enter_failed(link);
872 if (link->network->dhcp_hostname) {
873 const char *hostname = NULL;
875 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
876 if (r >= 0 && hostname) {
877 r = link_set_hostname(link, "");
879 log_error_link(link, "Failed to reset transient hostname");
883 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
888 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
889 sd_dhcp_lease *lease;
890 struct in_addr address;
891 struct in_addr netmask;
892 struct in_addr gateway;
899 r = sd_dhcp_client_get_lease(client, &lease);
901 log_warning_link(link, "DHCP error: no lease: %s",
906 r = sd_dhcp_lease_get_address(lease, &address);
908 log_warning_link(link, "DHCP error: no address: %s",
913 r = sd_dhcp_lease_get_netmask(lease, &netmask);
915 log_warning_link(link, "DHCP error: no netmask: %s",
920 prefixlen = net_netmask_to_prefixlen(&netmask);
922 r = sd_dhcp_lease_get_router(lease, &gateway);
923 if (r < 0 && r != -ENOENT) {
924 log_warning_link(link, "DHCP error: %s", strerror(-r));
929 log_struct_link(LOG_INFO, link,
930 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
933 ADDRESS_FMT_VAL(address),
935 ADDRESS_FMT_VAL(gateway),
936 "ADDRESS=%u.%u.%u.%u",
937 ADDRESS_FMT_VAL(address),
940 "GATEWAY=%u.%u.%u.%u",
941 ADDRESS_FMT_VAL(gateway),
944 log_struct_link(LOG_INFO, link,
945 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
948 ADDRESS_FMT_VAL(address),
950 "ADDRESS=%u.%u.%u.%u",
951 ADDRESS_FMT_VAL(address),
956 link->dhcp_lease = lease;
958 if (link->network->dhcp_mtu) {
961 r = sd_dhcp_lease_get_mtu(lease, &mtu);
963 r = link_set_mtu(link, mtu);
965 log_error_link(link, "Failed to set MTU "
970 if (link->network->dhcp_hostname) {
971 const char *hostname;
973 r = sd_dhcp_lease_get_hostname(lease, &hostname);
975 r = link_set_hostname(link, hostname);
977 log_error_link(link, "Failed to set transient hostname "
978 "to '%s'", hostname);
982 link_enter_set_addresses(link);
987 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
988 Link *link = userdata;
992 assert(link->network);
993 assert(link->manager);
995 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
999 case DHCP_EVENT_NO_LEASE:
1000 log_debug_link(link, "IP address in use.");
1002 case DHCP_EVENT_EXPIRED:
1003 case DHCP_EVENT_STOP:
1004 case DHCP_EVENT_IP_CHANGE:
1005 if (link->network->dhcp_critical) {
1006 log_error_link(link, "DHCPv4 connection considered system critical, "
1007 "ignoring request to reconfigure it.");
1011 if (link->dhcp_lease) {
1012 r = dhcp_lease_lost(link);
1014 link_enter_failed(link);
1019 if (event == DHCP_EVENT_IP_CHANGE) {
1020 r = dhcp_lease_acquired(client, link);
1022 link_enter_failed(link);
1027 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1028 if (!sd_ipv4ll_is_running(link->ipv4ll))
1029 r = sd_ipv4ll_start(link->ipv4ll);
1030 else if (ipv4ll_is_bound(link->ipv4ll))
1031 r = ipv4ll_address_update(link, false);
1033 link_enter_failed(link);
1039 case DHCP_EVENT_IP_ACQUIRE:
1040 r = dhcp_lease_acquired(client, link);
1042 link_enter_failed(link);
1046 if (ipv4ll_is_bound(link->ipv4ll))
1047 r = ipv4ll_address_update(link, true);
1049 r = sd_ipv4ll_stop(link->ipv4ll);
1051 link_enter_failed(link);
1058 log_warning_link(link, "DHCP error: %s", strerror(-event));
1060 log_warning_link(link, "DHCP unknown event: %d", event);
1067 static int ipv4ll_address_update(Link *link, bool deprecate) {
1069 struct in_addr addr;
1073 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1075 _cleanup_address_free_ Address *address = NULL;
1077 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1078 deprecate ? "deprecate" : "approve",
1079 ADDRESS_FMT_VAL(addr));
1081 r = address_new_dynamic(&address);
1083 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1087 address->family = AF_INET;
1088 address->in_addr.in = addr;
1089 address->prefixlen = 16;
1090 address->scope = RT_SCOPE_LINK;
1091 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1092 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1094 address_update(address, link, &address_update_handler);
1102 static int ipv4ll_address_lost(Link *link) {
1104 struct in_addr addr;
1108 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1110 _cleanup_address_free_ Address *address = NULL;
1111 _cleanup_route_free_ Route *route = NULL;
1113 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1114 ADDRESS_FMT_VAL(addr));
1116 r = address_new_dynamic(&address);
1118 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1122 address->family = AF_INET;
1123 address->in_addr.in = addr;
1124 address->prefixlen = 16;
1125 address->scope = RT_SCOPE_LINK;
1127 address_drop(address, link, &address_drop_handler);
1130 r = route_new_dynamic(&route);
1132 log_error_link(link, "Could not allocate route: %s",
1137 route->family = AF_INET;
1138 route->scope = RT_SCOPE_LINK;
1139 route->metrics = 99;
1141 route_drop(route, link, &route_drop_handler);
1148 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1150 struct in_addr addr;
1154 r = sd_ipv4ll_get_address(ll, &addr);
1160 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1161 struct in_addr address;
1167 r = sd_ipv4ll_get_address(ll, &address);
1171 log_struct_link(LOG_INFO, link,
1172 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1175 ADDRESS_FMT_VAL(address),
1178 link_enter_set_addresses(link);
1183 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1184 Link *link = userdata;
1188 assert(link->network);
1189 assert(link->manager);
1191 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1195 case IPV4LL_EVENT_STOP:
1196 case IPV4LL_EVENT_CONFLICT:
1197 r = ipv4ll_address_lost(link);
1199 link_enter_failed(link);
1203 case IPV4LL_EVENT_BIND:
1204 r = ipv4ll_address_claimed(ll, link);
1206 link_enter_failed(link);
1212 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1214 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1219 static int link_acquire_conf(Link *link) {
1223 assert(link->network);
1224 assert(link->manager);
1225 assert(link->manager->event);
1227 if (link->network->ipv4ll) {
1228 assert(link->ipv4ll);
1230 log_debug_link(link, "acquiring IPv4 link-local address");
1232 r = sd_ipv4ll_start(link->ipv4ll);
1234 log_warning_link(link, "could not acquire IPv4 "
1235 "link-local address");
1240 if (link->network->dhcp) {
1241 assert(link->dhcp_client);
1243 log_debug_link(link, "acquiring DHCPv4 lease");
1245 r = sd_dhcp_client_start(link->dhcp_client);
1247 log_warning_link(link, "could not acquire DHCPv4 "
1256 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1257 /* see Documentation/networking/operstates.txt in the kernel sources */
1259 if (operstate == IF_OPER_UP)
1262 if (operstate == IF_OPER_UNKNOWN)
1263 /* operstate may not be implemented, so fall back to flags */
1264 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1270 #define FLAG_STRING(string, flag, old, new) \
1271 (((old ^ new) & flag) \
1272 ? ((old & flag) ? (" -" string) : (" +" string)) \
1275 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1276 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1278 bool carrier_gained = false, carrier_lost = false;
1283 r = sd_rtnl_message_link_get_flags(m, &flags);
1285 log_warning_link(link, "Could not get link flags");
1289 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1291 /* if we got a message without operstate, take it to mean
1292 the state was unchanged */
1293 operstate = link->kernel_operstate;
1295 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1298 if (link->flags != flags) {
1299 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",
1300 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1301 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1302 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1303 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1304 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1305 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1306 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1307 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1308 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1309 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1310 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1311 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1312 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1313 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1314 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1315 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1316 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1317 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1318 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1320 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1321 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1322 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1323 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1324 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1325 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1326 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1327 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1329 /* link flags are currently at most 18 bits, let's align to printing 20 */
1330 if (unknown_flags_added)
1331 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1332 unknown_flags_added);
1334 if (unknown_flags_removed)
1335 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1336 unknown_flags_removed);
1339 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1340 link_has_carrier(flags, operstate);
1341 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1342 !link_has_carrier(flags, operstate);
1344 link->flags = flags;
1345 link->kernel_operstate = operstate;
1349 if (link->state == LINK_STATE_FAILED ||
1350 link->state == LINK_STATE_UNMANAGED)
1353 if (carrier_gained) {
1354 log_info_link(link, "gained carrier");
1356 if (link->network) {
1357 r = link_acquire_conf(link);
1359 link_enter_failed(link);
1363 } else if (carrier_lost) {
1364 log_info_link(link, "lost carrier");
1366 r = link_stop_clients(link);
1368 link_enter_failed(link);
1376 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1377 Link *link = userdata;
1382 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1387 r = sd_rtnl_message_get_errno(m);
1389 /* we warn but don't fail the link, as it may
1390 be brought up later */
1391 log_struct_link(LOG_WARNING, link,
1392 "MESSAGE=%-*s: could not bring up interface: %s",
1394 link->ifname, strerror(-r),
1404 static int link_up(Link *link) {
1405 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1409 assert(link->manager);
1410 assert(link->manager->rtnl);
1412 log_debug_link(link, "bringing link up");
1414 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1415 RTM_SETLINK, link->ifindex);
1417 log_error_link(link, "Could not allocate RTM_SETLINK message");
1421 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1423 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1427 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1429 log_error_link(link,
1430 "Could not send rtnetlink message: %s", strerror(-r));
1439 static int link_enslaved(Link *link) {
1443 assert(link->state == LINK_STATE_ENSLAVING);
1444 assert(link->network);
1446 if (!(link->flags & IFF_UP)) {
1449 link_enter_failed(link);
1454 if (!link->network->dhcp && !link->network->ipv4ll)
1455 return link_enter_set_addresses(link);
1460 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1461 Link *link = userdata;
1465 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1466 LINK_STATE_LINGER));
1467 assert(link->network);
1471 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1476 r = sd_rtnl_message_get_errno(m);
1478 log_struct_link(LOG_ERR, link,
1479 "MESSAGE=%-*s: could not enslave: %s",
1481 link->ifname, strerror(-r),
1484 link_enter_failed(link);
1489 log_debug_link(link, "enslaved");
1491 if (link->enslaving == 0)
1492 link_enslaved(link);
1499 static int link_enter_enslave(Link *link) {
1500 NetDev *vlan, *macvlan, *vxlan;
1505 assert(link->network);
1506 assert(link->state == LINK_STATE_INITIALIZING);
1508 link->state = LINK_STATE_ENSLAVING;
1512 if (!link->network->bridge &&
1513 !link->network->bond &&
1514 !link->network->tunnel &&
1515 hashmap_isempty(link->network->vlans) &&
1516 hashmap_isempty(link->network->macvlans) &&
1517 hashmap_isempty(link->network->vxlans))
1518 return link_enslaved(link);
1520 if (link->network->bond) {
1521 log_struct_link(LOG_DEBUG, link,
1522 "MESSAGE=%-*s: enslaving by '%s'",
1524 link->ifname, link->network->bond->ifname,
1525 NETDEV(link->network->bond),
1528 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1530 log_struct_link(LOG_WARNING, link,
1531 "MESSAGE=%-*s: could not enslave by '%s': %s",
1533 link->ifname, link->network->bond->ifname, strerror(-r),
1534 NETDEV(link->network->bond),
1536 link_enter_failed(link);
1544 if (link->network->bridge) {
1545 log_struct_link(LOG_DEBUG, link,
1546 "MESSAGE=%-*s: enslaving by '%s'",
1548 link->ifname, link->network->bridge->ifname,
1549 NETDEV(link->network->bridge),
1552 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1554 log_struct_link(LOG_WARNING, link,
1555 "MESSAGE=%-*s: could not enslave by '%s': %s",
1557 link->ifname, link->network->bridge->ifname, strerror(-r),
1558 NETDEV(link->network->bridge),
1560 link_enter_failed(link);
1568 if (link->network->tunnel) {
1569 log_struct_link(LOG_DEBUG, link,
1570 "MESSAGE=%-*s: enslaving by '%s'",
1572 link->ifname, link->network->tunnel->ifname,
1573 NETDEV(link->network->tunnel),
1576 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1578 log_struct_link(LOG_WARNING, link,
1579 "MESSAGE=%-*s: could not enslave by '%s': %s",
1581 link->ifname, link->network->tunnel->ifname, strerror(-r),
1582 NETDEV(link->network->tunnel),
1584 link_enter_failed(link);
1592 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1593 log_struct_link(LOG_DEBUG, link,
1594 "MESSAGE=%-*s: enslaving by '%s'",
1596 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1598 r = netdev_enslave(vlan, link, &enslave_handler);
1600 log_struct_link(LOG_WARNING, link,
1601 "MESSAGE=%-*s: could not enslave by '%s': %s",
1603 link->ifname, vlan->ifname, strerror(-r),
1604 NETDEV(vlan), NULL);
1605 link_enter_failed(link);
1613 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1614 log_struct_link(LOG_DEBUG, link,
1615 "MESSAGE=%-*s: enslaving by '%s'",
1617 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1619 r = netdev_enslave(macvlan, link, &enslave_handler);
1621 log_struct_link(LOG_WARNING, link,
1622 "MESSAGE=%-*s: could not enslave by '%s': %s",
1624 link->ifname, macvlan->ifname, strerror(-r),
1625 NETDEV(macvlan), NULL);
1626 link_enter_failed(link);
1634 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1635 log_struct_link(LOG_DEBUG, link,
1636 "MESSAGE=%*s: enslaving by '%s'",
1638 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1640 r = netdev_enslave(vxlan, link, &enslave_handler);
1642 log_struct_link(LOG_WARNING, link,
1643 "MESSAGE=%*s: could not enslave by '%s': %s",
1645 link->ifname, vxlan->ifname, strerror(-r),
1646 NETDEV(vxlan), NULL);
1647 link_enter_failed(link);
1658 static int link_configure(Link *link) {
1662 assert(link->state == LINK_STATE_INITIALIZING);
1664 if (link->network->ipv4ll) {
1667 r = sd_ipv4ll_new(&link->ipv4ll);
1671 if (link->udev_device) {
1672 r = net_get_unique_predictable_data(link->udev_device, seed);
1674 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1680 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1684 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1688 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1692 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1697 if (link->network->dhcp) {
1698 r = sd_dhcp_client_new(&link->dhcp_client);
1702 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1706 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1710 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1714 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1718 if (link->network->dhcp_mtu) {
1719 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1725 if (link->network->dhcp_server) {
1728 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1732 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1736 LIST_FOREACH(addresses, address,
1737 link->network->static_addresses) {
1738 struct in_addr pool_start;
1740 if (address->family != AF_INET)
1743 /* currently this is picked essentially at random */
1744 r = sd_dhcp_server_set_address(link->dhcp_server,
1745 &address->in_addr.in);
1749 /* offer 32 addresses starting from the address following the server address */
1750 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
1751 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
1760 r = sd_dhcp_server_set_router(link->dhcp_server,
1761 &main_address->in_addr.in);
1765 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
1766 main_address->prefixlen);
1772 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1773 r = link_acquire_conf(link);
1778 return link_enter_enslave(link);
1781 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1782 Link *link = userdata;
1787 assert(link->ifname);
1788 assert(link->manager);
1790 if (link->state != LINK_STATE_INITIALIZING)
1793 log_debug_link(link, "link state is up-to-date");
1795 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1797 link_enter_unmanaged(link);
1802 r = network_apply(link->manager, network, link);
1806 r = link_configure(link);
1813 int link_initialized(Link *link, struct udev_device *device) {
1814 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1818 assert(link->manager);
1819 assert(link->manager->rtnl);
1822 if (link->state != LINK_STATE_INITIALIZING)
1825 log_debug_link(link, "udev initialized link");
1827 link->udev_device = udev_device_ref(device);
1829 /* udev has initialized the link, but we don't know if we have yet processed
1830 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1831 we know that the pending NEWLINKs have already been processed and that we
1834 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1838 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1845 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1846 Manager *m = userdata;
1849 _cleanup_address_free_ Address *address = NULL;
1851 char buf[INET6_ADDRSTRLEN];
1852 bool address_dropped = false;
1859 r = sd_rtnl_message_get_type(message, &type);
1861 log_warning("rtnl: could not get message type");
1865 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1866 if (r < 0 || ifindex <= 0) {
1867 log_warning("rtnl: received address message without valid ifindex, ignoring");
1870 r = link_get(m, ifindex, &link);
1871 if (r < 0 || !link) {
1872 log_warning("rtnl: received address for a nonexistent link, ignoring");
1877 r = address_new_dynamic(&address);
1881 r = sd_rtnl_message_addr_get_family(message, &address->family);
1882 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1883 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
1887 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1889 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
1893 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1895 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
1899 switch (address->family) {
1901 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1903 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1910 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1912 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1919 assert_not_reached("invalid address family");
1922 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
1923 log_warning_link(link, "could not print address");
1927 LIST_FOREACH(addresses, ad, link->addresses) {
1928 if (address_equal(ad, address)) {
1929 LIST_REMOVE(addresses, link->addresses, ad);
1933 address_dropped = true;
1941 if (!address_dropped)
1942 log_debug_link(link, "added address: %s/%u", buf,
1943 address->prefixlen);
1945 LIST_PREPEND(addresses, link->addresses, address);
1952 if (address_dropped) {
1953 log_debug_link(link, "removed address: %s/%u", buf,
1954 address->prefixlen);
1961 assert_not_reached("Received invalid RTNL message type");
1967 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1968 Link *link = userdata;
1975 for (; m; m = sd_rtnl_message_next(m)) {
1976 r = sd_rtnl_message_get_errno(m);
1978 log_debug_link(link, "getting address failed: %s", strerror(-r));
1982 r = link_rtnl_process_address(rtnl, m, link->manager);
1984 log_warning_link(link, "could not process address: %s", strerror(-r));
1990 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1992 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1993 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1994 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2002 r = link_new(m, message, ret);
2008 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2010 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2014 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2018 if (detect_container(NULL) <= 0) {
2019 /* not in a container, udev will be around */
2020 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2021 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2023 log_warning_link(link, "could not find udev device");
2027 if (udev_device_get_is_initialized(device) <= 0) {
2029 log_debug_link(link, "udev initializing link...");
2033 r = link_initialized(link, device);
2037 r = link_initialized_and_synced(m->rtnl, NULL, link);
2045 int link_update(Link *link, sd_rtnl_message *m) {
2046 struct ether_addr mac;
2051 assert(link->ifname);
2054 if (link->state == LINK_STATE_LINGER) {
2056 log_info_link(link, "link readded");
2057 link->state = LINK_STATE_ENSLAVING;
2060 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2061 if (r >= 0 && !streq(ifname, link->ifname)) {
2062 log_info_link(link, "renamed to %s", ifname);
2065 link->ifname = strdup(ifname);
2070 if (!link->original_mtu) {
2071 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2073 log_debug_link(link, "saved original MTU: %"
2074 PRIu16, link->original_mtu);
2077 /* The kernel may broadcast NEWLINK messages without the MAC address
2078 set, simply ignore them. */
2079 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2081 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2083 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2085 log_debug_link(link, "MAC address: "
2086 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2087 mac.ether_addr_octet[0],
2088 mac.ether_addr_octet[1],
2089 mac.ether_addr_octet[2],
2090 mac.ether_addr_octet[3],
2091 mac.ether_addr_octet[4],
2092 mac.ether_addr_octet[5]);
2095 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2097 log_warning_link(link, "Could not update MAC "
2098 "address in IPv4LL client: %s",
2104 if (link->dhcp_client) {
2105 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2107 log_warning_link(link, "Could not update MAC "
2108 "address in DHCP client: %s",
2116 return link_update_flags(link, m);
2119 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2128 fprintf(f, "%s=", key);
2130 LIST_FOREACH(addresses, ad, address) {
2131 char buf[INET6_ADDRSTRLEN];
2133 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2134 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2140 static void link_update_operstate(Link *link) {
2144 if (link->kernel_operstate == IF_OPER_DORMANT)
2145 link->operstate = LINK_OPERSTATE_DORMANT;
2146 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2148 uint8_t scope = RT_SCOPE_NOWHERE;
2150 /* if we have carrier, check what addresses we have */
2151 LIST_FOREACH(addresses, address, link->addresses) {
2152 if (address->scope < scope)
2153 scope = address->scope;
2156 if (scope < RT_SCOPE_SITE)
2157 /* universally accessible addresses found */
2158 link->operstate = LINK_OPERSTATE_ROUTABLE;
2159 else if (scope < RT_SCOPE_HOST)
2160 /* only link or site local addresses found */
2161 link->operstate = LINK_OPERSTATE_DEGRADED;
2163 /* no useful addresses found */
2164 link->operstate = LINK_OPERSTATE_CARRIER;
2166 link->operstate = LINK_OPERSTATE_UNKNOWN;
2169 int link_save(Link *link) {
2170 _cleanup_free_ char *temp_path = NULL;
2171 _cleanup_fclose_ FILE *f = NULL;
2172 const char *admin_state, *oper_state;
2176 assert(link->state_file);
2177 assert(link->lease_file);
2178 assert(link->manager);
2180 link_update_operstate(link);
2182 r = manager_save(link->manager);
2186 if (link->state == LINK_STATE_LINGER) {
2187 unlink(link->state_file);
2191 admin_state = link_state_to_string(link->state);
2192 assert(admin_state);
2194 oper_state = link_operstate_to_string(link->operstate);
2197 r = fopen_temporary(link->state_file, &f, &temp_path);
2201 fchmod(fileno(f), 0644);
2204 "# This is private data. Do not parse.\n"
2208 admin_state, oper_state, link->flags);
2210 if (link->network) {
2211 serialize_addresses(f, "DNS", link->network->dns);
2212 serialize_addresses(f, "NTP", link->network->ntp);
2215 if (link->dhcp_lease) {
2216 assert(link->network);
2218 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2225 "DHCP_USE_NTP=%s\n",
2227 yes_no(link->network->dhcp_dns),
2228 yes_no(link->network->dhcp_ntp));
2230 unlink(link->lease_file);
2234 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2236 unlink(link->state_file);
2242 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2247 static const char* const link_state_table[_LINK_STATE_MAX] = {
2248 [LINK_STATE_INITIALIZING] = "initializing",
2249 [LINK_STATE_ENSLAVING] = "configuring",
2250 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2251 [LINK_STATE_SETTING_ROUTES] = "configuring",
2252 [LINK_STATE_CONFIGURED] = "configured",
2253 [LINK_STATE_UNMANAGED] = "unmanaged",
2254 [LINK_STATE_FAILED] = "failed",
2255 [LINK_STATE_LINGER] = "linger",
2258 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2260 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2261 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2262 [LINK_OPERSTATE_DORMANT] = "dormant",
2263 [LINK_OPERSTATE_CARRIER] = "carrier",
2264 [LINK_OPERSTATE_DEGRADED] = "degraded",
2265 [LINK_OPERSTATE_ROUTABLE] = "routable",
2268 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);