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 Address* link_find_dhcp_server_address(Link *link) {
258 assert(link->network);
260 /* The the first statically configured address if there is any */
261 LIST_FOREACH(addresses, address, link->network->static_addresses) {
263 if (address->family != AF_INET)
266 if (in_addr_null(address->family, &address->in_addr))
272 /* If that didn't work, find a suitable address we got from the pool */
273 LIST_FOREACH(addresses, address, link->pool_addresses) {
274 if (address->family != AF_INET)
283 static int link_enter_configured(Link *link) {
287 assert(link->network);
288 assert(link->state == LINK_STATE_SETTING_ROUTES);
290 if (link->network->dhcp_server) {
291 struct in_addr pool_start;
294 address = link_find_dhcp_server_address(link);
296 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
297 link_enter_failed(link);
301 log_debug_link(link, "offering DHCPv4 leases");
303 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in);
307 /* offer 32 addresses starting from the address following the server address */
308 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
309 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
315 r = sd_dhcp_server_set_router(link->dhcp_server,
316 &main_address->in_addr.in);
320 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
321 main_address->prefixlen);
326 r = sd_dhcp_server_start(link->dhcp_server);
328 log_warning_link(link, "could not start DHCPv4 server "
329 "instance: %s", strerror(-r));
331 link_enter_failed(link);
337 log_info_link(link, "link configured");
339 link->state = LINK_STATE_CONFIGURED;
346 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
347 Link *link = userdata;
350 assert(link->route_messages > 0);
351 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
352 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
355 link->route_messages --;
357 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
362 r = sd_rtnl_message_get_errno(m);
363 if (r < 0 && r != -EEXIST)
364 log_struct_link(LOG_WARNING, link,
365 "MESSAGE=%-*s: could not set route: %s",
367 link->ifname, strerror(-r),
371 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
373 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
374 log_debug_link(link, "routes set");
375 link_enter_configured(link);
383 static int link_enter_set_routes(Link *link) {
388 assert(link->network);
389 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
391 link->state = LINK_STATE_SETTING_ROUTES;
393 if (!link->network->static_routes && !link->dhcp_lease &&
394 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
395 return link_enter_configured(link);
397 log_debug_link(link, "setting routes");
399 LIST_FOREACH(routes, rt, link->network->static_routes) {
400 r = route_configure(rt, link, &route_handler);
402 log_warning_link(link,
403 "could not set routes: %s", strerror(-r));
404 link_enter_failed(link);
409 link->route_messages ++;
412 if (link->ipv4ll && !link->dhcp_lease) {
413 _cleanup_route_free_ Route *route = NULL;
416 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
417 if (r < 0 && r != -ENOENT) {
418 log_warning_link(link, "IPV4LL error: no address: %s",
424 r = route_new_dynamic(&route);
426 log_error_link(link, "Could not allocate route: %s",
431 route->family = AF_INET;
432 route->scope = RT_SCOPE_LINK;
435 r = route_configure(route, link, &route_handler);
437 log_warning_link(link,
438 "could not set routes: %s", strerror(-r));
439 link_enter_failed(link);
444 link->route_messages ++;
448 if (link->dhcp_lease) {
449 _cleanup_route_free_ Route *route = NULL;
450 _cleanup_route_free_ Route *route_gw = NULL;
451 struct in_addr gateway;
453 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
454 if (r < 0 && r != -ENOENT) {
455 log_warning_link(link, "DHCP error: %s", strerror(-r));
460 r = route_new_dynamic(&route);
462 log_error_link(link, "Could not allocate route: %s",
467 r = route_new_dynamic(&route_gw);
469 log_error_link(link, "Could not allocate route: %s",
474 /* The dhcp netmask may mask out the gateway. Add an explicit
475 * route for the gw host so that we can route no matter the
476 * netmask or existing kernel route tables. */
477 route_gw->family = AF_INET;
478 route_gw->dst_addr.in = gateway;
479 route_gw->dst_prefixlen = 32;
480 route_gw->scope = RT_SCOPE_LINK;
482 r = route_configure(route_gw, link, &route_handler);
484 log_warning_link(link,
485 "could not set host route: %s", strerror(-r));
490 link->route_messages ++;
492 route->family = AF_INET;
493 route->in_addr.in = gateway;
495 r = route_configure(route, link, &route_handler);
497 log_warning_link(link,
498 "could not set routes: %s", strerror(-r));
499 link_enter_failed(link);
504 link->route_messages ++;
508 if (link->route_messages == 0) {
509 link_enter_configured(link);
515 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
516 Link *link = userdata;
521 assert(link->ifname);
523 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
528 r = sd_rtnl_message_get_errno(m);
529 if (r < 0 && r != -ESRCH)
530 log_struct_link(LOG_WARNING, link,
531 "MESSAGE=%-*s: could not drop route: %s",
533 link->ifname, strerror(-r),
542 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
543 Link *link = userdata;
548 assert(link->ifname);
549 assert(link->addr_messages > 0);
550 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
551 LINK_STATE_FAILED, LINK_STATE_LINGER));
553 link->addr_messages --;
555 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
560 r = sd_rtnl_message_get_errno(m);
561 if (r < 0 && r != -EEXIST)
562 log_struct_link(LOG_WARNING, link,
563 "MESSAGE=%-*s: could not set address: %s",
565 link->ifname, strerror(-r),
569 if (link->addr_messages == 0) {
570 log_debug_link(link, "addresses set");
571 link_enter_set_routes(link);
579 static int link_enter_set_addresses(Link *link) {
584 assert(link->network);
585 assert(link->state != _LINK_STATE_INVALID);
587 link->state = LINK_STATE_SETTING_ADDRESSES;
589 if (!link->network->static_addresses && !link->dhcp_lease &&
590 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
591 return link_enter_set_routes(link);
593 log_debug_link(link, "setting addresses");
595 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
596 r = address_configure(ad, link, &address_handler);
598 log_warning_link(link,
599 "could not set addresses: %s", strerror(-r));
600 link_enter_failed(link);
605 link->addr_messages ++;
608 if (link->ipv4ll && !link->dhcp_lease) {
609 _cleanup_address_free_ Address *ll_addr = NULL;
612 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
613 if (r < 0 && r != -ENOENT) {
614 log_warning_link(link, "IPV4LL error: no address: %s",
620 r = address_new_dynamic(&ll_addr);
622 log_error_link(link, "Could not allocate address: %s", strerror(-r));
626 ll_addr->family = AF_INET;
627 ll_addr->in_addr.in = addr;
628 ll_addr->prefixlen = 16;
629 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
630 ll_addr->scope = RT_SCOPE_LINK;
632 r = address_configure(ll_addr, link, &address_handler);
634 log_warning_link(link,
635 "could not set addresses: %s", strerror(-r));
636 link_enter_failed(link);
641 link->addr_messages ++;
645 if (link->dhcp_lease) {
646 _cleanup_address_free_ Address *address = NULL;
648 struct in_addr netmask;
651 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
653 log_warning_link(link, "DHCP error: no address: %s",
658 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
660 log_warning_link(link, "DHCP error: no netmask: %s",
665 prefixlen = net_netmask_to_prefixlen(&netmask);
667 r = address_new_dynamic(&address);
669 log_error_link(link, "Could not allocate address: %s",
674 address->family = AF_INET;
675 address->in_addr.in = addr;
676 address->prefixlen = prefixlen;
677 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
679 r = address_configure(address, link, &address_handler);
681 log_warning_link(link,
682 "could not set addresses: %s", strerror(-r));
683 link_enter_failed(link);
688 link->addr_messages ++;
694 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
695 Link *link = userdata;
700 assert(link->ifname);
702 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
707 r = sd_rtnl_message_get_errno(m);
708 if (r < 0 && r != -ENOENT)
709 log_struct_link(LOG_WARNING, link,
710 "MESSAGE=%-*s: could not update address: %s",
712 link->ifname, strerror(-r),
721 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
722 Link *link = userdata;
727 assert(link->ifname);
729 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
734 r = sd_rtnl_message_get_errno(m);
735 if (r < 0 && r != -EADDRNOTAVAIL)
736 log_struct_link(LOG_WARNING, link,
737 "MESSAGE=%-*s: could not drop address: %s",
739 link->ifname, strerror(-r),
748 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
749 Link *link = userdata;
754 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
759 r = sd_bus_message_get_errno(m);
761 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
768 static int link_set_hostname(Link *link, const char *hostname) {
769 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
773 assert(link->manager);
776 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
778 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
779 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
783 r = sd_bus_message_new_method_call(
786 "org.freedesktop.hostname1",
787 "/org/freedesktop/hostname1",
788 "org.freedesktop.hostname1",
793 r = sd_bus_message_append(m, "sb", hostname, false);
797 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
799 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
806 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
807 Link *link = userdata;
812 assert(link->ifname);
814 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
819 r = sd_rtnl_message_get_errno(m);
821 log_struct_link(LOG_WARNING, link,
822 "MESSAGE=%-*s: could not set MTU: %s",
823 IFNAMSIZ, link->ifname, strerror(-r),
832 static int link_set_mtu(Link *link, uint32_t mtu) {
833 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
837 assert(link->manager);
838 assert(link->manager->rtnl);
840 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
842 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
843 RTM_SETLINK, link->ifindex);
845 log_error_link(link, "Could not allocate RTM_SETLINK message");
849 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
851 log_error_link(link, "Could not append MTU: %s", strerror(-r));
855 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
858 "Could not send rtnetlink message: %s", strerror(-r));
867 static int dhcp_lease_lost(Link *link) {
868 _cleanup_address_free_ Address *address = NULL;
869 _cleanup_route_free_ Route *route_gw = NULL;
870 _cleanup_route_free_ Route *route = NULL;
872 struct in_addr netmask;
873 struct in_addr gateway;
878 assert(link->dhcp_lease);
880 log_warning_link(link, "DHCP lease lost");
882 r = address_new_dynamic(&address);
884 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
886 r = route_new_dynamic(&route_gw);
888 route_gw->family = AF_INET;
889 route_gw->dst_addr.in = gateway;
890 route_gw->dst_prefixlen = 32;
891 route_gw->scope = RT_SCOPE_LINK;
893 route_drop(route_gw, link, &route_drop_handler);
897 r = route_new_dynamic(&route);
899 route->family = AF_INET;
900 route->in_addr.in = gateway;
902 route_drop(route, link, &route_drop_handler);
907 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
908 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
909 prefixlen = net_netmask_to_prefixlen(&netmask);
911 address->family = AF_INET;
912 address->in_addr.in = addr;
913 address->prefixlen = prefixlen;
915 address_drop(address, link, &address_drop_handler);
919 if (link->network->dhcp_mtu) {
922 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
923 if (r >= 0 && link->original_mtu != mtu) {
924 r = link_set_mtu(link, link->original_mtu);
926 log_warning_link(link, "DHCP error: could not reset MTU");
927 link_enter_failed(link);
933 if (link->network->dhcp_hostname) {
934 const char *hostname = NULL;
936 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
937 if (r >= 0 && hostname) {
938 r = link_set_hostname(link, "");
940 log_error_link(link, "Failed to reset transient hostname");
944 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
949 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
950 sd_dhcp_lease *lease;
951 struct in_addr address;
952 struct in_addr netmask;
953 struct in_addr gateway;
960 r = sd_dhcp_client_get_lease(client, &lease);
962 log_warning_link(link, "DHCP error: no lease: %s",
967 r = sd_dhcp_lease_get_address(lease, &address);
969 log_warning_link(link, "DHCP error: no address: %s",
974 r = sd_dhcp_lease_get_netmask(lease, &netmask);
976 log_warning_link(link, "DHCP error: no netmask: %s",
981 prefixlen = net_netmask_to_prefixlen(&netmask);
983 r = sd_dhcp_lease_get_router(lease, &gateway);
984 if (r < 0 && r != -ENOENT) {
985 log_warning_link(link, "DHCP error: %s", strerror(-r));
990 log_struct_link(LOG_INFO, link,
991 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
994 ADDRESS_FMT_VAL(address),
996 ADDRESS_FMT_VAL(gateway),
997 "ADDRESS=%u.%u.%u.%u",
998 ADDRESS_FMT_VAL(address),
1001 "GATEWAY=%u.%u.%u.%u",
1002 ADDRESS_FMT_VAL(gateway),
1005 log_struct_link(LOG_INFO, link,
1006 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1009 ADDRESS_FMT_VAL(address),
1011 "ADDRESS=%u.%u.%u.%u",
1012 ADDRESS_FMT_VAL(address),
1017 link->dhcp_lease = lease;
1019 if (link->network->dhcp_mtu) {
1022 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1024 r = link_set_mtu(link, mtu);
1026 log_error_link(link, "Failed to set MTU "
1027 "to %" PRIu16, mtu);
1031 if (link->network->dhcp_hostname) {
1032 const char *hostname;
1034 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1036 r = link_set_hostname(link, hostname);
1038 log_error_link(link, "Failed to set transient hostname "
1039 "to '%s'", hostname);
1043 link_enter_set_addresses(link);
1048 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1049 Link *link = userdata;
1053 assert(link->network);
1054 assert(link->manager);
1056 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1060 case DHCP_EVENT_NO_LEASE:
1061 log_debug_link(link, "IP address in use.");
1063 case DHCP_EVENT_EXPIRED:
1064 case DHCP_EVENT_STOP:
1065 case DHCP_EVENT_IP_CHANGE:
1066 if (link->network->dhcp_critical) {
1067 log_error_link(link, "DHCPv4 connection considered system critical, "
1068 "ignoring request to reconfigure it.");
1072 if (link->dhcp_lease) {
1073 r = dhcp_lease_lost(link);
1075 link_enter_failed(link);
1080 if (event == DHCP_EVENT_IP_CHANGE) {
1081 r = dhcp_lease_acquired(client, link);
1083 link_enter_failed(link);
1088 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1089 if (!sd_ipv4ll_is_running(link->ipv4ll))
1090 r = sd_ipv4ll_start(link->ipv4ll);
1091 else if (ipv4ll_is_bound(link->ipv4ll))
1092 r = ipv4ll_address_update(link, false);
1094 link_enter_failed(link);
1100 case DHCP_EVENT_IP_ACQUIRE:
1101 r = dhcp_lease_acquired(client, link);
1103 link_enter_failed(link);
1107 if (ipv4ll_is_bound(link->ipv4ll))
1108 r = ipv4ll_address_update(link, true);
1110 r = sd_ipv4ll_stop(link->ipv4ll);
1112 link_enter_failed(link);
1119 log_warning_link(link, "DHCP error: %s", strerror(-event));
1121 log_warning_link(link, "DHCP unknown event: %d", event);
1128 static int ipv4ll_address_update(Link *link, bool deprecate) {
1130 struct in_addr addr;
1134 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1136 _cleanup_address_free_ Address *address = NULL;
1138 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1139 deprecate ? "deprecate" : "approve",
1140 ADDRESS_FMT_VAL(addr));
1142 r = address_new_dynamic(&address);
1144 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1148 address->family = AF_INET;
1149 address->in_addr.in = addr;
1150 address->prefixlen = 16;
1151 address->scope = RT_SCOPE_LINK;
1152 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1153 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1155 address_update(address, link, &address_update_handler);
1163 static int ipv4ll_address_lost(Link *link) {
1165 struct in_addr addr;
1169 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1171 _cleanup_address_free_ Address *address = NULL;
1172 _cleanup_route_free_ Route *route = NULL;
1174 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1175 ADDRESS_FMT_VAL(addr));
1177 r = address_new_dynamic(&address);
1179 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1183 address->family = AF_INET;
1184 address->in_addr.in = addr;
1185 address->prefixlen = 16;
1186 address->scope = RT_SCOPE_LINK;
1188 address_drop(address, link, &address_drop_handler);
1191 r = route_new_dynamic(&route);
1193 log_error_link(link, "Could not allocate route: %s",
1198 route->family = AF_INET;
1199 route->scope = RT_SCOPE_LINK;
1200 route->metrics = 99;
1202 route_drop(route, link, &route_drop_handler);
1209 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1211 struct in_addr addr;
1215 r = sd_ipv4ll_get_address(ll, &addr);
1221 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1222 struct in_addr address;
1228 r = sd_ipv4ll_get_address(ll, &address);
1232 log_struct_link(LOG_INFO, link,
1233 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1236 ADDRESS_FMT_VAL(address),
1239 link_enter_set_addresses(link);
1244 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1245 Link *link = userdata;
1249 assert(link->network);
1250 assert(link->manager);
1252 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1256 case IPV4LL_EVENT_STOP:
1257 case IPV4LL_EVENT_CONFLICT:
1258 r = ipv4ll_address_lost(link);
1260 link_enter_failed(link);
1264 case IPV4LL_EVENT_BIND:
1265 r = ipv4ll_address_claimed(ll, link);
1267 link_enter_failed(link);
1273 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1275 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1280 static int link_acquire_conf(Link *link) {
1284 assert(link->network);
1285 assert(link->manager);
1286 assert(link->manager->event);
1288 if (link->network->ipv4ll) {
1289 assert(link->ipv4ll);
1291 log_debug_link(link, "acquiring IPv4 link-local address");
1293 r = sd_ipv4ll_start(link->ipv4ll);
1295 log_warning_link(link, "could not acquire IPv4 "
1296 "link-local address");
1301 if (link->network->dhcp) {
1302 assert(link->dhcp_client);
1304 log_debug_link(link, "acquiring DHCPv4 lease");
1306 r = sd_dhcp_client_start(link->dhcp_client);
1308 log_warning_link(link, "could not acquire DHCPv4 "
1317 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1318 /* see Documentation/networking/operstates.txt in the kernel sources */
1320 if (operstate == IF_OPER_UP)
1323 if (operstate == IF_OPER_UNKNOWN)
1324 /* operstate may not be implemented, so fall back to flags */
1325 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1331 #define FLAG_STRING(string, flag, old, new) \
1332 (((old ^ new) & flag) \
1333 ? ((old & flag) ? (" -" string) : (" +" string)) \
1336 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1337 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1339 bool carrier_gained = false, carrier_lost = false;
1344 r = sd_rtnl_message_link_get_flags(m, &flags);
1346 log_warning_link(link, "Could not get link flags");
1350 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1352 /* if we got a message without operstate, take it to mean
1353 the state was unchanged */
1354 operstate = link->kernel_operstate;
1356 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1359 if (link->flags != flags) {
1360 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",
1361 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1362 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1363 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1364 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1365 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1366 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1367 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1368 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1369 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1370 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1371 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1372 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1373 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1374 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1375 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1376 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1377 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1378 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1379 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1381 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1382 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1383 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1384 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1385 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1386 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1387 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1388 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1390 /* link flags are currently at most 18 bits, let's align to printing 20 */
1391 if (unknown_flags_added)
1392 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1393 unknown_flags_added);
1395 if (unknown_flags_removed)
1396 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1397 unknown_flags_removed);
1400 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1401 link_has_carrier(flags, operstate);
1402 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1403 !link_has_carrier(flags, operstate);
1405 link->flags = flags;
1406 link->kernel_operstate = operstate;
1410 if (link->state == LINK_STATE_FAILED ||
1411 link->state == LINK_STATE_UNMANAGED)
1414 if (carrier_gained) {
1415 log_info_link(link, "gained carrier");
1417 if (link->network) {
1418 r = link_acquire_conf(link);
1420 link_enter_failed(link);
1424 } else if (carrier_lost) {
1425 log_info_link(link, "lost carrier");
1427 r = link_stop_clients(link);
1429 link_enter_failed(link);
1437 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1438 Link *link = userdata;
1443 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1448 r = sd_rtnl_message_get_errno(m);
1450 /* we warn but don't fail the link, as it may
1451 be brought up later */
1452 log_struct_link(LOG_WARNING, link,
1453 "MESSAGE=%-*s: could not bring up interface: %s",
1455 link->ifname, strerror(-r),
1465 static int link_up(Link *link) {
1466 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1470 assert(link->manager);
1471 assert(link->manager->rtnl);
1473 log_debug_link(link, "bringing link up");
1475 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1476 RTM_SETLINK, link->ifindex);
1478 log_error_link(link, "Could not allocate RTM_SETLINK message");
1482 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1484 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1488 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1490 log_error_link(link,
1491 "Could not send rtnetlink message: %s", strerror(-r));
1500 static int link_enslaved(Link *link) {
1504 assert(link->state == LINK_STATE_ENSLAVING);
1505 assert(link->network);
1507 if (!(link->flags & IFF_UP)) {
1510 link_enter_failed(link);
1515 if (!link->network->dhcp && !link->network->ipv4ll)
1516 return link_enter_set_addresses(link);
1521 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1522 Link *link = userdata;
1526 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1527 LINK_STATE_LINGER));
1528 assert(link->network);
1532 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1537 r = sd_rtnl_message_get_errno(m);
1539 log_struct_link(LOG_ERR, link,
1540 "MESSAGE=%-*s: could not enslave: %s",
1542 link->ifname, strerror(-r),
1545 link_enter_failed(link);
1550 log_debug_link(link, "enslaved");
1552 if (link->enslaving == 0)
1553 link_enslaved(link);
1560 static int link_enter_enslave(Link *link) {
1561 NetDev *vlan, *macvlan, *vxlan;
1566 assert(link->network);
1567 assert(link->state == LINK_STATE_INITIALIZING);
1569 link->state = LINK_STATE_ENSLAVING;
1573 if (!link->network->bridge &&
1574 !link->network->bond &&
1575 !link->network->tunnel &&
1576 hashmap_isempty(link->network->vlans) &&
1577 hashmap_isempty(link->network->macvlans) &&
1578 hashmap_isempty(link->network->vxlans))
1579 return link_enslaved(link);
1581 if (link->network->bond) {
1582 log_struct_link(LOG_DEBUG, link,
1583 "MESSAGE=%-*s: enslaving by '%s'",
1585 link->ifname, link->network->bond->ifname,
1586 NETDEV(link->network->bond),
1589 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1591 log_struct_link(LOG_WARNING, link,
1592 "MESSAGE=%-*s: could not enslave by '%s': %s",
1594 link->ifname, link->network->bond->ifname, strerror(-r),
1595 NETDEV(link->network->bond),
1597 link_enter_failed(link);
1605 if (link->network->bridge) {
1606 log_struct_link(LOG_DEBUG, link,
1607 "MESSAGE=%-*s: enslaving by '%s'",
1609 link->ifname, link->network->bridge->ifname,
1610 NETDEV(link->network->bridge),
1613 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1615 log_struct_link(LOG_WARNING, link,
1616 "MESSAGE=%-*s: could not enslave by '%s': %s",
1618 link->ifname, link->network->bridge->ifname, strerror(-r),
1619 NETDEV(link->network->bridge),
1621 link_enter_failed(link);
1629 if (link->network->tunnel) {
1630 log_struct_link(LOG_DEBUG, link,
1631 "MESSAGE=%-*s: enslaving by '%s'",
1633 link->ifname, link->network->tunnel->ifname,
1634 NETDEV(link->network->tunnel),
1637 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1639 log_struct_link(LOG_WARNING, link,
1640 "MESSAGE=%-*s: could not enslave by '%s': %s",
1642 link->ifname, link->network->tunnel->ifname, strerror(-r),
1643 NETDEV(link->network->tunnel),
1645 link_enter_failed(link);
1653 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1654 log_struct_link(LOG_DEBUG, link,
1655 "MESSAGE=%-*s: enslaving by '%s'",
1657 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1659 r = netdev_enslave(vlan, link, &enslave_handler);
1661 log_struct_link(LOG_WARNING, link,
1662 "MESSAGE=%-*s: could not enslave by '%s': %s",
1664 link->ifname, vlan->ifname, strerror(-r),
1665 NETDEV(vlan), NULL);
1666 link_enter_failed(link);
1674 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1675 log_struct_link(LOG_DEBUG, link,
1676 "MESSAGE=%-*s: enslaving by '%s'",
1678 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1680 r = netdev_enslave(macvlan, link, &enslave_handler);
1682 log_struct_link(LOG_WARNING, link,
1683 "MESSAGE=%-*s: could not enslave by '%s': %s",
1685 link->ifname, macvlan->ifname, strerror(-r),
1686 NETDEV(macvlan), NULL);
1687 link_enter_failed(link);
1695 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1696 log_struct_link(LOG_DEBUG, link,
1697 "MESSAGE=%*s: enslaving by '%s'",
1699 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1701 r = netdev_enslave(vxlan, link, &enslave_handler);
1703 log_struct_link(LOG_WARNING, link,
1704 "MESSAGE=%*s: could not enslave by '%s': %s",
1706 link->ifname, vxlan->ifname, strerror(-r),
1707 NETDEV(vxlan), NULL);
1708 link_enter_failed(link);
1719 static int link_configure(Link *link) {
1723 assert(link->state == LINK_STATE_INITIALIZING);
1725 if (link->network->ipv4ll) {
1728 r = sd_ipv4ll_new(&link->ipv4ll);
1732 if (link->udev_device) {
1733 r = net_get_unique_predictable_data(link->udev_device, seed);
1735 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1741 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1745 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1749 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1753 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1758 if (link->network->dhcp) {
1759 r = sd_dhcp_client_new(&link->dhcp_client);
1763 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1767 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1771 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1775 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1779 if (link->network->dhcp_mtu) {
1780 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1786 if (link->network->dhcp_server) {
1787 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1791 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1796 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1797 r = link_acquire_conf(link);
1802 return link_enter_enslave(link);
1805 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1806 Link *link = userdata;
1811 assert(link->ifname);
1812 assert(link->manager);
1814 if (link->state != LINK_STATE_INITIALIZING)
1817 log_debug_link(link, "link state is up-to-date");
1819 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1821 link_enter_unmanaged(link);
1826 r = network_apply(link->manager, network, link);
1830 r = link_configure(link);
1837 int link_initialized(Link *link, struct udev_device *device) {
1838 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1842 assert(link->manager);
1843 assert(link->manager->rtnl);
1846 if (link->state != LINK_STATE_INITIALIZING)
1849 log_debug_link(link, "udev initialized link");
1851 link->udev_device = udev_device_ref(device);
1853 /* udev has initialized the link, but we don't know if we have yet processed
1854 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1855 we know that the pending NEWLINKs have already been processed and that we
1858 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1862 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1869 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1870 Manager *m = userdata;
1873 _cleanup_address_free_ Address *address = NULL;
1875 char buf[INET6_ADDRSTRLEN];
1876 bool address_dropped = false;
1883 r = sd_rtnl_message_get_type(message, &type);
1885 log_warning("rtnl: could not get message type");
1889 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1890 if (r < 0 || ifindex <= 0) {
1891 log_warning("rtnl: received address message without valid ifindex, ignoring");
1894 r = link_get(m, ifindex, &link);
1895 if (r < 0 || !link) {
1896 log_warning("rtnl: received address for a nonexistent link, ignoring");
1901 r = address_new_dynamic(&address);
1905 r = sd_rtnl_message_addr_get_family(message, &address->family);
1906 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1907 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
1911 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1913 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
1917 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1919 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
1923 switch (address->family) {
1925 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1927 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1934 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1936 log_warning_link(link, "rtnl: received address without valid address, ignoring");
1943 assert_not_reached("invalid address family");
1946 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
1947 log_warning_link(link, "could not print address");
1951 LIST_FOREACH(addresses, ad, link->addresses) {
1952 if (address_equal(ad, address)) {
1953 LIST_REMOVE(addresses, link->addresses, ad);
1957 address_dropped = true;
1965 if (!address_dropped)
1966 log_debug_link(link, "added address: %s/%u", buf,
1967 address->prefixlen);
1969 LIST_PREPEND(addresses, link->addresses, address);
1976 if (address_dropped) {
1977 log_debug_link(link, "removed address: %s/%u", buf,
1978 address->prefixlen);
1985 assert_not_reached("Received invalid RTNL message type");
1991 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1992 Link *link = userdata;
1999 for (; m; m = sd_rtnl_message_next(m)) {
2000 r = sd_rtnl_message_get_errno(m);
2002 log_debug_link(link, "getting address failed: %s", strerror(-r));
2006 r = link_rtnl_process_address(rtnl, m, link->manager);
2008 log_warning_link(link, "could not process address: %s", strerror(-r));
2014 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2016 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2017 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2018 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2026 r = link_new(m, message, ret);
2032 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2034 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2038 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2042 if (detect_container(NULL) <= 0) {
2043 /* not in a container, udev will be around */
2044 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2045 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2047 log_warning_link(link, "could not find udev device");
2051 if (udev_device_get_is_initialized(device) <= 0) {
2053 log_debug_link(link, "udev initializing link...");
2057 r = link_initialized(link, device);
2061 r = link_initialized_and_synced(m->rtnl, NULL, link);
2069 int link_update(Link *link, sd_rtnl_message *m) {
2070 struct ether_addr mac;
2075 assert(link->ifname);
2078 if (link->state == LINK_STATE_LINGER) {
2080 log_info_link(link, "link readded");
2081 link->state = LINK_STATE_ENSLAVING;
2084 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2085 if (r >= 0 && !streq(ifname, link->ifname)) {
2086 log_info_link(link, "renamed to %s", ifname);
2089 link->ifname = strdup(ifname);
2094 if (!link->original_mtu) {
2095 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2097 log_debug_link(link, "saved original MTU: %"
2098 PRIu16, link->original_mtu);
2101 /* The kernel may broadcast NEWLINK messages without the MAC address
2102 set, simply ignore them. */
2103 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2105 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2107 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2109 log_debug_link(link, "MAC address: "
2110 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2111 mac.ether_addr_octet[0],
2112 mac.ether_addr_octet[1],
2113 mac.ether_addr_octet[2],
2114 mac.ether_addr_octet[3],
2115 mac.ether_addr_octet[4],
2116 mac.ether_addr_octet[5]);
2119 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2121 log_warning_link(link, "Could not update MAC "
2122 "address in IPv4LL client: %s",
2128 if (link->dhcp_client) {
2129 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2131 log_warning_link(link, "Could not update MAC "
2132 "address in DHCP client: %s",
2140 return link_update_flags(link, m);
2143 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2152 fprintf(f, "%s=", key);
2154 LIST_FOREACH(addresses, ad, address) {
2155 char buf[INET6_ADDRSTRLEN];
2157 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2158 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2164 static void link_update_operstate(Link *link) {
2168 if (link->kernel_operstate == IF_OPER_DORMANT)
2169 link->operstate = LINK_OPERSTATE_DORMANT;
2170 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2172 uint8_t scope = RT_SCOPE_NOWHERE;
2174 /* if we have carrier, check what addresses we have */
2175 LIST_FOREACH(addresses, address, link->addresses) {
2176 if (address->scope < scope)
2177 scope = address->scope;
2180 if (scope < RT_SCOPE_SITE)
2181 /* universally accessible addresses found */
2182 link->operstate = LINK_OPERSTATE_ROUTABLE;
2183 else if (scope < RT_SCOPE_HOST)
2184 /* only link or site local addresses found */
2185 link->operstate = LINK_OPERSTATE_DEGRADED;
2187 /* no useful addresses found */
2188 link->operstate = LINK_OPERSTATE_CARRIER;
2190 link->operstate = LINK_OPERSTATE_UNKNOWN;
2193 int link_save(Link *link) {
2194 _cleanup_free_ char *temp_path = NULL;
2195 _cleanup_fclose_ FILE *f = NULL;
2196 const char *admin_state, *oper_state;
2200 assert(link->state_file);
2201 assert(link->lease_file);
2202 assert(link->manager);
2204 link_update_operstate(link);
2206 r = manager_save(link->manager);
2210 if (link->state == LINK_STATE_LINGER) {
2211 unlink(link->state_file);
2215 admin_state = link_state_to_string(link->state);
2216 assert(admin_state);
2218 oper_state = link_operstate_to_string(link->operstate);
2221 r = fopen_temporary(link->state_file, &f, &temp_path);
2225 fchmod(fileno(f), 0644);
2228 "# This is private data. Do not parse.\n"
2232 admin_state, oper_state, link->flags);
2234 if (link->network) {
2235 serialize_addresses(f, "DNS", link->network->dns);
2236 serialize_addresses(f, "NTP", link->network->ntp);
2239 if (link->dhcp_lease) {
2240 assert(link->network);
2242 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2249 "DHCP_USE_NTP=%s\n",
2251 yes_no(link->network->dhcp_dns),
2252 yes_no(link->network->dhcp_ntp));
2254 unlink(link->lease_file);
2258 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2260 unlink(link->state_file);
2266 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2271 static const char* const link_state_table[_LINK_STATE_MAX] = {
2272 [LINK_STATE_INITIALIZING] = "initializing",
2273 [LINK_STATE_ENSLAVING] = "configuring",
2274 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2275 [LINK_STATE_SETTING_ROUTES] = "configuring",
2276 [LINK_STATE_CONFIGURED] = "configured",
2277 [LINK_STATE_UNMANAGED] = "unmanaged",
2278 [LINK_STATE_FAILED] = "failed",
2279 [LINK_STATE_LINGER] = "linger",
2282 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2284 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2285 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2286 [LINK_OPERSTATE_DORMANT] = "dormant",
2287 [LINK_OPERSTATE_CARRIER] = "carrier",
2288 [LINK_OPERSTATE_DEGRADED] = "degraded",
2289 [LINK_OPERSTATE_ROUTABLE] = "routable",
2292 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);