1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <netinet/ether.h>
26 #include "libudev-private.h"
27 #include "udev-util.h"
31 #include "network-internal.h"
33 #include "network-util.h"
34 #include "dhcp-lease-internal.h"
36 static int ipv4ll_address_update(Link *link, bool deprecate);
37 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
39 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
40 _cleanup_link_unref_ Link *link = NULL;
46 assert(manager->links);
50 r = sd_rtnl_message_get_type(message, &type);
53 else if (type != RTM_NEWLINK)
56 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
59 else if (ifindex <= 0)
62 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
71 link->manager = manager;
72 link->state = LINK_STATE_INITIALIZING;
73 link->ifindex = ifindex;
74 link->ifname = strdup(ifname);
78 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
83 r = asprintf(&link->lease_file, "/run/systemd/network/leases/%"PRIu64,
88 r = hashmap_put(manager->links, &link->ifindex, link);
98 static void link_free(Link *link) {
102 assert(link->manager);
104 sd_dhcp_client_unref(link->dhcp_client);
105 sd_dhcp_lease_unref(link->dhcp_lease);
107 unlink(link->lease_file);
108 free(link->lease_file);
110 sd_ipv4ll_unref(link->ipv4ll);
112 hashmap_remove(link->manager->links, &link->ifindex);
116 unlink(link->state_file);
117 free(link->state_file);
119 udev_device_unref(link->udev_device);
124 Link *link_unref(Link *link) {
125 if (link && (-- link->n_ref <= 0))
131 Link *link_ref(Link *link) {
133 assert_se(++ link->n_ref >= 2);
138 int link_get(Manager *m, int ifindex, Link **ret) {
147 ifindex_64 = ifindex;
148 link = hashmap_get(m->links, &ifindex_64);
157 void link_drop(Link *link) {
158 if (!link || link->state == LINK_STATE_LINGER)
161 link->state = LINK_STATE_LINGER;
163 log_debug_link(link, "link removed");
170 static int link_enter_configured(Link *link) {
172 assert(link->state == LINK_STATE_SETTING_ROUTES);
174 log_info_link(link, "link configured");
176 link->state = LINK_STATE_CONFIGURED;
183 static void link_enter_unmanaged(Link *link) {
186 log_debug_link(link, "unmanaged");
188 link->state = LINK_STATE_UNMANAGED;
193 static int link_stop_clients(Link *link) {
197 assert(link->manager);
198 assert(link->manager->event);
203 if (link->network->dhcp) {
204 assert(link->dhcp_client);
206 k = sd_dhcp_client_stop(link->dhcp_client);
208 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
213 if (link->network->ipv4ll) {
214 assert(link->ipv4ll);
216 k = sd_ipv4ll_stop(link->ipv4ll);
218 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
226 static void link_enter_failed(Link *link) {
229 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
232 log_warning_link(link, "failed");
234 link->state = LINK_STATE_FAILED;
236 link_stop_clients(link);
241 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
242 Link *link = userdata;
245 assert(link->route_messages > 0);
246 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
247 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
250 link->route_messages --;
252 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
257 r = sd_rtnl_message_get_errno(m);
258 if (r < 0 && r != -EEXIST)
259 log_struct_link(LOG_WARNING, link,
260 "MESSAGE=%s: could not set route: %s",
261 link->ifname, strerror(-r),
265 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
267 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
268 log_debug_link(link, "routes set");
269 link_enter_configured(link);
277 static int link_enter_set_routes(Link *link) {
282 assert(link->network);
283 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
285 link->state = LINK_STATE_SETTING_ROUTES;
287 if (!link->network->static_routes && !link->dhcp_lease &&
288 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
289 return link_enter_configured(link);
291 log_debug_link(link, "setting routes");
293 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
294 r = route_configure(rt, link, &route_handler);
296 log_warning_link(link,
297 "could not set routes: %s", strerror(-r));
298 link_enter_failed(link);
303 link->route_messages ++;
306 if (link->ipv4ll && !link->dhcp_lease) {
307 _cleanup_route_free_ Route *route = NULL;
310 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
311 if (r < 0 && r != -ENOENT) {
312 log_warning_link(link, "IPV4LL error: no address: %s",
318 r = route_new_dynamic(&route);
320 log_error_link(link, "Could not allocate route: %s",
325 route->family = AF_INET;
326 route->scope = RT_SCOPE_LINK;
329 r = route_configure(route, link, &route_handler);
331 log_warning_link(link,
332 "could not set routes: %s", strerror(-r));
333 link_enter_failed(link);
338 link->route_messages ++;
342 if (link->dhcp_lease) {
343 _cleanup_route_free_ Route *route = NULL;
344 _cleanup_route_free_ Route *route_gw = NULL;
345 struct in_addr gateway;
347 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
348 if (r < 0 && r != -ENOENT) {
349 log_warning_link(link, "DHCP error: %s", strerror(-r));
354 r = route_new_dynamic(&route);
356 log_error_link(link, "Could not allocate route: %s",
361 r = route_new_dynamic(&route_gw);
363 log_error_link(link, "Could not allocate route: %s",
368 /* The dhcp netmask may mask out the gateway. Add an explicit
369 * route for the gw host so that we can route no matter the
370 * netmask or existing kernel route tables. */
371 route_gw->family = AF_INET;
372 route_gw->dst_addr.in = gateway;
373 route_gw->dst_prefixlen = 32;
374 route_gw->scope = RT_SCOPE_LINK;
376 r = route_configure(route_gw, link, &route_handler);
378 log_warning_link(link,
379 "could not set host route: %s", strerror(-r));
384 link->route_messages ++;
386 route->family = AF_INET;
387 route->in_addr.in = gateway;
389 r = route_configure(route, link, &route_handler);
391 log_warning_link(link,
392 "could not set routes: %s", strerror(-r));
393 link_enter_failed(link);
398 link->route_messages ++;
402 if (link->route_messages == 0) {
403 link_enter_configured(link);
409 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
410 Link *link = userdata;
415 assert(link->ifname);
417 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
422 r = sd_rtnl_message_get_errno(m);
423 if (r < 0 && r != -ESRCH)
424 log_struct_link(LOG_WARNING, link,
425 "MESSAGE=%s: could not drop route: %s",
426 link->ifname, strerror(-r),
435 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
436 Link *link = userdata;
441 assert(link->ifname);
442 assert(link->addr_messages > 0);
443 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
444 LINK_STATE_FAILED, LINK_STATE_LINGER));
446 link->addr_messages --;
448 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
453 r = sd_rtnl_message_get_errno(m);
454 if (r < 0 && r != -EEXIST)
455 log_struct_link(LOG_WARNING, link,
456 "MESSAGE=%s: could not set address: %s",
457 link->ifname, strerror(-r),
461 if (link->addr_messages == 0) {
462 log_debug_link(link, "addresses set");
463 link_enter_set_routes(link);
471 static int link_enter_set_addresses(Link *link) {
476 assert(link->network);
477 assert(link->state != _LINK_STATE_INVALID);
479 link->state = LINK_STATE_SETTING_ADDRESSES;
481 if (!link->network->static_addresses && !link->dhcp_lease &&
482 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
483 return link_enter_set_routes(link);
485 log_debug_link(link, "setting addresses");
487 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
488 r = address_configure(ad, link, &address_handler);
490 log_warning_link(link,
491 "could not set addresses: %s", strerror(-r));
492 link_enter_failed(link);
497 link->addr_messages ++;
500 if (link->ipv4ll && !link->dhcp_lease) {
501 _cleanup_address_free_ Address *ll_addr = NULL;
504 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
505 if (r < 0 && r != -ENOENT) {
506 log_warning_link(link, "IPV4LL error: no address: %s",
512 r = address_new_dynamic(&ll_addr);
514 log_error_link(link, "Could not allocate address: %s", strerror(-r));
518 ll_addr->family = AF_INET;
519 ll_addr->in_addr.in = addr;
520 ll_addr->prefixlen = 16;
521 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
522 ll_addr->scope = RT_SCOPE_LINK;
524 r = address_configure(ll_addr, link, &address_handler);
526 log_warning_link(link,
527 "could not set addresses: %s", strerror(-r));
528 link_enter_failed(link);
533 link->addr_messages ++;
537 if (link->dhcp_lease) {
538 _cleanup_address_free_ Address *address = NULL;
540 struct in_addr netmask;
543 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
545 log_warning_link(link, "DHCP error: no address: %s",
550 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
552 log_warning_link(link, "DHCP error: no netmask: %s",
557 prefixlen = net_netmask_to_prefixlen(&netmask);
559 r = address_new_dynamic(&address);
561 log_error_link(link, "Could not allocate address: %s",
566 address->family = AF_INET;
567 address->in_addr.in = addr;
568 address->prefixlen = prefixlen;
569 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
571 r = address_configure(address, link, &address_handler);
573 log_warning_link(link,
574 "could not set addresses: %s", strerror(-r));
575 link_enter_failed(link);
580 link->addr_messages ++;
586 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
587 Link *link = userdata;
592 assert(link->ifname);
594 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
599 r = sd_rtnl_message_get_errno(m);
600 if (r < 0 && r != -ENOENT)
601 log_struct_link(LOG_WARNING, link,
602 "MESSAGE=%s: could not update address: %s",
603 link->ifname, strerror(-r),
612 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
613 Link *link = userdata;
618 assert(link->ifname);
620 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
625 r = sd_rtnl_message_get_errno(m);
626 if (r < 0 && r != -EADDRNOTAVAIL)
627 log_struct_link(LOG_WARNING, link,
628 "MESSAGE=%s: could not drop address: %s",
629 link->ifname, strerror(-r),
638 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
639 Link *link = userdata;
644 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
649 r = sd_bus_message_get_errno(m);
651 log_warning("Could not set hostname: %s", strerror(-r));
658 static int link_set_hostname(Link *link, const char *hostname) {
659 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
663 assert(link->manager);
666 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
668 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
669 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
673 r = sd_bus_message_new_method_call(
676 "org.freedesktop.hostname1",
677 "/org/freedesktop/hostname1",
678 "org.freedesktop.hostname1",
683 r = sd_bus_message_append(m, "sb", hostname, false);
687 r = sd_bus_call_async(link->manager->bus, m, set_hostname_handler, link, 0, NULL);
689 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
696 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
697 Link *link = userdata;
702 assert(link->ifname);
704 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
709 r = sd_rtnl_message_get_errno(m);
711 log_struct_link(LOG_WARNING, link,
712 "MESSAGE=%s: could not set MTU: %s",
713 link->ifname, strerror(-r),
722 static int link_set_mtu(Link *link, uint32_t mtu) {
723 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
727 assert(link->manager);
728 assert(link->manager->rtnl);
730 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
732 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
733 RTM_SETLINK, link->ifindex);
735 log_error_link(link, "Could not allocate RTM_SETLINK message");
739 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
741 log_error_link(link, "Could not append MTU: %s", strerror(-r));
745 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
748 "Could not send rtnetlink message: %s", strerror(-r));
757 static int dhcp_lease_lost(Link *link) {
758 _cleanup_address_free_ Address *address = NULL;
759 _cleanup_route_free_ Route *route_gw = NULL;
760 _cleanup_route_free_ Route *route = NULL;
762 struct in_addr netmask;
763 struct in_addr gateway;
768 assert(link->dhcp_lease);
770 log_warning_link(link, "DHCP lease lost");
772 r = address_new_dynamic(&address);
774 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
776 r = route_new_dynamic(&route_gw);
778 route_gw->family = AF_INET;
779 route_gw->dst_addr.in = gateway;
780 route_gw->dst_prefixlen = 32;
781 route_gw->scope = RT_SCOPE_LINK;
783 route_drop(route_gw, link, &route_drop_handler);
787 r = route_new_dynamic(&route);
789 route->family = AF_INET;
790 route->in_addr.in = gateway;
792 route_drop(route, link, &route_drop_handler);
797 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
798 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
799 prefixlen = net_netmask_to_prefixlen(&netmask);
801 address->family = AF_INET;
802 address->in_addr.in = addr;
803 address->prefixlen = prefixlen;
805 address_drop(address, link, &address_drop_handler);
809 if (link->network->dhcp_mtu) {
812 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
813 if (r >= 0 && link->original_mtu != mtu) {
814 r = link_set_mtu(link, link->original_mtu);
816 log_warning_link(link, "DHCP error: could not reset MTU");
817 link_enter_failed(link);
823 if (link->network->dhcp_hostname) {
824 const char *hostname = NULL;
826 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
827 if (r >= 0 && hostname) {
828 r = link_set_hostname(link, "");
830 log_error("Failed to reset transient hostname");
834 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
839 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
840 sd_dhcp_lease *lease;
841 struct in_addr address;
842 struct in_addr netmask;
843 struct in_addr gateway;
845 struct in_addr *nameservers;
846 size_t nameservers_size;
852 r = sd_dhcp_client_get_lease(client, &lease);
854 log_warning_link(link, "DHCP error: no lease: %s",
859 r = sd_dhcp_lease_get_address(lease, &address);
861 log_warning_link(link, "DHCP error: no address: %s",
866 r = sd_dhcp_lease_get_netmask(lease, &netmask);
868 log_warning_link(link, "DHCP error: no netmask: %s",
873 prefixlen = net_netmask_to_prefixlen(&netmask);
875 r = sd_dhcp_lease_get_router(lease, &gateway);
876 if (r < 0 && r != -ENOENT) {
877 log_warning_link(link, "DHCP error: %s", strerror(-r));
882 log_struct_link(LOG_INFO, link,
883 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
885 ADDRESS_FMT_VAL(address),
887 ADDRESS_FMT_VAL(gateway),
888 "ADDRESS=%u.%u.%u.%u",
889 ADDRESS_FMT_VAL(address),
892 "GATEWAY=%u.%u.%u.%u",
893 ADDRESS_FMT_VAL(gateway),
896 log_struct_link(LOG_INFO, link,
897 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u",
899 ADDRESS_FMT_VAL(address),
901 "ADDRESS=%u.%u.%u.%u",
902 ADDRESS_FMT_VAL(address),
907 link->dhcp_lease = lease;
909 if (link->network->dhcp_dns) {
910 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
912 r = manager_update_resolv_conf(link->manager);
914 log_error("Failed to update resolv.conf");
918 if (link->network->dhcp_mtu) {
921 r = sd_dhcp_lease_get_mtu(lease, &mtu);
923 r = link_set_mtu(link, mtu);
925 log_error_link(link, "Failed to set MTU "
930 if (link->network->dhcp_hostname) {
931 const char *hostname;
933 r = sd_dhcp_lease_get_hostname(lease, &hostname);
935 r = link_set_hostname(link, hostname);
937 log_error("Failed to set transient hostname "
938 "to '%s'", hostname);
942 link_enter_set_addresses(link);
947 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
948 Link *link = userdata;
952 assert(link->network);
953 assert(link->manager);
955 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
959 case DHCP_EVENT_NO_LEASE:
960 log_debug_link(link, "IP address in use.");
962 case DHCP_EVENT_EXPIRED:
963 case DHCP_EVENT_STOP:
964 case DHCP_EVENT_IP_CHANGE:
965 if (link->network->dhcp_critical) {
966 log_error_link(link, "DHCPv4 connection considered system critical, "
967 "ignoring request to reconfigure it.");
971 if (link->dhcp_lease) {
972 r = dhcp_lease_lost(link);
974 link_enter_failed(link);
979 if (event == DHCP_EVENT_IP_CHANGE) {
980 r = dhcp_lease_acquired(client, link);
982 link_enter_failed(link);
987 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
988 if (!sd_ipv4ll_is_running(link->ipv4ll))
989 r = sd_ipv4ll_start(link->ipv4ll);
990 else if (ipv4ll_is_bound(link->ipv4ll))
991 r = ipv4ll_address_update(link, false);
993 link_enter_failed(link);
999 case DHCP_EVENT_IP_ACQUIRE:
1000 r = dhcp_lease_acquired(client, link);
1002 link_enter_failed(link);
1006 if (ipv4ll_is_bound(link->ipv4ll))
1007 r = ipv4ll_address_update(link, true);
1009 r = sd_ipv4ll_stop(link->ipv4ll);
1011 link_enter_failed(link);
1018 log_warning_link(link, "DHCP error: %s", strerror(-event));
1020 log_warning_link(link, "DHCP unknown event: %d", event);
1027 static int ipv4ll_address_update(Link *link, bool deprecate) {
1029 struct in_addr addr;
1033 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1035 _cleanup_address_free_ Address *address = NULL;
1037 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1038 deprecate ? "deprecate" : "approve",
1039 ADDRESS_FMT_VAL(addr));
1041 r = address_new_dynamic(&address);
1043 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1047 address->family = AF_INET;
1048 address->in_addr.in = addr;
1049 address->prefixlen = 16;
1050 address->scope = RT_SCOPE_LINK;
1051 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1052 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1054 address_update(address, link, &address_update_handler);
1062 static int ipv4ll_address_lost(Link *link) {
1064 struct in_addr addr;
1068 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1070 _cleanup_address_free_ Address *address = NULL;
1071 _cleanup_route_free_ Route *route = NULL;
1073 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1074 ADDRESS_FMT_VAL(addr));
1076 r = address_new_dynamic(&address);
1078 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1082 address->family = AF_INET;
1083 address->in_addr.in = addr;
1084 address->prefixlen = 16;
1085 address->scope = RT_SCOPE_LINK;
1087 address_drop(address, link, &address_drop_handler);
1090 r = route_new_dynamic(&route);
1092 log_error_link(link, "Could not allocate route: %s",
1097 route->family = AF_INET;
1098 route->scope = RT_SCOPE_LINK;
1099 route->metrics = 99;
1101 route_drop(route, link, &route_drop_handler);
1108 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1110 struct in_addr addr;
1114 r = sd_ipv4ll_get_address(ll, &addr);
1120 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1121 struct in_addr address;
1127 r = sd_ipv4ll_get_address(ll, &address);
1131 log_struct_link(LOG_INFO, link,
1132 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1134 ADDRESS_FMT_VAL(address),
1137 link_enter_set_addresses(link);
1142 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1143 Link *link = userdata;
1147 assert(link->network);
1148 assert(link->manager);
1150 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1154 case IPV4LL_EVENT_STOP:
1155 case IPV4LL_EVENT_CONFLICT:
1156 r = ipv4ll_address_lost(link);
1158 link_enter_failed(link);
1162 case IPV4LL_EVENT_BIND:
1163 r = ipv4ll_address_claimed(ll, link);
1165 link_enter_failed(link);
1171 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1173 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1178 static int link_acquire_conf(Link *link) {
1182 assert(link->network);
1183 assert(link->manager);
1184 assert(link->manager->event);
1186 if (link->network->ipv4ll) {
1187 assert(link->ipv4ll);
1189 log_debug_link(link, "acquiring IPv4 link-local address");
1191 r = sd_ipv4ll_start(link->ipv4ll);
1193 log_warning_link(link, "could not acquire IPv4 "
1194 "link-local address");
1199 if (link->network->dhcp) {
1200 assert(link->dhcp_client);
1202 log_debug_link(link, "acquiring DHCPv4 lease");
1204 r = sd_dhcp_client_start(link->dhcp_client);
1206 log_warning_link(link, "could not acquire DHCPv4 "
1215 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1216 /* see Documentation/networking/operstates.txt in the kernel sources */
1218 if (operstate == IF_OPER_UP)
1221 if (operstate == IF_OPER_UNKNOWN)
1222 /* operstate may not be implemented, so fall back to flags */
1223 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1229 #define FLAG_STRING(string, flag, old, new) \
1230 (((old ^ new) & flag) \
1231 ? ((old & flag) ? (" -" string) : (" +" string)) \
1234 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1235 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1237 bool carrier_gained = false, carrier_lost = false;
1242 r = sd_rtnl_message_link_get_flags(m, &flags);
1244 log_warning_link(link, "Could not get link flags");
1248 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1250 /* if we got a message without operstate, take it to mean
1251 the state was unchanged */
1252 operstate = link->operstate;
1254 if ((link->flags == flags) && (link->operstate == operstate))
1257 if (link->flags != flags) {
1258 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",
1259 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1260 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1261 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1262 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1263 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1264 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1265 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1266 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1267 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1268 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1269 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1270 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1271 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1272 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1273 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1274 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1275 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1276 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1277 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1279 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1280 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1281 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1282 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1283 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1284 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1285 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1286 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1288 /* link flags are currently at most 18 bits, let's align to printing 20 */
1289 if (unknown_flags_added)
1290 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1291 unknown_flags_added);
1293 if (unknown_flags_removed)
1294 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1295 unknown_flags_removed);
1298 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1299 link_has_carrier(flags, operstate);
1300 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1301 !link_has_carrier(flags, operstate);
1303 link->flags = flags;
1304 link->operstate = operstate;
1308 if (link->state == LINK_STATE_FAILED ||
1309 link->state == LINK_STATE_UNMANAGED)
1312 if (carrier_gained) {
1313 log_info_link(link, "gained carrier");
1315 if (link->network) {
1316 r = link_acquire_conf(link);
1318 link_enter_failed(link);
1322 } else if (carrier_lost) {
1323 log_info_link(link, "lost carrier");
1325 r = link_stop_clients(link);
1327 link_enter_failed(link);
1335 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1336 Link *link = userdata;
1341 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1346 r = sd_rtnl_message_get_errno(m);
1348 /* we warn but don't fail the link, as it may
1349 be brought up later */
1350 log_struct_link(LOG_WARNING, link,
1351 "MESSAGE=%s: could not bring up interface: %s",
1352 link->ifname, strerror(-r),
1362 static int link_up(Link *link) {
1363 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1367 assert(link->manager);
1368 assert(link->manager->rtnl);
1370 log_debug_link(link, "bringing link up");
1372 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1373 RTM_SETLINK, link->ifindex);
1375 log_error_link(link, "Could not allocate RTM_SETLINK message");
1379 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1381 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1385 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1387 log_error_link(link,
1388 "Could not send rtnetlink message: %s", strerror(-r));
1397 static int link_enslaved(Link *link) {
1401 assert(link->state == LINK_STATE_ENSLAVING);
1402 assert(link->network);
1404 if (!(link->flags & IFF_UP)) {
1407 link_enter_failed(link);
1412 if (!link->network->dhcp && !link->network->ipv4ll)
1413 return link_enter_set_addresses(link);
1418 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1419 Link *link = userdata;
1423 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1424 LINK_STATE_LINGER));
1425 assert(link->network);
1429 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1434 r = sd_rtnl_message_get_errno(m);
1436 log_struct_link(LOG_ERR, link,
1437 "MESSAGE=%s: could not enslave: %s",
1438 link->ifname, strerror(-r),
1441 link_enter_failed(link);
1446 log_debug_link(link, "enslaved");
1448 if (link->enslaving == 0)
1449 link_enslaved(link);
1456 static int link_enter_enslave(Link *link) {
1457 NetDev *vlan, *macvlan;
1462 assert(link->network);
1463 assert(link->state == LINK_STATE_INITIALIZING);
1465 link->state = LINK_STATE_ENSLAVING;
1469 if (!link->network->bridge && !link->network->bond &&
1470 hashmap_isempty(link->network->vlans) &&
1471 hashmap_isempty(link->network->macvlans))
1472 return link_enslaved(link);
1474 if (link->network->bond) {
1475 log_struct_link(LOG_DEBUG, link,
1476 "MESSAGE=%s: enslaving by '%s'",
1477 link->ifname, link->network->bond->name,
1478 NETDEV(link->network->bond),
1481 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1483 log_struct_link(LOG_WARNING, link,
1484 "MESSAGE=%s: could not enslave by '%s': %s",
1485 link->ifname, link->network->bond->name, strerror(-r),
1486 NETDEV(link->network->bond),
1488 link_enter_failed(link);
1496 if (link->network->bridge) {
1497 log_struct_link(LOG_DEBUG, link,
1498 "MESSAGE=%s: enslaving by '%s'",
1499 link->ifname, link->network->bridge->name,
1500 NETDEV(link->network->bridge),
1503 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1505 log_struct_link(LOG_WARNING, link,
1506 "MESSAGE=%s: could not enslave by '%s': %s",
1507 link->ifname, link->network->bridge->name, strerror(-r),
1508 NETDEV(link->network->bridge),
1510 link_enter_failed(link);
1518 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1519 log_struct_link(LOG_DEBUG, link,
1520 "MESSAGE=%s: enslaving by '%s'",
1521 link->ifname, vlan->name, NETDEV(vlan), NULL);
1523 r = netdev_enslave(vlan, link, &enslave_handler);
1525 log_struct_link(LOG_WARNING, link,
1526 "MESSAGE=%s: could not enslave by '%s': %s",
1527 link->ifname, vlan->name, strerror(-r),
1528 NETDEV(vlan), NULL);
1529 link_enter_failed(link);
1537 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1538 log_struct_link(LOG_DEBUG, link,
1539 "MESSAGE=%s: enslaving by '%s'",
1540 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1542 r = netdev_enslave(macvlan, link, &enslave_handler);
1544 log_struct_link(LOG_WARNING, link,
1545 "MESSAGE=%s: could not enslave by '%s': %s",
1546 link->ifname, macvlan->name, strerror(-r),
1547 NETDEV(macvlan), NULL);
1548 link_enter_failed(link);
1559 static int link_configure(Link *link) {
1563 assert(link->state == LINK_STATE_INITIALIZING);
1565 if (link->network->ipv4ll) {
1568 r = sd_ipv4ll_new(&link->ipv4ll);
1572 if (link->udev_device) {
1573 r = net_get_unique_predictable_data(link->udev_device, seed);
1575 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1581 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1585 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1589 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1593 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1598 if (link->network->dhcp) {
1599 r = sd_dhcp_client_new(&link->dhcp_client);
1603 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1607 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1611 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1615 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1619 if (link->network->dhcp_mtu) {
1620 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1626 if (link_has_carrier(link->flags, link->operstate)) {
1627 r = link_acquire_conf(link);
1632 return link_enter_enslave(link);
1635 int link_initialized(Link *link, struct udev_device *device) {
1640 assert(link->ifname);
1641 assert(link->manager);
1643 if (link->state != LINK_STATE_INITIALIZING)
1647 link->udev_device = udev_device_ref(device);
1649 log_debug_link(link, "link initialized");
1651 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1653 link_enter_unmanaged(link);
1658 r = network_apply(link->manager, network, link);
1662 r = link_configure(link);
1669 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1671 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1672 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1679 r = link_new(m, message, ret);
1685 log_debug_link(link, "link added");
1687 if (detect_container(NULL) <= 0) {
1688 /* not in a container, udev will be around */
1689 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1690 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1692 log_warning_link(link, "could not find udev device");
1696 if (udev_device_get_is_initialized(device) <= 0)
1701 r = link_initialized(link, device);
1708 int link_update(Link *link, sd_rtnl_message *m) {
1709 struct ether_addr mac;
1714 assert(link->ifname);
1717 if (link->state == LINK_STATE_LINGER) {
1719 log_info_link(link, "link readded");
1720 link->state = LINK_STATE_ENSLAVING;
1723 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1724 if (r >= 0 && !streq(ifname, link->ifname)) {
1725 log_info_link(link, "renamed to %s", ifname);
1728 link->ifname = strdup(ifname);
1733 if (!link->original_mtu) {
1734 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1736 log_debug_link(link, "saved original MTU: %"
1737 PRIu16, link->original_mtu);
1740 /* The kernel may broadcast NEWLINK messages without the MAC address
1741 set, simply ignore them. */
1742 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1744 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1746 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1748 log_debug_link(link, "MAC address: "
1749 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1750 mac.ether_addr_octet[0],
1751 mac.ether_addr_octet[1],
1752 mac.ether_addr_octet[2],
1753 mac.ether_addr_octet[3],
1754 mac.ether_addr_octet[4],
1755 mac.ether_addr_octet[5]);
1758 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1760 log_warning_link(link, "Could not update MAC "
1761 "address in IPv4LL client: %s",
1767 if (link->dhcp_client) {
1768 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1770 log_warning_link(link, "Could not update MAC "
1771 "address in DHCP client: %s",
1779 return link_update_flags(link, m);
1782 int link_save(Link *link) {
1783 _cleanup_free_ char *temp_path = NULL;
1784 _cleanup_fclose_ FILE *f = NULL;
1785 const char *admin_state, *oper_state = "unknown";
1789 assert(link->state_file);
1790 assert(link->lease_file);
1791 assert(link->manager);
1793 r = manager_save(link->manager);
1797 if (link->state == LINK_STATE_LINGER) {
1798 unlink(link->state_file);
1802 admin_state = link_state_to_string(link->state);
1803 assert(admin_state);
1805 if (link->operstate == IF_OPER_DORMANT)
1806 oper_state = "dormant";
1807 else if (link_has_carrier(link->flags, link->operstate))
1808 oper_state = "carrier";
1810 r = fopen_temporary(link->state_file, &f, &temp_path);
1814 fchmod(fileno(f), 0644);
1817 "# This is private data. Do not parse.\n"
1821 admin_state, oper_state, link->flags);
1823 if (link->dhcp_lease) {
1824 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
1828 fprintf(f, "DHCP_LEASE=%s\n", link->lease_file);
1830 unlink(link->lease_file);
1834 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1836 unlink(link->state_file);
1842 log_error("Failed to save link data to %s: %s", link->state_file, strerror(-r));
1847 static const char* const link_state_table[_LINK_STATE_MAX] = {
1848 [LINK_STATE_INITIALIZING] = "initializing",
1849 [LINK_STATE_ENSLAVING] = "configuring",
1850 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1851 [LINK_STATE_SETTING_ROUTES] = "configuring",
1852 [LINK_STATE_CONFIGURED] = "configured",
1853 [LINK_STATE_UNMANAGED] = "unmanaged",
1854 [LINK_STATE_FAILED] = "failed",
1855 [LINK_STATE_LINGER] = "linger",
1858 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);