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 r = sd_rtnl_message_link_get_flags(m, &flags);
1144 log_warning_link(link, "Could not get link flags");
1148 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1150 /* if we got a message without operstate, take it to mean
1151 the state was unchanged */
1152 operstate = link->operstate;
1154 if ((link->flags == flags) && (link->operstate == operstate))
1157 flags_added = (link->flags ^ flags) & flags;
1158 flags_removed = (link->flags ^ flags) & link->flags;
1159 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1160 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1161 IFF_NOARP | IFF_MASTER | IFF_SLAVE | IFF_RUNNING);
1163 if (flags_added & IFF_UP)
1164 log_debug_link(link, "link is up");
1165 else if (flags_removed & IFF_UP)
1166 log_debug_link(link, "link is down");
1168 if (flags_added & IFF_LOWER_UP)
1169 log_debug_link(link, "link is lower up");
1170 else if (flags_removed & IFF_LOWER_UP)
1171 log_debug_link(link, "link is lower down");
1173 if (flags_added & IFF_DORMANT)
1174 log_debug_link(link, "link is dormant");
1175 else if (flags_removed & IFF_DORMANT)
1176 log_debug_link(link, "link is not dormant");
1178 if (flags_added & IFF_DEBUG)
1179 log_debug_link(link, "debugging enabled in the kernel");
1180 else if (flags_removed & IFF_DEBUG)
1181 log_debug_link(link, "debugging disabled in the kernel");
1183 if (flags_added & IFF_MULTICAST)
1184 log_debug_link(link, "multicast enabled");
1185 else if (flags_removed & IFF_MULTICAST)
1186 log_debug_link(link, "multicast disabled");
1188 if (flags_added & IFF_BROADCAST)
1189 log_debug_link(link, "broadcast enabled");
1190 else if (flags_removed & IFF_BROADCAST)
1191 log_debug_link(link, "broadcast disabled");
1193 if (flags_added & IFF_PROMISC)
1194 log_debug_link(link, "promiscuous mode enabled");
1195 else if (flags_removed & IFF_PROMISC)
1196 log_debug_link(link, "promiscuous mode disabled");
1198 if (flags_added & IFF_NOARP)
1199 log_debug_link(link, "ARP protocol disabled");
1200 else if (flags_removed & IFF_NOARP)
1201 log_debug_link(link, "ARP protocol enabled");
1203 if (flags_added & IFF_MASTER)
1204 log_debug_link(link, "link is master");
1205 else if (flags_removed & IFF_MASTER)
1206 log_debug_link(link, "link is no longer master");
1208 if (flags_added & IFF_SLAVE)
1209 log_debug_link(link, "link is slave");
1210 else if (flags_removed & IFF_SLAVE)
1211 log_debug_link(link, "link is no longer slave");
1213 /* link flags are currently at most 18 bits, let's default to printing 20 */
1214 if (flags_added & generic_flags)
1215 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1216 flags_added & generic_flags);
1218 if (flags_removed & generic_flags)
1219 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1220 flags_removed & generic_flags);
1222 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1223 link_has_carrier(flags, operstate);
1224 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1225 !link_has_carrier(flags, operstate);
1227 link->flags = flags;
1228 link->operstate = operstate;
1232 if (link->state == LINK_STATE_FAILED ||
1233 link->state == LINK_STATE_UNMANAGED)
1236 if (carrier_gained) {
1237 log_info_link(link, "gained carrier");
1239 if (link->network) {
1240 r = link_acquire_conf(link);
1242 link_enter_failed(link);
1246 } else if (carrier_lost) {
1247 log_info_link(link, "lost carrier");
1249 r = link_stop_clients(link);
1251 link_enter_failed(link);
1259 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1260 Link *link = userdata;
1265 if (link->state == LINK_STATE_FAILED)
1268 r = sd_rtnl_message_get_errno(m);
1270 /* we warn but don't fail the link, as it may
1271 be brought up later */
1272 log_struct_link(LOG_WARNING, link,
1273 "MESSAGE=%s: could not bring up interface: %s",
1274 link->ifname, strerror(-r),
1282 static int link_up(Link *link) {
1283 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1287 assert(link->manager);
1288 assert(link->manager->rtnl);
1290 log_debug_link(link, "bringing link up");
1292 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1293 RTM_SETLINK, link->ifindex);
1295 log_error_link(link, "Could not allocate RTM_SETLINK message");
1299 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1301 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1305 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1307 log_error_link(link,
1308 "Could not send rtnetlink message: %s", strerror(-r));
1315 static int link_enslaved(Link *link) {
1319 assert(link->state == LINK_STATE_ENSLAVING);
1320 assert(link->network);
1322 if (!(link->flags & IFF_UP)) {
1325 link_enter_failed(link);
1330 if (!link->network->dhcp && !link->network->ipv4ll)
1331 return link_enter_set_addresses(link);
1336 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1337 Link *link = userdata;
1341 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1342 assert(link->network);
1346 if (link->state == LINK_STATE_FAILED)
1349 r = sd_rtnl_message_get_errno(m);
1351 log_struct_link(LOG_ERR, link,
1352 "MESSAGE=%s: could not enslave: %s",
1353 link->ifname, strerror(-r),
1356 link_enter_failed(link);
1360 log_debug_link(link, "enslaved");
1362 if (link->enslaving == 0)
1363 link_enslaved(link);
1368 static int link_enter_enslave(Link *link) {
1369 NetDev *vlan, *macvlan;
1374 assert(link->network);
1375 assert(link->state == LINK_STATE_INITIALIZING);
1377 link->state = LINK_STATE_ENSLAVING;
1381 if (!link->network->bridge && !link->network->bond &&
1382 hashmap_isempty(link->network->vlans) &&
1383 hashmap_isempty(link->network->macvlans))
1384 return link_enslaved(link);
1386 if (link->network->bridge) {
1387 log_struct_link(LOG_DEBUG, link,
1388 "MESSAGE=%s: enslaving by '%s'",
1389 link->ifname, link->network->bridge->name,
1390 NETDEV(link->network->bridge),
1393 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1395 log_struct_link(LOG_WARNING, link,
1396 "MESSAGE=%s: could not enslave by '%s': %s",
1397 link->ifname, link->network->bridge->name, strerror(-r),
1398 NETDEV(link->network->bridge),
1400 link_enter_failed(link);
1407 if (link->network->bond) {
1408 log_struct_link(LOG_DEBUG, link,
1409 "MESSAGE=%s: enslaving by '%s'",
1410 link->ifname, link->network->bond->name,
1411 NETDEV(link->network->bond),
1414 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1416 log_struct_link(LOG_WARNING, link,
1417 "MESSAGE=%s: could not enslave by '%s': %s",
1418 link->ifname, link->network->bond->name, strerror(-r),
1419 NETDEV(link->network->bond),
1421 link_enter_failed(link);
1428 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1429 log_struct_link(LOG_DEBUG, link,
1430 "MESSAGE=%s: enslaving by '%s'",
1431 link->ifname, vlan->name, NETDEV(vlan), NULL);
1433 r = netdev_enslave(vlan, link, &enslave_handler);
1435 log_struct_link(LOG_WARNING, link,
1436 "MESSAGE=%s: could not enslave by '%s': %s",
1437 link->ifname, vlan->name, strerror(-r),
1438 NETDEV(vlan), NULL);
1439 link_enter_failed(link);
1446 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1447 log_struct_link(LOG_DEBUG, link,
1448 "MESSAGE=%s: enslaving by '%s'",
1449 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1451 r = netdev_enslave(macvlan, link, &enslave_handler);
1453 log_struct_link(LOG_WARNING, link,
1454 "MESSAGE=%s: could not enslave by '%s': %s",
1455 link->ifname, macvlan->name, strerror(-r),
1456 NETDEV(macvlan), NULL);
1457 link_enter_failed(link);
1467 static int link_configure(Link *link) {
1471 assert(link->state == LINK_STATE_INITIALIZING);
1473 if (link->network->ipv4ll) {
1476 r = sd_ipv4ll_new(&link->ipv4ll);
1480 if (link->udev_device) {
1481 r = net_get_unique_predictable_data(link->udev_device, seed);
1483 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1489 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1493 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1497 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1501 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1506 if (link->network->dhcp) {
1507 r = sd_dhcp_client_new(&link->dhcp_client);
1511 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1515 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1519 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1523 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1527 if (link->network->dhcp_mtu) {
1528 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1534 if (link_has_carrier(link->flags, link->operstate)) {
1535 r = link_acquire_conf(link);
1540 return link_enter_enslave(link);
1543 int link_initialized(Link *link, struct udev_device *device) {
1548 assert(link->ifname);
1549 assert(link->manager);
1551 if (link->state != LINK_STATE_INITIALIZING)
1555 link->udev_device = udev_device_ref(device);
1557 log_debug_link(link, "link initialized");
1559 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1561 link_enter_unmanaged(link);
1566 r = network_apply(link->manager, network, link);
1570 r = link_configure(link);
1577 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1579 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1580 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1587 r = link_new(m, message, ret);
1593 log_debug_link(link, "link added");
1595 if (detect_container(NULL) <= 0) {
1596 /* not in a container, udev will be around */
1597 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1598 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1600 log_warning_link(link, "could not find udev device");
1604 if (udev_device_get_is_initialized(device) <= 0)
1609 r = link_initialized(link, device);
1616 int link_update(Link *link, sd_rtnl_message *m) {
1617 struct ether_addr mac;
1622 assert(link->ifname);
1625 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1626 if (r >= 0 && !streq(ifname, link->ifname)) {
1627 log_info_link(link, "renamed to %s", ifname);
1630 link->ifname = strdup(ifname);
1635 if (!link->original_mtu) {
1636 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1638 log_debug_link(link, "saved original MTU: %"
1639 PRIu16, link->original_mtu);
1642 /* The kernel may broadcast NEWLINK messages without the MAC address
1643 set, simply ignore them. */
1644 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1646 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1648 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1650 log_debug_link(link, "MAC address: "
1651 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1652 mac.ether_addr_octet[0],
1653 mac.ether_addr_octet[1],
1654 mac.ether_addr_octet[2],
1655 mac.ether_addr_octet[3],
1656 mac.ether_addr_octet[4],
1657 mac.ether_addr_octet[5]);
1660 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1662 log_warning_link(link, "Could not update MAC "
1663 "address in IPv4LL client: %s",
1669 if (link->dhcp_client) {
1670 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1672 log_warning_link(link, "Could not update MAC "
1673 "address in DHCP client: %s",
1681 return link_update_flags(link, m);
1684 int link_save(Link *link) {
1685 _cleanup_free_ char *temp_path = NULL, *lease_file = NULL;
1686 _cleanup_fclose_ FILE *f = NULL;
1687 const char *admin_state, *oper_state = "unknown";
1691 assert(link->state_file);
1693 admin_state = link_state_to_string(link->state);
1694 assert(admin_state);
1696 if (link->operstate & IF_OPER_DORMANT)
1697 oper_state = "dormant";
1698 else if (link_has_carrier(link->flags, link->operstate))
1699 oper_state = "carrier";
1701 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1706 r = fopen_temporary(link->state_file, &f, &temp_path);
1710 fchmod(fileno(f), 0644);
1713 "# This is private data. Do not parse.\n"
1717 admin_state, oper_state, link->flags);
1719 if (link->dhcp_lease) {
1720 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1724 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1730 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1732 unlink(link->state_file);
1738 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1743 static const char* const link_state_table[_LINK_STATE_MAX] = {
1744 [LINK_STATE_INITIALIZING] = "initializing",
1745 [LINK_STATE_ENSLAVING] = "configuring",
1746 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1747 [LINK_STATE_SETTING_ROUTES] = "configuring",
1748 [LINK_STATE_CONFIGURED] = "configured",
1749 [LINK_STATE_UNMANAGED] = "unmanaged",
1750 [LINK_STATE_FAILED] = "failed",
1753 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);