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;
39 assert(manager->links);
47 link->manager = manager;
48 link->state = _LINK_STATE_INVALID;
50 link->ifindex = udev_device_get_ifindex(device);
51 if (link->ifindex <= 0)
54 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
59 ifname = udev_device_get_sysname(device);
60 link->ifname = strdup(ifname);
62 r = hashmap_put(manager->links, &link->ifindex, link);
72 void link_free(Link *link) {
76 assert(link->manager);
78 sd_dhcp_client_free(link->dhcp_client);
79 sd_dhcp_lease_unref(link->dhcp_lease);
81 sd_ipv4ll_free(link->ipv4ll);
83 hashmap_remove(link->manager->links, &link->ifindex);
86 free(link->state_file);
91 int link_get(Manager *m, int ifindex, Link **ret) {
100 ifindex_64 = ifindex;
101 link = hashmap_get(m->links, &ifindex_64);
110 static int link_enter_configured(Link *link) {
112 assert(link->state == LINK_STATE_SETTING_ROUTES);
114 log_info_link(link, "link configured");
116 link->state = LINK_STATE_CONFIGURED;
123 static void link_enter_failed(Link *link) {
126 log_warning_link(link, "failed");
128 link->state = LINK_STATE_FAILED;
133 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
134 Link *link = userdata;
137 assert(link->route_messages > 0);
138 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
139 link->state == LINK_STATE_SETTING_ROUTES ||
140 link->state == LINK_STATE_FAILED);
142 link->route_messages --;
144 if (link->state == LINK_STATE_FAILED)
147 r = sd_rtnl_message_get_errno(m);
148 if (r < 0 && r != -EEXIST)
149 log_struct_link(LOG_WARNING, link,
150 "MESSAGE=%s: could not set route: %s",
151 link->ifname, strerror(-r),
155 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
157 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
158 log_debug_link(link, "routes set");
159 link_enter_configured(link);
165 static int link_enter_set_routes(Link *link) {
171 assert(link->network);
172 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
174 link->state = LINK_STATE_SETTING_ROUTES;
176 if (!link->network->static_routes && !link->dhcp_lease &&
177 (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
178 return link_enter_configured(link);
180 log_debug_link(link, "setting routes");
182 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
183 r = route_configure(rt, link, &route_handler);
185 log_warning_link(link,
186 "could not set routes: %s", strerror(-r));
187 link_enter_failed(link);
191 link->route_messages ++;
194 if (link->ipv4ll && !link->dhcp_lease) {
195 _cleanup_route_free_ Route *route = NULL;
198 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
199 if (r < 0 && r != -ENOENT) {
200 log_warning_link(link, "IPV4LL error: no address: %s",
206 r = route_new_dynamic(&route);
208 log_error_link(link, "Could not allocate route: %s",
213 route->family = AF_INET;
214 route->scope = RT_SCOPE_LINK;
217 r = route_configure(route, link, &route_handler);
219 log_warning_link(link,
220 "could not set routes: %s", strerror(-r));
221 link_enter_failed(link);
225 link->route_messages ++;
229 if (link->dhcp_lease) {
230 _cleanup_route_free_ Route *route = NULL;
231 struct in_addr gateway;
233 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
235 log_warning_link(link, "DHCP error: no router: %s",
240 r = route_new_dynamic(&route);
242 log_error_link(link, "Could not allocate route: %s",
247 route->family = AF_INET;
248 route->in_addr.in = gateway;
250 r = route_configure(route, link, &route_handler);
252 log_warning_link(link,
253 "could not set routes: %s", strerror(-r));
254 link_enter_failed(link);
258 link->route_messages ++;
264 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
265 Link *link = userdata;
270 assert(link->ifname);
272 if (link->state == LINK_STATE_FAILED)
275 r = sd_rtnl_message_get_errno(m);
276 if (r < 0 && r != -ENOENT)
277 log_struct_link(LOG_WARNING, link,
278 "MESSAGE=%s: could not drop route: %s",
279 link->ifname, strerror(-r),
286 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
287 Link *link = userdata;
292 assert(link->ifname);
293 assert(link->addr_messages > 0);
294 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
296 link->addr_messages --;
298 if (link->state == LINK_STATE_FAILED)
301 r = sd_rtnl_message_get_errno(m);
302 if (r < 0 && r != -EEXIST)
303 log_struct_link(LOG_WARNING, link,
304 "MESSAGE=%s: could not set address: %s",
305 link->ifname, strerror(-r),
309 if (link->addr_messages == 0) {
310 log_debug_link(link, "addresses set");
311 link_enter_set_routes(link);
317 static int link_enter_set_addresses(Link *link) {
323 assert(link->network);
324 assert(link->state != _LINK_STATE_INVALID);
326 link->state = LINK_STATE_SETTING_ADDRESSES;
328 if (!link->network->static_addresses && !link->dhcp_lease &&
329 (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
330 return link_enter_set_routes(link);
332 log_debug_link(link, "setting addresses");
334 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
335 r = address_configure(ad, link, &address_handler);
337 log_warning_link(link,
338 "could not set addresses: %s", strerror(-r));
339 link_enter_failed(link);
343 link->addr_messages ++;
346 if (link->ipv4ll && !link->dhcp_lease) {
347 _cleanup_address_free_ Address *ll_addr = NULL;
350 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
351 if (r < 0 && r != -ENOENT) {
352 log_warning_link(link, "IPV4LL error: no address: %s",
358 r = address_new_dynamic(&ll_addr);
360 log_error_link(link, "Could not allocate address: %s", strerror(-r));
364 ll_addr->family = AF_INET;
365 ll_addr->in_addr.in = addr;
366 ll_addr->prefixlen = 16;
367 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
368 ll_addr->scope = RT_SCOPE_LINK;
370 r = address_configure(ll_addr, link, &address_handler);
372 log_warning_link(link,
373 "could not set addresses: %s", strerror(-r));
374 link_enter_failed(link);
378 link->addr_messages ++;
382 if (link->dhcp_lease) {
383 _cleanup_address_free_ Address *address = NULL;
385 struct in_addr netmask;
388 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
390 log_warning_link(link, "DHCP error: no address: %s",
395 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
397 log_warning_link(link, "DHCP error: no netmask: %s",
402 prefixlen = net_netmask_to_prefixlen(&netmask);
404 r = address_new_dynamic(&address);
406 log_error_link(link, "Could not allocate address: %s",
411 address->family = AF_INET;
412 address->in_addr.in = addr;
413 address->prefixlen = prefixlen;
414 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
416 r = address_configure(address, link, &address_handler);
418 log_warning_link(link,
419 "could not set addresses: %s", strerror(-r));
420 link_enter_failed(link);
424 link->addr_messages ++;
430 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
431 Link *link = userdata;
436 assert(link->ifname);
438 if (link->state == LINK_STATE_FAILED)
441 r = sd_rtnl_message_get_errno(m);
442 if (r < 0 && r != -ENOENT)
443 log_struct_link(LOG_WARNING, link,
444 "MESSAGE=%s: could not drop address: %s",
445 link->ifname, strerror(-r),
452 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
455 r = sd_bus_message_get_errno(m);
457 log_warning("Could not set hostname: %s", strerror(-r));
462 static int set_hostname(sd_bus *bus, const char *hostname) {
463 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
468 log_debug("Setting transient hostname: '%s'", hostname);
470 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
471 log_info("Not connected to system bus, ignoring transient hostname.");
475 r = sd_bus_message_new_method_call(
478 "org.freedesktop.hostname1",
479 "/org/freedesktop/hostname1",
480 "org.freedesktop.hostname1",
485 r = sd_bus_message_append(m, "sb", hostname, false);
489 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
491 log_error("Could not set transient hostname: %s", strerror(-r));
496 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
497 Link *link = userdata;
502 assert(link->ifname);
504 if (link->state == LINK_STATE_FAILED)
507 r = sd_rtnl_message_get_errno(m);
509 log_struct_link(LOG_WARNING, link,
510 "MESSAGE=%s: could not set MTU: %s",
511 link->ifname, strerror(-r),
518 static int link_set_mtu(Link *link, uint32_t mtu) {
519 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
523 assert(link->manager);
524 assert(link->manager->rtnl);
526 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
528 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
529 RTM_SETLINK, link->ifindex);
531 log_error_link(link, "Could not allocate RTM_SETLINK message");
535 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
537 log_error_link(link, "Could not append MTU: %s", strerror(-r));
541 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
544 "Could not send rtnetlink message: %s", strerror(-r));
551 static int dhcp_lease_lost(Link *link) {
552 _cleanup_address_free_ Address *address = NULL;
554 struct in_addr netmask;
559 assert(link->dhcp_lease);
561 log_warning_link(link, "DHCP lease lost");
563 r = address_new_dynamic(&address);
565 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
566 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
567 prefixlen = net_netmask_to_prefixlen(&netmask);
569 address->family = AF_INET;
570 address->in_addr.in = addr;
571 address->prefixlen = prefixlen;
573 address_drop(address, link, &address_drop_handler);
576 if (link->network->dhcp_mtu) {
579 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
580 if (r >= 0 && link->original_mtu != mtu) {
581 r = link_set_mtu(link, link->original_mtu);
583 log_warning_link(link, "DHCP error: could not reset MTU");
584 link_enter_failed(link);
590 if (link->network->dhcp_hostname) {
591 const char *hostname = NULL;
593 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
594 if (r >= 0 && hostname) {
595 r = set_hostname(link->manager->bus, "");
597 log_error("Failed to reset transient hostname");
601 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
606 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
607 sd_dhcp_lease *lease;
608 struct in_addr address;
609 struct in_addr netmask;
610 struct in_addr gateway;
612 struct in_addr *nameservers;
613 size_t nameservers_size;
619 r = sd_dhcp_client_get_lease(client, &lease);
621 log_warning_link(link, "DHCP error: no lease: %s",
626 r = sd_dhcp_lease_get_address(lease, &address);
628 log_warning_link(link, "DHCP error: no address: %s",
633 r = sd_dhcp_lease_get_netmask(lease, &netmask);
635 log_warning_link(link, "DHCP error: no netmask: %s",
640 prefixlen = net_netmask_to_prefixlen(&netmask);
642 r = sd_dhcp_lease_get_router(lease, &gateway);
644 log_warning_link(link, "DHCP error: no router: %s",
649 log_struct_link(LOG_INFO, link,
650 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
652 ADDRESS_FMT_VAL(address),
654 ADDRESS_FMT_VAL(gateway),
655 "ADDRESS=%u.%u.%u.%u",
656 ADDRESS_FMT_VAL(address),
659 "GATEWAY=%u.%u.%u.%u",
660 ADDRESS_FMT_VAL(gateway),
663 link->dhcp_lease = lease;
665 if (link->network->dhcp_dns) {
666 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
668 r = manager_update_resolv_conf(link->manager);
670 log_error("Failed to update resolv.conf");
674 if (link->network->dhcp_mtu) {
677 r = sd_dhcp_lease_get_mtu(lease, &mtu);
679 r = link_set_mtu(link, mtu);
681 log_error_link(link, "Failed to set MTU "
686 if (link->network->dhcp_hostname) {
687 const char *hostname;
689 r = sd_dhcp_lease_get_hostname(lease, &hostname);
691 r = set_hostname(link->manager->bus, hostname);
693 log_error("Failed to set transient hostname "
694 "to '%s'", hostname);
698 link_enter_set_addresses(link);
703 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
704 Link *link = userdata;
708 assert(link->network);
709 assert(link->manager);
711 if (link->state == LINK_STATE_FAILED)
715 case DHCP_EVENT_NO_LEASE:
716 log_debug_link(link, "IP address in use.");
718 case DHCP_EVENT_EXPIRED:
719 case DHCP_EVENT_STOP:
720 case DHCP_EVENT_IP_CHANGE:
721 if (link->network->dhcp_critical) {
722 log_error_link(link, "DHCPv4 connection considered system critical, "
723 "ignoring request to reconfigure it.");
727 if (link->dhcp_lease) {
728 r = dhcp_lease_lost(link);
730 link_enter_failed(link);
735 if (event == DHCP_EVENT_IP_CHANGE) {
736 r = dhcp_lease_acquired(client, link);
738 link_enter_failed(link);
743 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
744 r = sd_ipv4ll_start (link->ipv4ll);
746 link_enter_failed(link);
752 case DHCP_EVENT_IP_ACQUIRE:
753 r = dhcp_lease_acquired(client, link);
755 link_enter_failed(link);
759 r = sd_ipv4ll_stop(link->ipv4ll);
761 link_enter_failed(link);
768 log_warning_link(link, "DHCP error: %s", strerror(-event));
770 log_warning_link(link, "DHCP unknown event: %d", event);
777 static int ipv4ll_address_lost(sd_ipv4ll *ll, Link *link) {
784 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
786 _cleanup_address_free_ Address *address = NULL;
787 _cleanup_route_free_ Route *route = NULL;
789 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
790 ADDRESS_FMT_VAL(addr));
792 r = address_new_dynamic(&address);
794 log_error_link(link, "Could not allocate address: %s", strerror(-r));
798 address->family = AF_INET;
799 address->in_addr.in = addr;
800 address->prefixlen = 16;
801 address->scope = RT_SCOPE_LINK;
803 address_drop(address, link, &address_drop_handler);
805 r = route_new_dynamic(&route);
807 log_error_link(link, "Could not allocate route: %s",
812 route->family = AF_INET;
813 route->scope = RT_SCOPE_LINK;
816 route_drop(route, link, &route_drop_handler);
822 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
823 struct in_addr address;
829 r = sd_ipv4ll_get_address(ll, &address);
833 log_struct_link(LOG_INFO, link,
834 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
836 ADDRESS_FMT_VAL(address),
839 link_enter_set_addresses(link);
844 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
845 Link *link = userdata;
849 assert(link->network);
850 assert(link->manager);
853 case IPV4LL_EVENT_STOP:
854 case IPV4LL_EVENT_CONFLICT:
855 r = ipv4ll_address_lost(ll, link);
857 link_enter_failed(link);
861 case IPV4LL_EVENT_BIND:
862 r = ipv4ll_address_claimed(ll, link);
864 link_enter_failed(link);
870 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
872 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
877 static int link_acquire_conf(Link *link) {
881 assert(link->network);
882 assert(link->manager);
883 assert(link->manager->event);
885 if (link->network->ipv4ll) {
887 r = sd_ipv4ll_new(&link->ipv4ll);
891 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
895 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
899 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
903 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
908 log_debug_link(link, "acquiring IPv4 link-local address");
910 r = sd_ipv4ll_start(link->ipv4ll);
915 if (link->network->dhcp) {
916 if (!link->dhcp_client) {
917 r = sd_dhcp_client_new(&link->dhcp_client);
921 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
925 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
929 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
933 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
937 if (link->network->dhcp_mtu) {
938 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
944 log_debug_link(link, "acquiring DHCPv4 lease");
946 r = sd_dhcp_client_start(link->dhcp_client);
954 static int link_update_flags(Link *link, unsigned flags) {
958 assert(link->network);
960 if (link->state == LINK_STATE_FAILED)
963 if (link->flags == flags)
966 log_debug_link(link, "link status updated: %#.8x -> %#.8x",
969 if ((link->flags & IFF_UP) != (flags & IFF_UP))
971 "link is %s", flags & IFF_UP ? "up": "down");
973 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
974 if (flags & IFF_LOWER_UP) {
975 log_info_link(link, "carrier on");
977 if (link->network->dhcp || link->network->ipv4ll) {
978 r = link_acquire_conf(link);
980 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
981 link_enter_failed(link);
986 log_info_link(link, "carrier off");
988 if (link->network->dhcp) {
989 r = sd_dhcp_client_stop(link->dhcp_client);
991 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
992 link_enter_failed(link);
997 if (link->network->ipv4ll) {
998 r = sd_ipv4ll_stop(link->ipv4ll);
1000 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
1001 link_enter_failed(link);
1008 link->flags = flags;
1013 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1014 Link *link = userdata;
1019 if (link->state == LINK_STATE_FAILED)
1022 r = sd_rtnl_message_get_errno(m);
1024 link_update_flags(link, link->flags | IFF_UP);
1026 log_struct_link(LOG_WARNING, link,
1027 "MESSAGE=%s: could not bring up interface: %s",
1028 link->ifname, strerror(-r),
1034 static int link_up(Link *link) {
1035 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1039 assert(link->manager);
1040 assert(link->manager->rtnl);
1042 log_debug_link(link, "bringing link up");
1044 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1045 RTM_SETLINK, link->ifindex);
1047 log_error_link(link, "Could not allocate RTM_SETLINK message");
1051 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1053 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1057 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1059 log_error_link(link,
1060 "Could not send rtnetlink message: %s", strerror(-r));
1067 static int link_enslaved(Link *link) {
1071 assert(link->state == LINK_STATE_ENSLAVING);
1072 assert(link->network);
1076 link_enter_failed(link);
1080 if (!link->network->dhcp && !link->network->ipv4ll)
1081 return link_enter_set_addresses(link);
1086 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1087 Link *link = userdata;
1091 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1092 assert(link->network);
1096 if (link->state == LINK_STATE_FAILED)
1099 r = sd_rtnl_message_get_errno(m);
1101 log_struct_link(LOG_ERR, link,
1102 "MESSAGE=%s: could not enslave: %s",
1103 link->ifname, strerror(-r),
1106 link_enter_failed(link);
1110 log_debug_link(link, "enslaved");
1112 if (link->enslaving == 0)
1113 link_enslaved(link);
1118 static int link_enter_enslave(Link *link) {
1119 NetDev *vlan, *macvlan;
1124 assert(link->network);
1125 assert(link->state == _LINK_STATE_INVALID);
1127 link->state = LINK_STATE_ENSLAVING;
1131 if (!link->network->bridge && !link->network->bond &&
1132 hashmap_isempty(link->network->vlans) &&
1133 hashmap_isempty(link->network->macvlans))
1134 return link_enslaved(link);
1136 if (link->network->bridge) {
1137 log_struct_link(LOG_DEBUG, link,
1138 "MESSAGE=%s: enslaving by '%s'",
1139 link->ifname, link->network->bridge->name,
1140 NETDEV(link->network->bridge),
1143 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1145 log_struct_link(LOG_WARNING, link,
1146 "MESSAGE=%s: could not enslave by '%s': %s",
1147 link->ifname, link->network->bridge->name, strerror(-r),
1148 NETDEV(link->network->bridge),
1150 link_enter_failed(link);
1157 if (link->network->bond) {
1158 log_struct_link(LOG_DEBUG, link,
1159 "MESSAGE=%s: enslaving by '%s'",
1160 link->ifname, link->network->bond->name,
1161 NETDEV(link->network->bond),
1164 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1166 log_struct_link(LOG_WARNING, link,
1167 "MESSAGE=%s: could not enslave by '%s': %s",
1168 link->ifname, link->network->bond->name, strerror(-r),
1169 NETDEV(link->network->bond),
1171 link_enter_failed(link);
1178 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1179 log_struct_link(LOG_DEBUG, link,
1180 "MESSAGE=%s: enslaving by '%s'",
1181 link->ifname, vlan->name, NETDEV(vlan), NULL);
1183 r = netdev_enslave(vlan, link, &enslave_handler);
1185 log_struct_link(LOG_WARNING, link,
1186 "MESSAGE=%s: could not enslave by '%s': %s",
1187 link->ifname, vlan->name, strerror(-r),
1188 NETDEV(vlan), NULL);
1189 link_enter_failed(link);
1196 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1197 log_struct_link(LOG_DEBUG, link,
1198 "MESSAGE=%s: enslaving by '%s'",
1199 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1201 r = netdev_enslave(macvlan, link, &enslave_handler);
1203 log_struct_link(LOG_WARNING, link,
1204 "MESSAGE=%s: could not enslave by '%s': %s",
1205 link->ifname, macvlan->name, strerror(-r),
1206 NETDEV(macvlan), NULL);
1207 link_enter_failed(link);
1217 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1219 Link *link = userdata;
1224 if (link->state == LINK_STATE_FAILED)
1227 r = sd_rtnl_message_get_errno(m);
1229 log_struct_link(LOG_ERR, link,
1230 "MESSAGE=%s: could not get state: %s",
1231 link->ifname, strerror(-r),
1234 link_enter_failed(link);
1238 link_update(link, m);
1243 static int link_getlink(Link *link) {
1244 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1248 assert(link->manager);
1249 assert(link->manager->rtnl);
1251 log_debug_link(link, "requesting link status");
1253 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1254 RTM_GETLINK, link->ifindex);
1256 log_error_link(link, "Could not allocate RTM_GETLINK message");
1260 r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1263 log_error_link(link,
1264 "Could not send rtnetlink message: %s", strerror(-r));
1271 static int link_configure(Link *link) {
1275 assert(link->state == _LINK_STATE_INVALID);
1277 r = link_getlink(link);
1281 return link_enter_enslave(link);
1284 int link_add(Manager *m, struct udev_device *device, Link **ret) {
1292 r = link_new(m, device, &link);
1298 r = network_get(m, device, &network);
1300 return r == -ENOENT ? 0 : r;
1302 r = network_apply(m, network, link);
1306 r = link_configure(link);
1313 int link_update(Link *link, sd_rtnl_message *m) {
1315 struct ether_addr mac;
1319 assert(link->network);
1322 if (link->state == LINK_STATE_FAILED)
1325 if (link->network->dhcp && link->network->dhcp_mtu &&
1326 !link->original_mtu) {
1327 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1329 log_debug_link(link, "saved original MTU: %"
1330 PRIu16, link->original_mtu);
1333 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1334 if (r >= 0 && memcmp(&link->mac.ether_addr_octet, &mac.ether_addr_octet, ETH_ALEN)) {
1336 memcpy(&link->mac.ether_addr_octet, &mac.ether_addr_octet, ETH_ALEN);
1338 log_debug_link(link, "MAC address: "
1339 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1340 mac.ether_addr_octet[0],
1341 mac.ether_addr_octet[1],
1342 mac.ether_addr_octet[2],
1343 mac.ether_addr_octet[3],
1344 mac.ether_addr_octet[4],
1345 mac.ether_addr_octet[5]);
1348 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1350 log_warning_link(link, "Could not update MAC "
1351 "address in IPv4LL client: %s",
1357 if (link->dhcp_client) {
1358 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1360 log_warning_link(link, "Could not update MAC "
1361 "address in DHCP client: %s",
1368 r = sd_rtnl_message_link_get_flags(m, &flags);
1370 log_warning_link(link, "Could not get link flags");
1374 return link_update_flags(link, flags);
1377 int link_save(Link *link) {
1378 _cleanup_free_ char *temp_path = NULL;
1379 _cleanup_fclose_ FILE *f = NULL;
1383 assert(link->state_file);
1385 r = fopen_temporary(link->state_file, &f, &temp_path);
1389 fchmod(fileno(f), 0644);
1392 "# This is private data. Do not parse.\n"
1394 link_state_to_string(link->state));
1396 if (link->dhcp_lease) {
1399 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1404 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1408 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1413 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1415 unlink(link->state_file);
1421 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1426 static const char* const link_state_table[_LINK_STATE_MAX] = {
1427 [LINK_STATE_ENSLAVING] = "configuring",
1428 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1429 [LINK_STATE_SETTING_ROUTES] = "configuring",
1430 [LINK_STATE_CONFIGURED] = "configured",
1431 [LINK_STATE_FAILED] = "failed",
1434 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);