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"
31 #include "dhcp-lease-internal.h"
33 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
34 _cleanup_link_free_ Link *link = NULL;
36 struct ether_addr *mac_addr;
41 assert(manager->links);
49 link->manager = manager;
50 link->state = _LINK_STATE_INVALID;
52 link->ifindex = udev_device_get_ifindex(device);
53 if (link->ifindex <= 0)
56 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
61 mac = udev_device_get_sysattr_value(device, "address");
63 mac_addr = ether_aton(mac);
65 memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
68 ifname = udev_device_get_sysname(device);
69 link->ifname = strdup(ifname);
71 r = hashmap_put(manager->links, &link->ifindex, link);
81 void link_free(Link *link) {
85 assert(link->manager);
87 sd_dhcp_client_free(link->dhcp_client);
88 sd_dhcp_lease_unref(link->dhcp_lease);
90 sd_ipv4ll_free(link->ipv4ll);
92 hashmap_remove(link->manager->links, &link->ifindex);
95 free(link->state_file);
100 int link_get(Manager *m, int ifindex, Link **ret) {
109 ifindex_64 = ifindex;
110 link = hashmap_get(m->links, &ifindex_64);
119 static int link_enter_configured(Link *link) {
121 assert(link->state == LINK_STATE_SETTING_ROUTES);
123 log_info_link(link, "link configured");
125 link->state = LINK_STATE_CONFIGURED;
132 static void link_enter_failed(Link *link) {
135 log_warning_link(link, "failed");
137 link->state = LINK_STATE_FAILED;
142 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
143 Link *link = userdata;
146 assert(link->route_messages > 0);
147 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
148 link->state == LINK_STATE_SETTING_ROUTES ||
149 link->state == LINK_STATE_FAILED);
151 link->route_messages --;
153 if (link->state == LINK_STATE_FAILED)
156 r = sd_rtnl_message_get_errno(m);
157 if (r < 0 && r != -EEXIST)
158 log_struct_link(LOG_WARNING, link,
159 "MESSAGE=%s: could not set route: %s",
160 link->ifname, strerror(-r),
164 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
166 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
167 log_debug_link(link, "routes set");
168 link_enter_configured(link);
174 static int link_enter_set_routes(Link *link) {
180 assert(link->network);
181 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
183 link->state = LINK_STATE_SETTING_ROUTES;
185 if (!link->network->static_routes && !link->dhcp_lease &&
186 (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
187 return link_enter_configured(link);
189 log_debug_link(link, "setting routes");
191 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
192 r = route_configure(rt, link, &route_handler);
194 log_warning_link(link,
195 "could not set routes: %s", strerror(-r));
196 link_enter_failed(link);
200 link->route_messages ++;
203 if (link->ipv4ll && !link->dhcp_lease) {
204 _cleanup_route_free_ Route *route = NULL;
207 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
208 if (r < 0 && r != -ENOENT) {
209 log_warning_link(link, "IPV4LL error: no address: %s",
215 r = route_new_dynamic(&route);
217 log_error_link(link, "Could not allocate route: %s",
222 route->family = AF_INET;
223 route->scope = RT_SCOPE_LINK;
226 r = route_configure(route, link, &route_handler);
228 log_warning_link(link,
229 "could not set routes: %s", strerror(-r));
230 link_enter_failed(link);
234 link->route_messages ++;
238 if (link->dhcp_lease) {
239 _cleanup_route_free_ Route *route = NULL;
240 struct in_addr gateway;
242 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
244 log_warning_link(link, "DHCP error: no router: %s",
249 r = route_new_dynamic(&route);
251 log_error_link(link, "Could not allocate route: %s",
256 route->family = AF_INET;
257 route->in_addr.in = gateway;
259 r = route_configure(route, link, &route_handler);
261 log_warning_link(link,
262 "could not set routes: %s", strerror(-r));
263 link_enter_failed(link);
267 link->route_messages ++;
273 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
274 Link *link = userdata;
279 assert(link->ifname);
281 if (link->state == LINK_STATE_FAILED)
284 r = sd_rtnl_message_get_errno(m);
285 if (r < 0 && r != -ENOENT)
286 log_struct_link(LOG_WARNING, link,
287 "MESSAGE=%s: could not drop route: %s",
288 link->ifname, strerror(-r),
295 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
296 Link *link = userdata;
301 assert(link->ifname);
302 assert(link->addr_messages > 0);
303 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
305 link->addr_messages --;
307 if (link->state == LINK_STATE_FAILED)
310 r = sd_rtnl_message_get_errno(m);
311 if (r < 0 && r != -EEXIST)
312 log_struct_link(LOG_WARNING, link,
313 "MESSAGE=%s: could not set address: %s",
314 link->ifname, strerror(-r),
318 if (link->addr_messages == 0) {
319 log_debug_link(link, "addresses set");
320 link_enter_set_routes(link);
326 static int link_enter_set_addresses(Link *link) {
332 assert(link->network);
333 assert(link->state != _LINK_STATE_INVALID);
335 link->state = LINK_STATE_SETTING_ADDRESSES;
337 if (!link->network->static_addresses && !link->dhcp_lease &&
338 (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
339 return link_enter_set_routes(link);
341 log_debug_link(link, "setting addresses");
343 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
344 r = address_configure(ad, link, &address_handler);
346 log_warning_link(link,
347 "could not set addresses: %s", strerror(-r));
348 link_enter_failed(link);
352 link->addr_messages ++;
355 if (link->ipv4ll && !link->dhcp_lease) {
356 _cleanup_address_free_ Address *ll_addr = NULL;
359 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
360 if (r < 0 && r != -ENOENT) {
361 log_warning_link(link, "IPV4LL error: no address: %s",
367 r = address_new_dynamic(&ll_addr);
369 log_error_link(link, "Could not allocate address: %s", strerror(-r));
373 ll_addr->family = AF_INET;
374 ll_addr->in_addr.in = addr;
375 ll_addr->prefixlen = 16;
376 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
377 ll_addr->scope = RT_SCOPE_LINK;
379 r = address_configure(ll_addr, link, &address_handler);
381 log_warning_link(link,
382 "could not set addresses: %s", strerror(-r));
383 link_enter_failed(link);
387 link->addr_messages ++;
391 if (link->dhcp_lease) {
392 _cleanup_address_free_ Address *address = NULL;
394 struct in_addr netmask;
397 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
399 log_warning_link(link, "DHCP error: no address: %s",
404 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
406 log_warning_link(link, "DHCP error: no netmask: %s",
411 prefixlen = net_netmask_to_prefixlen(&netmask);
413 r = address_new_dynamic(&address);
415 log_error_link(link, "Could not allocate address: %s",
420 address->family = AF_INET;
421 address->in_addr.in = addr;
422 address->prefixlen = prefixlen;
423 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
425 r = address_configure(address, link, &address_handler);
427 log_warning_link(link,
428 "could not set addresses: %s", strerror(-r));
429 link_enter_failed(link);
433 link->addr_messages ++;
439 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
440 Link *link = userdata;
445 assert(link->ifname);
447 if (link->state == LINK_STATE_FAILED)
450 r = sd_rtnl_message_get_errno(m);
451 if (r < 0 && r != -ENOENT)
452 log_struct_link(LOG_WARNING, link,
453 "MESSAGE=%s: could not drop address: %s",
454 link->ifname, strerror(-r),
461 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
464 r = sd_bus_message_get_errno(m);
466 log_warning("Could not set hostname: %s", strerror(-r));
471 static int set_hostname(sd_bus *bus, const char *hostname) {
472 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
477 log_debug("Setting transient hostname: '%s'", hostname);
479 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
480 log_info("Not connected to system bus, ignoring transient hostname.");
484 r = sd_bus_message_new_method_call(
487 "org.freedesktop.hostname1",
488 "/org/freedesktop/hostname1",
489 "org.freedesktop.hostname1",
494 r = sd_bus_message_append(m, "sb", hostname, false);
498 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
500 log_error("Could not set transient hostname: %s", strerror(-r));
505 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
506 Link *link = userdata;
511 assert(link->ifname);
513 if (link->state == LINK_STATE_FAILED)
516 r = sd_rtnl_message_get_errno(m);
518 log_struct_link(LOG_WARNING, link,
519 "MESSAGE=%s: could not set MTU: %s",
520 link->ifname, strerror(-r),
527 static int link_set_mtu(Link *link, uint32_t mtu) {
528 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
532 assert(link->manager);
533 assert(link->manager->rtnl);
535 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
537 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
538 RTM_SETLINK, link->ifindex);
540 log_error_link(link, "Could not allocate RTM_SETLINK message");
544 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
546 log_error_link(link, "Could not append MTU: %s", strerror(-r));
550 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
553 "Could not send rtnetlink message: %s", strerror(-r));
560 static int dhcp_lease_lost(Link *link) {
561 _cleanup_address_free_ Address *address = NULL;
563 struct in_addr netmask;
568 assert(link->dhcp_lease);
570 log_warning_link(link, "DHCP lease lost");
572 r = address_new_dynamic(&address);
574 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
575 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
576 prefixlen = net_netmask_to_prefixlen(&netmask);
578 address->family = AF_INET;
579 address->in_addr.in = addr;
580 address->prefixlen = prefixlen;
582 address_drop(address, link, &address_drop_handler);
585 if (link->network->dhcp_mtu) {
588 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
589 if (r >= 0 && link->original_mtu != mtu) {
590 r = link_set_mtu(link, link->original_mtu);
592 log_warning_link(link, "DHCP error: could not reset MTU");
593 link_enter_failed(link);
599 if (link->network->dhcp_hostname) {
600 const char *hostname = NULL;
602 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
603 if (r >= 0 && hostname) {
604 r = set_hostname(link->manager->bus, "");
606 log_error("Failed to reset transient hostname");
610 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
615 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
616 sd_dhcp_lease *lease;
617 struct in_addr address;
618 struct in_addr netmask;
619 struct in_addr gateway;
621 struct in_addr *nameservers;
622 size_t nameservers_size;
628 r = sd_dhcp_client_get_lease(client, &lease);
630 log_warning_link(link, "DHCP error: no lease: %s",
635 r = sd_dhcp_lease_get_address(lease, &address);
637 log_warning_link(link, "DHCP error: no address: %s",
642 r = sd_dhcp_lease_get_netmask(lease, &netmask);
644 log_warning_link(link, "DHCP error: no netmask: %s",
649 prefixlen = net_netmask_to_prefixlen(&netmask);
651 r = sd_dhcp_lease_get_router(lease, &gateway);
653 log_warning_link(link, "DHCP error: no router: %s",
658 log_struct_link(LOG_INFO, link,
659 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
661 ADDRESS_FMT_VAL(address),
663 ADDRESS_FMT_VAL(gateway),
664 "ADDRESS=%u.%u.%u.%u",
665 ADDRESS_FMT_VAL(address),
668 "GATEWAY=%u.%u.%u.%u",
669 ADDRESS_FMT_VAL(gateway),
672 link->dhcp_lease = lease;
674 if (link->network->dhcp_dns) {
675 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
677 r = manager_update_resolv_conf(link->manager);
679 log_error("Failed to update resolv.conf");
683 if (link->network->dhcp_mtu) {
686 r = sd_dhcp_lease_get_mtu(lease, &mtu);
688 r = link_set_mtu(link, mtu);
690 log_error_link(link, "Failed to set MTU "
695 if (link->network->dhcp_hostname) {
696 const char *hostname;
698 r = sd_dhcp_lease_get_hostname(lease, &hostname);
700 r = set_hostname(link->manager->bus, hostname);
702 log_error("Failed to set transient hostname "
703 "to '%s'", hostname);
707 link_enter_set_addresses(link);
712 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
713 Link *link = userdata;
717 assert(link->network);
718 assert(link->manager);
720 if (link->state == LINK_STATE_FAILED)
724 case DHCP_EVENT_NO_LEASE:
725 log_debug_link(link, "IP address in use.");
727 case DHCP_EVENT_EXPIRED:
728 case DHCP_EVENT_STOP:
729 case DHCP_EVENT_IP_CHANGE:
730 if (link->network->dhcp_critical) {
731 log_error_link(link, "DHCPv4 connection considered system critical, "
732 "ignoring request to reconfigure it.");
736 if (link->dhcp_lease) {
737 r = dhcp_lease_lost(link);
739 link_enter_failed(link);
744 if (event == DHCP_EVENT_IP_CHANGE) {
745 r = dhcp_lease_acquired(client, link);
747 link_enter_failed(link);
752 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
753 r = sd_ipv4ll_start (link->ipv4ll);
755 link_enter_failed(link);
761 case DHCP_EVENT_IP_ACQUIRE:
762 r = dhcp_lease_acquired(client, link);
764 link_enter_failed(link);
768 r = sd_ipv4ll_stop(link->ipv4ll);
770 link_enter_failed(link);
777 log_warning_link(link, "DHCP error: %s", strerror(-event));
779 log_warning_link(link, "DHCP unknown event: %d", event);
786 static int ipv4ll_address_lost(sd_ipv4ll *ll, Link *link) {
793 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
795 _cleanup_address_free_ Address *address = NULL;
796 _cleanup_route_free_ Route *route = NULL;
798 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
799 ADDRESS_FMT_VAL(addr));
801 r = address_new_dynamic(&address);
803 log_error_link(link, "Could not allocate address: %s", strerror(-r));
807 address->family = AF_INET;
808 address->in_addr.in = addr;
809 address->prefixlen = 16;
810 address->scope = RT_SCOPE_LINK;
812 address_drop(address, link, &address_drop_handler);
814 r = route_new_dynamic(&route);
816 log_error_link(link, "Could not allocate route: %s",
821 route->family = AF_INET;
822 route->scope = RT_SCOPE_LINK;
825 route_drop(route, link, &route_drop_handler);
831 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
832 struct in_addr address;
838 r = sd_ipv4ll_get_address(ll, &address);
842 log_struct_link(LOG_INFO, link,
843 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
845 ADDRESS_FMT_VAL(address),
848 link_enter_set_addresses(link);
853 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
854 Link *link = userdata;
858 assert(link->network);
859 assert(link->manager);
862 case IPV4LL_EVENT_STOP:
863 case IPV4LL_EVENT_CONFLICT:
864 r = ipv4ll_address_lost(ll, link);
866 link_enter_failed(link);
870 case IPV4LL_EVENT_BIND:
871 r = ipv4ll_address_claimed(ll, link);
873 link_enter_failed(link);
879 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
881 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
886 static int link_acquire_conf(Link *link) {
890 assert(link->network);
891 assert(link->manager);
892 assert(link->manager->event);
894 if (link->network->ipv4ll) {
896 r = sd_ipv4ll_new(&link->ipv4ll);
900 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
904 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
908 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
912 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
917 log_debug_link(link, "acquiring IPv4 link-local address");
919 r = sd_ipv4ll_start(link->ipv4ll);
924 if (link->network->dhcp) {
925 if (!link->dhcp_client) {
926 r = sd_dhcp_client_new(&link->dhcp_client);
930 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
934 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
938 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
942 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
946 if (link->network->dhcp_mtu) {
947 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
953 log_debug_link(link, "acquiring DHCPv4 lease");
955 r = sd_dhcp_client_start(link->dhcp_client);
963 static int link_update_flags(Link *link, unsigned flags) {
967 assert(link->network);
969 if (link->state == LINK_STATE_FAILED)
972 if (link->flags == flags)
975 if ((link->flags & IFF_UP) != (flags & IFF_UP))
977 "link is %s", flags & IFF_UP ? "up": "down");
979 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
980 if (flags & IFF_LOWER_UP) {
981 log_info_link(link, "carrier on");
983 if (link->network->dhcp || link->network->ipv4ll) {
984 r = link_acquire_conf(link);
986 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
987 link_enter_failed(link);
992 log_info_link(link, "carrier off");
994 if (link->network->dhcp) {
995 r = sd_dhcp_client_stop(link->dhcp_client);
997 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
998 link_enter_failed(link);
1003 if (link->network->ipv4ll) {
1004 r = sd_ipv4ll_stop(link->ipv4ll);
1006 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
1007 link_enter_failed(link);
1014 log_debug_link(link, "link status updated: %#.8x -> %#.8x",
1015 link->flags, flags);
1017 link->flags = flags;
1022 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1023 Link *link = userdata;
1028 if (link->state == LINK_STATE_FAILED)
1031 r = sd_rtnl_message_get_errno(m);
1033 link_update_flags(link, link->flags | IFF_UP);
1035 log_struct_link(LOG_WARNING, link,
1036 "MESSAGE=%s: could not bring up interface: %s",
1037 link->ifname, strerror(-r),
1043 static int link_up(Link *link) {
1044 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1048 assert(link->manager);
1049 assert(link->manager->rtnl);
1051 log_debug_link(link, "bringing link up");
1053 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1054 RTM_SETLINK, link->ifindex);
1056 log_error_link(link, "Could not allocate RTM_SETLINK message");
1060 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1062 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1066 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1068 log_error_link(link,
1069 "Could not send rtnetlink message: %s", strerror(-r));
1076 static int link_enslaved(Link *link) {
1080 assert(link->state == LINK_STATE_ENSLAVING);
1081 assert(link->network);
1085 link_enter_failed(link);
1089 if (!link->network->dhcp && !link->network->ipv4ll)
1090 return link_enter_set_addresses(link);
1095 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1096 Link *link = userdata;
1100 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1101 assert(link->network);
1105 if (link->state == LINK_STATE_FAILED)
1108 r = sd_rtnl_message_get_errno(m);
1110 log_struct_link(LOG_ERR, link,
1111 "MESSAGE=%s: could not enslave: %s",
1112 link->ifname, strerror(-r),
1115 link_enter_failed(link);
1119 log_debug_link(link, "enslaved");
1121 if (link->enslaving == 0)
1122 link_enslaved(link);
1127 static int link_enter_enslave(Link *link) {
1128 NetDev *vlan, *macvlan;
1133 assert(link->network);
1134 assert(link->state == _LINK_STATE_INVALID);
1136 link->state = LINK_STATE_ENSLAVING;
1140 if (!link->network->bridge && !link->network->bond &&
1141 hashmap_isempty(link->network->vlans) &&
1142 hashmap_isempty(link->network->macvlans))
1143 return link_enslaved(link);
1145 if (link->network->bridge) {
1146 log_struct_link(LOG_DEBUG, link,
1147 "MESSAGE=%s: enslaving by '%s'",
1148 link->ifname, link->network->bridge->name,
1149 NETDEV(link->network->bridge),
1152 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1154 log_struct_link(LOG_WARNING, link,
1155 "MESSAGE=%s: could not enslave by '%s': %s",
1156 link->ifname, link->network->bridge->name, strerror(-r),
1157 NETDEV(link->network->bridge),
1159 link_enter_failed(link);
1166 if (link->network->bond) {
1167 log_struct_link(LOG_DEBUG, link,
1168 "MESSAGE=%s: enslaving by '%s'",
1169 link->ifname, link->network->bond->name,
1170 NETDEV(link->network->bond),
1173 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1175 log_struct_link(LOG_WARNING, link,
1176 "MESSAGE=%s: could not enslave by '%s': %s",
1177 link->ifname, link->network->bond->name, strerror(-r),
1178 NETDEV(link->network->bond),
1180 link_enter_failed(link);
1187 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1188 log_struct_link(LOG_DEBUG, link,
1189 "MESSAGE=%s: enslaving by '%s'",
1190 link->ifname, vlan->name, NETDEV(vlan), NULL);
1192 r = netdev_enslave(vlan, link, &enslave_handler);
1194 log_struct_link(LOG_WARNING, link,
1195 "MESSAGE=%s: could not enslave by '%s': %s",
1196 link->ifname, vlan->name, strerror(-r),
1197 NETDEV(vlan), NULL);
1198 link_enter_failed(link);
1205 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1206 log_struct_link(LOG_DEBUG, link,
1207 "MESSAGE=%s: enslaving by '%s'",
1208 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1210 r = netdev_enslave(macvlan, link, &enslave_handler);
1212 log_struct_link(LOG_WARNING, link,
1213 "MESSAGE=%s: could not enslave by '%s': %s",
1214 link->ifname, macvlan->name, strerror(-r),
1215 NETDEV(macvlan), NULL);
1216 link_enter_failed(link);
1226 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1228 Link *link = userdata;
1233 if (link->state == LINK_STATE_FAILED)
1236 r = sd_rtnl_message_get_errno(m);
1238 log_struct_link(LOG_ERR, link,
1239 "MESSAGE=%s: could not get state: %s",
1240 link->ifname, strerror(-r),
1243 link_enter_failed(link);
1247 link_update(link, m);
1252 static int link_getlink(Link *link) {
1253 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1257 assert(link->manager);
1258 assert(link->manager->rtnl);
1260 log_debug_link(link, "requesting link status");
1262 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1263 RTM_GETLINK, link->ifindex);
1265 log_error_link(link, "Could not allocate RTM_GETLINK message");
1269 r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1272 log_error_link(link,
1273 "Could not send rtnetlink message: %s", strerror(-r));
1280 static int link_configure(Link *link) {
1284 assert(link->state == _LINK_STATE_INVALID);
1286 r = link_getlink(link);
1290 return link_enter_enslave(link);
1293 int link_add(Manager *m, struct udev_device *device, Link **ret) {
1301 r = link_new(m, device, &link);
1307 r = network_get(m, device, &network);
1309 return r == -ENOENT ? 0 : r;
1311 r = network_apply(m, network, link);
1315 r = link_configure(link);
1322 int link_update(Link *link, sd_rtnl_message *m) {
1327 assert(link->network);
1330 if (link->state == LINK_STATE_FAILED)
1333 if (link->network->dhcp && link->network->dhcp_mtu &&
1334 !link->original_mtu) {
1335 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1337 log_debug_link(link, "saved original MTU: %"
1338 PRIu16, link->original_mtu);
1341 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &link->mac);
1343 log_debug_link(link, "MAC address: "
1344 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1345 link->mac.ether_addr_octet[0],
1346 link->mac.ether_addr_octet[1],
1347 link->mac.ether_addr_octet[2],
1348 link->mac.ether_addr_octet[3],
1349 link->mac.ether_addr_octet[4],
1350 link->mac.ether_addr_octet[5]);
1353 r = sd_rtnl_message_link_get_flags(m, &flags);
1355 log_warning_link(link, "Could not get link flags");
1359 return link_update_flags(link, flags);
1362 int link_save(Link *link) {
1363 _cleanup_free_ char *temp_path = NULL;
1364 _cleanup_fclose_ FILE *f = NULL;
1368 assert(link->state_file);
1370 r = fopen_temporary(link->state_file, &f, &temp_path);
1374 fchmod(fileno(f), 0644);
1377 "# This is private data. Do not parse.\n"
1379 link_state_to_string(link->state));
1381 if (link->dhcp_lease) {
1384 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1389 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1393 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1398 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1400 unlink(link->state_file);
1406 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1411 static const char* const link_state_table[_LINK_STATE_MAX] = {
1412 [LINK_STATE_ENSLAVING] = "configuring",
1413 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1414 [LINK_STATE_SETTING_ROUTES] = "configuring",
1415 [LINK_STATE_CONFIGURED] = "configured",
1416 [LINK_STATE_FAILED] = "failed",
1419 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);