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 int link_update_flags(Link *link, sd_rtnl_message *m) {
1121 unsigned flags, flags_added, flags_removed, generic_flags;
1123 bool carrier_gained = false, carrier_lost = false;
1128 if (link->state == LINK_STATE_FAILED)
1131 r = sd_rtnl_message_link_get_flags(m, &flags);
1133 log_warning_link(link, "Could not get link flags");
1137 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1139 /* if we got a message without operstate, take it to mean
1140 the state was unchanged */
1141 operstate = link->operstate;
1143 if ((link->flags == flags) && (link->operstate == operstate))
1146 flags_added = (link->flags ^ flags) & flags;
1147 flags_removed = (link->flags ^ flags) & link->flags;
1148 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1149 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1150 IFF_NOARP | IFF_MASTER | IFF_SLAVE | IFF_RUNNING);
1152 if (flags_added & IFF_UP)
1153 log_debug_link(link, "link is up");
1154 else if (flags_removed & IFF_UP)
1155 log_debug_link(link, "link is down");
1157 if (flags_added & IFF_LOWER_UP)
1158 log_debug_link(link, "link is lower up");
1159 else if (flags_removed & IFF_LOWER_UP)
1160 log_debug_link(link, "link is lower down");
1162 if (flags_added & IFF_DORMANT)
1163 log_debug_link(link, "link is dormant");
1164 else if (flags_removed & IFF_DORMANT)
1165 log_debug_link(link, "link is not dormant");
1167 if (flags_added & IFF_DEBUG)
1168 log_debug_link(link, "debugging enabled in the kernel");
1169 else if (flags_removed & IFF_DEBUG)
1170 log_debug_link(link, "debugging disabled in the kernel");
1172 if (flags_added & IFF_MULTICAST)
1173 log_debug_link(link, "multicast enabled");
1174 else if (flags_removed & IFF_MULTICAST)
1175 log_debug_link(link, "multicast disabled");
1177 if (flags_added & IFF_BROADCAST)
1178 log_debug_link(link, "broadcast enabled");
1179 else if (flags_removed & IFF_BROADCAST)
1180 log_debug_link(link, "broadcast disabled");
1182 if (flags_added & IFF_PROMISC)
1183 log_debug_link(link, "promiscuous mode enabled");
1184 else if (flags_removed & IFF_PROMISC)
1185 log_debug_link(link, "promiscuous mode disabled");
1187 if (flags_added & IFF_NOARP)
1188 log_debug_link(link, "ARP protocol disabled");
1189 else if (flags_removed & IFF_NOARP)
1190 log_debug_link(link, "ARP protocol enabled");
1192 if (flags_added & IFF_MASTER)
1193 log_debug_link(link, "link is master");
1194 else if (flags_removed & IFF_MASTER)
1195 log_debug_link(link, "link is no longer master");
1197 if (flags_added & IFF_SLAVE)
1198 log_debug_link(link, "link is slave");
1199 else if (flags_removed & IFF_SLAVE)
1200 log_debug_link(link, "link is no longer slave");
1202 /* link flags are currently at most 18 bits, let's default to printing 20 */
1203 if (flags_added & generic_flags)
1204 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1205 flags_added & generic_flags);
1207 if (flags_removed & generic_flags)
1208 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1209 flags_removed & generic_flags);
1211 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1212 link_has_carrier(flags, operstate);
1213 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1214 !link_has_carrier(flags, operstate);
1216 link->flags = flags;
1217 link->operstate = operstate;
1219 if (carrier_gained) {
1220 log_info_link(link, "gained carrier");
1222 if (link->network) {
1223 r = link_acquire_conf(link);
1225 link_enter_failed(link);
1229 } else if (carrier_lost) {
1230 log_info_link(link, "lost carrier");
1232 r = link_stop_clients(link);
1234 link_enter_failed(link);
1242 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1243 Link *link = userdata;
1248 if (link->state == LINK_STATE_FAILED)
1251 r = sd_rtnl_message_get_errno(m);
1253 /* we warn but don't fail the link, as it may
1254 be brought up later */
1255 log_struct_link(LOG_WARNING, link,
1256 "MESSAGE=%s: could not bring up interface: %s",
1257 link->ifname, strerror(-r),
1265 static int link_up(Link *link) {
1266 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1270 assert(link->manager);
1271 assert(link->manager->rtnl);
1273 log_debug_link(link, "bringing link up");
1275 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1276 RTM_SETLINK, link->ifindex);
1278 log_error_link(link, "Could not allocate RTM_SETLINK message");
1282 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1284 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1288 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1290 log_error_link(link,
1291 "Could not send rtnetlink message: %s", strerror(-r));
1298 static int link_enslaved(Link *link) {
1302 assert(link->state == LINK_STATE_ENSLAVING);
1303 assert(link->network);
1305 if (!(link->flags & IFF_UP)) {
1308 link_enter_failed(link);
1313 if (!link->network->dhcp && !link->network->ipv4ll)
1314 return link_enter_set_addresses(link);
1319 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1320 Link *link = userdata;
1324 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1325 assert(link->network);
1329 if (link->state == LINK_STATE_FAILED)
1332 r = sd_rtnl_message_get_errno(m);
1334 log_struct_link(LOG_ERR, link,
1335 "MESSAGE=%s: could not enslave: %s",
1336 link->ifname, strerror(-r),
1339 link_enter_failed(link);
1343 log_debug_link(link, "enslaved");
1345 if (link->enslaving == 0)
1346 link_enslaved(link);
1351 static int link_enter_enslave(Link *link) {
1352 NetDev *vlan, *macvlan;
1357 assert(link->network);
1358 assert(link->state == LINK_STATE_INITIALIZING);
1360 link->state = LINK_STATE_ENSLAVING;
1364 if (!link->network->bridge && !link->network->bond &&
1365 hashmap_isempty(link->network->vlans) &&
1366 hashmap_isempty(link->network->macvlans))
1367 return link_enslaved(link);
1369 if (link->network->bridge) {
1370 log_struct_link(LOG_DEBUG, link,
1371 "MESSAGE=%s: enslaving by '%s'",
1372 link->ifname, link->network->bridge->name,
1373 NETDEV(link->network->bridge),
1376 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1378 log_struct_link(LOG_WARNING, link,
1379 "MESSAGE=%s: could not enslave by '%s': %s",
1380 link->ifname, link->network->bridge->name, strerror(-r),
1381 NETDEV(link->network->bridge),
1383 link_enter_failed(link);
1390 if (link->network->bond) {
1391 log_struct_link(LOG_DEBUG, link,
1392 "MESSAGE=%s: enslaving by '%s'",
1393 link->ifname, link->network->bond->name,
1394 NETDEV(link->network->bond),
1397 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1399 log_struct_link(LOG_WARNING, link,
1400 "MESSAGE=%s: could not enslave by '%s': %s",
1401 link->ifname, link->network->bond->name, strerror(-r),
1402 NETDEV(link->network->bond),
1404 link_enter_failed(link);
1411 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1412 log_struct_link(LOG_DEBUG, link,
1413 "MESSAGE=%s: enslaving by '%s'",
1414 link->ifname, vlan->name, NETDEV(vlan), NULL);
1416 r = netdev_enslave(vlan, link, &enslave_handler);
1418 log_struct_link(LOG_WARNING, link,
1419 "MESSAGE=%s: could not enslave by '%s': %s",
1420 link->ifname, vlan->name, strerror(-r),
1421 NETDEV(vlan), NULL);
1422 link_enter_failed(link);
1429 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1430 log_struct_link(LOG_DEBUG, link,
1431 "MESSAGE=%s: enslaving by '%s'",
1432 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1434 r = netdev_enslave(macvlan, link, &enslave_handler);
1436 log_struct_link(LOG_WARNING, link,
1437 "MESSAGE=%s: could not enslave by '%s': %s",
1438 link->ifname, macvlan->name, strerror(-r),
1439 NETDEV(macvlan), NULL);
1440 link_enter_failed(link);
1450 static int link_configure(Link *link) {
1454 assert(link->state == LINK_STATE_INITIALIZING);
1456 if (link->network->ipv4ll) {
1459 r = sd_ipv4ll_new(&link->ipv4ll);
1463 if (link->udev_device) {
1464 r = net_get_unique_predictable_data(link->udev_device, seed);
1466 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1472 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1476 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1480 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1484 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1489 if (link->network->dhcp) {
1490 r = sd_dhcp_client_new(&link->dhcp_client);
1494 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1498 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1502 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1506 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1510 if (link->network->dhcp_mtu) {
1511 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1517 if (link_has_carrier(link->flags, link->operstate))
1519 r = link_acquire_conf(link);
1524 return link_enter_enslave(link);
1527 int link_initialized(Link *link, struct udev_device *device) {
1532 assert(link->ifname);
1533 assert(link->manager);
1535 if (link->state != LINK_STATE_INITIALIZING)
1539 link->udev_device = udev_device_ref(device);
1541 log_debug_link(link, "link initialized");
1543 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1545 link_enter_unmanaged(link);
1550 r = network_apply(link->manager, network, link);
1554 r = link_configure(link);
1561 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1563 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1564 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1571 r = link_new(m, message, ret);
1577 log_debug_link(link, "link added");
1579 if (detect_container(NULL) <= 0) {
1580 /* not in a container, udev will be around */
1581 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1582 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1584 log_warning_link(link, "could not find udev device");
1588 if (udev_device_get_is_initialized(device) <= 0)
1593 r = link_initialized(link, device);
1600 int link_update(Link *link, sd_rtnl_message *m) {
1601 struct ether_addr mac;
1606 assert(link->ifname);
1609 if (link->state == LINK_STATE_FAILED || link->state == LINK_STATE_UNMANAGED)
1612 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1613 if (r >= 0 && !streq(ifname, link->ifname)) {
1614 log_info_link(link, "renamed to %s", ifname);
1617 link->ifname = strdup(ifname);
1622 if (!link->original_mtu) {
1623 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1625 log_debug_link(link, "saved original MTU: %"
1626 PRIu16, link->original_mtu);
1629 /* The kernel may broadcast NEWLINK messages without the MAC address
1630 set, simply ignore them. */
1631 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1633 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1635 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1637 log_debug_link(link, "MAC address: "
1638 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1639 mac.ether_addr_octet[0],
1640 mac.ether_addr_octet[1],
1641 mac.ether_addr_octet[2],
1642 mac.ether_addr_octet[3],
1643 mac.ether_addr_octet[4],
1644 mac.ether_addr_octet[5]);
1647 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1649 log_warning_link(link, "Could not update MAC "
1650 "address in IPv4LL client: %s",
1656 if (link->dhcp_client) {
1657 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1659 log_warning_link(link, "Could not update MAC "
1660 "address in DHCP client: %s",
1668 return link_update_flags(link, m);
1671 int link_save(Link *link) {
1672 _cleanup_free_ char *temp_path = NULL;
1673 _cleanup_fclose_ FILE *f = NULL;
1678 assert(link->state_file);
1680 state = link_state_to_string(link->state);
1683 r = fopen_temporary(link->state_file, &f, &temp_path);
1687 fchmod(fileno(f), 0644);
1690 "# This is private data. Do not parse.\n"
1691 "STATE=%s\n", state);
1693 if (link->dhcp_lease) {
1694 _cleanup_free_ char *lease_file = NULL;
1696 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1701 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1705 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1710 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1712 unlink(link->state_file);
1718 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1723 static const char* const link_state_table[_LINK_STATE_MAX] = {
1724 [LINK_STATE_INITIALIZING] = "configuring",
1725 [LINK_STATE_ENSLAVING] = "configuring",
1726 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1727 [LINK_STATE_SETTING_ROUTES] = "configuring",
1728 [LINK_STATE_CONFIGURED] = "configured",
1729 [LINK_STATE_UNMANAGED] = "unmanaged",
1730 [LINK_STATE_FAILED] = "failed",
1733 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);