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"
32 #include "conf-parser.h"
34 #include "network-util.h"
35 #include "dhcp-lease-internal.h"
37 static int ipv4ll_address_update(Link *link, bool deprecate);
38 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
40 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
41 _cleanup_link_unref_ Link *link = NULL;
47 assert(manager->links);
51 r = sd_rtnl_message_get_type(message, &type);
54 else if (type != RTM_NEWLINK)
57 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
60 else if (ifindex <= 0)
63 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
72 link->manager = manager;
73 link->state = LINK_STATE_INITIALIZING;
74 link->ifindex = ifindex;
75 link->ifname = strdup(ifname);
79 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
83 r = asprintf(&link->state_file, "/run/systemd/netif/links/%"PRIu64,
88 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%"PRIu64,
93 r = hashmap_put(manager->links, &link->ifindex, link);
103 static void link_free(Link *link) {
109 assert(link->manager);
111 while ((address = link->addresses)) {
112 LIST_REMOVE(addresses, link->addresses, address);
113 address_free(address);
116 while ((address = link->pool_addresses)) {
117 LIST_REMOVE(addresses, link->pool_addresses, address);
118 address_free(address);
121 sd_dhcp_client_unref(link->dhcp_client);
122 sd_dhcp_lease_unref(link->dhcp_lease);
124 unlink(link->lease_file);
125 free(link->lease_file);
127 sd_ipv4ll_unref(link->ipv4ll);
128 sd_dhcp6_client_unref(link->dhcp6_client);
129 sd_icmp6_nd_unref(link->icmp6_router_discovery);
131 hashmap_remove(link->manager->links, &link->ifindex);
135 unlink(link->state_file);
136 free(link->state_file);
138 udev_device_unref(link->udev_device);
143 Link *link_unref(Link *link) {
144 if (link && (-- link->n_ref <= 0))
150 Link *link_ref(Link *link) {
152 assert_se(++ link->n_ref >= 2);
157 int link_get(Manager *m, int ifindex, Link **ret) {
166 ifindex_64 = ifindex;
167 link = hashmap_get(m->links, &ifindex_64);
176 void link_drop(Link *link) {
177 if (!link || link->state == LINK_STATE_LINGER)
180 link->state = LINK_STATE_LINGER;
182 log_debug_link(link, "link removed");
189 static void link_enter_unmanaged(Link *link) {
192 log_debug_link(link, "unmanaged");
194 link->state = LINK_STATE_UNMANAGED;
199 static int link_stop_clients(Link *link) {
203 assert(link->manager);
204 assert(link->manager->event);
209 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
210 assert(link->dhcp_client);
212 k = sd_dhcp_client_stop(link->dhcp_client);
214 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
219 if (link->network->ipv4ll) {
220 assert(link->ipv4ll);
222 k = sd_ipv4ll_stop(link->ipv4ll);
224 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
229 if (link->network->dhcp_server) {
230 assert(link->dhcp_server);
232 k = sd_dhcp_server_stop(link->dhcp_server);
234 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
239 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
240 assert(link->icmp6_router_discovery);
242 if (link->dhcp6_client) {
243 k = sd_dhcp6_client_stop(link->dhcp6_client);
245 log_warning_link(link, "Could not stop DHCPv6 client: %s", strerror(-r));
250 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
252 log_warning_link(link, "Could not stop ICMPv6 router discovery: %s", strerror(-r));
260 static void link_enter_failed(Link *link) {
263 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
266 log_warning_link(link, "failed");
268 link->state = LINK_STATE_FAILED;
270 link_stop_clients(link);
275 static Address* link_find_dhcp_server_address(Link *link) {
279 assert(link->network);
281 /* The the first statically configured address if there is any */
282 LIST_FOREACH(addresses, address, link->network->static_addresses) {
284 if (address->family != AF_INET)
287 if (in_addr_null(address->family, &address->in_addr))
293 /* If that didn't work, find a suitable address we got from the pool */
294 LIST_FOREACH(addresses, address, link->pool_addresses) {
295 if (address->family != AF_INET)
304 static int link_enter_configured(Link *link) {
308 assert(link->network);
309 assert(link->state == LINK_STATE_SETTING_ROUTES);
311 if (link->network->dhcp_server &&
312 !sd_dhcp_server_is_running(link->dhcp_server)) {
313 struct in_addr pool_start;
316 address = link_find_dhcp_server_address(link);
318 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
319 link_enter_failed(link);
323 log_debug_link(link, "offering DHCPv4 leases");
325 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in);
329 /* offer 32 addresses starting from the address following the server address */
330 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
331 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
337 r = sd_dhcp_server_set_router(link->dhcp_server,
338 &main_address->in_addr.in);
342 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
343 main_address->prefixlen);
348 r = sd_dhcp_server_start(link->dhcp_server);
350 log_warning_link(link, "could not start DHCPv4 server "
351 "instance: %s", strerror(-r));
353 link_enter_failed(link);
359 log_info_link(link, "link configured");
361 link->state = LINK_STATE_CONFIGURED;
368 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
369 Link *link = userdata;
372 assert(link->route_messages > 0);
373 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
374 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
377 link->route_messages --;
379 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
384 r = sd_rtnl_message_get_errno(m);
385 if (r < 0 && r != -EEXIST)
386 log_struct_link(LOG_WARNING, link,
387 "MESSAGE=%-*s: could not set route: %s",
389 link->ifname, strerror(-r),
393 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
395 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
396 log_debug_link(link, "routes set");
397 link_enter_configured(link);
405 static int link_enter_set_routes(Link *link) {
410 assert(link->network);
411 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
413 link->state = LINK_STATE_SETTING_ROUTES;
415 if (!link->network->static_routes && !link->dhcp_lease &&
416 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
417 return link_enter_configured(link);
419 log_debug_link(link, "setting routes");
421 LIST_FOREACH(routes, rt, link->network->static_routes) {
422 r = route_configure(rt, link, &route_handler);
424 log_warning_link(link,
425 "could not set routes: %s", strerror(-r));
426 link_enter_failed(link);
431 link->route_messages ++;
434 if (link->ipv4ll && !link->dhcp_lease) {
435 _cleanup_route_free_ Route *route = NULL;
438 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
439 if (r < 0 && r != -ENOENT) {
440 log_warning_link(link, "IPV4LL error: no address: %s",
446 r = route_new_dynamic(&route);
448 log_error_link(link, "Could not allocate route: %s",
453 route->family = AF_INET;
454 route->scope = RT_SCOPE_LINK;
457 r = route_configure(route, link, &route_handler);
459 log_warning_link(link,
460 "could not set routes: %s", strerror(-r));
461 link_enter_failed(link);
466 link->route_messages ++;
470 if (link->dhcp_lease) {
471 _cleanup_route_free_ Route *route = NULL;
472 _cleanup_route_free_ Route *route_gw = NULL;
473 struct in_addr gateway;
475 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
476 if (r < 0 && r != -ENOENT) {
477 log_warning_link(link, "DHCP error: %s", strerror(-r));
482 r = route_new_dynamic(&route);
484 log_error_link(link, "Could not allocate route: %s",
489 r = route_new_dynamic(&route_gw);
491 log_error_link(link, "Could not allocate route: %s",
496 /* The dhcp netmask may mask out the gateway. Add an explicit
497 * route for the gw host so that we can route no matter the
498 * netmask or existing kernel route tables. */
499 route_gw->family = AF_INET;
500 route_gw->dst_addr.in = gateway;
501 route_gw->dst_prefixlen = 32;
502 route_gw->scope = RT_SCOPE_LINK;
504 r = route_configure(route_gw, link, &route_handler);
506 log_warning_link(link,
507 "could not set host route: %s", strerror(-r));
512 link->route_messages ++;
514 route->family = AF_INET;
515 route->in_addr.in = gateway;
517 r = route_configure(route, link, &route_handler);
519 log_warning_link(link,
520 "could not set routes: %s", strerror(-r));
521 link_enter_failed(link);
526 link->route_messages ++;
530 if (link->route_messages == 0) {
531 link_enter_configured(link);
537 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
538 Link *link = userdata;
543 assert(link->ifname);
545 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
550 r = sd_rtnl_message_get_errno(m);
551 if (r < 0 && r != -ESRCH)
552 log_struct_link(LOG_WARNING, link,
553 "MESSAGE=%-*s: could not drop route: %s",
555 link->ifname, strerror(-r),
564 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
565 Link *link = userdata;
570 assert(link->ifname);
571 assert(link->addr_messages > 0);
572 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
573 LINK_STATE_FAILED, LINK_STATE_LINGER));
575 link->addr_messages --;
577 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
582 r = sd_rtnl_message_get_errno(m);
583 if (r < 0 && r != -EEXIST)
584 log_struct_link(LOG_WARNING, link,
585 "MESSAGE=%-*s: could not set address: %s",
587 link->ifname, strerror(-r),
591 if (link->addr_messages == 0) {
592 log_debug_link(link, "addresses set");
593 link_enter_set_routes(link);
601 static int link_enter_set_addresses(Link *link) {
604 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
607 assert(link->network);
608 assert(link->state != _LINK_STATE_INVALID);
610 link->state = LINK_STATE_SETTING_ADDRESSES;
612 if (!link->network->static_addresses && !link->dhcp_lease &&
613 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
614 return link_enter_set_routes(link);
616 log_debug_link(link, "setting addresses");
618 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
619 r = address_configure(ad, link, &address_handler);
621 log_warning_link(link,
622 "could not set addresses: %s", strerror(-r));
623 link_enter_failed(link);
628 link->addr_messages ++;
631 if (link->ipv4ll && !link->dhcp_lease) {
632 _cleanup_address_free_ Address *ll_addr = NULL;
635 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
636 if (r < 0 && r != -ENOENT) {
637 log_warning_link(link, "IPV4LL error: no address: %s",
643 r = address_new_dynamic(&ll_addr);
645 log_error_link(link, "Could not allocate address: %s", strerror(-r));
649 ll_addr->family = AF_INET;
650 ll_addr->in_addr.in = addr;
651 ll_addr->prefixlen = 16;
652 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
653 ll_addr->scope = RT_SCOPE_LINK;
655 r = address_configure(ll_addr, link, &address_handler);
657 log_warning_link(link,
658 "could not set addresses: %s", strerror(-r));
659 link_enter_failed(link);
664 link->addr_messages ++;
668 if (link->dhcp_lease) {
669 _cleanup_address_free_ Address *address = NULL;
671 struct in_addr netmask;
674 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
676 log_warning_link(link, "DHCP error: no address: %s",
681 if (!link->network->dhcp_critical) {
682 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
685 log_warning_link(link, "DHCP error: no lifetime: %s",
691 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
693 log_warning_link(link, "DHCP error: no netmask: %s",
698 prefixlen = net_netmask_to_prefixlen(&netmask);
700 r = address_new_dynamic(&address);
702 log_error_link(link, "Could not allocate address: %s",
707 address->family = AF_INET;
708 address->in_addr.in = addr;
709 address->cinfo.ifa_prefered = lifetime;
710 address->cinfo.ifa_valid = lifetime;
711 address->prefixlen = prefixlen;
712 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
714 r = address_configure(address, link, &address_handler);
716 log_warning_link(link,
717 "could not set addresses: %s", strerror(-r));
718 link_enter_failed(link);
723 link->addr_messages ++;
729 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
730 Link *link = userdata;
735 assert(link->ifname);
737 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
742 r = sd_rtnl_message_get_errno(m);
743 if (r < 0 && r != -ENOENT)
744 log_struct_link(LOG_WARNING, link,
745 "MESSAGE=%-*s: could not update address: %s",
747 link->ifname, strerror(-r),
756 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
757 Link *link = userdata;
762 assert(link->ifname);
764 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
769 r = sd_rtnl_message_get_errno(m);
770 if (r < 0 && r != -EADDRNOTAVAIL)
771 log_struct_link(LOG_WARNING, link,
772 "MESSAGE=%-*s: could not drop address: %s",
774 link->ifname, strerror(-r),
783 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
784 Link *link = userdata;
789 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
794 r = sd_bus_message_get_errno(m);
796 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
803 static int link_set_hostname(Link *link, const char *hostname) {
804 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
808 assert(link->manager);
811 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
813 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
814 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
818 r = sd_bus_message_new_method_call(
821 "org.freedesktop.hostname1",
822 "/org/freedesktop/hostname1",
823 "org.freedesktop.hostname1",
828 r = sd_bus_message_append(m, "sb", hostname, false);
832 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
834 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
841 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
842 Link *link = userdata;
847 assert(link->ifname);
849 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
854 r = sd_rtnl_message_get_errno(m);
856 log_struct_link(LOG_WARNING, link,
857 "MESSAGE=%-*s: could not set MTU: %s",
858 IFNAMSIZ, link->ifname, strerror(-r),
867 static int link_set_mtu(Link *link, uint32_t mtu) {
868 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
872 assert(link->manager);
873 assert(link->manager->rtnl);
875 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
877 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
878 RTM_SETLINK, link->ifindex);
880 log_error_link(link, "Could not allocate RTM_SETLINK message");
884 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
886 log_error_link(link, "Could not append MTU: %s", strerror(-r));
890 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
893 "Could not send rtnetlink message: %s", strerror(-r));
902 static int dhcp_lease_lost(Link *link) {
903 _cleanup_address_free_ Address *address = NULL;
904 _cleanup_route_free_ Route *route_gw = NULL;
905 _cleanup_route_free_ Route *route = NULL;
907 struct in_addr netmask;
908 struct in_addr gateway;
913 assert(link->dhcp_lease);
915 log_warning_link(link, "DHCP lease lost");
917 r = address_new_dynamic(&address);
919 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
921 r = route_new_dynamic(&route_gw);
923 route_gw->family = AF_INET;
924 route_gw->dst_addr.in = gateway;
925 route_gw->dst_prefixlen = 32;
926 route_gw->scope = RT_SCOPE_LINK;
928 route_drop(route_gw, link, &route_drop_handler);
932 r = route_new_dynamic(&route);
934 route->family = AF_INET;
935 route->in_addr.in = gateway;
937 route_drop(route, link, &route_drop_handler);
942 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
943 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
944 prefixlen = net_netmask_to_prefixlen(&netmask);
946 address->family = AF_INET;
947 address->in_addr.in = addr;
948 address->prefixlen = prefixlen;
950 address_drop(address, link, &address_drop_handler);
954 if (link->network->dhcp_mtu) {
957 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
958 if (r >= 0 && link->original_mtu != mtu) {
959 r = link_set_mtu(link, link->original_mtu);
961 log_warning_link(link, "DHCP error: could not reset MTU");
962 link_enter_failed(link);
968 if (link->network->dhcp_hostname) {
969 const char *hostname = NULL;
971 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
972 if (r >= 0 && hostname) {
973 r = link_set_hostname(link, "");
975 log_error_link(link, "Failed to reset transient hostname");
979 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
984 static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
985 sd_dhcp_lease *lease;
988 r = sd_dhcp_client_get_lease(client, &lease);
990 log_warning_link(link, "DHCP error: no lease %s",
995 sd_dhcp_lease_unref(link->dhcp_lease);
996 link->dhcp_lease = lease;
998 link_enter_set_addresses(link);
1003 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1004 sd_dhcp_lease *lease;
1005 struct in_addr address;
1006 struct in_addr netmask;
1007 struct in_addr gateway;
1014 r = sd_dhcp_client_get_lease(client, &lease);
1016 log_warning_link(link, "DHCP error: no lease: %s",
1021 r = sd_dhcp_lease_get_address(lease, &address);
1023 log_warning_link(link, "DHCP error: no address: %s",
1028 r = sd_dhcp_lease_get_netmask(lease, &netmask);
1030 log_warning_link(link, "DHCP error: no netmask: %s",
1035 prefixlen = net_netmask_to_prefixlen(&netmask);
1037 r = sd_dhcp_lease_get_router(lease, &gateway);
1038 if (r < 0 && r != -ENOENT) {
1039 log_warning_link(link, "DHCP error: %s", strerror(-r));
1044 log_struct_link(LOG_INFO, link,
1045 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
1048 ADDRESS_FMT_VAL(address),
1050 ADDRESS_FMT_VAL(gateway),
1051 "ADDRESS=%u.%u.%u.%u",
1052 ADDRESS_FMT_VAL(address),
1055 "GATEWAY=%u.%u.%u.%u",
1056 ADDRESS_FMT_VAL(gateway),
1059 log_struct_link(LOG_INFO, link,
1060 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1063 ADDRESS_FMT_VAL(address),
1065 "ADDRESS=%u.%u.%u.%u",
1066 ADDRESS_FMT_VAL(address),
1071 link->dhcp_lease = lease;
1073 if (link->network->dhcp_mtu) {
1076 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1078 r = link_set_mtu(link, mtu);
1080 log_error_link(link, "Failed to set MTU "
1081 "to %" PRIu16, mtu);
1085 if (link->network->dhcp_hostname) {
1086 const char *hostname;
1088 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1090 r = link_set_hostname(link, hostname);
1092 log_error_link(link, "Failed to set transient hostname "
1093 "to '%s'", hostname);
1097 link_enter_set_addresses(link);
1102 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1103 Link *link = userdata;
1107 assert(link->network);
1108 assert(link->manager);
1110 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1114 case DHCP_EVENT_NO_LEASE:
1115 log_debug_link(link, "IP address in use.");
1117 case DHCP_EVENT_EXPIRED:
1118 case DHCP_EVENT_STOP:
1119 case DHCP_EVENT_IP_CHANGE:
1120 if (link->network->dhcp_critical) {
1121 log_error_link(link, "DHCPv4 connection considered system critical, "
1122 "ignoring request to reconfigure it.");
1126 if (link->dhcp_lease) {
1127 r = dhcp_lease_lost(link);
1129 link_enter_failed(link);
1134 if (event == DHCP_EVENT_IP_CHANGE) {
1135 r = dhcp_lease_acquired(client, link);
1137 link_enter_failed(link);
1142 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1143 if (!sd_ipv4ll_is_running(link->ipv4ll))
1144 r = sd_ipv4ll_start(link->ipv4ll);
1145 else if (ipv4ll_is_bound(link->ipv4ll))
1146 r = ipv4ll_address_update(link, false);
1148 link_enter_failed(link);
1154 case DHCP_EVENT_RENEW:
1155 r = dhcp_lease_renew(client, link);
1157 link_enter_failed(link);
1161 case DHCP_EVENT_IP_ACQUIRE:
1162 r = dhcp_lease_acquired(client, link);
1164 link_enter_failed(link);
1168 if (ipv4ll_is_bound(link->ipv4ll))
1169 r = ipv4ll_address_update(link, true);
1171 r = sd_ipv4ll_stop(link->ipv4ll);
1173 link_enter_failed(link);
1180 log_warning_link(link, "DHCP error: %s", strerror(-event));
1182 log_warning_link(link, "DHCP unknown event: %d", event);
1189 static int ipv4ll_address_update(Link *link, bool deprecate) {
1191 struct in_addr addr;
1195 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1197 _cleanup_address_free_ Address *address = NULL;
1199 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1200 deprecate ? "deprecate" : "approve",
1201 ADDRESS_FMT_VAL(addr));
1203 r = address_new_dynamic(&address);
1205 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1209 address->family = AF_INET;
1210 address->in_addr.in = addr;
1211 address->prefixlen = 16;
1212 address->scope = RT_SCOPE_LINK;
1213 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1214 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1216 address_update(address, link, &address_update_handler);
1224 static int ipv4ll_address_lost(Link *link) {
1226 struct in_addr addr;
1230 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1232 _cleanup_address_free_ Address *address = NULL;
1233 _cleanup_route_free_ Route *route = NULL;
1235 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1236 ADDRESS_FMT_VAL(addr));
1238 r = address_new_dynamic(&address);
1240 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1244 address->family = AF_INET;
1245 address->in_addr.in = addr;
1246 address->prefixlen = 16;
1247 address->scope = RT_SCOPE_LINK;
1249 address_drop(address, link, &address_drop_handler);
1252 r = route_new_dynamic(&route);
1254 log_error_link(link, "Could not allocate route: %s",
1259 route->family = AF_INET;
1260 route->scope = RT_SCOPE_LINK;
1261 route->metrics = 99;
1263 route_drop(route, link, &route_drop_handler);
1270 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1272 struct in_addr addr;
1276 r = sd_ipv4ll_get_address(ll, &addr);
1282 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1283 struct in_addr address;
1289 r = sd_ipv4ll_get_address(ll, &address);
1293 log_struct_link(LOG_INFO, link,
1294 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1297 ADDRESS_FMT_VAL(address),
1300 link_enter_set_addresses(link);
1305 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1306 Link *link = userdata;
1310 assert(link->network);
1311 assert(link->manager);
1313 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1317 case IPV4LL_EVENT_STOP:
1318 case IPV4LL_EVENT_CONFLICT:
1319 r = ipv4ll_address_lost(link);
1321 link_enter_failed(link);
1325 case IPV4LL_EVENT_BIND:
1326 r = ipv4ll_address_claimed(ll, link);
1328 link_enter_failed(link);
1334 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1336 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1341 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1342 Link *link = userdata;
1345 assert(link->network);
1346 assert(link->manager);
1348 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1352 case DHCP6_EVENT_STOP:
1353 case DHCP6_EVENT_RESEND_EXPIRE:
1354 case DHCP6_EVENT_RETRANS_MAX:
1355 case DHCP6_EVENT_IP_ACQUIRE:
1356 log_debug_link(link, "DHCPv6 event %d", event);
1362 log_warning_link(link, "DHCPv6 error: %s",
1365 log_warning_link(link, "DHCPv6 unknown event: %d",
1371 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1372 Link *link = userdata;
1376 assert(link->network);
1377 assert(link->manager);
1379 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1383 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1384 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1387 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1388 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1393 log_warning_link(link, "ICMPv6 error: %s",
1396 log_warning_link(link, "ICMPv6 unknown event: %d",
1402 if (link->dhcp6_client)
1405 r = sd_dhcp6_client_new(&link->dhcp6_client);
1409 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1411 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1415 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1417 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1421 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1423 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1427 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1430 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1434 r = sd_dhcp6_client_start(link->dhcp6_client);
1436 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1439 static int link_acquire_conf(Link *link) {
1443 assert(link->network);
1444 assert(link->manager);
1445 assert(link->manager->event);
1447 if (link->network->ipv4ll) {
1448 assert(link->ipv4ll);
1450 log_debug_link(link, "acquiring IPv4 link-local address");
1452 r = sd_ipv4ll_start(link->ipv4ll);
1454 log_warning_link(link, "could not acquire IPv4 "
1455 "link-local address");
1460 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1461 assert(link->dhcp_client);
1463 log_debug_link(link, "acquiring DHCPv4 lease");
1465 r = sd_dhcp_client_start(link->dhcp_client);
1467 log_warning_link(link, "could not acquire DHCPv4 "
1473 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1474 assert(link->icmp6_router_discovery);
1476 log_debug_link(link, "discovering IPv6 routers");
1478 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1480 log_warning_link(link, "could not start IPv6 router discovery");
1488 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1489 /* see Documentation/networking/operstates.txt in the kernel sources */
1491 if (operstate == IF_OPER_UP)
1494 if (operstate == IF_OPER_UNKNOWN)
1495 /* operstate may not be implemented, so fall back to flags */
1496 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1502 #define FLAG_STRING(string, flag, old, new) \
1503 (((old ^ new) & flag) \
1504 ? ((old & flag) ? (" -" string) : (" +" string)) \
1507 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1508 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1510 bool carrier_gained = false, carrier_lost = false;
1515 r = sd_rtnl_message_link_get_flags(m, &flags);
1517 log_warning_link(link, "Could not get link flags");
1521 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1523 /* if we got a message without operstate, take it to mean
1524 the state was unchanged */
1525 operstate = link->kernel_operstate;
1527 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1530 if (link->flags != flags) {
1531 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",
1532 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1533 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1534 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1535 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1536 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1537 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1538 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1539 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1540 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1541 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1542 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1543 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1544 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1545 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1546 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1547 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1548 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1549 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1550 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1552 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1553 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1554 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1555 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1556 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1557 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1558 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1559 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1561 /* link flags are currently at most 18 bits, let's align to printing 20 */
1562 if (unknown_flags_added)
1563 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1564 unknown_flags_added);
1566 if (unknown_flags_removed)
1567 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1568 unknown_flags_removed);
1571 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1572 link_has_carrier(flags, operstate);
1573 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1574 !link_has_carrier(flags, operstate);
1576 link->flags = flags;
1577 link->kernel_operstate = operstate;
1581 if (link->state == LINK_STATE_FAILED ||
1582 link->state == LINK_STATE_UNMANAGED)
1585 if (carrier_gained) {
1586 log_info_link(link, "gained carrier");
1588 if (link->network) {
1589 r = link_acquire_conf(link);
1591 link_enter_failed(link);
1595 } else if (carrier_lost) {
1596 log_info_link(link, "lost carrier");
1598 r = link_stop_clients(link);
1600 link_enter_failed(link);
1608 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1609 Link *link = userdata;
1614 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1619 r = sd_rtnl_message_get_errno(m);
1621 /* we warn but don't fail the link, as it may
1622 be brought up later */
1623 log_struct_link(LOG_WARNING, link,
1624 "MESSAGE=%-*s: could not bring up interface: %s",
1626 link->ifname, strerror(-r),
1636 static int link_up(Link *link) {
1637 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1641 assert(link->manager);
1642 assert(link->manager->rtnl);
1644 log_debug_link(link, "bringing link up");
1646 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1647 RTM_SETLINK, link->ifindex);
1649 log_error_link(link, "Could not allocate RTM_SETLINK message");
1653 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1655 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1659 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1661 log_error_link(link,
1662 "Could not send rtnetlink message: %s", strerror(-r));
1671 static int link_enslaved(Link *link) {
1675 assert(link->state == LINK_STATE_ENSLAVING);
1676 assert(link->network);
1678 if (!(link->flags & IFF_UP)) {
1681 link_enter_failed(link);
1686 if ((link->network->dhcp == DHCP_SUPPORT_NONE) && !link->network->ipv4ll)
1687 return link_enter_set_addresses(link);
1692 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1693 Link *link = userdata;
1697 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1698 LINK_STATE_LINGER));
1699 assert(link->network);
1703 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1708 r = sd_rtnl_message_get_errno(m);
1710 log_struct_link(LOG_ERR, link,
1711 "MESSAGE=%-*s: could not enslave: %s",
1713 link->ifname, strerror(-r),
1716 link_enter_failed(link);
1721 log_debug_link(link, "enslaved");
1723 if (link->enslaving == 0)
1724 link_enslaved(link);
1731 static int link_enter_enslave(Link *link) {
1732 NetDev *vlan, *macvlan, *vxlan;
1737 assert(link->network);
1738 assert(link->state == LINK_STATE_INITIALIZING);
1740 link->state = LINK_STATE_ENSLAVING;
1744 if (!link->network->bridge &&
1745 !link->network->bond &&
1746 !link->network->tunnel &&
1747 hashmap_isempty(link->network->vlans) &&
1748 hashmap_isempty(link->network->macvlans) &&
1749 hashmap_isempty(link->network->vxlans))
1750 return link_enslaved(link);
1752 if (link->network->bond) {
1753 log_struct_link(LOG_DEBUG, link,
1754 "MESSAGE=%-*s: enslaving by '%s'",
1756 link->ifname, link->network->bond->ifname,
1757 NETDEV(link->network->bond),
1760 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1762 log_struct_link(LOG_WARNING, link,
1763 "MESSAGE=%-*s: could not enslave by '%s': %s",
1765 link->ifname, link->network->bond->ifname, strerror(-r),
1766 NETDEV(link->network->bond),
1768 link_enter_failed(link);
1776 if (link->network->bridge) {
1777 log_struct_link(LOG_DEBUG, link,
1778 "MESSAGE=%-*s: enslaving by '%s'",
1780 link->ifname, link->network->bridge->ifname,
1781 NETDEV(link->network->bridge),
1784 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1786 log_struct_link(LOG_WARNING, link,
1787 "MESSAGE=%-*s: could not enslave by '%s': %s",
1789 link->ifname, link->network->bridge->ifname, strerror(-r),
1790 NETDEV(link->network->bridge),
1792 link_enter_failed(link);
1800 if (link->network->tunnel) {
1801 log_struct_link(LOG_DEBUG, link,
1802 "MESSAGE=%-*s: enslaving by '%s'",
1804 link->ifname, link->network->tunnel->ifname,
1805 NETDEV(link->network->tunnel),
1808 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1810 log_struct_link(LOG_WARNING, link,
1811 "MESSAGE=%-*s: could not enslave by '%s': %s",
1813 link->ifname, link->network->tunnel->ifname, strerror(-r),
1814 NETDEV(link->network->tunnel),
1816 link_enter_failed(link);
1824 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1825 log_struct_link(LOG_DEBUG, link,
1826 "MESSAGE=%-*s: enslaving by '%s'",
1828 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1830 r = netdev_enslave(vlan, link, &enslave_handler);
1832 log_struct_link(LOG_WARNING, link,
1833 "MESSAGE=%-*s: could not enslave by '%s': %s",
1835 link->ifname, vlan->ifname, strerror(-r),
1836 NETDEV(vlan), NULL);
1837 link_enter_failed(link);
1845 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1846 log_struct_link(LOG_DEBUG, link,
1847 "MESSAGE=%-*s: enslaving by '%s'",
1849 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1851 r = netdev_enslave(macvlan, link, &enslave_handler);
1853 log_struct_link(LOG_WARNING, link,
1854 "MESSAGE=%-*s: could not enslave by '%s': %s",
1856 link->ifname, macvlan->ifname, strerror(-r),
1857 NETDEV(macvlan), NULL);
1858 link_enter_failed(link);
1866 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1867 log_struct_link(LOG_DEBUG, link,
1868 "MESSAGE=%*s: enslaving by '%s'",
1870 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1872 r = netdev_enslave(vxlan, link, &enslave_handler);
1874 log_struct_link(LOG_WARNING, link,
1875 "MESSAGE=%*s: could not enslave by '%s': %s",
1877 link->ifname, vxlan->ifname, strerror(-r),
1878 NETDEV(vxlan), NULL);
1879 link_enter_failed(link);
1890 static int link_configure(Link *link) {
1894 assert(link->state == LINK_STATE_INITIALIZING);
1896 if (link->network->ipv4ll) {
1899 r = sd_ipv4ll_new(&link->ipv4ll);
1903 if (link->udev_device) {
1904 r = net_get_unique_predictable_data(link->udev_device, seed);
1906 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1912 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1916 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1920 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1924 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1929 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1930 r = sd_dhcp_client_new(&link->dhcp_client);
1934 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1938 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1942 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1946 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1950 if (link->network->dhcp_mtu) {
1951 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1957 if (link->network->dhcp_server) {
1958 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1962 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1967 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1968 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1972 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1977 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1982 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1987 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1988 icmp6_router_handler, link);
1993 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1994 r = link_acquire_conf(link);
1999 return link_enter_enslave(link);
2002 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2003 Link *link = userdata;
2008 assert(link->ifname);
2009 assert(link->manager);
2011 if (link->state != LINK_STATE_INITIALIZING)
2014 log_debug_link(link, "link state is up-to-date");
2016 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
2018 link_enter_unmanaged(link);
2023 r = network_apply(link->manager, network, link);
2027 r = link_configure(link);
2034 int link_initialized(Link *link, struct udev_device *device) {
2035 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2039 assert(link->manager);
2040 assert(link->manager->rtnl);
2043 if (link->state != LINK_STATE_INITIALIZING)
2046 log_debug_link(link, "udev initialized link");
2048 link->udev_device = udev_device_ref(device);
2050 /* udev has initialized the link, but we don't know if we have yet processed
2051 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
2052 we know that the pending NEWLINKs have already been processed and that we
2055 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
2059 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
2066 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
2067 Manager *m = userdata;
2070 _cleanup_address_free_ Address *address = NULL;
2072 char buf[INET6_ADDRSTRLEN];
2073 bool address_dropped = false;
2080 r = sd_rtnl_message_get_type(message, &type);
2082 log_warning("rtnl: could not get message type");
2086 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2087 if (r < 0 || ifindex <= 0) {
2088 log_warning("rtnl: received address message without valid ifindex, ignoring");
2091 r = link_get(m, ifindex, &link);
2092 if (r < 0 || !link) {
2093 log_warning("rtnl: received address for a nonexistent link, ignoring");
2098 r = address_new_dynamic(&address);
2102 r = sd_rtnl_message_addr_get_family(message, &address->family);
2103 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
2104 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
2108 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2110 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2114 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2116 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
2120 switch (address->family) {
2122 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2124 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2131 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2133 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2140 assert_not_reached("invalid address family");
2143 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
2144 log_warning_link(link, "could not print address");
2148 LIST_FOREACH(addresses, ad, link->addresses) {
2149 if (address_equal(ad, address)) {
2150 LIST_REMOVE(addresses, link->addresses, ad);
2154 address_dropped = true;
2162 if (!address_dropped)
2163 log_debug_link(link, "added address: %s/%u", buf,
2164 address->prefixlen);
2166 LIST_PREPEND(addresses, link->addresses, address);
2173 if (address_dropped) {
2174 log_debug_link(link, "removed address: %s/%u", buf,
2175 address->prefixlen);
2182 assert_not_reached("Received invalid RTNL message type");
2188 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2189 Link *link = userdata;
2196 for (; m; m = sd_rtnl_message_next(m)) {
2197 r = sd_rtnl_message_get_errno(m);
2199 log_debug_link(link, "getting address failed: %s", strerror(-r));
2203 r = link_rtnl_process_address(rtnl, m, link->manager);
2205 log_warning_link(link, "could not process address: %s", strerror(-r));
2211 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2213 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2214 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2215 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2223 r = link_new(m, message, ret);
2229 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2231 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2235 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2239 if (detect_container(NULL) <= 0) {
2240 /* not in a container, udev will be around */
2241 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2242 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2244 log_warning_link(link, "could not find udev device");
2248 if (udev_device_get_is_initialized(device) <= 0) {
2250 log_debug_link(link, "udev initializing link...");
2254 r = link_initialized(link, device);
2258 r = link_initialized_and_synced(m->rtnl, NULL, link);
2266 int link_update(Link *link, sd_rtnl_message *m) {
2267 struct ether_addr mac;
2272 assert(link->ifname);
2275 if (link->state == LINK_STATE_LINGER) {
2277 log_info_link(link, "link readded");
2278 link->state = LINK_STATE_ENSLAVING;
2281 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2282 if (r >= 0 && !streq(ifname, link->ifname)) {
2283 log_info_link(link, "renamed to %s", ifname);
2286 link->ifname = strdup(ifname);
2291 if (!link->original_mtu) {
2292 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2294 log_debug_link(link, "saved original MTU: %"
2295 PRIu16, link->original_mtu);
2298 /* The kernel may broadcast NEWLINK messages without the MAC address
2299 set, simply ignore them. */
2300 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2302 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2304 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2306 log_debug_link(link, "MAC address: "
2307 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2308 mac.ether_addr_octet[0],
2309 mac.ether_addr_octet[1],
2310 mac.ether_addr_octet[2],
2311 mac.ether_addr_octet[3],
2312 mac.ether_addr_octet[4],
2313 mac.ether_addr_octet[5]);
2316 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2318 log_warning_link(link, "Could not update MAC "
2319 "address in IPv4LL client: %s",
2325 if (link->dhcp_client) {
2326 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2328 log_warning_link(link, "Could not update MAC "
2329 "address in DHCP client: %s",
2335 if (link->dhcp6_client) {
2336 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2339 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2347 return link_update_flags(link, m);
2350 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2359 fprintf(f, "%s=", key);
2361 LIST_FOREACH(addresses, ad, address) {
2362 char buf[INET6_ADDRSTRLEN];
2364 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2365 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2371 static void link_update_operstate(Link *link) {
2375 if (link->kernel_operstate == IF_OPER_DORMANT)
2376 link->operstate = LINK_OPERSTATE_DORMANT;
2377 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2379 uint8_t scope = RT_SCOPE_NOWHERE;
2381 /* if we have carrier, check what addresses we have */
2382 LIST_FOREACH(addresses, address, link->addresses) {
2383 if (address->scope < scope)
2384 scope = address->scope;
2387 if (scope < RT_SCOPE_SITE)
2388 /* universally accessible addresses found */
2389 link->operstate = LINK_OPERSTATE_ROUTABLE;
2390 else if (scope < RT_SCOPE_HOST)
2391 /* only link or site local addresses found */
2392 link->operstate = LINK_OPERSTATE_DEGRADED;
2394 /* no useful addresses found */
2395 link->operstate = LINK_OPERSTATE_CARRIER;
2397 link->operstate = LINK_OPERSTATE_UNKNOWN;
2400 int link_save(Link *link) {
2401 _cleanup_free_ char *temp_path = NULL;
2402 _cleanup_fclose_ FILE *f = NULL;
2403 const char *admin_state, *oper_state;
2407 assert(link->state_file);
2408 assert(link->lease_file);
2409 assert(link->manager);
2411 link_update_operstate(link);
2413 r = manager_save(link->manager);
2417 if (link->state == LINK_STATE_LINGER) {
2418 unlink(link->state_file);
2422 admin_state = link_state_to_string(link->state);
2423 assert(admin_state);
2425 oper_state = link_operstate_to_string(link->operstate);
2428 r = fopen_temporary(link->state_file, &f, &temp_path);
2432 fchmod(fileno(f), 0644);
2435 "# This is private data. Do not parse.\n"
2439 admin_state, oper_state, link->flags);
2441 if (link->network) {
2442 serialize_addresses(f, "DNS", link->network->dns);
2443 serialize_addresses(f, "NTP", link->network->ntp);
2446 if (link->dhcp_lease) {
2447 assert(link->network);
2449 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2456 "DHCP_USE_NTP=%s\n",
2458 yes_no(link->network->dhcp_dns),
2459 yes_no(link->network->dhcp_ntp));
2461 unlink(link->lease_file);
2465 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2467 unlink(link->state_file);
2473 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2478 static const char* const link_state_table[_LINK_STATE_MAX] = {
2479 [LINK_STATE_INITIALIZING] = "initializing",
2480 [LINK_STATE_ENSLAVING] = "configuring",
2481 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2482 [LINK_STATE_SETTING_ROUTES] = "configuring",
2483 [LINK_STATE_CONFIGURED] = "configured",
2484 [LINK_STATE_UNMANAGED] = "unmanaged",
2485 [LINK_STATE_FAILED] = "failed",
2486 [LINK_STATE_LINGER] = "linger",
2489 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2491 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2492 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2493 [LINK_OPERSTATE_DORMANT] = "dormant",
2494 [LINK_OPERSTATE_CARRIER] = "carrier",
2495 [LINK_OPERSTATE_DEGRADED] = "degraded",
2496 [LINK_OPERSTATE_ROUTABLE] = "routable",
2499 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
2501 static const char* const dhcp_support_table[_DHCP_SUPPORT_MAX] = {
2502 [DHCP_SUPPORT_NONE] = "none",
2503 [DHCP_SUPPORT_BOTH] = "both",
2504 [DHCP_SUPPORT_V4] = "v4",
2505 [DHCP_SUPPORT_V6] = "v6",
2508 DEFINE_STRING_TABLE_LOOKUP(dhcp_support, DHCPSupport);
2510 int config_parse_dhcp(
2512 const char *filename,
2514 const char *section,
2515 unsigned section_line,
2522 DHCPSupport *dhcp = data;
2530 /* Our enum shall be a superset of booleans, hence first try
2531 * to parse as boolean, and then as enum */
2533 k = parse_boolean(rvalue);
2535 *dhcp = DHCP_SUPPORT_BOTH;
2537 *dhcp = DHCP_SUPPORT_NONE;
2541 s = dhcp_support_from_string(rvalue);
2543 log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse DHCP option, ignoring: %s", rvalue);