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);
127 sd_dhcp6_client_unref(link->dhcp6_client);
128 sd_icmp6_nd_unref(link->icmp6_router_discovery);
130 hashmap_remove(link->manager->links, &link->ifindex);
134 unlink(link->state_file);
135 free(link->state_file);
137 udev_device_unref(link->udev_device);
142 Link *link_unref(Link *link) {
143 if (link && (-- link->n_ref <= 0))
149 Link *link_ref(Link *link) {
151 assert_se(++ link->n_ref >= 2);
156 int link_get(Manager *m, int ifindex, Link **ret) {
165 ifindex_64 = ifindex;
166 link = hashmap_get(m->links, &ifindex_64);
175 void link_drop(Link *link) {
176 if (!link || link->state == LINK_STATE_LINGER)
179 link->state = LINK_STATE_LINGER;
181 log_debug_link(link, "link removed");
188 static void link_enter_unmanaged(Link *link) {
191 log_debug_link(link, "unmanaged");
193 link->state = LINK_STATE_UNMANAGED;
198 static int link_stop_clients(Link *link) {
202 assert(link->manager);
203 assert(link->manager->event);
208 if (link->network->dhcp) {
209 assert(link->dhcp_client);
211 k = sd_dhcp_client_stop(link->dhcp_client);
213 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
218 if (link->network->ipv4ll) {
219 assert(link->ipv4ll);
221 k = sd_ipv4ll_stop(link->ipv4ll);
223 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
228 if (link->network->dhcp_server) {
229 assert(link->dhcp_server);
231 k = sd_dhcp_server_stop(link->dhcp_server);
233 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
238 if (link->network->dhcp6) {
239 assert(link->icmp6_router_discovery);
241 if (link->dhcp6_client) {
242 k = sd_dhcp6_client_stop(link->dhcp6_client);
244 log_warning_link(link, "Could not stop DHCPv6 client: %s", strerror(-r));
249 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
251 log_warning_link(link, "Could not stop ICMPv6 router discovery: %s", strerror(-r));
259 static void link_enter_failed(Link *link) {
262 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
265 log_warning_link(link, "failed");
267 link->state = LINK_STATE_FAILED;
269 link_stop_clients(link);
274 static Address* link_find_dhcp_server_address(Link *link) {
278 assert(link->network);
280 /* The the first statically configured address if there is any */
281 LIST_FOREACH(addresses, address, link->network->static_addresses) {
283 if (address->family != AF_INET)
286 if (in_addr_null(address->family, &address->in_addr))
292 /* If that didn't work, find a suitable address we got from the pool */
293 LIST_FOREACH(addresses, address, link->pool_addresses) {
294 if (address->family != AF_INET)
303 static int link_enter_configured(Link *link) {
307 assert(link->network);
308 assert(link->state == LINK_STATE_SETTING_ROUTES);
310 if (link->network->dhcp_server &&
311 !sd_dhcp_server_is_running(link->dhcp_server)) {
312 struct in_addr pool_start;
315 address = link_find_dhcp_server_address(link);
317 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
318 link_enter_failed(link);
322 log_debug_link(link, "offering DHCPv4 leases");
324 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in);
328 /* offer 32 addresses starting from the address following the server address */
329 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
330 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
336 r = sd_dhcp_server_set_router(link->dhcp_server,
337 &main_address->in_addr.in);
341 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
342 main_address->prefixlen);
347 r = sd_dhcp_server_start(link->dhcp_server);
349 log_warning_link(link, "could not start DHCPv4 server "
350 "instance: %s", strerror(-r));
352 link_enter_failed(link);
358 log_info_link(link, "link configured");
360 link->state = LINK_STATE_CONFIGURED;
367 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
368 Link *link = userdata;
371 assert(link->route_messages > 0);
372 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
373 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
376 link->route_messages --;
378 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
383 r = sd_rtnl_message_get_errno(m);
384 if (r < 0 && r != -EEXIST)
385 log_struct_link(LOG_WARNING, link,
386 "MESSAGE=%-*s: could not set route: %s",
388 link->ifname, strerror(-r),
392 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
394 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
395 log_debug_link(link, "routes set");
396 link_enter_configured(link);
404 static int link_enter_set_routes(Link *link) {
409 assert(link->network);
410 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
412 link->state = LINK_STATE_SETTING_ROUTES;
414 if (!link->network->static_routes && !link->dhcp_lease &&
415 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
416 return link_enter_configured(link);
418 log_debug_link(link, "setting routes");
420 LIST_FOREACH(routes, rt, link->network->static_routes) {
421 r = route_configure(rt, link, &route_handler);
423 log_warning_link(link,
424 "could not set routes: %s", strerror(-r));
425 link_enter_failed(link);
430 link->route_messages ++;
433 if (link->ipv4ll && !link->dhcp_lease) {
434 _cleanup_route_free_ Route *route = NULL;
437 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
438 if (r < 0 && r != -ENOENT) {
439 log_warning_link(link, "IPV4LL error: no address: %s",
445 r = route_new_dynamic(&route);
447 log_error_link(link, "Could not allocate route: %s",
452 route->family = AF_INET;
453 route->scope = RT_SCOPE_LINK;
456 r = route_configure(route, link, &route_handler);
458 log_warning_link(link,
459 "could not set routes: %s", strerror(-r));
460 link_enter_failed(link);
465 link->route_messages ++;
469 if (link->dhcp_lease) {
470 _cleanup_route_free_ Route *route = NULL;
471 _cleanup_route_free_ Route *route_gw = NULL;
472 struct in_addr gateway;
474 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
475 if (r < 0 && r != -ENOENT) {
476 log_warning_link(link, "DHCP error: %s", strerror(-r));
481 r = route_new_dynamic(&route);
483 log_error_link(link, "Could not allocate route: %s",
488 r = route_new_dynamic(&route_gw);
490 log_error_link(link, "Could not allocate route: %s",
495 /* The dhcp netmask may mask out the gateway. Add an explicit
496 * route for the gw host so that we can route no matter the
497 * netmask or existing kernel route tables. */
498 route_gw->family = AF_INET;
499 route_gw->dst_addr.in = gateway;
500 route_gw->dst_prefixlen = 32;
501 route_gw->scope = RT_SCOPE_LINK;
503 r = route_configure(route_gw, link, &route_handler);
505 log_warning_link(link,
506 "could not set host route: %s", strerror(-r));
511 link->route_messages ++;
513 route->family = AF_INET;
514 route->in_addr.in = gateway;
516 r = route_configure(route, link, &route_handler);
518 log_warning_link(link,
519 "could not set routes: %s", strerror(-r));
520 link_enter_failed(link);
525 link->route_messages ++;
529 if (link->route_messages == 0) {
530 link_enter_configured(link);
536 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
537 Link *link = userdata;
542 assert(link->ifname);
544 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
549 r = sd_rtnl_message_get_errno(m);
550 if (r < 0 && r != -ESRCH)
551 log_struct_link(LOG_WARNING, link,
552 "MESSAGE=%-*s: could not drop route: %s",
554 link->ifname, strerror(-r),
563 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
564 Link *link = userdata;
569 assert(link->ifname);
570 assert(link->addr_messages > 0);
571 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
572 LINK_STATE_FAILED, LINK_STATE_LINGER));
574 link->addr_messages --;
576 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
581 r = sd_rtnl_message_get_errno(m);
582 if (r < 0 && r != -EEXIST)
583 log_struct_link(LOG_WARNING, link,
584 "MESSAGE=%-*s: could not set address: %s",
586 link->ifname, strerror(-r),
590 if (link->addr_messages == 0) {
591 log_debug_link(link, "addresses set");
592 link_enter_set_routes(link);
600 static int link_enter_set_addresses(Link *link) {
603 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
606 assert(link->network);
607 assert(link->state != _LINK_STATE_INVALID);
609 link->state = LINK_STATE_SETTING_ADDRESSES;
611 if (!link->network->static_addresses && !link->dhcp_lease &&
612 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
613 return link_enter_set_routes(link);
615 log_debug_link(link, "setting addresses");
617 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
618 r = address_configure(ad, 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 ++;
630 if (link->ipv4ll && !link->dhcp_lease) {
631 _cleanup_address_free_ Address *ll_addr = NULL;
634 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
635 if (r < 0 && r != -ENOENT) {
636 log_warning_link(link, "IPV4LL error: no address: %s",
642 r = address_new_dynamic(&ll_addr);
644 log_error_link(link, "Could not allocate address: %s", strerror(-r));
648 ll_addr->family = AF_INET;
649 ll_addr->in_addr.in = addr;
650 ll_addr->prefixlen = 16;
651 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
652 ll_addr->scope = RT_SCOPE_LINK;
654 r = address_configure(ll_addr, link, &address_handler);
656 log_warning_link(link,
657 "could not set addresses: %s", strerror(-r));
658 link_enter_failed(link);
663 link->addr_messages ++;
667 if (link->dhcp_lease) {
668 _cleanup_address_free_ Address *address = NULL;
670 struct in_addr netmask;
673 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
675 log_warning_link(link, "DHCP error: no address: %s",
680 if (!link->network->dhcp_critical) {
681 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
684 log_warning_link(link, "DHCP error: no lifetime: %s",
690 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
692 log_warning_link(link, "DHCP error: no netmask: %s",
697 prefixlen = net_netmask_to_prefixlen(&netmask);
699 r = address_new_dynamic(&address);
701 log_error_link(link, "Could not allocate address: %s",
706 address->family = AF_INET;
707 address->in_addr.in = addr;
708 address->cinfo.ifa_prefered = lifetime;
709 address->cinfo.ifa_valid = lifetime;
710 address->prefixlen = prefixlen;
711 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
713 r = address_configure(address, link, &address_handler);
715 log_warning_link(link,
716 "could not set addresses: %s", strerror(-r));
717 link_enter_failed(link);
722 link->addr_messages ++;
728 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
729 Link *link = userdata;
734 assert(link->ifname);
736 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
741 r = sd_rtnl_message_get_errno(m);
742 if (r < 0 && r != -ENOENT)
743 log_struct_link(LOG_WARNING, link,
744 "MESSAGE=%-*s: could not update address: %s",
746 link->ifname, strerror(-r),
755 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
756 Link *link = userdata;
761 assert(link->ifname);
763 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
768 r = sd_rtnl_message_get_errno(m);
769 if (r < 0 && r != -EADDRNOTAVAIL)
770 log_struct_link(LOG_WARNING, link,
771 "MESSAGE=%-*s: could not drop address: %s",
773 link->ifname, strerror(-r),
782 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
783 Link *link = userdata;
788 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
793 r = sd_bus_message_get_errno(m);
795 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
802 static int link_set_hostname(Link *link, const char *hostname) {
803 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
807 assert(link->manager);
810 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
812 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
813 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
817 r = sd_bus_message_new_method_call(
820 "org.freedesktop.hostname1",
821 "/org/freedesktop/hostname1",
822 "org.freedesktop.hostname1",
827 r = sd_bus_message_append(m, "sb", hostname, false);
831 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
833 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
840 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
841 Link *link = userdata;
846 assert(link->ifname);
848 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
853 r = sd_rtnl_message_get_errno(m);
855 log_struct_link(LOG_WARNING, link,
856 "MESSAGE=%-*s: could not set MTU: %s",
857 IFNAMSIZ, link->ifname, strerror(-r),
866 static int link_set_mtu(Link *link, uint32_t mtu) {
867 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
871 assert(link->manager);
872 assert(link->manager->rtnl);
874 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
876 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
877 RTM_SETLINK, link->ifindex);
879 log_error_link(link, "Could not allocate RTM_SETLINK message");
883 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
885 log_error_link(link, "Could not append MTU: %s", strerror(-r));
889 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
892 "Could not send rtnetlink message: %s", strerror(-r));
901 static int dhcp_lease_lost(Link *link) {
902 _cleanup_address_free_ Address *address = NULL;
903 _cleanup_route_free_ Route *route_gw = NULL;
904 _cleanup_route_free_ Route *route = NULL;
906 struct in_addr netmask;
907 struct in_addr gateway;
912 assert(link->dhcp_lease);
914 log_warning_link(link, "DHCP lease lost");
916 r = address_new_dynamic(&address);
918 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
920 r = route_new_dynamic(&route_gw);
922 route_gw->family = AF_INET;
923 route_gw->dst_addr.in = gateway;
924 route_gw->dst_prefixlen = 32;
925 route_gw->scope = RT_SCOPE_LINK;
927 route_drop(route_gw, link, &route_drop_handler);
931 r = route_new_dynamic(&route);
933 route->family = AF_INET;
934 route->in_addr.in = gateway;
936 route_drop(route, link, &route_drop_handler);
941 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
942 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
943 prefixlen = net_netmask_to_prefixlen(&netmask);
945 address->family = AF_INET;
946 address->in_addr.in = addr;
947 address->prefixlen = prefixlen;
949 address_drop(address, link, &address_drop_handler);
953 if (link->network->dhcp_mtu) {
956 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
957 if (r >= 0 && link->original_mtu != mtu) {
958 r = link_set_mtu(link, link->original_mtu);
960 log_warning_link(link, "DHCP error: could not reset MTU");
961 link_enter_failed(link);
967 if (link->network->dhcp_hostname) {
968 const char *hostname = NULL;
970 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
971 if (r >= 0 && hostname) {
972 r = link_set_hostname(link, "");
974 log_error_link(link, "Failed to reset transient hostname");
978 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
983 static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
984 sd_dhcp_lease *lease;
987 r = sd_dhcp_client_get_lease(client, &lease);
989 log_warning_link(link, "DHCP error: no lease %s",
994 sd_dhcp_lease_unref(link->dhcp_lease);
995 link->dhcp_lease = lease;
997 link_enter_set_addresses(link);
1002 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1003 sd_dhcp_lease *lease;
1004 struct in_addr address;
1005 struct in_addr netmask;
1006 struct in_addr gateway;
1013 r = sd_dhcp_client_get_lease(client, &lease);
1015 log_warning_link(link, "DHCP error: no lease: %s",
1020 r = sd_dhcp_lease_get_address(lease, &address);
1022 log_warning_link(link, "DHCP error: no address: %s",
1027 r = sd_dhcp_lease_get_netmask(lease, &netmask);
1029 log_warning_link(link, "DHCP error: no netmask: %s",
1034 prefixlen = net_netmask_to_prefixlen(&netmask);
1036 r = sd_dhcp_lease_get_router(lease, &gateway);
1037 if (r < 0 && r != -ENOENT) {
1038 log_warning_link(link, "DHCP error: %s", strerror(-r));
1043 log_struct_link(LOG_INFO, link,
1044 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
1047 ADDRESS_FMT_VAL(address),
1049 ADDRESS_FMT_VAL(gateway),
1050 "ADDRESS=%u.%u.%u.%u",
1051 ADDRESS_FMT_VAL(address),
1054 "GATEWAY=%u.%u.%u.%u",
1055 ADDRESS_FMT_VAL(gateway),
1058 log_struct_link(LOG_INFO, link,
1059 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1062 ADDRESS_FMT_VAL(address),
1064 "ADDRESS=%u.%u.%u.%u",
1065 ADDRESS_FMT_VAL(address),
1070 link->dhcp_lease = lease;
1072 if (link->network->dhcp_mtu) {
1075 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1077 r = link_set_mtu(link, mtu);
1079 log_error_link(link, "Failed to set MTU "
1080 "to %" PRIu16, mtu);
1084 if (link->network->dhcp_hostname) {
1085 const char *hostname;
1087 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1089 r = link_set_hostname(link, hostname);
1091 log_error_link(link, "Failed to set transient hostname "
1092 "to '%s'", hostname);
1096 link_enter_set_addresses(link);
1101 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1102 Link *link = userdata;
1106 assert(link->network);
1107 assert(link->manager);
1109 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1113 case DHCP_EVENT_NO_LEASE:
1114 log_debug_link(link, "IP address in use.");
1116 case DHCP_EVENT_EXPIRED:
1117 case DHCP_EVENT_STOP:
1118 case DHCP_EVENT_IP_CHANGE:
1119 if (link->network->dhcp_critical) {
1120 log_error_link(link, "DHCPv4 connection considered system critical, "
1121 "ignoring request to reconfigure it.");
1125 if (link->dhcp_lease) {
1126 r = dhcp_lease_lost(link);
1128 link_enter_failed(link);
1133 if (event == DHCP_EVENT_IP_CHANGE) {
1134 r = dhcp_lease_acquired(client, link);
1136 link_enter_failed(link);
1141 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1142 if (!sd_ipv4ll_is_running(link->ipv4ll))
1143 r = sd_ipv4ll_start(link->ipv4ll);
1144 else if (ipv4ll_is_bound(link->ipv4ll))
1145 r = ipv4ll_address_update(link, false);
1147 link_enter_failed(link);
1153 case DHCP_EVENT_RENEW:
1154 r = dhcp_lease_renew(client, link);
1156 link_enter_failed(link);
1160 case DHCP_EVENT_IP_ACQUIRE:
1161 r = dhcp_lease_acquired(client, link);
1163 link_enter_failed(link);
1167 if (ipv4ll_is_bound(link->ipv4ll))
1168 r = ipv4ll_address_update(link, true);
1170 r = sd_ipv4ll_stop(link->ipv4ll);
1172 link_enter_failed(link);
1179 log_warning_link(link, "DHCP error: %s", strerror(-event));
1181 log_warning_link(link, "DHCP unknown event: %d", event);
1188 static int ipv4ll_address_update(Link *link, bool deprecate) {
1190 struct in_addr addr;
1194 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1196 _cleanup_address_free_ Address *address = NULL;
1198 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1199 deprecate ? "deprecate" : "approve",
1200 ADDRESS_FMT_VAL(addr));
1202 r = address_new_dynamic(&address);
1204 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1208 address->family = AF_INET;
1209 address->in_addr.in = addr;
1210 address->prefixlen = 16;
1211 address->scope = RT_SCOPE_LINK;
1212 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1213 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1215 address_update(address, link, &address_update_handler);
1223 static int ipv4ll_address_lost(Link *link) {
1225 struct in_addr addr;
1229 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1231 _cleanup_address_free_ Address *address = NULL;
1232 _cleanup_route_free_ Route *route = NULL;
1234 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1235 ADDRESS_FMT_VAL(addr));
1237 r = address_new_dynamic(&address);
1239 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1243 address->family = AF_INET;
1244 address->in_addr.in = addr;
1245 address->prefixlen = 16;
1246 address->scope = RT_SCOPE_LINK;
1248 address_drop(address, link, &address_drop_handler);
1251 r = route_new_dynamic(&route);
1253 log_error_link(link, "Could not allocate route: %s",
1258 route->family = AF_INET;
1259 route->scope = RT_SCOPE_LINK;
1260 route->metrics = 99;
1262 route_drop(route, link, &route_drop_handler);
1269 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1271 struct in_addr addr;
1275 r = sd_ipv4ll_get_address(ll, &addr);
1281 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1282 struct in_addr address;
1288 r = sd_ipv4ll_get_address(ll, &address);
1292 log_struct_link(LOG_INFO, link,
1293 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1296 ADDRESS_FMT_VAL(address),
1299 link_enter_set_addresses(link);
1304 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1305 Link *link = userdata;
1309 assert(link->network);
1310 assert(link->manager);
1312 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1316 case IPV4LL_EVENT_STOP:
1317 case IPV4LL_EVENT_CONFLICT:
1318 r = ipv4ll_address_lost(link);
1320 link_enter_failed(link);
1324 case IPV4LL_EVENT_BIND:
1325 r = ipv4ll_address_claimed(ll, link);
1327 link_enter_failed(link);
1333 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1335 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1340 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1341 Link *link = userdata;
1344 assert(link->network);
1345 assert(link->manager);
1347 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1351 case DHCP6_EVENT_STOP:
1352 case DHCP6_EVENT_RESEND_EXPIRE:
1353 case DHCP6_EVENT_RETRANS_MAX:
1354 case DHCP6_EVENT_IP_ACQUIRE:
1355 log_debug_link(link, "DHCPv6 event %d", event);
1361 log_warning_link(link, "DHCPv6 error: %s",
1364 log_warning_link(link, "DHCPv6 unknown event: %d",
1370 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1371 Link *link = userdata;
1375 assert(link->network);
1376 assert(link->manager);
1378 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1382 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1383 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1386 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1387 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1392 log_warning_link(link, "ICMPv6 error: %s",
1395 log_warning_link(link, "ICMPv6 unknown event: %d",
1401 if (link->dhcp6_client)
1404 r = sd_dhcp6_client_new(&link->dhcp6_client);
1408 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1410 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1414 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1416 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1420 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1422 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1426 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1429 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1433 r = sd_dhcp6_client_start(link->dhcp6_client);
1435 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1438 static int link_acquire_conf(Link *link) {
1442 assert(link->network);
1443 assert(link->manager);
1444 assert(link->manager->event);
1446 if (link->network->ipv4ll) {
1447 assert(link->ipv4ll);
1449 log_debug_link(link, "acquiring IPv4 link-local address");
1451 r = sd_ipv4ll_start(link->ipv4ll);
1453 log_warning_link(link, "could not acquire IPv4 "
1454 "link-local address");
1459 if (link->network->dhcp) {
1460 assert(link->dhcp_client);
1462 log_debug_link(link, "acquiring DHCPv4 lease");
1464 r = sd_dhcp_client_start(link->dhcp_client);
1466 log_warning_link(link, "could not acquire DHCPv4 "
1472 if (link->network->dhcp6) {
1473 assert(link->icmp6_router_discovery);
1475 log_debug_link(link, "discovering IPv6 routers");
1477 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1479 log_warning_link(link, "could not start IPv6 router discovery");
1487 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1488 /* see Documentation/networking/operstates.txt in the kernel sources */
1490 if (operstate == IF_OPER_UP)
1493 if (operstate == IF_OPER_UNKNOWN)
1494 /* operstate may not be implemented, so fall back to flags */
1495 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1501 #define FLAG_STRING(string, flag, old, new) \
1502 (((old ^ new) & flag) \
1503 ? ((old & flag) ? (" -" string) : (" +" string)) \
1506 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1507 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1509 bool carrier_gained = false, carrier_lost = false;
1514 r = sd_rtnl_message_link_get_flags(m, &flags);
1516 log_warning_link(link, "Could not get link flags");
1520 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1522 /* if we got a message without operstate, take it to mean
1523 the state was unchanged */
1524 operstate = link->kernel_operstate;
1526 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1529 if (link->flags != flags) {
1530 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1531 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1532 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1533 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1534 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1535 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1536 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1537 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1538 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1539 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1540 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1541 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1542 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1543 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1544 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1545 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1546 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1547 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1548 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1549 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1551 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1552 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1553 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1554 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1555 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1556 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1557 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1558 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1560 /* link flags are currently at most 18 bits, let's align to printing 20 */
1561 if (unknown_flags_added)
1562 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1563 unknown_flags_added);
1565 if (unknown_flags_removed)
1566 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1567 unknown_flags_removed);
1570 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1571 link_has_carrier(flags, operstate);
1572 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1573 !link_has_carrier(flags, operstate);
1575 link->flags = flags;
1576 link->kernel_operstate = operstate;
1580 if (link->state == LINK_STATE_FAILED ||
1581 link->state == LINK_STATE_UNMANAGED)
1584 if (carrier_gained) {
1585 log_info_link(link, "gained carrier");
1587 if (link->network) {
1588 r = link_acquire_conf(link);
1590 link_enter_failed(link);
1594 } else if (carrier_lost) {
1595 log_info_link(link, "lost carrier");
1597 r = link_stop_clients(link);
1599 link_enter_failed(link);
1607 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1608 Link *link = userdata;
1613 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1618 r = sd_rtnl_message_get_errno(m);
1620 /* we warn but don't fail the link, as it may
1621 be brought up later */
1622 log_struct_link(LOG_WARNING, link,
1623 "MESSAGE=%-*s: could not bring up interface: %s",
1625 link->ifname, strerror(-r),
1635 static int link_up(Link *link) {
1636 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1640 assert(link->manager);
1641 assert(link->manager->rtnl);
1643 log_debug_link(link, "bringing link up");
1645 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1646 RTM_SETLINK, link->ifindex);
1648 log_error_link(link, "Could not allocate RTM_SETLINK message");
1652 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1654 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1658 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1660 log_error_link(link,
1661 "Could not send rtnetlink message: %s", strerror(-r));
1670 static int link_enslaved(Link *link) {
1674 assert(link->state == LINK_STATE_ENSLAVING);
1675 assert(link->network);
1677 if (!(link->flags & IFF_UP)) {
1680 link_enter_failed(link);
1685 if (!link->network->dhcp && !link->network->ipv4ll)
1686 return link_enter_set_addresses(link);
1691 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1692 Link *link = userdata;
1696 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1697 LINK_STATE_LINGER));
1698 assert(link->network);
1702 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1707 r = sd_rtnl_message_get_errno(m);
1709 log_struct_link(LOG_ERR, link,
1710 "MESSAGE=%-*s: could not enslave: %s",
1712 link->ifname, strerror(-r),
1715 link_enter_failed(link);
1720 log_debug_link(link, "enslaved");
1722 if (link->enslaving == 0)
1723 link_enslaved(link);
1730 static int link_enter_enslave(Link *link) {
1731 NetDev *vlan, *macvlan, *vxlan;
1736 assert(link->network);
1737 assert(link->state == LINK_STATE_INITIALIZING);
1739 link->state = LINK_STATE_ENSLAVING;
1743 if (!link->network->bridge &&
1744 !link->network->bond &&
1745 !link->network->tunnel &&
1746 hashmap_isempty(link->network->vlans) &&
1747 hashmap_isempty(link->network->macvlans) &&
1748 hashmap_isempty(link->network->vxlans))
1749 return link_enslaved(link);
1751 if (link->network->bond) {
1752 log_struct_link(LOG_DEBUG, link,
1753 "MESSAGE=%-*s: enslaving by '%s'",
1755 link->ifname, link->network->bond->ifname,
1756 NETDEV(link->network->bond),
1759 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1761 log_struct_link(LOG_WARNING, link,
1762 "MESSAGE=%-*s: could not enslave by '%s': %s",
1764 link->ifname, link->network->bond->ifname, strerror(-r),
1765 NETDEV(link->network->bond),
1767 link_enter_failed(link);
1775 if (link->network->bridge) {
1776 log_struct_link(LOG_DEBUG, link,
1777 "MESSAGE=%-*s: enslaving by '%s'",
1779 link->ifname, link->network->bridge->ifname,
1780 NETDEV(link->network->bridge),
1783 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1785 log_struct_link(LOG_WARNING, link,
1786 "MESSAGE=%-*s: could not enslave by '%s': %s",
1788 link->ifname, link->network->bridge->ifname, strerror(-r),
1789 NETDEV(link->network->bridge),
1791 link_enter_failed(link);
1799 if (link->network->tunnel) {
1800 log_struct_link(LOG_DEBUG, link,
1801 "MESSAGE=%-*s: enslaving by '%s'",
1803 link->ifname, link->network->tunnel->ifname,
1804 NETDEV(link->network->tunnel),
1807 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1809 log_struct_link(LOG_WARNING, link,
1810 "MESSAGE=%-*s: could not enslave by '%s': %s",
1812 link->ifname, link->network->tunnel->ifname, strerror(-r),
1813 NETDEV(link->network->tunnel),
1815 link_enter_failed(link);
1823 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1824 log_struct_link(LOG_DEBUG, link,
1825 "MESSAGE=%-*s: enslaving by '%s'",
1827 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1829 r = netdev_enslave(vlan, link, &enslave_handler);
1831 log_struct_link(LOG_WARNING, link,
1832 "MESSAGE=%-*s: could not enslave by '%s': %s",
1834 link->ifname, vlan->ifname, strerror(-r),
1835 NETDEV(vlan), NULL);
1836 link_enter_failed(link);
1844 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1845 log_struct_link(LOG_DEBUG, link,
1846 "MESSAGE=%-*s: enslaving by '%s'",
1848 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1850 r = netdev_enslave(macvlan, link, &enslave_handler);
1852 log_struct_link(LOG_WARNING, link,
1853 "MESSAGE=%-*s: could not enslave by '%s': %s",
1855 link->ifname, macvlan->ifname, strerror(-r),
1856 NETDEV(macvlan), NULL);
1857 link_enter_failed(link);
1865 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1866 log_struct_link(LOG_DEBUG, link,
1867 "MESSAGE=%*s: enslaving by '%s'",
1869 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1871 r = netdev_enslave(vxlan, link, &enslave_handler);
1873 log_struct_link(LOG_WARNING, link,
1874 "MESSAGE=%*s: could not enslave by '%s': %s",
1876 link->ifname, vxlan->ifname, strerror(-r),
1877 NETDEV(vxlan), NULL);
1878 link_enter_failed(link);
1889 static int link_configure(Link *link) {
1893 assert(link->state == LINK_STATE_INITIALIZING);
1895 if (link->network->ipv4ll) {
1898 r = sd_ipv4ll_new(&link->ipv4ll);
1902 if (link->udev_device) {
1903 r = net_get_unique_predictable_data(link->udev_device, seed);
1905 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1911 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1915 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1919 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1923 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1928 if (link->network->dhcp) {
1929 r = sd_dhcp_client_new(&link->dhcp_client);
1933 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1937 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1941 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1945 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1949 if (link->network->dhcp_mtu) {
1950 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1956 if (link->network->dhcp_server) {
1957 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1961 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1966 if (link->network->dhcp6) {
1967 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1971 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1976 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1981 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1986 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1987 icmp6_router_handler, link);
1992 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1993 r = link_acquire_conf(link);
1998 return link_enter_enslave(link);
2001 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2002 Link *link = userdata;
2007 assert(link->ifname);
2008 assert(link->manager);
2010 if (link->state != LINK_STATE_INITIALIZING)
2013 log_debug_link(link, "link state is up-to-date");
2015 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
2017 link_enter_unmanaged(link);
2022 r = network_apply(link->manager, network, link);
2026 r = link_configure(link);
2033 int link_initialized(Link *link, struct udev_device *device) {
2034 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2038 assert(link->manager);
2039 assert(link->manager->rtnl);
2042 if (link->state != LINK_STATE_INITIALIZING)
2045 log_debug_link(link, "udev initialized link");
2047 link->udev_device = udev_device_ref(device);
2049 /* udev has initialized the link, but we don't know if we have yet processed
2050 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
2051 we know that the pending NEWLINKs have already been processed and that we
2054 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
2058 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
2065 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
2066 Manager *m = userdata;
2069 _cleanup_address_free_ Address *address = NULL;
2071 char buf[INET6_ADDRSTRLEN];
2072 bool address_dropped = false;
2079 r = sd_rtnl_message_get_type(message, &type);
2081 log_warning("rtnl: could not get message type");
2085 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2086 if (r < 0 || ifindex <= 0) {
2087 log_warning("rtnl: received address message without valid ifindex, ignoring");
2090 r = link_get(m, ifindex, &link);
2091 if (r < 0 || !link) {
2092 log_warning("rtnl: received address for a nonexistent link, ignoring");
2097 r = address_new_dynamic(&address);
2101 r = sd_rtnl_message_addr_get_family(message, &address->family);
2102 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
2103 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
2107 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2109 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2113 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2115 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
2119 switch (address->family) {
2121 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2123 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2130 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2132 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2139 assert_not_reached("invalid address family");
2142 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
2143 log_warning_link(link, "could not print address");
2147 LIST_FOREACH(addresses, ad, link->addresses) {
2148 if (address_equal(ad, address)) {
2149 LIST_REMOVE(addresses, link->addresses, ad);
2153 address_dropped = true;
2161 if (!address_dropped)
2162 log_debug_link(link, "added address: %s/%u", buf,
2163 address->prefixlen);
2165 LIST_PREPEND(addresses, link->addresses, address);
2172 if (address_dropped) {
2173 log_debug_link(link, "removed address: %s/%u", buf,
2174 address->prefixlen);
2181 assert_not_reached("Received invalid RTNL message type");
2187 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2188 Link *link = userdata;
2195 for (; m; m = sd_rtnl_message_next(m)) {
2196 r = sd_rtnl_message_get_errno(m);
2198 log_debug_link(link, "getting address failed: %s", strerror(-r));
2202 r = link_rtnl_process_address(rtnl, m, link->manager);
2204 log_warning_link(link, "could not process address: %s", strerror(-r));
2210 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2212 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2213 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2214 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2222 r = link_new(m, message, ret);
2228 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2230 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2234 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2238 if (detect_container(NULL) <= 0) {
2239 /* not in a container, udev will be around */
2240 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2241 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2243 log_warning_link(link, "could not find udev device");
2247 if (udev_device_get_is_initialized(device) <= 0) {
2249 log_debug_link(link, "udev initializing link...");
2253 r = link_initialized(link, device);
2257 r = link_initialized_and_synced(m->rtnl, NULL, link);
2265 int link_update(Link *link, sd_rtnl_message *m) {
2266 struct ether_addr mac;
2271 assert(link->ifname);
2274 if (link->state == LINK_STATE_LINGER) {
2276 log_info_link(link, "link readded");
2277 link->state = LINK_STATE_ENSLAVING;
2280 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2281 if (r >= 0 && !streq(ifname, link->ifname)) {
2282 log_info_link(link, "renamed to %s", ifname);
2285 link->ifname = strdup(ifname);
2290 if (!link->original_mtu) {
2291 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2293 log_debug_link(link, "saved original MTU: %"
2294 PRIu16, link->original_mtu);
2297 /* The kernel may broadcast NEWLINK messages without the MAC address
2298 set, simply ignore them. */
2299 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2301 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2303 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2305 log_debug_link(link, "MAC address: "
2306 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2307 mac.ether_addr_octet[0],
2308 mac.ether_addr_octet[1],
2309 mac.ether_addr_octet[2],
2310 mac.ether_addr_octet[3],
2311 mac.ether_addr_octet[4],
2312 mac.ether_addr_octet[5]);
2315 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2317 log_warning_link(link, "Could not update MAC "
2318 "address in IPv4LL client: %s",
2324 if (link->dhcp_client) {
2325 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2327 log_warning_link(link, "Could not update MAC "
2328 "address in DHCP client: %s",
2334 if (link->dhcp6_client) {
2335 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2338 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2346 return link_update_flags(link, m);
2349 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2358 fprintf(f, "%s=", key);
2360 LIST_FOREACH(addresses, ad, address) {
2361 char buf[INET6_ADDRSTRLEN];
2363 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2364 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2370 static void link_update_operstate(Link *link) {
2374 if (link->kernel_operstate == IF_OPER_DORMANT)
2375 link->operstate = LINK_OPERSTATE_DORMANT;
2376 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2378 uint8_t scope = RT_SCOPE_NOWHERE;
2380 /* if we have carrier, check what addresses we have */
2381 LIST_FOREACH(addresses, address, link->addresses) {
2382 if (address->scope < scope)
2383 scope = address->scope;
2386 if (scope < RT_SCOPE_SITE)
2387 /* universally accessible addresses found */
2388 link->operstate = LINK_OPERSTATE_ROUTABLE;
2389 else if (scope < RT_SCOPE_HOST)
2390 /* only link or site local addresses found */
2391 link->operstate = LINK_OPERSTATE_DEGRADED;
2393 /* no useful addresses found */
2394 link->operstate = LINK_OPERSTATE_CARRIER;
2396 link->operstate = LINK_OPERSTATE_UNKNOWN;
2399 int link_save(Link *link) {
2400 _cleanup_free_ char *temp_path = NULL;
2401 _cleanup_fclose_ FILE *f = NULL;
2402 const char *admin_state, *oper_state;
2406 assert(link->state_file);
2407 assert(link->lease_file);
2408 assert(link->manager);
2410 link_update_operstate(link);
2412 r = manager_save(link->manager);
2416 if (link->state == LINK_STATE_LINGER) {
2417 unlink(link->state_file);
2421 admin_state = link_state_to_string(link->state);
2422 assert(admin_state);
2424 oper_state = link_operstate_to_string(link->operstate);
2427 r = fopen_temporary(link->state_file, &f, &temp_path);
2431 fchmod(fileno(f), 0644);
2434 "# This is private data. Do not parse.\n"
2438 admin_state, oper_state, link->flags);
2440 if (link->network) {
2441 serialize_addresses(f, "DNS", link->network->dns);
2442 serialize_addresses(f, "NTP", link->network->ntp);
2445 if (link->dhcp_lease) {
2446 assert(link->network);
2448 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2455 "DHCP_USE_NTP=%s\n",
2457 yes_no(link->network->dhcp_dns),
2458 yes_no(link->network->dhcp_ntp));
2460 unlink(link->lease_file);
2464 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2466 unlink(link->state_file);
2472 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2477 static const char* const link_state_table[_LINK_STATE_MAX] = {
2478 [LINK_STATE_INITIALIZING] = "initializing",
2479 [LINK_STATE_ENSLAVING] = "configuring",
2480 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2481 [LINK_STATE_SETTING_ROUTES] = "configuring",
2482 [LINK_STATE_CONFIGURED] = "configured",
2483 [LINK_STATE_UNMANAGED] = "unmanaged",
2484 [LINK_STATE_FAILED] = "failed",
2485 [LINK_STATE_LINGER] = "linger",
2488 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2490 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2491 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2492 [LINK_OPERSTATE_DORMANT] = "dormant",
2493 [LINK_OPERSTATE_CARRIER] = "carrier",
2494 [LINK_OPERSTATE_DEGRADED] = "degraded",
2495 [LINK_OPERSTATE_ROUTABLE] = "routable",
2498 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);