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 struct in_addr pool_start;
314 address = link_find_dhcp_server_address(link);
316 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
317 link_enter_failed(link);
321 log_debug_link(link, "offering DHCPv4 leases");
323 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in);
327 /* offer 32 addresses starting from the address following the server address */
328 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
329 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
335 r = sd_dhcp_server_set_router(link->dhcp_server,
336 &main_address->in_addr.in);
340 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
341 main_address->prefixlen);
346 r = sd_dhcp_server_start(link->dhcp_server);
348 log_warning_link(link, "could not start DHCPv4 server "
349 "instance: %s", strerror(-r));
351 link_enter_failed(link);
357 log_info_link(link, "link configured");
359 link->state = LINK_STATE_CONFIGURED;
366 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
367 Link *link = userdata;
370 assert(link->route_messages > 0);
371 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
372 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
375 link->route_messages --;
377 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
382 r = sd_rtnl_message_get_errno(m);
383 if (r < 0 && r != -EEXIST)
384 log_struct_link(LOG_WARNING, link,
385 "MESSAGE=%-*s: could not set route: %s",
387 link->ifname, strerror(-r),
391 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
393 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
394 log_debug_link(link, "routes set");
395 link_enter_configured(link);
403 static int link_enter_set_routes(Link *link) {
408 assert(link->network);
409 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
411 link->state = LINK_STATE_SETTING_ROUTES;
413 if (!link->network->static_routes && !link->dhcp_lease &&
414 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
415 return link_enter_configured(link);
417 log_debug_link(link, "setting routes");
419 LIST_FOREACH(routes, rt, link->network->static_routes) {
420 r = route_configure(rt, link, &route_handler);
422 log_warning_link(link,
423 "could not set routes: %s", strerror(-r));
424 link_enter_failed(link);
429 link->route_messages ++;
432 if (link->ipv4ll && !link->dhcp_lease) {
433 _cleanup_route_free_ Route *route = NULL;
436 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
437 if (r < 0 && r != -ENOENT) {
438 log_warning_link(link, "IPV4LL error: no address: %s",
444 r = route_new_dynamic(&route);
446 log_error_link(link, "Could not allocate route: %s",
451 route->family = AF_INET;
452 route->scope = RT_SCOPE_LINK;
455 r = route_configure(route, link, &route_handler);
457 log_warning_link(link,
458 "could not set routes: %s", strerror(-r));
459 link_enter_failed(link);
464 link->route_messages ++;
468 if (link->dhcp_lease) {
469 _cleanup_route_free_ Route *route = NULL;
470 _cleanup_route_free_ Route *route_gw = NULL;
471 struct in_addr gateway;
473 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
474 if (r < 0 && r != -ENOENT) {
475 log_warning_link(link, "DHCP error: %s", strerror(-r));
480 r = route_new_dynamic(&route);
482 log_error_link(link, "Could not allocate route: %s",
487 r = route_new_dynamic(&route_gw);
489 log_error_link(link, "Could not allocate route: %s",
494 /* The dhcp netmask may mask out the gateway. Add an explicit
495 * route for the gw host so that we can route no matter the
496 * netmask or existing kernel route tables. */
497 route_gw->family = AF_INET;
498 route_gw->dst_addr.in = gateway;
499 route_gw->dst_prefixlen = 32;
500 route_gw->scope = RT_SCOPE_LINK;
502 r = route_configure(route_gw, link, &route_handler);
504 log_warning_link(link,
505 "could not set host route: %s", strerror(-r));
510 link->route_messages ++;
512 route->family = AF_INET;
513 route->in_addr.in = gateway;
515 r = route_configure(route, link, &route_handler);
517 log_warning_link(link,
518 "could not set routes: %s", strerror(-r));
519 link_enter_failed(link);
524 link->route_messages ++;
528 if (link->route_messages == 0) {
529 link_enter_configured(link);
535 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
536 Link *link = userdata;
541 assert(link->ifname);
543 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
548 r = sd_rtnl_message_get_errno(m);
549 if (r < 0 && r != -ESRCH)
550 log_struct_link(LOG_WARNING, link,
551 "MESSAGE=%-*s: could not drop route: %s",
553 link->ifname, strerror(-r),
562 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
563 Link *link = userdata;
568 assert(link->ifname);
569 assert(link->addr_messages > 0);
570 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
571 LINK_STATE_FAILED, LINK_STATE_LINGER));
573 link->addr_messages --;
575 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
580 r = sd_rtnl_message_get_errno(m);
581 if (r < 0 && r != -EEXIST)
582 log_struct_link(LOG_WARNING, link,
583 "MESSAGE=%-*s: could not set address: %s",
585 link->ifname, strerror(-r),
589 if (link->addr_messages == 0) {
590 log_debug_link(link, "addresses set");
591 link_enter_set_routes(link);
599 static int link_enter_set_addresses(Link *link) {
604 assert(link->network);
605 assert(link->state != _LINK_STATE_INVALID);
607 link->state = LINK_STATE_SETTING_ADDRESSES;
609 if (!link->network->static_addresses && !link->dhcp_lease &&
610 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
611 return link_enter_set_routes(link);
613 log_debug_link(link, "setting addresses");
615 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
616 r = address_configure(ad, link, &address_handler);
618 log_warning_link(link,
619 "could not set addresses: %s", strerror(-r));
620 link_enter_failed(link);
625 link->addr_messages ++;
628 if (link->ipv4ll && !link->dhcp_lease) {
629 _cleanup_address_free_ Address *ll_addr = NULL;
632 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
633 if (r < 0 && r != -ENOENT) {
634 log_warning_link(link, "IPV4LL error: no address: %s",
640 r = address_new_dynamic(&ll_addr);
642 log_error_link(link, "Could not allocate address: %s", strerror(-r));
646 ll_addr->family = AF_INET;
647 ll_addr->in_addr.in = addr;
648 ll_addr->prefixlen = 16;
649 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
650 ll_addr->scope = RT_SCOPE_LINK;
652 r = address_configure(ll_addr, link, &address_handler);
654 log_warning_link(link,
655 "could not set addresses: %s", strerror(-r));
656 link_enter_failed(link);
661 link->addr_messages ++;
665 if (link->dhcp_lease) {
666 _cleanup_address_free_ Address *address = NULL;
668 struct in_addr netmask;
671 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
673 log_warning_link(link, "DHCP error: no address: %s",
678 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
680 log_warning_link(link, "DHCP error: no netmask: %s",
685 prefixlen = net_netmask_to_prefixlen(&netmask);
687 r = address_new_dynamic(&address);
689 log_error_link(link, "Could not allocate address: %s",
694 address->family = AF_INET;
695 address->in_addr.in = addr;
696 address->prefixlen = prefixlen;
697 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
699 r = address_configure(address, link, &address_handler);
701 log_warning_link(link,
702 "could not set addresses: %s", strerror(-r));
703 link_enter_failed(link);
708 link->addr_messages ++;
714 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
715 Link *link = userdata;
720 assert(link->ifname);
722 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
727 r = sd_rtnl_message_get_errno(m);
728 if (r < 0 && r != -ENOENT)
729 log_struct_link(LOG_WARNING, link,
730 "MESSAGE=%-*s: could not update address: %s",
732 link->ifname, strerror(-r),
741 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
742 Link *link = userdata;
747 assert(link->ifname);
749 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
754 r = sd_rtnl_message_get_errno(m);
755 if (r < 0 && r != -EADDRNOTAVAIL)
756 log_struct_link(LOG_WARNING, link,
757 "MESSAGE=%-*s: could not drop address: %s",
759 link->ifname, strerror(-r),
768 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
769 Link *link = userdata;
774 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
779 r = sd_bus_message_get_errno(m);
781 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
788 static int link_set_hostname(Link *link, const char *hostname) {
789 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
793 assert(link->manager);
796 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
798 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
799 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
803 r = sd_bus_message_new_method_call(
806 "org.freedesktop.hostname1",
807 "/org/freedesktop/hostname1",
808 "org.freedesktop.hostname1",
813 r = sd_bus_message_append(m, "sb", hostname, false);
817 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
819 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
826 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
827 Link *link = userdata;
832 assert(link->ifname);
834 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
839 r = sd_rtnl_message_get_errno(m);
841 log_struct_link(LOG_WARNING, link,
842 "MESSAGE=%-*s: could not set MTU: %s",
843 IFNAMSIZ, link->ifname, strerror(-r),
852 static int link_set_mtu(Link *link, uint32_t mtu) {
853 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
857 assert(link->manager);
858 assert(link->manager->rtnl);
860 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
862 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
863 RTM_SETLINK, link->ifindex);
865 log_error_link(link, "Could not allocate RTM_SETLINK message");
869 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
871 log_error_link(link, "Could not append MTU: %s", strerror(-r));
875 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
878 "Could not send rtnetlink message: %s", strerror(-r));
887 static int dhcp_lease_lost(Link *link) {
888 _cleanup_address_free_ Address *address = NULL;
889 _cleanup_route_free_ Route *route_gw = NULL;
890 _cleanup_route_free_ Route *route = NULL;
892 struct in_addr netmask;
893 struct in_addr gateway;
898 assert(link->dhcp_lease);
900 log_warning_link(link, "DHCP lease lost");
902 r = address_new_dynamic(&address);
904 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
906 r = route_new_dynamic(&route_gw);
908 route_gw->family = AF_INET;
909 route_gw->dst_addr.in = gateway;
910 route_gw->dst_prefixlen = 32;
911 route_gw->scope = RT_SCOPE_LINK;
913 route_drop(route_gw, link, &route_drop_handler);
917 r = route_new_dynamic(&route);
919 route->family = AF_INET;
920 route->in_addr.in = gateway;
922 route_drop(route, link, &route_drop_handler);
927 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
928 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
929 prefixlen = net_netmask_to_prefixlen(&netmask);
931 address->family = AF_INET;
932 address->in_addr.in = addr;
933 address->prefixlen = prefixlen;
935 address_drop(address, link, &address_drop_handler);
939 if (link->network->dhcp_mtu) {
942 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
943 if (r >= 0 && link->original_mtu != mtu) {
944 r = link_set_mtu(link, link->original_mtu);
946 log_warning_link(link, "DHCP error: could not reset MTU");
947 link_enter_failed(link);
953 if (link->network->dhcp_hostname) {
954 const char *hostname = NULL;
956 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
957 if (r >= 0 && hostname) {
958 r = link_set_hostname(link, "");
960 log_error_link(link, "Failed to reset transient hostname");
964 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
969 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
970 sd_dhcp_lease *lease;
971 struct in_addr address;
972 struct in_addr netmask;
973 struct in_addr gateway;
980 r = sd_dhcp_client_get_lease(client, &lease);
982 log_warning_link(link, "DHCP error: no lease: %s",
987 r = sd_dhcp_lease_get_address(lease, &address);
989 log_warning_link(link, "DHCP error: no address: %s",
994 r = sd_dhcp_lease_get_netmask(lease, &netmask);
996 log_warning_link(link, "DHCP error: no netmask: %s",
1001 prefixlen = net_netmask_to_prefixlen(&netmask);
1003 r = sd_dhcp_lease_get_router(lease, &gateway);
1004 if (r < 0 && r != -ENOENT) {
1005 log_warning_link(link, "DHCP error: %s", strerror(-r));
1010 log_struct_link(LOG_INFO, link,
1011 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
1014 ADDRESS_FMT_VAL(address),
1016 ADDRESS_FMT_VAL(gateway),
1017 "ADDRESS=%u.%u.%u.%u",
1018 ADDRESS_FMT_VAL(address),
1021 "GATEWAY=%u.%u.%u.%u",
1022 ADDRESS_FMT_VAL(gateway),
1025 log_struct_link(LOG_INFO, link,
1026 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1029 ADDRESS_FMT_VAL(address),
1031 "ADDRESS=%u.%u.%u.%u",
1032 ADDRESS_FMT_VAL(address),
1037 link->dhcp_lease = lease;
1039 if (link->network->dhcp_mtu) {
1042 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1044 r = link_set_mtu(link, mtu);
1046 log_error_link(link, "Failed to set MTU "
1047 "to %" PRIu16, mtu);
1051 if (link->network->dhcp_hostname) {
1052 const char *hostname;
1054 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1056 r = link_set_hostname(link, hostname);
1058 log_error_link(link, "Failed to set transient hostname "
1059 "to '%s'", hostname);
1063 link_enter_set_addresses(link);
1068 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1069 Link *link = userdata;
1073 assert(link->network);
1074 assert(link->manager);
1076 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1080 case DHCP_EVENT_NO_LEASE:
1081 log_debug_link(link, "IP address in use.");
1083 case DHCP_EVENT_EXPIRED:
1084 case DHCP_EVENT_STOP:
1085 case DHCP_EVENT_IP_CHANGE:
1086 if (link->network->dhcp_critical) {
1087 log_error_link(link, "DHCPv4 connection considered system critical, "
1088 "ignoring request to reconfigure it.");
1092 if (link->dhcp_lease) {
1093 r = dhcp_lease_lost(link);
1095 link_enter_failed(link);
1100 if (event == DHCP_EVENT_IP_CHANGE) {
1101 r = dhcp_lease_acquired(client, link);
1103 link_enter_failed(link);
1108 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1109 if (!sd_ipv4ll_is_running(link->ipv4ll))
1110 r = sd_ipv4ll_start(link->ipv4ll);
1111 else if (ipv4ll_is_bound(link->ipv4ll))
1112 r = ipv4ll_address_update(link, false);
1114 link_enter_failed(link);
1120 case DHCP_EVENT_IP_ACQUIRE:
1121 r = dhcp_lease_acquired(client, link);
1123 link_enter_failed(link);
1127 if (ipv4ll_is_bound(link->ipv4ll))
1128 r = ipv4ll_address_update(link, true);
1130 r = sd_ipv4ll_stop(link->ipv4ll);
1132 link_enter_failed(link);
1139 log_warning_link(link, "DHCP error: %s", strerror(-event));
1141 log_warning_link(link, "DHCP unknown event: %d", event);
1148 static int ipv4ll_address_update(Link *link, bool deprecate) {
1150 struct in_addr addr;
1154 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1156 _cleanup_address_free_ Address *address = NULL;
1158 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1159 deprecate ? "deprecate" : "approve",
1160 ADDRESS_FMT_VAL(addr));
1162 r = address_new_dynamic(&address);
1164 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1168 address->family = AF_INET;
1169 address->in_addr.in = addr;
1170 address->prefixlen = 16;
1171 address->scope = RT_SCOPE_LINK;
1172 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1173 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1175 address_update(address, link, &address_update_handler);
1183 static int ipv4ll_address_lost(Link *link) {
1185 struct in_addr addr;
1189 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1191 _cleanup_address_free_ Address *address = NULL;
1192 _cleanup_route_free_ Route *route = NULL;
1194 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1195 ADDRESS_FMT_VAL(addr));
1197 r = address_new_dynamic(&address);
1199 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1203 address->family = AF_INET;
1204 address->in_addr.in = addr;
1205 address->prefixlen = 16;
1206 address->scope = RT_SCOPE_LINK;
1208 address_drop(address, link, &address_drop_handler);
1211 r = route_new_dynamic(&route);
1213 log_error_link(link, "Could not allocate route: %s",
1218 route->family = AF_INET;
1219 route->scope = RT_SCOPE_LINK;
1220 route->metrics = 99;
1222 route_drop(route, link, &route_drop_handler);
1229 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1231 struct in_addr addr;
1235 r = sd_ipv4ll_get_address(ll, &addr);
1241 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1242 struct in_addr address;
1248 r = sd_ipv4ll_get_address(ll, &address);
1252 log_struct_link(LOG_INFO, link,
1253 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1256 ADDRESS_FMT_VAL(address),
1259 link_enter_set_addresses(link);
1264 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1265 Link *link = userdata;
1269 assert(link->network);
1270 assert(link->manager);
1272 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1276 case IPV4LL_EVENT_STOP:
1277 case IPV4LL_EVENT_CONFLICT:
1278 r = ipv4ll_address_lost(link);
1280 link_enter_failed(link);
1284 case IPV4LL_EVENT_BIND:
1285 r = ipv4ll_address_claimed(ll, link);
1287 link_enter_failed(link);
1293 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1295 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1300 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1301 Link *link = userdata;
1304 assert(link->network);
1305 assert(link->manager);
1307 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1311 case DHCP6_EVENT_STOP:
1312 case DHCP6_EVENT_RESEND_EXPIRE:
1313 case DHCP6_EVENT_RETRANS_MAX:
1314 case DHCP6_EVENT_IP_ACQUIRE:
1315 log_debug_link(link, "DHCPv6 event %d", event);
1321 log_warning_link(link, "DHCPv6 error: %s",
1324 log_warning_link(link, "DHCPv6 unknown event: %d",
1330 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1331 Link *link = userdata;
1335 assert(link->network);
1336 assert(link->manager);
1338 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1342 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1343 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1346 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1347 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1352 log_warning_link(link, "ICMPv6 error: %s",
1355 log_warning_link(link, "ICMPv6 unknown event: %d",
1361 if (link->dhcp6_client)
1364 r = sd_dhcp6_client_new(&link->dhcp6_client);
1368 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1370 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1374 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1376 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1380 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1382 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1386 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1389 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1393 r = sd_dhcp6_client_start(link->dhcp6_client);
1395 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1398 static int link_acquire_conf(Link *link) {
1402 assert(link->network);
1403 assert(link->manager);
1404 assert(link->manager->event);
1406 if (link->network->ipv4ll) {
1407 assert(link->ipv4ll);
1409 log_debug_link(link, "acquiring IPv4 link-local address");
1411 r = sd_ipv4ll_start(link->ipv4ll);
1413 log_warning_link(link, "could not acquire IPv4 "
1414 "link-local address");
1419 if (link->network->dhcp) {
1420 assert(link->dhcp_client);
1422 log_debug_link(link, "acquiring DHCPv4 lease");
1424 r = sd_dhcp_client_start(link->dhcp_client);
1426 log_warning_link(link, "could not acquire DHCPv4 "
1432 if (link->network->dhcp6) {
1433 assert(link->icmp6_router_discovery);
1435 log_debug_link(link, "discovering IPv6 routers");
1437 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1439 log_warning_link(link, "could not start IPv6 router discovery");
1447 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1448 /* see Documentation/networking/operstates.txt in the kernel sources */
1450 if (operstate == IF_OPER_UP)
1453 if (operstate == IF_OPER_UNKNOWN)
1454 /* operstate may not be implemented, so fall back to flags */
1455 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1461 #define FLAG_STRING(string, flag, old, new) \
1462 (((old ^ new) & flag) \
1463 ? ((old & flag) ? (" -" string) : (" +" string)) \
1466 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1467 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1469 bool carrier_gained = false, carrier_lost = false;
1474 r = sd_rtnl_message_link_get_flags(m, &flags);
1476 log_warning_link(link, "Could not get link flags");
1480 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1482 /* if we got a message without operstate, take it to mean
1483 the state was unchanged */
1484 operstate = link->kernel_operstate;
1486 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1489 if (link->flags != flags) {
1490 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",
1491 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1492 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1493 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1494 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1495 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1496 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1497 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1498 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1499 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1500 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1501 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1502 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1503 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1504 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1505 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1506 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1507 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1508 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1509 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1511 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1512 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1513 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1514 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1515 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1516 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1517 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1518 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1520 /* link flags are currently at most 18 bits, let's align to printing 20 */
1521 if (unknown_flags_added)
1522 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1523 unknown_flags_added);
1525 if (unknown_flags_removed)
1526 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1527 unknown_flags_removed);
1530 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1531 link_has_carrier(flags, operstate);
1532 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1533 !link_has_carrier(flags, operstate);
1535 link->flags = flags;
1536 link->kernel_operstate = operstate;
1540 if (link->state == LINK_STATE_FAILED ||
1541 link->state == LINK_STATE_UNMANAGED)
1544 if (carrier_gained) {
1545 log_info_link(link, "gained carrier");
1547 if (link->network) {
1548 r = link_acquire_conf(link);
1550 link_enter_failed(link);
1554 } else if (carrier_lost) {
1555 log_info_link(link, "lost carrier");
1557 r = link_stop_clients(link);
1559 link_enter_failed(link);
1567 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1568 Link *link = userdata;
1573 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1578 r = sd_rtnl_message_get_errno(m);
1580 /* we warn but don't fail the link, as it may
1581 be brought up later */
1582 log_struct_link(LOG_WARNING, link,
1583 "MESSAGE=%-*s: could not bring up interface: %s",
1585 link->ifname, strerror(-r),
1595 static int link_up(Link *link) {
1596 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1600 assert(link->manager);
1601 assert(link->manager->rtnl);
1603 log_debug_link(link, "bringing link up");
1605 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1606 RTM_SETLINK, link->ifindex);
1608 log_error_link(link, "Could not allocate RTM_SETLINK message");
1612 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1614 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1618 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1620 log_error_link(link,
1621 "Could not send rtnetlink message: %s", strerror(-r));
1630 static int link_enslaved(Link *link) {
1634 assert(link->state == LINK_STATE_ENSLAVING);
1635 assert(link->network);
1637 if (!(link->flags & IFF_UP)) {
1640 link_enter_failed(link);
1645 if (!link->network->dhcp && !link->network->ipv4ll)
1646 return link_enter_set_addresses(link);
1651 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1652 Link *link = userdata;
1656 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1657 LINK_STATE_LINGER));
1658 assert(link->network);
1662 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1667 r = sd_rtnl_message_get_errno(m);
1669 log_struct_link(LOG_ERR, link,
1670 "MESSAGE=%-*s: could not enslave: %s",
1672 link->ifname, strerror(-r),
1675 link_enter_failed(link);
1680 log_debug_link(link, "enslaved");
1682 if (link->enslaving == 0)
1683 link_enslaved(link);
1690 static int link_enter_enslave(Link *link) {
1691 NetDev *vlan, *macvlan, *vxlan;
1696 assert(link->network);
1697 assert(link->state == LINK_STATE_INITIALIZING);
1699 link->state = LINK_STATE_ENSLAVING;
1703 if (!link->network->bridge &&
1704 !link->network->bond &&
1705 !link->network->tunnel &&
1706 hashmap_isempty(link->network->vlans) &&
1707 hashmap_isempty(link->network->macvlans) &&
1708 hashmap_isempty(link->network->vxlans))
1709 return link_enslaved(link);
1711 if (link->network->bond) {
1712 log_struct_link(LOG_DEBUG, link,
1713 "MESSAGE=%-*s: enslaving by '%s'",
1715 link->ifname, link->network->bond->ifname,
1716 NETDEV(link->network->bond),
1719 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1721 log_struct_link(LOG_WARNING, link,
1722 "MESSAGE=%-*s: could not enslave by '%s': %s",
1724 link->ifname, link->network->bond->ifname, strerror(-r),
1725 NETDEV(link->network->bond),
1727 link_enter_failed(link);
1735 if (link->network->bridge) {
1736 log_struct_link(LOG_DEBUG, link,
1737 "MESSAGE=%-*s: enslaving by '%s'",
1739 link->ifname, link->network->bridge->ifname,
1740 NETDEV(link->network->bridge),
1743 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1745 log_struct_link(LOG_WARNING, link,
1746 "MESSAGE=%-*s: could not enslave by '%s': %s",
1748 link->ifname, link->network->bridge->ifname, strerror(-r),
1749 NETDEV(link->network->bridge),
1751 link_enter_failed(link);
1759 if (link->network->tunnel) {
1760 log_struct_link(LOG_DEBUG, link,
1761 "MESSAGE=%-*s: enslaving by '%s'",
1763 link->ifname, link->network->tunnel->ifname,
1764 NETDEV(link->network->tunnel),
1767 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1769 log_struct_link(LOG_WARNING, link,
1770 "MESSAGE=%-*s: could not enslave by '%s': %s",
1772 link->ifname, link->network->tunnel->ifname, strerror(-r),
1773 NETDEV(link->network->tunnel),
1775 link_enter_failed(link);
1783 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1784 log_struct_link(LOG_DEBUG, link,
1785 "MESSAGE=%-*s: enslaving by '%s'",
1787 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1789 r = netdev_enslave(vlan, link, &enslave_handler);
1791 log_struct_link(LOG_WARNING, link,
1792 "MESSAGE=%-*s: could not enslave by '%s': %s",
1794 link->ifname, vlan->ifname, strerror(-r),
1795 NETDEV(vlan), NULL);
1796 link_enter_failed(link);
1804 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1805 log_struct_link(LOG_DEBUG, link,
1806 "MESSAGE=%-*s: enslaving by '%s'",
1808 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1810 r = netdev_enslave(macvlan, link, &enslave_handler);
1812 log_struct_link(LOG_WARNING, link,
1813 "MESSAGE=%-*s: could not enslave by '%s': %s",
1815 link->ifname, macvlan->ifname, strerror(-r),
1816 NETDEV(macvlan), NULL);
1817 link_enter_failed(link);
1825 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1826 log_struct_link(LOG_DEBUG, link,
1827 "MESSAGE=%*s: enslaving by '%s'",
1829 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1831 r = netdev_enslave(vxlan, link, &enslave_handler);
1833 log_struct_link(LOG_WARNING, link,
1834 "MESSAGE=%*s: could not enslave by '%s': %s",
1836 link->ifname, vxlan->ifname, strerror(-r),
1837 NETDEV(vxlan), NULL);
1838 link_enter_failed(link);
1849 static int link_configure(Link *link) {
1853 assert(link->state == LINK_STATE_INITIALIZING);
1855 if (link->network->ipv4ll) {
1858 r = sd_ipv4ll_new(&link->ipv4ll);
1862 if (link->udev_device) {
1863 r = net_get_unique_predictable_data(link->udev_device, seed);
1865 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1871 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1875 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1879 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1883 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1888 if (link->network->dhcp) {
1889 r = sd_dhcp_client_new(&link->dhcp_client);
1893 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1897 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1901 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1905 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1909 if (link->network->dhcp_mtu) {
1910 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1916 if (link->network->dhcp_server) {
1917 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1921 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1926 if (link->network->dhcp6) {
1927 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1931 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1936 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1941 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1946 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1947 icmp6_router_handler, link);
1952 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1953 r = link_acquire_conf(link);
1958 return link_enter_enslave(link);
1961 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1962 Link *link = userdata;
1967 assert(link->ifname);
1968 assert(link->manager);
1970 if (link->state != LINK_STATE_INITIALIZING)
1973 log_debug_link(link, "link state is up-to-date");
1975 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1977 link_enter_unmanaged(link);
1982 r = network_apply(link->manager, network, link);
1986 r = link_configure(link);
1993 int link_initialized(Link *link, struct udev_device *device) {
1994 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1998 assert(link->manager);
1999 assert(link->manager->rtnl);
2002 if (link->state != LINK_STATE_INITIALIZING)
2005 log_debug_link(link, "udev initialized link");
2007 link->udev_device = udev_device_ref(device);
2009 /* udev has initialized the link, but we don't know if we have yet processed
2010 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
2011 we know that the pending NEWLINKs have already been processed and that we
2014 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
2018 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
2025 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
2026 Manager *m = userdata;
2029 _cleanup_address_free_ Address *address = NULL;
2031 char buf[INET6_ADDRSTRLEN];
2032 bool address_dropped = false;
2039 r = sd_rtnl_message_get_type(message, &type);
2041 log_warning("rtnl: could not get message type");
2045 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2046 if (r < 0 || ifindex <= 0) {
2047 log_warning("rtnl: received address message without valid ifindex, ignoring");
2050 r = link_get(m, ifindex, &link);
2051 if (r < 0 || !link) {
2052 log_warning("rtnl: received address for a nonexistent link, ignoring");
2057 r = address_new_dynamic(&address);
2061 r = sd_rtnl_message_addr_get_family(message, &address->family);
2062 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
2063 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
2067 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2069 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2073 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2075 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
2079 switch (address->family) {
2081 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2083 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2090 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2092 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2099 assert_not_reached("invalid address family");
2102 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
2103 log_warning_link(link, "could not print address");
2107 LIST_FOREACH(addresses, ad, link->addresses) {
2108 if (address_equal(ad, address)) {
2109 LIST_REMOVE(addresses, link->addresses, ad);
2113 address_dropped = true;
2121 if (!address_dropped)
2122 log_debug_link(link, "added address: %s/%u", buf,
2123 address->prefixlen);
2125 LIST_PREPEND(addresses, link->addresses, address);
2132 if (address_dropped) {
2133 log_debug_link(link, "removed address: %s/%u", buf,
2134 address->prefixlen);
2141 assert_not_reached("Received invalid RTNL message type");
2147 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2148 Link *link = userdata;
2155 for (; m; m = sd_rtnl_message_next(m)) {
2156 r = sd_rtnl_message_get_errno(m);
2158 log_debug_link(link, "getting address failed: %s", strerror(-r));
2162 r = link_rtnl_process_address(rtnl, m, link->manager);
2164 log_warning_link(link, "could not process address: %s", strerror(-r));
2170 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2172 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2173 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2174 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2182 r = link_new(m, message, ret);
2188 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2190 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2194 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2198 if (detect_container(NULL) <= 0) {
2199 /* not in a container, udev will be around */
2200 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2201 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2203 log_warning_link(link, "could not find udev device");
2207 if (udev_device_get_is_initialized(device) <= 0) {
2209 log_debug_link(link, "udev initializing link...");
2213 r = link_initialized(link, device);
2217 r = link_initialized_and_synced(m->rtnl, NULL, link);
2225 int link_update(Link *link, sd_rtnl_message *m) {
2226 struct ether_addr mac;
2231 assert(link->ifname);
2234 if (link->state == LINK_STATE_LINGER) {
2236 log_info_link(link, "link readded");
2237 link->state = LINK_STATE_ENSLAVING;
2240 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2241 if (r >= 0 && !streq(ifname, link->ifname)) {
2242 log_info_link(link, "renamed to %s", ifname);
2245 link->ifname = strdup(ifname);
2250 if (!link->original_mtu) {
2251 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2253 log_debug_link(link, "saved original MTU: %"
2254 PRIu16, link->original_mtu);
2257 /* The kernel may broadcast NEWLINK messages without the MAC address
2258 set, simply ignore them. */
2259 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2261 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2263 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2265 log_debug_link(link, "MAC address: "
2266 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2267 mac.ether_addr_octet[0],
2268 mac.ether_addr_octet[1],
2269 mac.ether_addr_octet[2],
2270 mac.ether_addr_octet[3],
2271 mac.ether_addr_octet[4],
2272 mac.ether_addr_octet[5]);
2275 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2277 log_warning_link(link, "Could not update MAC "
2278 "address in IPv4LL client: %s",
2284 if (link->dhcp_client) {
2285 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2287 log_warning_link(link, "Could not update MAC "
2288 "address in DHCP client: %s",
2294 if (link->dhcp6_client) {
2295 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2298 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2306 return link_update_flags(link, m);
2309 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2318 fprintf(f, "%s=", key);
2320 LIST_FOREACH(addresses, ad, address) {
2321 char buf[INET6_ADDRSTRLEN];
2323 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2324 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2330 static void link_update_operstate(Link *link) {
2334 if (link->kernel_operstate == IF_OPER_DORMANT)
2335 link->operstate = LINK_OPERSTATE_DORMANT;
2336 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2338 uint8_t scope = RT_SCOPE_NOWHERE;
2340 /* if we have carrier, check what addresses we have */
2341 LIST_FOREACH(addresses, address, link->addresses) {
2342 if (address->scope < scope)
2343 scope = address->scope;
2346 if (scope < RT_SCOPE_SITE)
2347 /* universally accessible addresses found */
2348 link->operstate = LINK_OPERSTATE_ROUTABLE;
2349 else if (scope < RT_SCOPE_HOST)
2350 /* only link or site local addresses found */
2351 link->operstate = LINK_OPERSTATE_DEGRADED;
2353 /* no useful addresses found */
2354 link->operstate = LINK_OPERSTATE_CARRIER;
2356 link->operstate = LINK_OPERSTATE_UNKNOWN;
2359 int link_save(Link *link) {
2360 _cleanup_free_ char *temp_path = NULL;
2361 _cleanup_fclose_ FILE *f = NULL;
2362 const char *admin_state, *oper_state;
2366 assert(link->state_file);
2367 assert(link->lease_file);
2368 assert(link->manager);
2370 link_update_operstate(link);
2372 r = manager_save(link->manager);
2376 if (link->state == LINK_STATE_LINGER) {
2377 unlink(link->state_file);
2381 admin_state = link_state_to_string(link->state);
2382 assert(admin_state);
2384 oper_state = link_operstate_to_string(link->operstate);
2387 r = fopen_temporary(link->state_file, &f, &temp_path);
2391 fchmod(fileno(f), 0644);
2394 "# This is private data. Do not parse.\n"
2398 admin_state, oper_state, link->flags);
2400 if (link->network) {
2401 serialize_addresses(f, "DNS", link->network->dns);
2402 serialize_addresses(f, "NTP", link->network->ntp);
2405 if (link->dhcp_lease) {
2406 assert(link->network);
2408 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2415 "DHCP_USE_NTP=%s\n",
2417 yes_no(link->network->dhcp_dns),
2418 yes_no(link->network->dhcp_ntp));
2420 unlink(link->lease_file);
2424 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2426 unlink(link->state_file);
2432 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2437 static const char* const link_state_table[_LINK_STATE_MAX] = {
2438 [LINK_STATE_INITIALIZING] = "initializing",
2439 [LINK_STATE_ENSLAVING] = "configuring",
2440 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2441 [LINK_STATE_SETTING_ROUTES] = "configuring",
2442 [LINK_STATE_CONFIGURED] = "configured",
2443 [LINK_STATE_UNMANAGED] = "unmanaged",
2444 [LINK_STATE_FAILED] = "failed",
2445 [LINK_STATE_LINGER] = "linger",
2448 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2450 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2451 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2452 [LINK_OPERSTATE_DORMANT] = "dormant",
2453 [LINK_OPERSTATE_CARRIER] = "carrier",
2454 [LINK_OPERSTATE_DEGRADED] = "degraded",
2455 [LINK_OPERSTATE_ROUTABLE] = "routable",
2458 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);