1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <netinet/ether.h>
26 #include "libudev-private.h"
27 #include "udev-util.h"
31 #include "network-internal.h"
33 #include "network-util.h"
34 #include "dhcp-lease-internal.h"
36 static int ipv4ll_address_update(Link *link, bool deprecate);
37 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
39 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
40 _cleanup_link_unref_ Link *link = NULL;
46 assert(manager->links);
50 r = sd_rtnl_message_get_type(message, &type);
53 else if (type != RTM_NEWLINK)
56 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
59 else if (ifindex <= 0)
62 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
71 link->manager = manager;
72 link->state = LINK_STATE_INITIALIZING;
73 link->ifindex = ifindex;
74 link->ifname = strdup(ifname);
78 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
83 r = asprintf(&link->lease_file, "/run/systemd/network/leases/%"PRIu64,
88 r = hashmap_put(manager->links, &link->ifindex, link);
98 static void link_free(Link *link) {
102 assert(link->manager);
104 sd_dhcp_client_unref(link->dhcp_client);
105 sd_dhcp_lease_unref(link->dhcp_lease);
107 unlink(link->lease_file);
108 free(link->lease_file);
110 sd_ipv4ll_unref(link->ipv4ll);
112 hashmap_remove(link->manager->links, &link->ifindex);
116 unlink(link->state_file);
117 free(link->state_file);
119 udev_device_unref(link->udev_device);
124 Link *link_unref(Link *link) {
125 if (link && (-- link->n_ref <= 0))
131 Link *link_ref(Link *link) {
133 assert_se(++ link->n_ref >= 2);
138 int link_get(Manager *m, int ifindex, Link **ret) {
147 ifindex_64 = ifindex;
148 link = hashmap_get(m->links, &ifindex_64);
157 static int link_enter_configured(Link *link) {
159 assert(link->state == LINK_STATE_SETTING_ROUTES);
161 log_info_link(link, "link configured");
163 link->state = LINK_STATE_CONFIGURED;
170 static void link_enter_unmanaged(Link *link) {
173 log_debug_link(link, "unmanaged");
175 link->state = LINK_STATE_UNMANAGED;
180 static int link_stop_clients(Link *link) {
184 assert(link->manager);
185 assert(link->manager->event);
190 if (link->network->dhcp) {
191 assert(link->dhcp_client);
193 k = sd_dhcp_client_stop(link->dhcp_client);
195 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
200 if (link->network->ipv4ll) {
201 assert(link->ipv4ll);
203 k = sd_ipv4ll_stop(link->ipv4ll);
205 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
213 static void link_enter_failed(Link *link) {
216 if (link->state == LINK_STATE_FAILED)
219 log_warning_link(link, "failed");
221 link->state = LINK_STATE_FAILED;
223 link_stop_clients(link);
228 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
229 Link *link = userdata;
232 assert(link->route_messages > 0);
233 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
234 link->state == LINK_STATE_SETTING_ROUTES ||
235 link->state == LINK_STATE_FAILED);
237 link->route_messages --;
239 if (link->state == LINK_STATE_FAILED)
242 r = sd_rtnl_message_get_errno(m);
243 if (r < 0 && r != -EEXIST)
244 log_struct_link(LOG_WARNING, link,
245 "MESSAGE=%s: could not set route: %s",
246 link->ifname, strerror(-r),
250 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
252 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
253 log_debug_link(link, "routes set");
254 link_enter_configured(link);
260 static int link_enter_set_routes(Link *link) {
265 assert(link->network);
266 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
268 link->state = LINK_STATE_SETTING_ROUTES;
270 if (!link->network->static_routes && !link->dhcp_lease &&
271 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
272 return link_enter_configured(link);
274 log_debug_link(link, "setting routes");
276 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
277 r = route_configure(rt, link, &route_handler);
279 log_warning_link(link,
280 "could not set routes: %s", strerror(-r));
281 link_enter_failed(link);
285 link->route_messages ++;
288 if (link->ipv4ll && !link->dhcp_lease) {
289 _cleanup_route_free_ Route *route = NULL;
292 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
293 if (r < 0 && r != -ENOENT) {
294 log_warning_link(link, "IPV4LL error: no address: %s",
300 r = route_new_dynamic(&route);
302 log_error_link(link, "Could not allocate route: %s",
307 route->family = AF_INET;
308 route->scope = RT_SCOPE_LINK;
311 r = route_configure(route, link, &route_handler);
313 log_warning_link(link,
314 "could not set routes: %s", strerror(-r));
315 link_enter_failed(link);
319 link->route_messages ++;
323 if (link->dhcp_lease) {
324 _cleanup_route_free_ Route *route = NULL;
325 _cleanup_route_free_ Route *route_gw = NULL;
326 struct in_addr gateway;
328 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
329 if (r < 0 && r != -ENOENT) {
330 log_warning_link(link, "DHCP error: %s", strerror(-r));
335 r = route_new_dynamic(&route);
337 log_error_link(link, "Could not allocate route: %s",
342 r = route_new_dynamic(&route_gw);
344 log_error_link(link, "Could not allocate route: %s",
349 /* The dhcp netmask may mask out the gateway. Add an explicit
350 * route for the gw host so that we can route no matter the
351 * netmask or existing kernel route tables. */
352 route_gw->family = AF_INET;
353 route_gw->dst_addr.in = gateway;
354 route_gw->dst_prefixlen = 32;
355 route_gw->scope = RT_SCOPE_LINK;
357 r = route_configure(route_gw, link, &route_handler);
359 log_warning_link(link,
360 "could not set host route: %s", strerror(-r));
364 link->route_messages ++;
366 route->family = AF_INET;
367 route->in_addr.in = gateway;
369 r = route_configure(route, link, &route_handler);
371 log_warning_link(link,
372 "could not set routes: %s", strerror(-r));
373 link_enter_failed(link);
377 link->route_messages ++;
381 if (link->route_messages == 0) {
382 link_enter_configured(link);
388 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
389 Link *link = userdata;
394 assert(link->ifname);
396 if (link->state == LINK_STATE_FAILED)
399 r = sd_rtnl_message_get_errno(m);
400 if (r < 0 && r != -ENOENT)
401 log_struct_link(LOG_WARNING, link,
402 "MESSAGE=%s: could not drop route: %s",
403 link->ifname, strerror(-r),
410 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
411 Link *link = userdata;
416 assert(link->ifname);
417 assert(link->addr_messages > 0);
418 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
420 link->addr_messages --;
422 if (link->state == LINK_STATE_FAILED)
425 r = sd_rtnl_message_get_errno(m);
426 if (r < 0 && r != -EEXIST)
427 log_struct_link(LOG_WARNING, link,
428 "MESSAGE=%s: could not set address: %s",
429 link->ifname, strerror(-r),
433 if (link->addr_messages == 0) {
434 log_debug_link(link, "addresses set");
435 link_enter_set_routes(link);
441 static int link_enter_set_addresses(Link *link) {
446 assert(link->network);
447 assert(link->state != _LINK_STATE_INVALID);
449 link->state = LINK_STATE_SETTING_ADDRESSES;
451 if (!link->network->static_addresses && !link->dhcp_lease &&
452 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
453 return link_enter_set_routes(link);
455 log_debug_link(link, "setting addresses");
457 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
458 r = address_configure(ad, link, &address_handler);
460 log_warning_link(link,
461 "could not set addresses: %s", strerror(-r));
462 link_enter_failed(link);
466 link->addr_messages ++;
469 if (link->ipv4ll && !link->dhcp_lease) {
470 _cleanup_address_free_ Address *ll_addr = NULL;
473 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
474 if (r < 0 && r != -ENOENT) {
475 log_warning_link(link, "IPV4LL error: no address: %s",
481 r = address_new_dynamic(&ll_addr);
483 log_error_link(link, "Could not allocate address: %s", strerror(-r));
487 ll_addr->family = AF_INET;
488 ll_addr->in_addr.in = addr;
489 ll_addr->prefixlen = 16;
490 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
491 ll_addr->scope = RT_SCOPE_LINK;
493 r = address_configure(ll_addr, link, &address_handler);
495 log_warning_link(link,
496 "could not set addresses: %s", strerror(-r));
497 link_enter_failed(link);
501 link->addr_messages ++;
505 if (link->dhcp_lease) {
506 _cleanup_address_free_ Address *address = NULL;
508 struct in_addr netmask;
511 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
513 log_warning_link(link, "DHCP error: no address: %s",
518 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
520 log_warning_link(link, "DHCP error: no netmask: %s",
525 prefixlen = net_netmask_to_prefixlen(&netmask);
527 r = address_new_dynamic(&address);
529 log_error_link(link, "Could not allocate address: %s",
534 address->family = AF_INET;
535 address->in_addr.in = addr;
536 address->prefixlen = prefixlen;
537 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
539 r = address_configure(address, link, &address_handler);
541 log_warning_link(link,
542 "could not set addresses: %s", strerror(-r));
543 link_enter_failed(link);
547 link->addr_messages ++;
553 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
554 Link *link = userdata;
559 assert(link->ifname);
561 if (link->state == LINK_STATE_FAILED)
564 r = sd_rtnl_message_get_errno(m);
565 if (r < 0 && r != -ENOENT)
566 log_struct_link(LOG_WARNING, link,
567 "MESSAGE=%s: could not update address: %s",
568 link->ifname, strerror(-r),
575 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
576 Link *link = userdata;
581 assert(link->ifname);
583 if (link->state == LINK_STATE_FAILED)
586 r = sd_rtnl_message_get_errno(m);
587 if (r < 0 && r != -ENOENT)
588 log_struct_link(LOG_WARNING, link,
589 "MESSAGE=%s: could not drop address: %s",
590 link->ifname, strerror(-r),
597 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
600 r = sd_bus_message_get_errno(m);
602 log_warning("Could not set hostname: %s", strerror(-r));
607 static int set_hostname(sd_bus *bus, const char *hostname) {
608 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
613 log_debug("Setting transient hostname: '%s'", hostname);
615 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
616 log_info("Not connected to system bus, ignoring transient hostname.");
620 r = sd_bus_message_new_method_call(
623 "org.freedesktop.hostname1",
624 "/org/freedesktop/hostname1",
625 "org.freedesktop.hostname1",
630 r = sd_bus_message_append(m, "sb", hostname, false);
634 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
636 log_error("Could not set transient hostname: %s", strerror(-r));
641 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
642 Link *link = userdata;
647 assert(link->ifname);
649 if (link->state == LINK_STATE_FAILED)
652 r = sd_rtnl_message_get_errno(m);
654 log_struct_link(LOG_WARNING, link,
655 "MESSAGE=%s: could not set MTU: %s",
656 link->ifname, strerror(-r),
663 static int link_set_mtu(Link *link, uint32_t mtu) {
664 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
668 assert(link->manager);
669 assert(link->manager->rtnl);
671 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
673 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
674 RTM_SETLINK, link->ifindex);
676 log_error_link(link, "Could not allocate RTM_SETLINK message");
680 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
682 log_error_link(link, "Could not append MTU: %s", strerror(-r));
686 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
689 "Could not send rtnetlink message: %s", strerror(-r));
696 static int dhcp_lease_lost(Link *link) {
697 _cleanup_address_free_ Address *address = NULL;
698 _cleanup_route_free_ Route *route_gw = NULL;
699 _cleanup_route_free_ Route *route = NULL;
701 struct in_addr netmask;
702 struct in_addr gateway;
707 assert(link->dhcp_lease);
709 log_warning_link(link, "DHCP lease lost");
711 r = address_new_dynamic(&address);
713 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
715 r = route_new_dynamic(&route_gw);
717 route_gw->family = AF_INET;
718 route_gw->dst_addr.in = gateway;
719 route_gw->dst_prefixlen = 32;
720 route_gw->scope = RT_SCOPE_LINK;
722 route_drop(route_gw, link, &route_drop_handler);
725 r = route_new_dynamic(&route);
727 route->family = AF_INET;
728 route->in_addr.in = gateway;
730 route_drop(route, link, &route_drop_handler);
734 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
735 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
736 prefixlen = net_netmask_to_prefixlen(&netmask);
738 address->family = AF_INET;
739 address->in_addr.in = addr;
740 address->prefixlen = prefixlen;
742 address_drop(address, link, &address_drop_handler);
745 if (link->network->dhcp_mtu) {
748 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
749 if (r >= 0 && link->original_mtu != mtu) {
750 r = link_set_mtu(link, link->original_mtu);
752 log_warning_link(link, "DHCP error: could not reset MTU");
753 link_enter_failed(link);
759 if (link->network->dhcp_hostname) {
760 const char *hostname = NULL;
762 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
763 if (r >= 0 && hostname) {
764 r = set_hostname(link->manager->bus, "");
766 log_error("Failed to reset transient hostname");
770 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
775 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
776 sd_dhcp_lease *lease;
777 struct in_addr address;
778 struct in_addr netmask;
779 struct in_addr gateway;
781 struct in_addr *nameservers;
782 size_t nameservers_size;
788 r = sd_dhcp_client_get_lease(client, &lease);
790 log_warning_link(link, "DHCP error: no lease: %s",
795 r = sd_dhcp_lease_get_address(lease, &address);
797 log_warning_link(link, "DHCP error: no address: %s",
802 r = sd_dhcp_lease_get_netmask(lease, &netmask);
804 log_warning_link(link, "DHCP error: no netmask: %s",
809 prefixlen = net_netmask_to_prefixlen(&netmask);
811 r = sd_dhcp_lease_get_router(lease, &gateway);
812 if (r < 0 && r != -ENOENT) {
813 log_warning_link(link, "DHCP error: %s", strerror(-r));
818 log_struct_link(LOG_INFO, link,
819 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
821 ADDRESS_FMT_VAL(address),
823 ADDRESS_FMT_VAL(gateway),
824 "ADDRESS=%u.%u.%u.%u",
825 ADDRESS_FMT_VAL(address),
828 "GATEWAY=%u.%u.%u.%u",
829 ADDRESS_FMT_VAL(gateway),
832 log_struct_link(LOG_INFO, link,
833 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u",
835 ADDRESS_FMT_VAL(address),
837 "ADDRESS=%u.%u.%u.%u",
838 ADDRESS_FMT_VAL(address),
843 link->dhcp_lease = lease;
845 if (link->network->dhcp_dns) {
846 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
848 r = manager_update_resolv_conf(link->manager);
850 log_error("Failed to update resolv.conf");
854 if (link->network->dhcp_mtu) {
857 r = sd_dhcp_lease_get_mtu(lease, &mtu);
859 r = link_set_mtu(link, mtu);
861 log_error_link(link, "Failed to set MTU "
866 if (link->network->dhcp_hostname) {
867 const char *hostname;
869 r = sd_dhcp_lease_get_hostname(lease, &hostname);
871 r = set_hostname(link->manager->bus, hostname);
873 log_error("Failed to set transient hostname "
874 "to '%s'", hostname);
878 link_enter_set_addresses(link);
883 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
884 Link *link = userdata;
888 assert(link->network);
889 assert(link->manager);
891 if (link->state == LINK_STATE_FAILED)
895 case DHCP_EVENT_NO_LEASE:
896 log_debug_link(link, "IP address in use.");
898 case DHCP_EVENT_EXPIRED:
899 case DHCP_EVENT_STOP:
900 case DHCP_EVENT_IP_CHANGE:
901 if (link->network->dhcp_critical) {
902 log_error_link(link, "DHCPv4 connection considered system critical, "
903 "ignoring request to reconfigure it.");
907 if (link->dhcp_lease) {
908 r = dhcp_lease_lost(link);
910 link_enter_failed(link);
915 if (event == DHCP_EVENT_IP_CHANGE) {
916 r = dhcp_lease_acquired(client, link);
918 link_enter_failed(link);
923 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
924 if (!sd_ipv4ll_is_running(link->ipv4ll))
925 r = sd_ipv4ll_start(link->ipv4ll);
926 else if (ipv4ll_is_bound(link->ipv4ll))
927 r = ipv4ll_address_update(link, false);
929 link_enter_failed(link);
935 case DHCP_EVENT_IP_ACQUIRE:
936 r = dhcp_lease_acquired(client, link);
938 link_enter_failed(link);
942 if (ipv4ll_is_bound(link->ipv4ll))
943 r = ipv4ll_address_update(link, true);
945 r = sd_ipv4ll_stop(link->ipv4ll);
947 link_enter_failed(link);
954 log_warning_link(link, "DHCP error: %s", strerror(-event));
956 log_warning_link(link, "DHCP unknown event: %d", event);
963 static int ipv4ll_address_update(Link *link, bool deprecate) {
969 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
971 _cleanup_address_free_ Address *address = NULL;
973 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
974 deprecate ? "deprecate" : "approve",
975 ADDRESS_FMT_VAL(addr));
977 r = address_new_dynamic(&address);
979 log_error_link(link, "Could not allocate address: %s", strerror(-r));
983 address->family = AF_INET;
984 address->in_addr.in = addr;
985 address->prefixlen = 16;
986 address->scope = RT_SCOPE_LINK;
987 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
988 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
990 address_update(address, link, &address_update_handler);
997 static int ipv4ll_address_lost(Link *link) {
1003 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1005 _cleanup_address_free_ Address *address = NULL;
1006 _cleanup_route_free_ Route *route = NULL;
1008 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1009 ADDRESS_FMT_VAL(addr));
1011 r = address_new_dynamic(&address);
1013 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1017 address->family = AF_INET;
1018 address->in_addr.in = addr;
1019 address->prefixlen = 16;
1020 address->scope = RT_SCOPE_LINK;
1022 address_drop(address, link, &address_drop_handler);
1024 r = route_new_dynamic(&route);
1026 log_error_link(link, "Could not allocate route: %s",
1031 route->family = AF_INET;
1032 route->scope = RT_SCOPE_LINK;
1033 route->metrics = 99;
1035 route_drop(route, link, &route_drop_handler);
1041 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1043 struct in_addr addr;
1047 r = sd_ipv4ll_get_address(ll, &addr);
1053 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1054 struct in_addr address;
1060 r = sd_ipv4ll_get_address(ll, &address);
1064 log_struct_link(LOG_INFO, link,
1065 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1067 ADDRESS_FMT_VAL(address),
1070 link_enter_set_addresses(link);
1075 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1076 Link *link = userdata;
1080 assert(link->network);
1081 assert(link->manager);
1084 case IPV4LL_EVENT_STOP:
1085 case IPV4LL_EVENT_CONFLICT:
1086 r = ipv4ll_address_lost(link);
1088 link_enter_failed(link);
1092 case IPV4LL_EVENT_BIND:
1093 r = ipv4ll_address_claimed(ll, link);
1095 link_enter_failed(link);
1101 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1103 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1108 static int link_acquire_conf(Link *link) {
1112 assert(link->network);
1113 assert(link->manager);
1114 assert(link->manager->event);
1116 if (link->network->ipv4ll) {
1117 assert(link->ipv4ll);
1119 log_debug_link(link, "acquiring IPv4 link-local address");
1121 r = sd_ipv4ll_start(link->ipv4ll);
1123 log_warning_link(link, "could not acquire IPv4 "
1124 "link-local address");
1129 if (link->network->dhcp) {
1130 assert(link->dhcp_client);
1132 log_debug_link(link, "acquiring DHCPv4 lease");
1134 r = sd_dhcp_client_start(link->dhcp_client);
1136 log_warning_link(link, "could not acquire DHCPv4 "
1145 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1146 /* see Documentation/networking/operstates.txt in the kernel sources */
1148 if (operstate == IF_OPER_UP)
1151 if (operstate == IF_OPER_UNKNOWN)
1152 /* operstate may not be implemented, so fall back to flags */
1153 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1159 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1160 unsigned flags, flags_added, flags_removed, generic_flags;
1162 bool carrier_gained = false, carrier_lost = false;
1167 r = sd_rtnl_message_link_get_flags(m, &flags);
1169 log_warning_link(link, "Could not get link flags");
1173 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1175 /* if we got a message without operstate, take it to mean
1176 the state was unchanged */
1177 operstate = link->operstate;
1179 if ((link->flags == flags) && (link->operstate == operstate))
1182 flags_added = (link->flags ^ flags) & flags;
1183 flags_removed = (link->flags ^ flags) & link->flags;
1184 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1185 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1186 IFF_NOARP | IFF_MASTER | IFF_SLAVE | IFF_RUNNING);
1188 if (flags_added & IFF_UP)
1189 log_debug_link(link, "link is up");
1190 else if (flags_removed & IFF_UP)
1191 log_debug_link(link, "link is down");
1193 if (flags_added & IFF_LOWER_UP)
1194 log_debug_link(link, "link is lower up");
1195 else if (flags_removed & IFF_LOWER_UP)
1196 log_debug_link(link, "link is lower down");
1198 if (flags_added & IFF_DORMANT)
1199 log_debug_link(link, "link is dormant");
1200 else if (flags_removed & IFF_DORMANT)
1201 log_debug_link(link, "link is not dormant");
1203 if (flags_added & IFF_DEBUG)
1204 log_debug_link(link, "debugging enabled in the kernel");
1205 else if (flags_removed & IFF_DEBUG)
1206 log_debug_link(link, "debugging disabled in the kernel");
1208 if (flags_added & IFF_MULTICAST)
1209 log_debug_link(link, "multicast enabled");
1210 else if (flags_removed & IFF_MULTICAST)
1211 log_debug_link(link, "multicast disabled");
1213 if (flags_added & IFF_BROADCAST)
1214 log_debug_link(link, "broadcast enabled");
1215 else if (flags_removed & IFF_BROADCAST)
1216 log_debug_link(link, "broadcast disabled");
1218 if (flags_added & IFF_PROMISC)
1219 log_debug_link(link, "promiscuous mode enabled");
1220 else if (flags_removed & IFF_PROMISC)
1221 log_debug_link(link, "promiscuous mode disabled");
1223 if (flags_added & IFF_NOARP)
1224 log_debug_link(link, "ARP protocol disabled");
1225 else if (flags_removed & IFF_NOARP)
1226 log_debug_link(link, "ARP protocol enabled");
1228 if (flags_added & IFF_MASTER)
1229 log_debug_link(link, "link is master");
1230 else if (flags_removed & IFF_MASTER)
1231 log_debug_link(link, "link is no longer master");
1233 if (flags_added & IFF_SLAVE)
1234 log_debug_link(link, "link is slave");
1235 else if (flags_removed & IFF_SLAVE)
1236 log_debug_link(link, "link is no longer slave");
1238 /* link flags are currently at most 18 bits, let's default to printing 20 */
1239 if (flags_added & generic_flags)
1240 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1241 flags_added & generic_flags);
1243 if (flags_removed & generic_flags)
1244 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1245 flags_removed & generic_flags);
1247 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1248 link_has_carrier(flags, operstate);
1249 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1250 !link_has_carrier(flags, operstate);
1252 link->flags = flags;
1253 link->operstate = operstate;
1257 if (link->state == LINK_STATE_FAILED ||
1258 link->state == LINK_STATE_UNMANAGED)
1261 if (carrier_gained) {
1262 log_info_link(link, "gained carrier");
1264 if (link->network) {
1265 r = link_acquire_conf(link);
1267 link_enter_failed(link);
1271 } else if (carrier_lost) {
1272 log_info_link(link, "lost carrier");
1274 r = link_stop_clients(link);
1276 link_enter_failed(link);
1284 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1285 Link *link = userdata;
1290 if (link->state == LINK_STATE_FAILED)
1293 r = sd_rtnl_message_get_errno(m);
1295 /* we warn but don't fail the link, as it may
1296 be brought up later */
1297 log_struct_link(LOG_WARNING, link,
1298 "MESSAGE=%s: could not bring up interface: %s",
1299 link->ifname, strerror(-r),
1307 static int link_up(Link *link) {
1308 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1312 assert(link->manager);
1313 assert(link->manager->rtnl);
1315 log_debug_link(link, "bringing link up");
1317 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1318 RTM_SETLINK, link->ifindex);
1320 log_error_link(link, "Could not allocate RTM_SETLINK message");
1324 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1326 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1330 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1332 log_error_link(link,
1333 "Could not send rtnetlink message: %s", strerror(-r));
1340 static int link_enslaved(Link *link) {
1344 assert(link->state == LINK_STATE_ENSLAVING);
1345 assert(link->network);
1347 if (!(link->flags & IFF_UP)) {
1350 link_enter_failed(link);
1355 if (!link->network->dhcp && !link->network->ipv4ll)
1356 return link_enter_set_addresses(link);
1361 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1362 Link *link = userdata;
1366 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1367 assert(link->network);
1371 if (link->state == LINK_STATE_FAILED)
1374 r = sd_rtnl_message_get_errno(m);
1376 log_struct_link(LOG_ERR, link,
1377 "MESSAGE=%s: could not enslave: %s",
1378 link->ifname, strerror(-r),
1381 link_enter_failed(link);
1385 log_debug_link(link, "enslaved");
1387 if (link->enslaving == 0)
1388 link_enslaved(link);
1393 static int link_enter_enslave(Link *link) {
1394 NetDev *vlan, *macvlan;
1399 assert(link->network);
1400 assert(link->state == LINK_STATE_INITIALIZING);
1402 link->state = LINK_STATE_ENSLAVING;
1406 if (!link->network->bridge && !link->network->bond &&
1407 hashmap_isempty(link->network->vlans) &&
1408 hashmap_isempty(link->network->macvlans))
1409 return link_enslaved(link);
1411 if (link->network->bridge) {
1412 log_struct_link(LOG_DEBUG, link,
1413 "MESSAGE=%s: enslaving by '%s'",
1414 link->ifname, link->network->bridge->name,
1415 NETDEV(link->network->bridge),
1418 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1420 log_struct_link(LOG_WARNING, link,
1421 "MESSAGE=%s: could not enslave by '%s': %s",
1422 link->ifname, link->network->bridge->name, strerror(-r),
1423 NETDEV(link->network->bridge),
1425 link_enter_failed(link);
1432 if (link->network->bond) {
1433 log_struct_link(LOG_DEBUG, link,
1434 "MESSAGE=%s: enslaving by '%s'",
1435 link->ifname, link->network->bond->name,
1436 NETDEV(link->network->bond),
1439 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1441 log_struct_link(LOG_WARNING, link,
1442 "MESSAGE=%s: could not enslave by '%s': %s",
1443 link->ifname, link->network->bond->name, strerror(-r),
1444 NETDEV(link->network->bond),
1446 link_enter_failed(link);
1453 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1454 log_struct_link(LOG_DEBUG, link,
1455 "MESSAGE=%s: enslaving by '%s'",
1456 link->ifname, vlan->name, NETDEV(vlan), NULL);
1458 r = netdev_enslave(vlan, link, &enslave_handler);
1460 log_struct_link(LOG_WARNING, link,
1461 "MESSAGE=%s: could not enslave by '%s': %s",
1462 link->ifname, vlan->name, strerror(-r),
1463 NETDEV(vlan), NULL);
1464 link_enter_failed(link);
1471 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1472 log_struct_link(LOG_DEBUG, link,
1473 "MESSAGE=%s: enslaving by '%s'",
1474 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1476 r = netdev_enslave(macvlan, link, &enslave_handler);
1478 log_struct_link(LOG_WARNING, link,
1479 "MESSAGE=%s: could not enslave by '%s': %s",
1480 link->ifname, macvlan->name, strerror(-r),
1481 NETDEV(macvlan), NULL);
1482 link_enter_failed(link);
1492 static int link_configure(Link *link) {
1496 assert(link->state == LINK_STATE_INITIALIZING);
1498 if (link->network->ipv4ll) {
1501 r = sd_ipv4ll_new(&link->ipv4ll);
1505 if (link->udev_device) {
1506 r = net_get_unique_predictable_data(link->udev_device, seed);
1508 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1514 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1518 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1522 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1526 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1531 if (link->network->dhcp) {
1532 r = sd_dhcp_client_new(&link->dhcp_client);
1536 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1540 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1544 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1548 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1552 if (link->network->dhcp_mtu) {
1553 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1559 if (link_has_carrier(link->flags, link->operstate)) {
1560 r = link_acquire_conf(link);
1565 return link_enter_enslave(link);
1568 int link_initialized(Link *link, struct udev_device *device) {
1573 assert(link->ifname);
1574 assert(link->manager);
1576 if (link->state != LINK_STATE_INITIALIZING)
1580 link->udev_device = udev_device_ref(device);
1582 log_debug_link(link, "link initialized");
1584 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1586 link_enter_unmanaged(link);
1591 r = network_apply(link->manager, network, link);
1595 r = link_configure(link);
1602 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1604 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1605 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1612 r = link_new(m, message, ret);
1618 log_debug_link(link, "link added");
1620 if (detect_container(NULL) <= 0) {
1621 /* not in a container, udev will be around */
1622 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1623 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1625 log_warning_link(link, "could not find udev device");
1629 if (udev_device_get_is_initialized(device) <= 0)
1634 r = link_initialized(link, device);
1641 int link_update(Link *link, sd_rtnl_message *m) {
1642 struct ether_addr mac;
1647 assert(link->ifname);
1650 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1651 if (r >= 0 && !streq(ifname, link->ifname)) {
1652 log_info_link(link, "renamed to %s", ifname);
1655 link->ifname = strdup(ifname);
1660 if (!link->original_mtu) {
1661 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1663 log_debug_link(link, "saved original MTU: %"
1664 PRIu16, link->original_mtu);
1667 /* The kernel may broadcast NEWLINK messages without the MAC address
1668 set, simply ignore them. */
1669 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1671 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1673 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1675 log_debug_link(link, "MAC address: "
1676 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1677 mac.ether_addr_octet[0],
1678 mac.ether_addr_octet[1],
1679 mac.ether_addr_octet[2],
1680 mac.ether_addr_octet[3],
1681 mac.ether_addr_octet[4],
1682 mac.ether_addr_octet[5]);
1685 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1687 log_warning_link(link, "Could not update MAC "
1688 "address in IPv4LL client: %s",
1694 if (link->dhcp_client) {
1695 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1697 log_warning_link(link, "Could not update MAC "
1698 "address in DHCP client: %s",
1706 return link_update_flags(link, m);
1709 int link_save(Link *link) {
1710 _cleanup_free_ char *temp_path = NULL;
1711 _cleanup_fclose_ FILE *f = NULL;
1712 const char *admin_state, *oper_state = "unknown";
1716 assert(link->state_file);
1717 assert(link->lease_file);
1718 assert(link->manager);
1720 r = manager_save(link->manager);
1724 admin_state = link_state_to_string(link->state);
1725 assert(admin_state);
1727 if (link->operstate == IF_OPER_DORMANT)
1728 oper_state = "dormant";
1729 else if (link_has_carrier(link->flags, link->operstate))
1730 oper_state = "carrier";
1732 r = fopen_temporary(link->state_file, &f, &temp_path);
1736 fchmod(fileno(f), 0644);
1739 "# This is private data. Do not parse.\n"
1743 admin_state, oper_state, link->flags);
1745 if (link->dhcp_lease) {
1746 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
1750 fprintf(f, "DHCP_LEASE=%s\n", link->lease_file);
1752 unlink(link->lease_file);
1756 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1758 unlink(link->state_file);
1764 log_error("Failed to save link data to %s: %s", link->state_file, strerror(-r));
1769 static const char* const link_state_table[_LINK_STATE_MAX] = {
1770 [LINK_STATE_INITIALIZING] = "initializing",
1771 [LINK_STATE_ENSLAVING] = "configuring",
1772 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1773 [LINK_STATE_SETTING_ROUTES] = "configuring",
1774 [LINK_STATE_CONFIGURED] = "configured",
1775 [LINK_STATE_UNMANAGED] = "unmanaged",
1776 [LINK_STATE_FAILED] = "failed",
1779 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);