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;
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 return link_enslaved(link);
1514 if (link->network->bond) {
1515 log_struct_link(LOG_DEBUG, link,
1516 "MESSAGE=%-*s: enslaving by '%s'",
1518 link->ifname, link->network->bond->ifname,
1519 NETDEV(link->network->bond),
1522 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1524 log_struct_link(LOG_WARNING, link,
1525 "MESSAGE=%-*s: could not enslave by '%s': %s",
1527 link->ifname, link->network->bond->ifname, strerror(-r),
1528 NETDEV(link->network->bond),
1530 link_enter_failed(link);
1538 if (link->network->bridge) {
1539 log_struct_link(LOG_DEBUG, link,
1540 "MESSAGE=%-*s: enslaving by '%s'",
1542 link->ifname, link->network->bridge->ifname,
1543 NETDEV(link->network->bridge),
1546 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1548 log_struct_link(LOG_WARNING, link,
1549 "MESSAGE=%-*s: could not enslave by '%s': %s",
1551 link->ifname, link->network->bridge->ifname, strerror(-r),
1552 NETDEV(link->network->bridge),
1554 link_enter_failed(link);
1562 if (link->network->tunnel) {
1563 log_struct_link(LOG_DEBUG, link,
1564 "MESSAGE=%-*s: enslaving by '%s'",
1566 link->ifname, link->network->tunnel->ifname,
1567 NETDEV(link->network->tunnel),
1570 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1572 log_struct_link(LOG_WARNING, link,
1573 "MESSAGE=%-*s: could not enslave by '%s': %s",
1575 link->ifname, link->network->tunnel->ifname, strerror(-r),
1576 NETDEV(link->network->tunnel),
1578 link_enter_failed(link);
1586 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1587 log_struct_link(LOG_DEBUG, link,
1588 "MESSAGE=%-*s: enslaving by '%s'",
1590 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1592 r = netdev_enslave(vlan, link, &enslave_handler);
1594 log_struct_link(LOG_WARNING, link,
1595 "MESSAGE=%-*s: could not enslave by '%s': %s",
1597 link->ifname, vlan->ifname, strerror(-r),
1598 NETDEV(vlan), NULL);
1599 link_enter_failed(link);
1607 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1608 log_struct_link(LOG_DEBUG, link,
1609 "MESSAGE=%-*s: enslaving by '%s'",
1611 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1613 r = netdev_enslave(macvlan, link, &enslave_handler);
1615 log_struct_link(LOG_WARNING, link,
1616 "MESSAGE=%-*s: could not enslave by '%s': %s",
1618 link->ifname, macvlan->ifname, strerror(-r),
1619 NETDEV(macvlan), NULL);
1620 link_enter_failed(link);
1631 static int link_configure(Link *link) {
1635 assert(link->state == LINK_STATE_INITIALIZING);
1637 if (link->network->ipv4ll) {
1640 r = sd_ipv4ll_new(&link->ipv4ll);
1644 if (link->udev_device) {
1645 r = net_get_unique_predictable_data(link->udev_device, seed);
1647 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1653 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1657 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1661 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1665 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1670 if (link->network->dhcp) {
1671 r = sd_dhcp_client_new(&link->dhcp_client);
1675 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1679 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1683 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1687 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1691 if (link->network->dhcp_mtu) {
1692 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1698 if (link->network->dhcp_server) {
1701 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1705 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1709 LIST_FOREACH(addresses, address,
1710 link->network->static_addresses) {
1711 struct in_addr pool_start;
1713 if (address->family != AF_INET)
1716 /* currently this is picked essentially at random */
1717 r = sd_dhcp_server_set_address(link->dhcp_server,
1718 &address->in_addr.in);
1722 /* offer 32 addresses starting from the address following the server address */
1723 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
1724 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
1733 r = sd_dhcp_server_set_router(link->dhcp_server,
1734 &main_address->in_addr.in);
1738 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
1739 main_address->prefixlen);
1745 if (link_has_carrier(link->flags, link->operstate)) {
1746 r = link_acquire_conf(link);
1751 return link_enter_enslave(link);
1754 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1755 Link *link = userdata;
1760 assert(link->ifname);
1761 assert(link->manager);
1763 if (link->state != LINK_STATE_INITIALIZING)
1766 log_debug_link(link, "link state is up-to-date");
1768 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1770 link_enter_unmanaged(link);
1775 r = network_apply(link->manager, network, link);
1779 r = link_configure(link);
1786 int link_initialized(Link *link, struct udev_device *device) {
1787 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1791 assert(link->manager);
1792 assert(link->manager->rtnl);
1795 if (link->state != LINK_STATE_INITIALIZING)
1798 log_debug_link(link, "udev initialized link");
1800 link->udev_device = udev_device_ref(device);
1802 /* udev has initialized the link, but we don't know if we have yet processed
1803 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1804 we know that the pending NEWLINKs have already been processed and that we
1807 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1811 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1818 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1819 Manager *m = userdata;
1822 _cleanup_address_free_ Address *address = NULL;
1824 char buf[INET6_ADDRSTRLEN];
1825 bool address_dropped = false;
1832 r = sd_rtnl_message_get_type(message, &type);
1834 log_warning("rtnl: could not get message type");
1838 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1839 if (r < 0 || ifindex <= 0) {
1840 log_warning("rtnl: received address message without valid ifindex, ignoring");
1843 r = link_get(m, ifindex, &link);
1844 if (r < 0 || !link) {
1845 log_warning("rtnl: received address for a nonexistent link, ignoring");
1850 r = address_new_dynamic(&address);
1854 r = sd_rtnl_message_addr_get_family(message, &address->family);
1855 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1856 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
1860 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1862 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
1866 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1868 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
1872 switch (address->family) {
1874 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1876 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1883 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1885 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1892 assert_not_reached("invalid address family");
1895 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
1896 log_warning_link(link, "could not print address");
1900 LIST_FOREACH(addresses, ad, link->addresses) {
1901 if (address_equal(ad, address)) {
1902 LIST_REMOVE(addresses, link->addresses, ad);
1906 address_dropped = true;
1914 if (!address_dropped)
1915 log_debug_link(link, "added address: %s/%u", buf,
1916 address->prefixlen);
1918 LIST_PREPEND(addresses, link->addresses, address);
1925 if (address_dropped) {
1926 log_debug_link(link, "removed address: %s/%u", buf,
1927 address->prefixlen);
1934 assert_not_reached("Received invalid RTNL message type");
1940 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1941 Link *link = userdata;
1948 for (; m; m = sd_rtnl_message_next(m)) {
1949 r = sd_rtnl_message_get_errno(m);
1951 log_debug_link(link, "getting address failed: %s", strerror(-r));
1955 r = link_rtnl_process_address(rtnl, m, link->manager);
1957 log_warning_link(link, "could not process address: %s", strerror(-r));
1963 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1965 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1966 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1967 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1975 r = link_new(m, message, ret);
1981 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
1983 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
1987 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
1991 if (detect_container(NULL) <= 0) {
1992 /* not in a container, udev will be around */
1993 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1994 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1996 log_warning_link(link, "could not find udev device");
2000 if (udev_device_get_is_initialized(device) <= 0) {
2002 log_debug_link(link, "udev initializing link...");
2006 r = link_initialized(link, device);
2010 r = link_initialized_and_synced(m->rtnl, NULL, link);
2018 int link_update(Link *link, sd_rtnl_message *m) {
2019 struct ether_addr mac;
2024 assert(link->ifname);
2027 if (link->state == LINK_STATE_LINGER) {
2029 log_info_link(link, "link readded");
2030 link->state = LINK_STATE_ENSLAVING;
2033 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2034 if (r >= 0 && !streq(ifname, link->ifname)) {
2035 log_info_link(link, "renamed to %s", ifname);
2038 link->ifname = strdup(ifname);
2043 if (!link->original_mtu) {
2044 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2046 log_debug_link(link, "saved original MTU: %"
2047 PRIu16, link->original_mtu);
2050 /* The kernel may broadcast NEWLINK messages without the MAC address
2051 set, simply ignore them. */
2052 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2054 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2056 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2058 log_debug_link(link, "MAC address: "
2059 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2060 mac.ether_addr_octet[0],
2061 mac.ether_addr_octet[1],
2062 mac.ether_addr_octet[2],
2063 mac.ether_addr_octet[3],
2064 mac.ether_addr_octet[4],
2065 mac.ether_addr_octet[5]);
2068 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2070 log_warning_link(link, "Could not update MAC "
2071 "address in IPv4LL client: %s",
2077 if (link->dhcp_client) {
2078 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2080 log_warning_link(link, "Could not update MAC "
2081 "address in DHCP client: %s",
2089 return link_update_flags(link, m);
2092 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2101 fprintf(f, "%s=", key);
2103 LIST_FOREACH(addresses, ad, address) {
2104 char buf[INET6_ADDRSTRLEN];
2106 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2107 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2113 static void link_update_operstate(Link *link) {
2117 if (link->kernel_operstate == IF_OPER_DORMANT)
2118 link->operstate = LINK_OPERSTATE_DORMANT;
2119 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2121 uint8_t scope = RT_SCOPE_NOWHERE;
2123 /* if we have carrier, check what addresses we have */
2124 LIST_FOREACH(addresses, address, link->addresses) {
2125 if (address->scope < scope)
2126 scope = address->scope;
2129 if (scope < RT_SCOPE_SITE)
2130 /* universally accessible addresses found */
2131 link->operstate = LINK_OPERSTATE_ROUTABLE;
2132 else if (scope < RT_SCOPE_HOST)
2133 /* only link or site local addresses found */
2134 link->operstate = LINK_OPERSTATE_DEGRADED;
2136 /* no useful addresses found */
2137 link->operstate = LINK_OPERSTATE_CARRIER;
2139 link->operstate = LINK_OPERSTATE_UNKNOWN;
2142 int link_save(Link *link) {
2143 _cleanup_free_ char *temp_path = NULL;
2144 _cleanup_fclose_ FILE *f = NULL;
2145 const char *admin_state, *oper_state;
2149 assert(link->state_file);
2150 assert(link->lease_file);
2151 assert(link->manager);
2153 link_update_operstate(link);
2155 r = manager_save(link->manager);
2159 if (link->state == LINK_STATE_LINGER) {
2160 unlink(link->state_file);
2164 admin_state = link_state_to_string(link->state);
2165 assert(admin_state);
2167 oper_state = link_operstate_to_string(link->operstate);
2170 r = fopen_temporary(link->state_file, &f, &temp_path);
2174 fchmod(fileno(f), 0644);
2177 "# This is private data. Do not parse.\n"
2181 admin_state, oper_state, link->flags);
2183 if (link->network) {
2184 serialize_addresses(f, "DNS", link->network->dns);
2185 serialize_addresses(f, "NTP", link->network->ntp);
2188 if (link->dhcp_lease) {
2189 assert(link->network);
2191 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2198 "DHCP_USE_NTP=%s\n",
2200 yes_no(link->network->dhcp_dns),
2201 yes_no(link->network->dhcp_ntp));
2203 unlink(link->lease_file);
2207 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2209 unlink(link->state_file);
2215 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2220 static const char* const link_state_table[_LINK_STATE_MAX] = {
2221 [LINK_STATE_INITIALIZING] = "initializing",
2222 [LINK_STATE_ENSLAVING] = "configuring",
2223 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2224 [LINK_STATE_SETTING_ROUTES] = "configuring",
2225 [LINK_STATE_CONFIGURED] = "configured",
2226 [LINK_STATE_UNMANAGED] = "unmanaged",
2227 [LINK_STATE_FAILED] = "failed",
2228 [LINK_STATE_LINGER] = "linger",
2231 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2233 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2234 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2235 [LINK_OPERSTATE_DORMANT] = "dormant",
2236 [LINK_OPERSTATE_CARRIER] = "carrier",
2237 [LINK_OPERSTATE_DEGRADED] = "degraded",
2238 [LINK_OPERSTATE_ROUTABLE] = "routable",
2241 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);