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 "networkd-link.h"
27 #include "networkd-netdev.h"
28 #include "libudev-private.h"
29 #include "udev-util.h"
33 #include "network-internal.h"
34 #include "conf-parser.h"
36 #include "dhcp-lease-internal.h"
38 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
39 _cleanup_link_unref_ Link *link = NULL;
48 r = sd_rtnl_message_get_type(message, &type);
51 else if (type != RTM_NEWLINK)
54 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
57 else if (ifindex <= 0)
60 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
69 link->manager = manager;
70 link->state = LINK_STATE_INITIALIZING;
71 link->ifindex = ifindex;
72 link->ifname = strdup(ifname);
76 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
78 log_debug_link(link, "MAC address not found for new device, continuing without");
80 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex);
84 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex);
88 r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
92 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
102 static void link_free(Link *link) {
108 while ((address = link->addresses)) {
109 LIST_REMOVE(addresses, link->addresses, address);
110 address_free(address);
113 while ((address = link->pool_addresses)) {
114 LIST_REMOVE(addresses, link->pool_addresses, address);
115 address_free(address);
118 sd_dhcp_client_unref(link->dhcp_client);
119 sd_dhcp_lease_unref(link->dhcp_lease);
121 unlink(link->lease_file);
122 free(link->lease_file);
124 sd_ipv4ll_unref(link->ipv4ll);
125 sd_dhcp6_client_unref(link->dhcp6_client);
126 sd_icmp6_nd_unref(link->icmp6_router_discovery);
129 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
133 unlink(link->state_file);
134 free(link->state_file);
136 udev_device_unref(link->udev_device);
141 Link *link_unref(Link *link) {
142 if (link && (-- link->n_ref <= 0))
148 Link *link_ref(Link *link) {
150 assert_se(++ link->n_ref >= 2);
155 int link_get(Manager *m, int ifindex, Link **ret) {
162 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
171 void link_drop(Link *link) {
172 if (!link || link->state == LINK_STATE_LINGER)
175 link->state = LINK_STATE_LINGER;
177 log_debug_link(link, "link removed");
184 static void link_enter_unmanaged(Link *link) {
187 log_debug_link(link, "unmanaged");
189 link->state = LINK_STATE_UNMANAGED;
194 static int link_stop_clients(Link *link) {
198 assert(link->manager);
199 assert(link->manager->event);
204 if (link->dhcp_client) {
205 k = sd_dhcp_client_stop(link->dhcp_client);
207 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
213 k = sd_ipv4ll_stop(link->ipv4ll);
215 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
220 if (link->dhcp_server) {
221 k = sd_dhcp_server_stop(link->dhcp_server);
223 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
228 if(link->icmp6_router_discovery) {
230 if (link->dhcp6_client) {
231 k = sd_dhcp6_client_stop(link->dhcp6_client);
233 log_warning_link(link, "Could not stop DHCPv6 client: %s", strerror(-r));
238 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
240 log_warning_link(link, "Could not stop ICMPv6 router discovery: %s", strerror(-r));
248 static void link_enter_failed(Link *link) {
251 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
254 log_warning_link(link, "failed");
256 link->state = LINK_STATE_FAILED;
258 link_stop_clients(link);
263 static Address* link_find_dhcp_server_address(Link *link) {
267 assert(link->network);
269 /* The the first statically configured address if there is any */
270 LIST_FOREACH(addresses, address, link->network->static_addresses) {
272 if (address->family != AF_INET)
275 if (in_addr_is_null(address->family, &address->in_addr))
281 /* If that didn't work, find a suitable address we got from the pool */
282 LIST_FOREACH(addresses, address, link->pool_addresses) {
283 if (address->family != AF_INET)
292 static int link_enter_configured(Link *link) {
296 assert(link->network);
297 assert(link->state == LINK_STATE_SETTING_ROUTES);
299 if (link->network->dhcp_server &&
300 !sd_dhcp_server_is_running(link->dhcp_server)) {
301 struct in_addr pool_start;
304 address = link_find_dhcp_server_address(link);
306 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
307 link_enter_failed(link);
311 log_debug_link(link, "offering DHCPv4 leases");
313 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in, address->prefixlen);
317 /* offer 32 addresses starting from the address following the server address */
318 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
319 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
325 r = sd_dhcp_server_set_router(link->dhcp_server,
326 &main_address->in_addr.in);
330 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
331 main_address->prefixlen);
336 r = sd_dhcp_server_start(link->dhcp_server);
338 log_warning_link(link, "could not start DHCPv4 server "
339 "instance: %s", strerror(-r));
341 link_enter_failed(link);
347 log_info_link(link, "link configured");
349 link->state = LINK_STATE_CONFIGURED;
356 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
357 _cleanup_link_unref_ Link *link = userdata;
360 assert(link->route_messages > 0);
361 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
362 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
365 link->route_messages --;
367 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER))
370 r = sd_rtnl_message_get_errno(m);
371 if (r < 0 && r != -EEXIST)
372 log_struct_link(LOG_WARNING, link,
373 "MESSAGE=%-*s: could not set route: %s",
375 link->ifname, strerror(-r),
379 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
381 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
382 log_debug_link(link, "routes set");
383 link_enter_configured(link);
389 static int link_set_dhcp_routes(Link *link) {
390 struct sd_dhcp_route *static_routes;
395 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
398 log_warning_link(link, "DHCP error: could not get routes: %s", strerror(-n));
402 for (i = 0; i < n; i++) {
403 _cleanup_route_free_ Route *route = NULL;
405 r = route_new_dynamic(&route, RTPROT_DHCP);
407 log_error_link(link, "Could not allocate route: %s",
412 route->family = AF_INET;
413 route->in_addr.in = static_routes[i].gw_addr;
414 route->dst_addr.in = static_routes[i].dst_addr;
415 route->dst_prefixlen = static_routes[i].dst_prefixlen;
416 route->metrics = DHCP_ROUTE_METRIC;
418 r = route_configure(route, link, &route_handler);
420 log_warning_link(link,
421 "could not set host route: %s", strerror(-r));
425 link->route_messages ++;
431 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
438 r = sd_ipv4ll_get_address(ll, &addr);
445 static int link_enter_set_routes(Link *link) {
450 assert(link->network);
451 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
453 link->state = LINK_STATE_SETTING_ROUTES;
455 LIST_FOREACH(routes, rt, link->network->static_routes) {
456 r = route_configure(rt, link, &route_handler);
458 log_warning_link(link,
459 "could not set routes: %s", strerror(-r));
460 link_enter_failed(link);
464 link->route_messages ++;
467 if (ipv4ll_is_bound(link->ipv4ll)) {
468 _cleanup_route_free_ Route *route = NULL;
470 r = route_new_dynamic(&route, RTPROT_STATIC);
472 log_error_link(link, "Could not allocate route: %s",
477 route->family = AF_INET;
478 route->scope = RT_SCOPE_LINK;
479 route->metrics = IPV4LL_ROUTE_METRIC;
481 r = route_configure(route, link, &route_handler);
483 log_warning_link(link,
484 "could not set routes: %s", strerror(-r));
485 link_enter_failed(link);
489 link->route_messages ++;
492 if (link->dhcp_lease) {
493 _cleanup_route_free_ Route *route = NULL;
494 _cleanup_route_free_ Route *route_gw = NULL;
495 struct in_addr gateway;
497 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
498 if (r < 0 && r != -ENOENT) {
499 log_warning_link(link, "DHCP error: could not get gateway: %s",
505 r = route_new_dynamic(&route, RTPROT_DHCP);
507 log_error_link(link, "Could not allocate route: %s",
512 r = route_new_dynamic(&route_gw, RTPROT_DHCP);
514 log_error_link(link, "Could not allocate route: %s",
519 /* The dhcp netmask may mask out the gateway. Add an explicit
520 * route for the gw host so that we can route no matter the
521 * netmask or existing kernel route tables. */
522 route_gw->family = AF_INET;
523 route_gw->dst_addr.in = gateway;
524 route_gw->dst_prefixlen = 32;
525 route_gw->scope = RT_SCOPE_LINK;
526 route_gw->metrics = DHCP_ROUTE_METRIC;
528 r = route_configure(route_gw, link, &route_handler);
530 log_warning_link(link,
531 "could not set host route: %s", strerror(-r));
535 link->route_messages ++;
537 route->family = AF_INET;
538 route->in_addr.in = gateway;
539 route->metrics = DHCP_ROUTE_METRIC;
541 r = route_configure(route, link, &route_handler);
543 log_warning_link(link,
544 "could not set routes: %s", strerror(-r));
545 link_enter_failed(link);
549 link->route_messages ++;
552 if (link->network->dhcp_routes)
553 link_set_dhcp_routes(link);
556 if (link->route_messages == 0) {
557 link_enter_configured(link);
559 log_debug_link(link, "setting routes");
564 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
565 _cleanup_link_unref_ Link *link = userdata;
570 assert(link->ifname);
572 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
575 r = sd_rtnl_message_get_errno(m);
576 if (r < 0 && r != -ESRCH)
577 log_struct_link(LOG_WARNING, link,
578 "MESSAGE=%-*s: could not drop route: %s",
580 link->ifname, strerror(-r),
587 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
588 _cleanup_link_unref_ Link *link = userdata;
594 assert(link->manager);
596 for (; m; m = sd_rtnl_message_next(m)) {
597 r = sd_rtnl_message_get_errno(m);
599 log_debug_link(link, "getting address failed: %s", strerror(-r));
603 r = link_rtnl_process_address(rtnl, m, link->manager);
605 log_warning_link(link, "could not process address: %s", strerror(-r));
611 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
612 _cleanup_link_unref_ Link *link = userdata;
618 assert(link->ifname);
619 assert(link->addr_messages > 0);
620 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
621 LINK_STATE_FAILED, LINK_STATE_LINGER));
623 link->addr_messages --;
625 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
628 r = sd_rtnl_message_get_errno(m);
629 if (r < 0 && r != -EEXIST)
630 log_struct_link(LOG_WARNING, link,
631 "MESSAGE=%-*s: could not set address: %s",
633 link->ifname, strerror(-r),
637 /* calling handler directly so take a ref */
639 link_get_address_handler(rtnl, m, link);
642 if (link->addr_messages == 0) {
643 log_debug_link(link, "addresses set");
644 link_enter_set_routes(link);
650 static int link_enter_set_addresses(Link *link) {
653 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
656 assert(link->network);
657 assert(link->state != _LINK_STATE_INVALID);
659 link->state = LINK_STATE_SETTING_ADDRESSES;
661 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
662 r = address_configure(ad, link, &address_handler);
664 log_warning_link(link,
665 "could not set addresses: %s", strerror(-r));
666 link_enter_failed(link);
670 link->addr_messages ++;
674 _cleanup_address_free_ Address *ll_addr = NULL;
677 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
678 if (r < 0 && r != -ENOENT) {
679 log_warning_link(link, "IPV4LL error: no address: %s",
685 r = address_new_dynamic(&ll_addr);
687 log_error_link(link, "Could not allocate address: %s", strerror(-r));
691 ll_addr->family = AF_INET;
692 ll_addr->in_addr.in = addr;
693 ll_addr->prefixlen = 16;
694 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
695 ll_addr->scope = RT_SCOPE_LINK;
697 r = address_configure(ll_addr, link, &address_handler);
699 log_warning_link(link,
700 "could not set addresses: %s", strerror(-r));
701 link_enter_failed(link);
705 link->addr_messages ++;
709 if (link->dhcp_lease) {
710 _cleanup_address_free_ Address *address = NULL;
712 struct in_addr netmask;
715 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
717 log_warning_link(link, "DHCP error: no address: %s",
722 if (!link->network->dhcp_critical) {
723 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
726 log_warning_link(link, "DHCP error: no lifetime: %s",
732 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
734 log_warning_link(link, "DHCP error: no netmask: %s",
739 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
741 r = address_new_dynamic(&address);
743 log_error_link(link, "Could not allocate address: %s",
748 address->family = AF_INET;
749 address->in_addr.in = addr;
750 address->cinfo.ifa_prefered = lifetime;
751 address->cinfo.ifa_valid = lifetime;
752 address->prefixlen = prefixlen;
753 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
755 /* use update rather than configure so that we will update the lifetime
756 of an existing address if it has already been configured */
757 r = address_update(address, link, &address_handler);
759 log_warning_link(link,
760 "could not set addresses: %s", strerror(-r));
761 link_enter_failed(link);
765 link->addr_messages ++;
768 if (link->addr_messages == 0) {
769 link_enter_set_routes(link);
771 log_debug_link(link, "setting addresses");
776 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
777 _cleanup_link_unref_ Link *link = userdata;
782 assert(link->ifname);
784 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
787 r = sd_rtnl_message_get_errno(m);
788 if (r < 0 && r != -EADDRNOTAVAIL)
789 log_struct_link(LOG_WARNING, link,
790 "MESSAGE=%-*s: could not drop address: %s",
792 link->ifname, strerror(-r),
799 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
800 _cleanup_link_unref_ Link *link = userdata;
805 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
808 r = sd_bus_message_get_errno(m);
812 log_warning_link(link, "Could not set hostname: %s", strerror(r));
817 static int link_set_hostname(Link *link, const char *hostname) {
818 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
822 assert(link->manager);
825 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
827 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
828 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
832 r = sd_bus_message_new_method_call(
835 "org.freedesktop.hostname1",
836 "/org/freedesktop/hostname1",
837 "org.freedesktop.hostname1",
842 r = sd_bus_message_append(m, "sb", hostname, false);
846 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
848 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
857 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
858 _cleanup_link_unref_ Link *link = userdata;
863 assert(link->ifname);
865 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
868 r = sd_rtnl_message_get_errno(m);
870 log_struct_link(LOG_WARNING, link,
871 "MESSAGE=%-*s: could not set MTU: %s",
872 IFNAMSIZ, link->ifname, strerror(-r),
879 static int link_set_mtu(Link *link, uint32_t mtu) {
880 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
884 assert(link->manager);
885 assert(link->manager->rtnl);
887 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
889 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
890 RTM_SETLINK, link->ifindex);
892 log_error_link(link, "Could not allocate RTM_SETLINK message");
896 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
898 log_error_link(link, "Could not append MTU: %s", strerror(-r));
902 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
905 "Could not send rtnetlink message: %s", strerror(-r));
914 static int dhcp_lease_lost(Link *link) {
915 _cleanup_address_free_ Address *address = NULL;
917 struct in_addr netmask;
918 struct in_addr gateway;
923 assert(link->dhcp_lease);
925 log_warning_link(link, "DHCP lease lost");
927 if (link->network->dhcp_routes) {
928 struct sd_dhcp_route *routes;
931 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes);
933 for (i = 0; i < n; i++) {
934 _cleanup_route_free_ Route *route = NULL;
936 r = route_new_dynamic(&route, RTPROT_UNSPEC);
938 route->family = AF_INET;
939 route->in_addr.in = routes[i].gw_addr;
940 route->dst_addr.in = routes[i].dst_addr;
941 route->dst_prefixlen = routes[i].dst_prefixlen;
943 route_drop(route, link, &route_drop_handler);
949 r = address_new_dynamic(&address);
951 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
953 _cleanup_route_free_ Route *route_gw = NULL;
954 _cleanup_route_free_ Route *route = NULL;
956 r = route_new_dynamic(&route_gw, RTPROT_UNSPEC);
958 route_gw->family = AF_INET;
959 route_gw->dst_addr.in = gateway;
960 route_gw->dst_prefixlen = 32;
961 route_gw->scope = RT_SCOPE_LINK;
963 route_drop(route_gw, link, &route_drop_handler);
966 r = route_new_dynamic(&route, RTPROT_UNSPEC);
968 route->family = AF_INET;
969 route->in_addr.in = gateway;
971 route_drop(route, link, &route_drop_handler);
975 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
976 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
977 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
979 address->family = AF_INET;
980 address->in_addr.in = addr;
981 address->prefixlen = prefixlen;
983 address_drop(address, link, &address_drop_handler);
986 if (link->network->dhcp_mtu) {
989 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
990 if (r >= 0 && link->original_mtu != mtu) {
991 r = link_set_mtu(link, link->original_mtu);
993 log_warning_link(link, "DHCP error: could not reset MTU");
994 link_enter_failed(link);
1000 if (link->network->dhcp_hostname) {
1001 const char *hostname = NULL;
1003 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
1004 if (r >= 0 && hostname) {
1005 r = link_set_hostname(link, "");
1007 log_error_link(link, "Failed to reset transient hostname");
1011 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
1016 static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
1017 sd_dhcp_lease *lease;
1020 r = sd_dhcp_client_get_lease(client, &lease);
1022 log_warning_link(link, "DHCP error: no lease %s",
1027 sd_dhcp_lease_unref(link->dhcp_lease);
1028 link->dhcp_lease = lease;
1030 link_enter_set_addresses(link);
1035 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1036 sd_dhcp_lease *lease;
1037 struct in_addr address;
1038 struct in_addr netmask;
1039 struct in_addr gateway;
1046 r = sd_dhcp_client_get_lease(client, &lease);
1048 log_warning_link(link, "DHCP error: no lease: %s",
1053 r = sd_dhcp_lease_get_address(lease, &address);
1055 log_warning_link(link, "DHCP error: no address: %s",
1060 r = sd_dhcp_lease_get_netmask(lease, &netmask);
1062 log_warning_link(link, "DHCP error: no netmask: %s",
1067 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
1069 r = sd_dhcp_lease_get_router(lease, &gateway);
1070 if (r < 0 && r != -ENOENT) {
1071 log_warning_link(link, "DHCP error: could not get gateway: %s",
1077 log_struct_link(LOG_INFO, link,
1078 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
1081 ADDRESS_FMT_VAL(address),
1083 ADDRESS_FMT_VAL(gateway),
1084 "ADDRESS=%u.%u.%u.%u",
1085 ADDRESS_FMT_VAL(address),
1088 "GATEWAY=%u.%u.%u.%u",
1089 ADDRESS_FMT_VAL(gateway),
1092 log_struct_link(LOG_INFO, link,
1093 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1096 ADDRESS_FMT_VAL(address),
1098 "ADDRESS=%u.%u.%u.%u",
1099 ADDRESS_FMT_VAL(address),
1104 link->dhcp_lease = lease;
1106 if (link->network->dhcp_mtu) {
1109 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1111 r = link_set_mtu(link, mtu);
1113 log_error_link(link, "Failed to set MTU "
1114 "to %" PRIu16, mtu);
1118 if (link->network->dhcp_hostname) {
1119 const char *hostname;
1121 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1123 r = link_set_hostname(link, hostname);
1125 log_error_link(link, "Failed to set transient hostname "
1126 "to '%s'", hostname);
1130 link_enter_set_addresses(link);
1135 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1136 Link *link = userdata;
1140 assert(link->network);
1141 assert(link->manager);
1143 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1147 case DHCP_EVENT_EXPIRED:
1148 case DHCP_EVENT_STOP:
1149 case DHCP_EVENT_IP_CHANGE:
1150 if (link->network->dhcp_critical) {
1151 log_error_link(link, "DHCPv4 connection considered system critical, "
1152 "ignoring request to reconfigure it.");
1156 if (link->dhcp_lease) {
1157 r = dhcp_lease_lost(link);
1159 link_enter_failed(link);
1164 if (event == DHCP_EVENT_IP_CHANGE) {
1165 r = dhcp_lease_acquired(client, link);
1167 link_enter_failed(link);
1173 case DHCP_EVENT_RENEW:
1174 r = dhcp_lease_renew(client, link);
1176 link_enter_failed(link);
1180 case DHCP_EVENT_IP_ACQUIRE:
1181 r = dhcp_lease_acquired(client, link);
1183 link_enter_failed(link);
1189 log_warning_link(link, "DHCP error: client failed: %s", strerror(-event));
1191 log_warning_link(link, "DHCP unknown event: %d", event);
1198 static int ipv4ll_address_lost(Link *link) {
1200 struct in_addr addr;
1204 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1206 _cleanup_address_free_ Address *address = NULL;
1207 _cleanup_route_free_ Route *route = NULL;
1209 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1210 ADDRESS_FMT_VAL(addr));
1212 r = address_new_dynamic(&address);
1214 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1218 address->family = AF_INET;
1219 address->in_addr.in = addr;
1220 address->prefixlen = 16;
1221 address->scope = RT_SCOPE_LINK;
1223 address_drop(address, link, &address_drop_handler);
1225 r = route_new_dynamic(&route, RTPROT_UNSPEC);
1227 log_error_link(link, "Could not allocate route: %s",
1232 route->family = AF_INET;
1233 route->scope = RT_SCOPE_LINK;
1234 route->metrics = 99;
1236 route_drop(route, link, &route_drop_handler);
1242 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1243 struct in_addr address;
1249 r = sd_ipv4ll_get_address(ll, &address);
1253 log_struct_link(LOG_INFO, link,
1254 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1257 ADDRESS_FMT_VAL(address),
1260 link_enter_set_addresses(link);
1265 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1266 Link *link = userdata;
1270 assert(link->network);
1271 assert(link->manager);
1273 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1277 case IPV4LL_EVENT_STOP:
1278 case IPV4LL_EVENT_CONFLICT:
1279 r = ipv4ll_address_lost(link);
1281 link_enter_failed(link);
1285 case IPV4LL_EVENT_BIND:
1286 r = ipv4ll_address_claimed(ll, link);
1288 link_enter_failed(link);
1294 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1296 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1301 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1302 Link *link = userdata;
1305 assert(link->network);
1306 assert(link->manager);
1308 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1312 case DHCP6_EVENT_STOP:
1313 case DHCP6_EVENT_RESEND_EXPIRE:
1314 case DHCP6_EVENT_RETRANS_MAX:
1315 case DHCP6_EVENT_IP_ACQUIRE:
1316 log_debug_link(link, "DHCPv6 event %d", event);
1322 log_warning_link(link, "DHCPv6 error: %s",
1325 log_warning_link(link, "DHCPv6 unknown event: %d",
1331 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1332 Link *link = userdata;
1336 assert(link->network);
1337 assert(link->manager);
1339 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1343 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1344 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1347 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1348 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1353 log_warning_link(link, "ICMPv6 error: %s",
1356 log_warning_link(link, "ICMPv6 unknown event: %d",
1362 if (link->dhcp6_client)
1365 r = sd_dhcp6_client_new(&link->dhcp6_client);
1369 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1371 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1375 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1377 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1381 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1383 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1387 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1390 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1394 r = sd_dhcp6_client_start(link->dhcp6_client);
1396 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1399 static int link_acquire_conf(Link *link) {
1403 assert(link->network);
1404 assert(link->manager);
1405 assert(link->manager->event);
1407 if (link->network->ipv4ll) {
1408 assert(link->ipv4ll);
1410 log_debug_link(link, "acquiring IPv4 link-local address");
1412 r = sd_ipv4ll_start(link->ipv4ll);
1414 log_warning_link(link, "could not acquire IPv4 "
1415 "link-local address");
1420 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1421 assert(link->dhcp_client);
1423 log_debug_link(link, "acquiring DHCPv4 lease");
1425 r = sd_dhcp_client_start(link->dhcp_client);
1427 log_warning_link(link, "could not acquire DHCPv4 "
1433 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1434 assert(link->icmp6_router_discovery);
1436 log_debug_link(link, "discovering IPv6 routers");
1438 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1440 log_warning_link(link, "could not start IPv6 router discovery");
1448 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1449 /* see Documentation/networking/operstates.txt in the kernel sources */
1451 if (operstate == IF_OPER_UP)
1454 if (operstate == IF_OPER_UNKNOWN)
1455 /* operstate may not be implemented, so fall back to flags */
1456 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1462 #define FLAG_STRING(string, flag, old, new) \
1463 (((old ^ new) & flag) \
1464 ? ((old & flag) ? (" -" string) : (" +" string)) \
1467 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1468 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1470 bool carrier_gained = false, carrier_lost = false;
1475 r = sd_rtnl_message_link_get_flags(m, &flags);
1477 log_warning_link(link, "Could not get link flags");
1481 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1483 /* if we got a message without operstate, take it to mean
1484 the state was unchanged */
1485 operstate = link->kernel_operstate;
1487 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1490 if (link->flags != flags) {
1491 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",
1492 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1493 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1494 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1495 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1496 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1497 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1498 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1499 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1500 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1501 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1502 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1503 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1504 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1505 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1506 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1507 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1508 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1509 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1510 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1512 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1513 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1514 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1515 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1516 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1517 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1518 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1519 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1521 /* link flags are currently at most 18 bits, let's align to printing 20 */
1522 if (unknown_flags_added)
1523 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1524 unknown_flags_added);
1526 if (unknown_flags_removed)
1527 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1528 unknown_flags_removed);
1531 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1532 link_has_carrier(flags, operstate);
1533 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1534 !link_has_carrier(flags, operstate);
1536 link->flags = flags;
1537 link->kernel_operstate = operstate;
1541 if (link->state == LINK_STATE_FAILED ||
1542 link->state == LINK_STATE_UNMANAGED)
1545 if (carrier_gained) {
1546 log_info_link(link, "gained carrier");
1548 if (link->network) {
1549 r = link_acquire_conf(link);
1551 link_enter_failed(link);
1555 } else if (carrier_lost) {
1556 log_info_link(link, "lost carrier");
1558 r = link_stop_clients(link);
1560 link_enter_failed(link);
1568 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1569 _cleanup_link_unref_ Link *link = userdata;
1574 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1577 r = sd_rtnl_message_get_errno(m);
1579 /* we warn but don't fail the link, as it may
1580 be brought up later */
1581 log_struct_link(LOG_WARNING, link,
1582 "MESSAGE=%-*s: could not bring up interface: %s",
1584 link->ifname, strerror(-r),
1592 static int link_up(Link *link) {
1593 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1597 assert(link->manager);
1598 assert(link->manager->rtnl);
1600 log_debug_link(link, "bringing link up");
1602 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1603 RTM_SETLINK, link->ifindex);
1605 log_error_link(link, "Could not allocate RTM_SETLINK message");
1609 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1611 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1615 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1617 log_error_link(link,
1618 "Could not send rtnetlink message: %s", strerror(-r));
1627 static int link_joined(Link *link) {
1631 assert(link->state == LINK_STATE_ENSLAVING);
1632 assert(link->network);
1634 if (!(link->flags & IFF_UP)) {
1637 link_enter_failed(link);
1642 return link_enter_set_addresses(link);
1645 static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1646 _cleanup_link_unref_ Link *link = userdata;
1650 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1651 LINK_STATE_LINGER));
1652 assert(link->network);
1656 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1659 r = sd_rtnl_message_get_errno(m);
1660 if (r < 0 && r != -EEXIST) {
1661 log_struct_link(LOG_ERR, link,
1662 "MESSAGE=%-*s: could not join netdev: %s",
1664 link->ifname, strerror(-r),
1667 link_enter_failed(link);
1670 log_debug_link(link, "joined netdev");
1672 if (link->enslaving <= 0)
1678 static int link_enter_join_netdev(Link *link) {
1684 assert(link->network);
1685 assert(link->state == LINK_STATE_INITIALIZING);
1687 link->state = LINK_STATE_ENSLAVING;
1691 if (!link->network->bridge &&
1692 !link->network->bond &&
1693 hashmap_isempty(link->network->stacked_netdevs))
1694 return link_joined(link);
1696 if (link->network->bond) {
1697 log_struct_link(LOG_DEBUG, link,
1698 "MESSAGE=%-*s: enslaving by '%s'",
1700 link->ifname, link->network->bond->ifname,
1701 NETDEVIF(link->network->bond),
1704 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1706 log_struct_link(LOG_WARNING, link,
1707 "MESSAGE=%-*s: could not join netdev '%s': %s",
1709 link->ifname, link->network->bond->ifname, strerror(-r),
1710 NETDEVIF(link->network->bond),
1712 link_enter_failed(link);
1719 if (link->network->bridge) {
1720 log_struct_link(LOG_DEBUG, link,
1721 "MESSAGE=%-*s: enslaving by '%s'",
1723 link->ifname, link->network->bridge->ifname,
1724 NETDEVIF(link->network->bridge),
1727 r = netdev_join(link->network->bridge, link, &netdev_join_handler);
1729 log_struct_link(LOG_WARNING, link,
1730 "MESSAGE=%-*s: could not join netdev '%s': %s",
1732 link->ifname, link->network->bridge->ifname, strerror(-r),
1733 NETDEVIF(link->network->bridge),
1735 link_enter_failed(link);
1742 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1743 log_struct_link(LOG_DEBUG, link,
1744 "MESSAGE=%-*s: enslaving by '%s'",
1746 link->ifname, netdev->ifname, NETDEVIF(netdev), NULL);
1748 r = netdev_join(netdev, link, &netdev_join_handler);
1750 log_struct_link(LOG_WARNING, link,
1751 "MESSAGE=%-*s: could not join netdev '%s': %s",
1753 link->ifname, netdev->ifname, strerror(-r),
1754 NETDEVIF(netdev), NULL);
1755 link_enter_failed(link);
1765 static int link_configure(Link *link) {
1769 assert(link->state == LINK_STATE_INITIALIZING);
1771 if (link->network->ipv4ll) {
1774 r = sd_ipv4ll_new(&link->ipv4ll);
1778 if (link->udev_device) {
1779 r = net_get_unique_predictable_data(link->udev_device, seed);
1781 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1787 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1791 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1795 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1799 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1804 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1805 r = sd_dhcp_client_new(&link->dhcp_client);
1809 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1813 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1817 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1821 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1825 r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast);
1830 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
1835 if (link->network->dhcp_mtu) {
1836 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_INTERFACE_MTU);
1841 if (link->network->dhcp_routes) {
1842 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
1845 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
1850 if (link->network->dhcp_sendhost) {
1851 _cleanup_free_ char *hostname = gethostname_malloc();
1855 if (!is_localhost(hostname)) {
1856 r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname);
1862 if (link->network->dhcp_vendor_class_identifier) {
1863 r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
1864 link->network->dhcp_vendor_class_identifier);
1870 if (link->network->dhcp_server) {
1871 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1875 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1880 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1881 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1885 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1890 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1895 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1900 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1901 icmp6_router_handler, link);
1906 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1907 r = link_acquire_conf(link);
1912 return link_enter_join_netdev(link);
1915 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1916 _cleanup_link_unref_ Link *link = userdata;
1921 assert(link->ifname);
1922 assert(link->manager);
1924 if (link->state != LINK_STATE_INITIALIZING)
1927 log_debug_link(link, "link state is up-to-date");
1929 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1931 link_enter_unmanaged(link);
1936 r = network_apply(link->manager, network, link);
1940 r = link_configure(link);
1947 int link_initialized(Link *link, struct udev_device *device) {
1948 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1952 assert(link->manager);
1953 assert(link->manager->rtnl);
1956 if (link->state != LINK_STATE_INITIALIZING)
1959 if (link->udev_device)
1962 log_debug_link(link, "udev initialized link");
1964 link->udev_device = udev_device_ref(device);
1966 /* udev has initialized the link, but we don't know if we have yet processed
1967 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1968 we know that the pending NEWLINKs have already been processed and that we
1971 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1975 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1984 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1985 Manager *m = userdata;
1988 _cleanup_address_free_ Address *address = NULL;
1990 char buf[INET6_ADDRSTRLEN];
1991 bool address_dropped = false;
1998 r = sd_rtnl_message_get_type(message, &type);
2000 log_warning("rtnl: could not get message type");
2004 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2005 if (r < 0 || ifindex <= 0) {
2006 log_warning("rtnl: received address message without valid ifindex, ignoring");
2009 r = link_get(m, ifindex, &link);
2010 if (r < 0 || !link) {
2011 log_warning("rtnl: received address for a nonexistent link, ignoring");
2016 r = address_new_dynamic(&address);
2020 r = sd_rtnl_message_addr_get_family(message, &address->family);
2021 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
2022 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
2026 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2028 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2032 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2034 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
2038 switch (address->family) {
2040 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2042 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2049 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2051 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2058 assert_not_reached("invalid address family");
2061 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
2062 log_warning_link(link, "could not print address");
2066 LIST_FOREACH(addresses, ad, link->addresses) {
2067 if (address_equal(ad, address)) {
2068 LIST_REMOVE(addresses, link->addresses, ad);
2072 address_dropped = true;
2080 if (!address_dropped)
2081 log_debug_link(link, "added address: %s/%u", buf,
2082 address->prefixlen);
2084 log_debug_link(link, "updated address: %s/%u", buf,
2085 address->prefixlen);
2087 LIST_PREPEND(addresses, link->addresses, address);
2094 if (address_dropped) {
2095 log_debug_link(link, "removed address: %s/%u", buf,
2096 address->prefixlen);
2100 log_warning_link(link, "removing non-existent address: %s/%u",
2101 buf, address->prefixlen);
2105 assert_not_reached("Received invalid RTNL message type");
2111 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2113 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2114 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2115 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2123 r = link_new(m, message, ret);
2129 log_debug_link(link, "link %d added", link->ifindex);
2131 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2135 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2141 if (detect_container(NULL) <= 0) {
2142 /* not in a container, udev will be around */
2143 sprintf(ifindex_str, "n%d", link->ifindex);
2144 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2146 log_warning_link(link, "could not find udev device: %m");
2150 if (udev_device_get_is_initialized(device) <= 0) {
2152 log_debug_link(link, "udev initializing link...");
2156 r = link_initialized(link, device);
2160 /* we are calling a callback directly, so must take a ref */
2163 r = link_initialized_and_synced(m->rtnl, NULL, link);
2171 int link_update(Link *link, sd_rtnl_message *m) {
2172 struct ether_addr mac;
2178 assert(link->ifname);
2181 if (link->state == LINK_STATE_LINGER) {
2183 log_info_link(link, "link readded");
2184 link->state = LINK_STATE_ENSLAVING;
2187 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2188 if (r >= 0 && !streq(ifname, link->ifname)) {
2189 log_info_link(link, "renamed to %s", ifname);
2192 link->ifname = strdup(ifname);
2197 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
2198 if (r >= 0 && mtu > 0) {
2200 if (!link->original_mtu) {
2201 link->original_mtu = mtu;
2202 log_debug_link(link, "saved original MTU: %"
2203 PRIu32, link->original_mtu);
2206 if (link->dhcp_client) {
2207 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
2209 log_warning_link(link, "Could not update MTU in DHCP client: %s",
2216 /* The kernel may broadcast NEWLINK messages without the MAC address
2217 set, simply ignore them. */
2218 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2220 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2222 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2224 log_debug_link(link, "MAC address: "
2225 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2226 mac.ether_addr_octet[0],
2227 mac.ether_addr_octet[1],
2228 mac.ether_addr_octet[2],
2229 mac.ether_addr_octet[3],
2230 mac.ether_addr_octet[4],
2231 mac.ether_addr_octet[5]);
2234 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2236 log_warning_link(link, "Could not update MAC "
2237 "address in IPv4LL client: %s",
2243 if (link->dhcp_client) {
2244 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2246 log_warning_link(link, "Could not update MAC "
2247 "address in DHCP client: %s",
2253 if (link->dhcp6_client) {
2254 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2257 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2265 return link_update_flags(link, m);
2268 static void link_update_operstate(Link *link) {
2272 if (link->kernel_operstate == IF_OPER_DORMANT)
2273 link->operstate = LINK_OPERSTATE_DORMANT;
2274 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2276 uint8_t scope = RT_SCOPE_NOWHERE;
2278 /* if we have carrier, check what addresses we have */
2279 LIST_FOREACH(addresses, address, link->addresses) {
2280 if (address->scope < scope)
2281 scope = address->scope;
2284 if (scope < RT_SCOPE_SITE)
2285 /* universally accessible addresses found */
2286 link->operstate = LINK_OPERSTATE_ROUTABLE;
2287 else if (scope < RT_SCOPE_HOST)
2288 /* only link or site local addresses found */
2289 link->operstate = LINK_OPERSTATE_DEGRADED;
2291 /* no useful addresses found */
2292 link->operstate = LINK_OPERSTATE_CARRIER;
2294 link->operstate = LINK_OPERSTATE_UNKNOWN;
2297 int link_save(Link *link) {
2298 _cleanup_free_ char *temp_path = NULL;
2299 _cleanup_fclose_ FILE *f = NULL;
2300 const char *admin_state, *oper_state;
2304 assert(link->state_file);
2305 assert(link->lease_file);
2306 assert(link->manager);
2308 link_update_operstate(link);
2310 r = manager_save(link->manager);
2314 if (link->state == LINK_STATE_LINGER) {
2315 unlink(link->state_file);
2319 admin_state = link_state_to_string(link->state);
2320 assert(admin_state);
2322 oper_state = link_operstate_to_string(link->operstate);
2325 r = fopen_temporary(link->state_file, &f, &temp_path);
2329 fchmod(fileno(f), 0644);
2332 "# This is private data. Do not parse.\n"
2335 admin_state, oper_state);
2337 if (link->network) {
2342 if (link->network->dhcp_dns &&
2344 const struct in_addr *addresses;
2346 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2348 serialize_in_addrs(f, addresses, r);
2349 if (link->network->dns)
2354 STRV_FOREACH(address, link->network->dns)
2355 fprintf(f, "%s%s", *address,
2356 (address + 1 ? " " : ""));
2362 if (link->network->dhcp_ntp &&
2364 const struct in_addr *addresses;
2366 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2368 serialize_in_addrs(f, addresses, r);
2369 if (link->network->ntp)
2374 STRV_FOREACH(address, link->network->ntp)
2375 fprintf(f, "%s%s", *address,
2376 (address + 1 ? " " : ""));
2380 fprintf(f, "LLMNR=%s\n", llmnr_support_to_string(link->network->llmnr));
2383 if (link->dhcp_lease) {
2384 assert(link->network);
2386 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2394 unlink(link->lease_file);
2396 r = fflush_and_check(f);
2400 if (rename(temp_path, link->state_file) < 0) {
2408 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2409 unlink(link->state_file);
2414 static const char* const link_state_table[_LINK_STATE_MAX] = {
2415 [LINK_STATE_INITIALIZING] = "initializing",
2416 [LINK_STATE_ENSLAVING] = "configuring",
2417 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2418 [LINK_STATE_SETTING_ROUTES] = "configuring",
2419 [LINK_STATE_CONFIGURED] = "configured",
2420 [LINK_STATE_UNMANAGED] = "unmanaged",
2421 [LINK_STATE_FAILED] = "failed",
2422 [LINK_STATE_LINGER] = "linger",
2425 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2427 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2428 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2429 [LINK_OPERSTATE_DORMANT] = "dormant",
2430 [LINK_OPERSTATE_CARRIER] = "carrier",
2431 [LINK_OPERSTATE_DEGRADED] = "degraded",
2432 [LINK_OPERSTATE_ROUTABLE] = "routable",
2435 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);