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_free_ 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);
70 link->manager = manager;
71 link->state = LINK_STATE_INITIALIZING;
72 link->ifindex = ifindex;
73 link->ifname = strdup(ifname);
77 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
82 r = hashmap_put(manager->links, &link->ifindex, link);
92 void link_free(Link *link) {
96 assert(link->manager);
98 sd_dhcp_client_unref(link->dhcp_client);
99 sd_dhcp_lease_unref(link->dhcp_lease);
101 sd_ipv4ll_unref(link->ipv4ll);
103 hashmap_remove(link->manager->links, &link->ifindex);
106 free(link->state_file);
108 udev_device_unref(link->udev_device);
113 int link_get(Manager *m, int ifindex, Link **ret) {
122 ifindex_64 = ifindex;
123 link = hashmap_get(m->links, &ifindex_64);
132 static int link_enter_configured(Link *link) {
134 assert(link->state == LINK_STATE_SETTING_ROUTES);
136 log_info_link(link, "link configured");
138 link->state = LINK_STATE_CONFIGURED;
145 static void link_enter_unmanaged(Link *link) {
148 log_debug_link(link, "unmanaged");
150 link->state = LINK_STATE_UNMANAGED;
155 static int link_stop_clients(Link *link) {
159 assert(link->manager);
160 assert(link->manager->event);
165 if (link->network->dhcp) {
166 assert(link->dhcp_client);
168 k = sd_dhcp_client_stop(link->dhcp_client);
170 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
175 if (link->network->ipv4ll) {
176 assert(link->ipv4ll);
178 k = sd_ipv4ll_stop(link->ipv4ll);
180 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
188 static void link_enter_failed(Link *link) {
191 if (link->state == LINK_STATE_FAILED)
194 log_warning_link(link, "failed");
196 link->state = LINK_STATE_FAILED;
198 link_stop_clients(link);
203 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
204 Link *link = userdata;
207 assert(link->route_messages > 0);
208 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
209 link->state == LINK_STATE_SETTING_ROUTES ||
210 link->state == LINK_STATE_FAILED);
212 link->route_messages --;
214 if (link->state == LINK_STATE_FAILED)
217 r = sd_rtnl_message_get_errno(m);
218 if (r < 0 && r != -EEXIST)
219 log_struct_link(LOG_WARNING, link,
220 "MESSAGE=%s: could not set route: %s",
221 link->ifname, strerror(-r),
225 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
227 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
228 log_debug_link(link, "routes set");
229 link_enter_configured(link);
235 static int link_enter_set_routes(Link *link) {
240 assert(link->network);
241 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
243 link->state = LINK_STATE_SETTING_ROUTES;
245 if (!link->network->static_routes && !link->dhcp_lease &&
246 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
247 return link_enter_configured(link);
249 log_debug_link(link, "setting routes");
251 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
252 r = route_configure(rt, link, &route_handler);
254 log_warning_link(link,
255 "could not set routes: %s", strerror(-r));
256 link_enter_failed(link);
260 link->route_messages ++;
263 if (link->ipv4ll && !link->dhcp_lease) {
264 _cleanup_route_free_ Route *route = NULL;
267 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
268 if (r < 0 && r != -ENOENT) {
269 log_warning_link(link, "IPV4LL error: no address: %s",
275 r = route_new_dynamic(&route);
277 log_error_link(link, "Could not allocate route: %s",
282 route->family = AF_INET;
283 route->scope = RT_SCOPE_LINK;
286 r = route_configure(route, link, &route_handler);
288 log_warning_link(link,
289 "could not set routes: %s", strerror(-r));
290 link_enter_failed(link);
294 link->route_messages ++;
298 if (link->dhcp_lease) {
299 _cleanup_route_free_ Route *route = NULL;
300 _cleanup_route_free_ Route *route_gw = NULL;
301 struct in_addr gateway;
303 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
304 if (r < 0 && r != -ENOENT) {
305 log_warning_link(link, "DHCP error: %s", strerror(-r));
310 r = route_new_dynamic(&route);
312 log_error_link(link, "Could not allocate route: %s",
317 r = route_new_dynamic(&route_gw);
319 log_error_link(link, "Could not allocate route: %s",
324 /* The dhcp netmask may mask out the gateway. Add an explicit
325 * route for the gw host so that we can route no matter the
326 * netmask or existing kernel route tables. */
327 route_gw->family = AF_INET;
328 route_gw->dst_addr.in = gateway;
329 route_gw->dst_prefixlen = 32;
330 route_gw->scope = RT_SCOPE_LINK;
332 r = route_configure(route_gw, link, &route_handler);
334 log_warning_link(link,
335 "could not set host route: %s", strerror(-r));
339 link->route_messages ++;
341 route->family = AF_INET;
342 route->in_addr.in = gateway;
344 r = route_configure(route, link, &route_handler);
346 log_warning_link(link,
347 "could not set routes: %s", strerror(-r));
348 link_enter_failed(link);
352 link->route_messages ++;
356 if (link->route_messages == 0) {
357 link_enter_configured(link);
363 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
364 Link *link = userdata;
369 assert(link->ifname);
371 if (link->state == LINK_STATE_FAILED)
374 r = sd_rtnl_message_get_errno(m);
375 if (r < 0 && r != -ENOENT)
376 log_struct_link(LOG_WARNING, link,
377 "MESSAGE=%s: could not drop route: %s",
378 link->ifname, strerror(-r),
385 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
386 Link *link = userdata;
391 assert(link->ifname);
392 assert(link->addr_messages > 0);
393 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
395 link->addr_messages --;
397 if (link->state == LINK_STATE_FAILED)
400 r = sd_rtnl_message_get_errno(m);
401 if (r < 0 && r != -EEXIST)
402 log_struct_link(LOG_WARNING, link,
403 "MESSAGE=%s: could not set address: %s",
404 link->ifname, strerror(-r),
408 if (link->addr_messages == 0) {
409 log_debug_link(link, "addresses set");
410 link_enter_set_routes(link);
416 static int link_enter_set_addresses(Link *link) {
421 assert(link->network);
422 assert(link->state != _LINK_STATE_INVALID);
424 link->state = LINK_STATE_SETTING_ADDRESSES;
426 if (!link->network->static_addresses && !link->dhcp_lease &&
427 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
428 return link_enter_set_routes(link);
430 log_debug_link(link, "setting addresses");
432 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
433 r = address_configure(ad, link, &address_handler);
435 log_warning_link(link,
436 "could not set addresses: %s", strerror(-r));
437 link_enter_failed(link);
441 link->addr_messages ++;
444 if (link->ipv4ll && !link->dhcp_lease) {
445 _cleanup_address_free_ Address *ll_addr = NULL;
448 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
449 if (r < 0 && r != -ENOENT) {
450 log_warning_link(link, "IPV4LL error: no address: %s",
456 r = address_new_dynamic(&ll_addr);
458 log_error_link(link, "Could not allocate address: %s", strerror(-r));
462 ll_addr->family = AF_INET;
463 ll_addr->in_addr.in = addr;
464 ll_addr->prefixlen = 16;
465 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
466 ll_addr->scope = RT_SCOPE_LINK;
468 r = address_configure(ll_addr, link, &address_handler);
470 log_warning_link(link,
471 "could not set addresses: %s", strerror(-r));
472 link_enter_failed(link);
476 link->addr_messages ++;
480 if (link->dhcp_lease) {
481 _cleanup_address_free_ Address *address = NULL;
483 struct in_addr netmask;
486 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
488 log_warning_link(link, "DHCP error: no address: %s",
493 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
495 log_warning_link(link, "DHCP error: no netmask: %s",
500 prefixlen = net_netmask_to_prefixlen(&netmask);
502 r = address_new_dynamic(&address);
504 log_error_link(link, "Could not allocate address: %s",
509 address->family = AF_INET;
510 address->in_addr.in = addr;
511 address->prefixlen = prefixlen;
512 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
514 r = address_configure(address, link, &address_handler);
516 log_warning_link(link,
517 "could not set addresses: %s", strerror(-r));
518 link_enter_failed(link);
522 link->addr_messages ++;
528 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
529 Link *link = userdata;
534 assert(link->ifname);
536 if (link->state == LINK_STATE_FAILED)
539 r = sd_rtnl_message_get_errno(m);
540 if (r < 0 && r != -ENOENT)
541 log_struct_link(LOG_WARNING, link,
542 "MESSAGE=%s: could not update address: %s",
543 link->ifname, strerror(-r),
550 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
551 Link *link = userdata;
556 assert(link->ifname);
558 if (link->state == LINK_STATE_FAILED)
561 r = sd_rtnl_message_get_errno(m);
562 if (r < 0 && r != -ENOENT)
563 log_struct_link(LOG_WARNING, link,
564 "MESSAGE=%s: could not drop address: %s",
565 link->ifname, strerror(-r),
572 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
575 r = sd_bus_message_get_errno(m);
577 log_warning("Could not set hostname: %s", strerror(-r));
582 static int set_hostname(sd_bus *bus, const char *hostname) {
583 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
588 log_debug("Setting transient hostname: '%s'", hostname);
590 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
591 log_info("Not connected to system bus, ignoring transient hostname.");
595 r = sd_bus_message_new_method_call(
598 "org.freedesktop.hostname1",
599 "/org/freedesktop/hostname1",
600 "org.freedesktop.hostname1",
605 r = sd_bus_message_append(m, "sb", hostname, false);
609 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
611 log_error("Could not set transient hostname: %s", strerror(-r));
616 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
617 Link *link = userdata;
622 assert(link->ifname);
624 if (link->state == LINK_STATE_FAILED)
627 r = sd_rtnl_message_get_errno(m);
629 log_struct_link(LOG_WARNING, link,
630 "MESSAGE=%s: could not set MTU: %s",
631 link->ifname, strerror(-r),
638 static int link_set_mtu(Link *link, uint32_t mtu) {
639 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
643 assert(link->manager);
644 assert(link->manager->rtnl);
646 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
648 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
649 RTM_SETLINK, link->ifindex);
651 log_error_link(link, "Could not allocate RTM_SETLINK message");
655 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
657 log_error_link(link, "Could not append MTU: %s", strerror(-r));
661 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
664 "Could not send rtnetlink message: %s", strerror(-r));
671 static int dhcp_lease_lost(Link *link) {
672 _cleanup_address_free_ Address *address = NULL;
673 _cleanup_route_free_ Route *route_gw = NULL;
674 _cleanup_route_free_ Route *route = NULL;
676 struct in_addr netmask;
677 struct in_addr gateway;
682 assert(link->dhcp_lease);
684 log_warning_link(link, "DHCP lease lost");
686 r = address_new_dynamic(&address);
688 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
690 r = route_new_dynamic(&route_gw);
692 route_gw->family = AF_INET;
693 route_gw->dst_addr.in = gateway;
694 route_gw->dst_prefixlen = 32;
695 route_gw->scope = RT_SCOPE_LINK;
697 route_drop(route_gw, link, &route_drop_handler);
700 r = route_new_dynamic(&route);
702 route->family = AF_INET;
703 route->in_addr.in = gateway;
705 route_drop(route, link, &route_drop_handler);
709 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
710 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
711 prefixlen = net_netmask_to_prefixlen(&netmask);
713 address->family = AF_INET;
714 address->in_addr.in = addr;
715 address->prefixlen = prefixlen;
717 address_drop(address, link, &address_drop_handler);
720 if (link->network->dhcp_mtu) {
723 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
724 if (r >= 0 && link->original_mtu != mtu) {
725 r = link_set_mtu(link, link->original_mtu);
727 log_warning_link(link, "DHCP error: could not reset MTU");
728 link_enter_failed(link);
734 if (link->network->dhcp_hostname) {
735 const char *hostname = NULL;
737 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
738 if (r >= 0 && hostname) {
739 r = set_hostname(link->manager->bus, "");
741 log_error("Failed to reset transient hostname");
745 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
750 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
751 sd_dhcp_lease *lease;
752 struct in_addr address;
753 struct in_addr netmask;
754 struct in_addr gateway;
756 struct in_addr *nameservers;
757 size_t nameservers_size;
763 r = sd_dhcp_client_get_lease(client, &lease);
765 log_warning_link(link, "DHCP error: no lease: %s",
770 r = sd_dhcp_lease_get_address(lease, &address);
772 log_warning_link(link, "DHCP error: no address: %s",
777 r = sd_dhcp_lease_get_netmask(lease, &netmask);
779 log_warning_link(link, "DHCP error: no netmask: %s",
784 prefixlen = net_netmask_to_prefixlen(&netmask);
786 r = sd_dhcp_lease_get_router(lease, &gateway);
787 if (r < 0 && r != -ENOENT) {
788 log_warning_link(link, "DHCP error: %s", strerror(-r));
793 log_struct_link(LOG_INFO, link,
794 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
796 ADDRESS_FMT_VAL(address),
798 ADDRESS_FMT_VAL(gateway),
799 "ADDRESS=%u.%u.%u.%u",
800 ADDRESS_FMT_VAL(address),
803 "GATEWAY=%u.%u.%u.%u",
804 ADDRESS_FMT_VAL(gateway),
807 log_struct_link(LOG_INFO, link,
808 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u",
810 ADDRESS_FMT_VAL(address),
812 "ADDRESS=%u.%u.%u.%u",
813 ADDRESS_FMT_VAL(address),
818 link->dhcp_lease = lease;
820 if (link->network->dhcp_dns) {
821 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
823 r = manager_update_resolv_conf(link->manager);
825 log_error("Failed to update resolv.conf");
829 if (link->network->dhcp_mtu) {
832 r = sd_dhcp_lease_get_mtu(lease, &mtu);
834 r = link_set_mtu(link, mtu);
836 log_error_link(link, "Failed to set MTU "
841 if (link->network->dhcp_hostname) {
842 const char *hostname;
844 r = sd_dhcp_lease_get_hostname(lease, &hostname);
846 r = set_hostname(link->manager->bus, hostname);
848 log_error("Failed to set transient hostname "
849 "to '%s'", hostname);
853 link_enter_set_addresses(link);
858 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
859 Link *link = userdata;
863 assert(link->network);
864 assert(link->manager);
866 if (link->state == LINK_STATE_FAILED)
870 case DHCP_EVENT_NO_LEASE:
871 log_debug_link(link, "IP address in use.");
873 case DHCP_EVENT_EXPIRED:
874 case DHCP_EVENT_STOP:
875 case DHCP_EVENT_IP_CHANGE:
876 if (link->network->dhcp_critical) {
877 log_error_link(link, "DHCPv4 connection considered system critical, "
878 "ignoring request to reconfigure it.");
882 if (link->dhcp_lease) {
883 r = dhcp_lease_lost(link);
885 link_enter_failed(link);
890 if (event == DHCP_EVENT_IP_CHANGE) {
891 r = dhcp_lease_acquired(client, link);
893 link_enter_failed(link);
898 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
899 if (!sd_ipv4ll_is_running(link->ipv4ll))
900 r = sd_ipv4ll_start(link->ipv4ll);
901 else if (ipv4ll_is_bound(link->ipv4ll))
902 r = ipv4ll_address_update(link, false);
904 link_enter_failed(link);
910 case DHCP_EVENT_IP_ACQUIRE:
911 r = dhcp_lease_acquired(client, link);
913 link_enter_failed(link);
917 if (ipv4ll_is_bound(link->ipv4ll))
918 r = ipv4ll_address_update(link, true);
920 r = sd_ipv4ll_stop(link->ipv4ll);
922 link_enter_failed(link);
929 log_warning_link(link, "DHCP error: %s", strerror(-event));
931 log_warning_link(link, "DHCP unknown event: %d", event);
938 static int ipv4ll_address_update(Link *link, bool deprecate) {
944 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
946 _cleanup_address_free_ Address *address = NULL;
948 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
949 deprecate ? "deprecate" : "approve",
950 ADDRESS_FMT_VAL(addr));
952 r = address_new_dynamic(&address);
954 log_error_link(link, "Could not allocate address: %s", strerror(-r));
958 address->family = AF_INET;
959 address->in_addr.in = addr;
960 address->prefixlen = 16;
961 address->scope = RT_SCOPE_LINK;
962 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
963 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
965 address_update(address, link, &address_update_handler);
972 static int ipv4ll_address_lost(Link *link) {
978 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
980 _cleanup_address_free_ Address *address = NULL;
981 _cleanup_route_free_ Route *route = NULL;
983 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
984 ADDRESS_FMT_VAL(addr));
986 r = address_new_dynamic(&address);
988 log_error_link(link, "Could not allocate address: %s", strerror(-r));
992 address->family = AF_INET;
993 address->in_addr.in = addr;
994 address->prefixlen = 16;
995 address->scope = RT_SCOPE_LINK;
997 address_drop(address, link, &address_drop_handler);
999 r = route_new_dynamic(&route);
1001 log_error_link(link, "Could not allocate route: %s",
1006 route->family = AF_INET;
1007 route->scope = RT_SCOPE_LINK;
1008 route->metrics = 99;
1010 route_drop(route, link, &route_drop_handler);
1016 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1018 struct in_addr addr;
1022 r = sd_ipv4ll_get_address(ll, &addr);
1028 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1029 struct in_addr address;
1035 r = sd_ipv4ll_get_address(ll, &address);
1039 log_struct_link(LOG_INFO, link,
1040 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1042 ADDRESS_FMT_VAL(address),
1045 link_enter_set_addresses(link);
1050 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1051 Link *link = userdata;
1055 assert(link->network);
1056 assert(link->manager);
1059 case IPV4LL_EVENT_STOP:
1060 case IPV4LL_EVENT_CONFLICT:
1061 r = ipv4ll_address_lost(link);
1063 link_enter_failed(link);
1067 case IPV4LL_EVENT_BIND:
1068 r = ipv4ll_address_claimed(ll, link);
1070 link_enter_failed(link);
1076 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1078 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1083 static int link_acquire_conf(Link *link) {
1087 assert(link->network);
1088 assert(link->manager);
1089 assert(link->manager->event);
1091 if (link->network->ipv4ll) {
1092 assert(link->ipv4ll);
1094 log_debug_link(link, "acquiring IPv4 link-local address");
1096 r = sd_ipv4ll_start(link->ipv4ll);
1098 log_warning_link(link, "could not acquire IPv4 "
1099 "link-local address");
1104 if (link->network->dhcp) {
1105 assert(link->dhcp_client);
1107 log_debug_link(link, "acquiring DHCPv4 lease");
1109 r = sd_dhcp_client_start(link->dhcp_client);
1111 log_warning_link(link, "could not acquire DHCPv4 "
1120 static bool link_has_carrier(unsigned flags, uint8_t operstate) {
1121 /* see Documentation/networking/operstates.txt in the kernel sources */
1123 if (operstate == IF_OPER_UP)
1126 if (operstate == IF_OPER_UNKNOWN)
1127 /* operstate may not be implemented, so fall back to flags */
1128 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1134 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1135 unsigned flags, flags_added, flags_removed, generic_flags;
1137 bool carrier_gained = false, carrier_lost = false;
1142 if (link->state == LINK_STATE_FAILED)
1145 r = sd_rtnl_message_link_get_flags(m, &flags);
1147 log_warning_link(link, "Could not get link flags");
1151 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1153 /* if we got a message without operstate, take it to mean
1154 the state was unchanged */
1155 operstate = link->operstate;
1157 if ((link->flags == flags) && (link->operstate == operstate))
1160 flags_added = (link->flags ^ flags) & flags;
1161 flags_removed = (link->flags ^ flags) & link->flags;
1162 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1163 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1164 IFF_NOARP | IFF_MASTER | IFF_SLAVE | IFF_RUNNING);
1166 if (flags_added & IFF_UP)
1167 log_debug_link(link, "link is up");
1168 else if (flags_removed & IFF_UP)
1169 log_debug_link(link, "link is down");
1171 if (flags_added & IFF_LOWER_UP)
1172 log_debug_link(link, "link is lower up");
1173 else if (flags_removed & IFF_LOWER_UP)
1174 log_debug_link(link, "link is lower down");
1176 if (flags_added & IFF_DORMANT)
1177 log_debug_link(link, "link is dormant");
1178 else if (flags_removed & IFF_DORMANT)
1179 log_debug_link(link, "link is not dormant");
1181 if (flags_added & IFF_DEBUG)
1182 log_debug_link(link, "debugging enabled in the kernel");
1183 else if (flags_removed & IFF_DEBUG)
1184 log_debug_link(link, "debugging disabled in the kernel");
1186 if (flags_added & IFF_MULTICAST)
1187 log_debug_link(link, "multicast enabled");
1188 else if (flags_removed & IFF_MULTICAST)
1189 log_debug_link(link, "multicast disabled");
1191 if (flags_added & IFF_BROADCAST)
1192 log_debug_link(link, "broadcast enabled");
1193 else if (flags_removed & IFF_BROADCAST)
1194 log_debug_link(link, "broadcast disabled");
1196 if (flags_added & IFF_PROMISC)
1197 log_debug_link(link, "promiscuous mode enabled");
1198 else if (flags_removed & IFF_PROMISC)
1199 log_debug_link(link, "promiscuous mode disabled");
1201 if (flags_added & IFF_NOARP)
1202 log_debug_link(link, "ARP protocol disabled");
1203 else if (flags_removed & IFF_NOARP)
1204 log_debug_link(link, "ARP protocol enabled");
1206 if (flags_added & IFF_MASTER)
1207 log_debug_link(link, "link is master");
1208 else if (flags_removed & IFF_MASTER)
1209 log_debug_link(link, "link is no longer master");
1211 if (flags_added & IFF_SLAVE)
1212 log_debug_link(link, "link is slave");
1213 else if (flags_removed & IFF_SLAVE)
1214 log_debug_link(link, "link is no longer slave");
1216 /* link flags are currently at most 18 bits, let's default to printing 20 */
1217 if (flags_added & generic_flags)
1218 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1219 flags_added & generic_flags);
1221 if (flags_removed & generic_flags)
1222 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1223 flags_removed & generic_flags);
1225 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1226 link_has_carrier(flags, operstate);
1227 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1228 !link_has_carrier(flags, operstate);
1230 link->flags = flags;
1231 link->operstate = operstate;
1235 if (carrier_gained) {
1236 log_info_link(link, "gained carrier");
1238 if (link->network) {
1239 r = link_acquire_conf(link);
1241 link_enter_failed(link);
1245 } else if (carrier_lost) {
1246 log_info_link(link, "lost carrier");
1248 r = link_stop_clients(link);
1250 link_enter_failed(link);
1258 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1259 Link *link = userdata;
1264 if (link->state == LINK_STATE_FAILED)
1267 r = sd_rtnl_message_get_errno(m);
1269 /* we warn but don't fail the link, as it may
1270 be brought up later */
1271 log_struct_link(LOG_WARNING, link,
1272 "MESSAGE=%s: could not bring up interface: %s",
1273 link->ifname, strerror(-r),
1281 static int link_up(Link *link) {
1282 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1286 assert(link->manager);
1287 assert(link->manager->rtnl);
1289 log_debug_link(link, "bringing link up");
1291 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1292 RTM_SETLINK, link->ifindex);
1294 log_error_link(link, "Could not allocate RTM_SETLINK message");
1298 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1300 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1304 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1306 log_error_link(link,
1307 "Could not send rtnetlink message: %s", strerror(-r));
1314 static int link_enslaved(Link *link) {
1318 assert(link->state == LINK_STATE_ENSLAVING);
1319 assert(link->network);
1321 if (!(link->flags & IFF_UP)) {
1324 link_enter_failed(link);
1329 if (!link->network->dhcp && !link->network->ipv4ll)
1330 return link_enter_set_addresses(link);
1335 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1336 Link *link = userdata;
1340 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1341 assert(link->network);
1345 if (link->state == LINK_STATE_FAILED)
1348 r = sd_rtnl_message_get_errno(m);
1350 log_struct_link(LOG_ERR, link,
1351 "MESSAGE=%s: could not enslave: %s",
1352 link->ifname, strerror(-r),
1355 link_enter_failed(link);
1359 log_debug_link(link, "enslaved");
1361 if (link->enslaving == 0)
1362 link_enslaved(link);
1367 static int link_enter_enslave(Link *link) {
1368 NetDev *vlan, *macvlan;
1373 assert(link->network);
1374 assert(link->state == LINK_STATE_INITIALIZING);
1376 link->state = LINK_STATE_ENSLAVING;
1380 if (!link->network->bridge && !link->network->bond &&
1381 hashmap_isempty(link->network->vlans) &&
1382 hashmap_isempty(link->network->macvlans))
1383 return link_enslaved(link);
1385 if (link->network->bridge) {
1386 log_struct_link(LOG_DEBUG, link,
1387 "MESSAGE=%s: enslaving by '%s'",
1388 link->ifname, link->network->bridge->name,
1389 NETDEV(link->network->bridge),
1392 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1394 log_struct_link(LOG_WARNING, link,
1395 "MESSAGE=%s: could not enslave by '%s': %s",
1396 link->ifname, link->network->bridge->name, strerror(-r),
1397 NETDEV(link->network->bridge),
1399 link_enter_failed(link);
1406 if (link->network->bond) {
1407 log_struct_link(LOG_DEBUG, link,
1408 "MESSAGE=%s: enslaving by '%s'",
1409 link->ifname, link->network->bond->name,
1410 NETDEV(link->network->bond),
1413 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1415 log_struct_link(LOG_WARNING, link,
1416 "MESSAGE=%s: could not enslave by '%s': %s",
1417 link->ifname, link->network->bond->name, strerror(-r),
1418 NETDEV(link->network->bond),
1420 link_enter_failed(link);
1427 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1428 log_struct_link(LOG_DEBUG, link,
1429 "MESSAGE=%s: enslaving by '%s'",
1430 link->ifname, vlan->name, NETDEV(vlan), NULL);
1432 r = netdev_enslave(vlan, link, &enslave_handler);
1434 log_struct_link(LOG_WARNING, link,
1435 "MESSAGE=%s: could not enslave by '%s': %s",
1436 link->ifname, vlan->name, strerror(-r),
1437 NETDEV(vlan), NULL);
1438 link_enter_failed(link);
1445 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1446 log_struct_link(LOG_DEBUG, link,
1447 "MESSAGE=%s: enslaving by '%s'",
1448 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1450 r = netdev_enslave(macvlan, link, &enslave_handler);
1452 log_struct_link(LOG_WARNING, link,
1453 "MESSAGE=%s: could not enslave by '%s': %s",
1454 link->ifname, macvlan->name, strerror(-r),
1455 NETDEV(macvlan), NULL);
1456 link_enter_failed(link);
1466 static int link_configure(Link *link) {
1470 assert(link->state == LINK_STATE_INITIALIZING);
1472 if (link->network->ipv4ll) {
1475 r = sd_ipv4ll_new(&link->ipv4ll);
1479 if (link->udev_device) {
1480 r = net_get_unique_predictable_data(link->udev_device, seed);
1482 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1488 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1492 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1496 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1500 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1505 if (link->network->dhcp) {
1506 r = sd_dhcp_client_new(&link->dhcp_client);
1510 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1514 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1518 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1522 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1526 if (link->network->dhcp_mtu) {
1527 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1533 if (link_has_carrier(link->flags, link->operstate)) {
1534 r = link_acquire_conf(link);
1539 return link_enter_enslave(link);
1542 int link_initialized(Link *link, struct udev_device *device) {
1547 assert(link->ifname);
1548 assert(link->manager);
1550 if (link->state != LINK_STATE_INITIALIZING)
1554 link->udev_device = udev_device_ref(device);
1556 log_debug_link(link, "link initialized");
1558 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1560 link_enter_unmanaged(link);
1565 r = network_apply(link->manager, network, link);
1569 r = link_configure(link);
1576 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1578 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1579 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1586 r = link_new(m, message, ret);
1592 log_debug_link(link, "link added");
1594 if (detect_container(NULL) <= 0) {
1595 /* not in a container, udev will be around */
1596 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1597 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1599 log_warning_link(link, "could not find udev device");
1603 if (udev_device_get_is_initialized(device) <= 0)
1608 r = link_initialized(link, device);
1615 int link_update(Link *link, sd_rtnl_message *m) {
1616 struct ether_addr mac;
1621 assert(link->ifname);
1624 if (link->state == LINK_STATE_FAILED || link->state == LINK_STATE_UNMANAGED)
1627 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1628 if (r >= 0 && !streq(ifname, link->ifname)) {
1629 log_info_link(link, "renamed to %s", ifname);
1632 link->ifname = strdup(ifname);
1637 if (!link->original_mtu) {
1638 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1640 log_debug_link(link, "saved original MTU: %"
1641 PRIu16, link->original_mtu);
1644 /* The kernel may broadcast NEWLINK messages without the MAC address
1645 set, simply ignore them. */
1646 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1648 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1650 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1652 log_debug_link(link, "MAC address: "
1653 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1654 mac.ether_addr_octet[0],
1655 mac.ether_addr_octet[1],
1656 mac.ether_addr_octet[2],
1657 mac.ether_addr_octet[3],
1658 mac.ether_addr_octet[4],
1659 mac.ether_addr_octet[5]);
1662 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1664 log_warning_link(link, "Could not update MAC "
1665 "address in IPv4LL client: %s",
1671 if (link->dhcp_client) {
1672 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1674 log_warning_link(link, "Could not update MAC "
1675 "address in DHCP client: %s",
1683 return link_update_flags(link, m);
1686 int link_save(Link *link) {
1687 _cleanup_free_ char *temp_path = NULL, *lease_file = NULL;
1688 _cleanup_fclose_ FILE *f = NULL;
1689 const char *admin_state, *oper_state = "unknown";
1693 assert(link->state_file);
1695 admin_state = link_state_to_string(link->state);
1696 assert(admin_state);
1698 if (link->operstate & IF_OPER_DORMANT)
1699 oper_state = "dormant";
1700 else if (link_has_carrier(link->flags, link->operstate))
1701 oper_state = "carrier";
1703 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1708 r = fopen_temporary(link->state_file, &f, &temp_path);
1712 fchmod(fileno(f), 0644);
1715 "# This is private data. Do not parse.\n"
1719 admin_state, oper_state, link->flags);
1721 if (link->dhcp_lease) {
1722 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1726 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1732 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1734 unlink(link->state_file);
1740 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1745 static const char* const link_state_table[_LINK_STATE_MAX] = {
1746 [LINK_STATE_INITIALIZING] = "initializing",
1747 [LINK_STATE_ENSLAVING] = "configuring",
1748 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1749 [LINK_STATE_SETTING_ROUTES] = "configuring",
1750 [LINK_STATE_CONFIGURED] = "configured",
1751 [LINK_STATE_UNMANAGED] = "unmanaged",
1752 [LINK_STATE_FAILED] = "failed",
1755 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);