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 _cleanup_route_free_ Route *route_gw = NULL;
232 struct in_addr gateway;
234 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
236 log_warning_link(link, "DHCP error: no router: %s",
241 r = route_new_dynamic(&route);
243 log_error_link(link, "Could not allocate route: %s",
248 r = route_new_dynamic(&route_gw);
250 log_error_link(link, "Could not allocate route: %s",
255 /* The dhcp netmask may mask out the gateway. Add an explicit
256 * route for the gw host so that we can route no matter the
257 * netmask or existing kernel route tables. */
258 route_gw->family = AF_INET;
259 route_gw->dst_addr.in = gateway;
260 route_gw->dst_prefixlen = 32;
261 route_gw->scope = RT_SCOPE_LINK;
263 r = route_configure(route_gw, link, &route_handler);
265 log_warning_link(link,
266 "could not set host route: %s", strerror(-r));
270 link->route_messages ++;
272 route->family = AF_INET;
273 route->in_addr.in = gateway;
275 r = route_configure(route, link, &route_handler);
277 log_warning_link(link,
278 "could not set routes: %s", strerror(-r));
279 link_enter_failed(link);
283 link->route_messages ++;
289 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
290 Link *link = userdata;
295 assert(link->ifname);
297 if (link->state == LINK_STATE_FAILED)
300 r = sd_rtnl_message_get_errno(m);
301 if (r < 0 && r != -ENOENT)
302 log_struct_link(LOG_WARNING, link,
303 "MESSAGE=%s: could not drop route: %s",
304 link->ifname, strerror(-r),
311 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
312 Link *link = userdata;
317 assert(link->ifname);
318 assert(link->addr_messages > 0);
319 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
321 link->addr_messages --;
323 if (link->state == LINK_STATE_FAILED)
326 r = sd_rtnl_message_get_errno(m);
327 if (r < 0 && r != -EEXIST)
328 log_struct_link(LOG_WARNING, link,
329 "MESSAGE=%s: could not set address: %s",
330 link->ifname, strerror(-r),
334 if (link->addr_messages == 0) {
335 log_debug_link(link, "addresses set");
336 link_enter_set_routes(link);
342 static int link_enter_set_addresses(Link *link) {
348 assert(link->network);
349 assert(link->state != _LINK_STATE_INVALID);
351 link->state = LINK_STATE_SETTING_ADDRESSES;
353 if (!link->network->static_addresses && !link->dhcp_lease &&
354 (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
355 return link_enter_set_routes(link);
357 log_debug_link(link, "setting addresses");
359 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
360 r = address_configure(ad, link, &address_handler);
362 log_warning_link(link,
363 "could not set addresses: %s", strerror(-r));
364 link_enter_failed(link);
368 link->addr_messages ++;
371 if (link->ipv4ll && !link->dhcp_lease) {
372 _cleanup_address_free_ Address *ll_addr = NULL;
375 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
376 if (r < 0 && r != -ENOENT) {
377 log_warning_link(link, "IPV4LL error: no address: %s",
383 r = address_new_dynamic(&ll_addr);
385 log_error_link(link, "Could not allocate address: %s", strerror(-r));
389 ll_addr->family = AF_INET;
390 ll_addr->in_addr.in = addr;
391 ll_addr->prefixlen = 16;
392 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
393 ll_addr->scope = RT_SCOPE_LINK;
395 r = address_configure(ll_addr, link, &address_handler);
397 log_warning_link(link,
398 "could not set addresses: %s", strerror(-r));
399 link_enter_failed(link);
403 link->addr_messages ++;
407 if (link->dhcp_lease) {
408 _cleanup_address_free_ Address *address = NULL;
410 struct in_addr netmask;
413 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
415 log_warning_link(link, "DHCP error: no address: %s",
420 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
422 log_warning_link(link, "DHCP error: no netmask: %s",
427 prefixlen = net_netmask_to_prefixlen(&netmask);
429 r = address_new_dynamic(&address);
431 log_error_link(link, "Could not allocate address: %s",
436 address->family = AF_INET;
437 address->in_addr.in = addr;
438 address->prefixlen = prefixlen;
439 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
441 r = address_configure(address, link, &address_handler);
443 log_warning_link(link,
444 "could not set addresses: %s", strerror(-r));
445 link_enter_failed(link);
449 link->addr_messages ++;
455 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
456 Link *link = userdata;
461 assert(link->ifname);
463 if (link->state == LINK_STATE_FAILED)
466 r = sd_rtnl_message_get_errno(m);
467 if (r < 0 && r != -ENOENT)
468 log_struct_link(LOG_WARNING, link,
469 "MESSAGE=%s: could not drop address: %s",
470 link->ifname, strerror(-r),
477 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
480 r = sd_bus_message_get_errno(m);
482 log_warning("Could not set hostname: %s", strerror(-r));
487 static int set_hostname(sd_bus *bus, const char *hostname) {
488 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
493 log_debug("Setting transient hostname: '%s'", hostname);
495 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
496 log_info("Not connected to system bus, ignoring transient hostname.");
500 r = sd_bus_message_new_method_call(
503 "org.freedesktop.hostname1",
504 "/org/freedesktop/hostname1",
505 "org.freedesktop.hostname1",
510 r = sd_bus_message_append(m, "sb", hostname, false);
514 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
516 log_error("Could not set transient hostname: %s", strerror(-r));
521 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
522 Link *link = userdata;
527 assert(link->ifname);
529 if (link->state == LINK_STATE_FAILED)
532 r = sd_rtnl_message_get_errno(m);
534 log_struct_link(LOG_WARNING, link,
535 "MESSAGE=%s: could not set MTU: %s",
536 link->ifname, strerror(-r),
543 static int link_set_mtu(Link *link, uint32_t mtu) {
544 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
548 assert(link->manager);
549 assert(link->manager->rtnl);
551 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
553 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
554 RTM_SETLINK, link->ifindex);
556 log_error_link(link, "Could not allocate RTM_SETLINK message");
560 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
562 log_error_link(link, "Could not append MTU: %s", strerror(-r));
566 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
569 "Could not send rtnetlink message: %s", strerror(-r));
576 static int dhcp_lease_lost(Link *link) {
577 _cleanup_address_free_ Address *address = NULL;
579 struct in_addr netmask;
584 assert(link->dhcp_lease);
586 log_warning_link(link, "DHCP lease lost");
588 r = address_new_dynamic(&address);
590 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
591 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
592 prefixlen = net_netmask_to_prefixlen(&netmask);
594 address->family = AF_INET;
595 address->in_addr.in = addr;
596 address->prefixlen = prefixlen;
598 address_drop(address, link, &address_drop_handler);
601 if (link->network->dhcp_mtu) {
604 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
605 if (r >= 0 && link->original_mtu != mtu) {
606 r = link_set_mtu(link, link->original_mtu);
608 log_warning_link(link, "DHCP error: could not reset MTU");
609 link_enter_failed(link);
615 if (link->network->dhcp_hostname) {
616 const char *hostname = NULL;
618 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
619 if (r >= 0 && hostname) {
620 r = set_hostname(link->manager->bus, "");
622 log_error("Failed to reset transient hostname");
626 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
631 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
632 sd_dhcp_lease *lease;
633 struct in_addr address;
634 struct in_addr netmask;
635 struct in_addr gateway;
637 struct in_addr *nameservers;
638 size_t nameservers_size;
644 r = sd_dhcp_client_get_lease(client, &lease);
646 log_warning_link(link, "DHCP error: no lease: %s",
651 r = sd_dhcp_lease_get_address(lease, &address);
653 log_warning_link(link, "DHCP error: no address: %s",
658 r = sd_dhcp_lease_get_netmask(lease, &netmask);
660 log_warning_link(link, "DHCP error: no netmask: %s",
665 prefixlen = net_netmask_to_prefixlen(&netmask);
667 r = sd_dhcp_lease_get_router(lease, &gateway);
669 log_warning_link(link, "DHCP error: no router: %s",
674 log_struct_link(LOG_INFO, link,
675 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
677 ADDRESS_FMT_VAL(address),
679 ADDRESS_FMT_VAL(gateway),
680 "ADDRESS=%u.%u.%u.%u",
681 ADDRESS_FMT_VAL(address),
684 "GATEWAY=%u.%u.%u.%u",
685 ADDRESS_FMT_VAL(gateway),
688 link->dhcp_lease = lease;
690 if (link->network->dhcp_dns) {
691 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
693 r = manager_update_resolv_conf(link->manager);
695 log_error("Failed to update resolv.conf");
699 if (link->network->dhcp_mtu) {
702 r = sd_dhcp_lease_get_mtu(lease, &mtu);
704 r = link_set_mtu(link, mtu);
706 log_error_link(link, "Failed to set MTU "
711 if (link->network->dhcp_hostname) {
712 const char *hostname;
714 r = sd_dhcp_lease_get_hostname(lease, &hostname);
716 r = set_hostname(link->manager->bus, hostname);
718 log_error("Failed to set transient hostname "
719 "to '%s'", hostname);
723 link_enter_set_addresses(link);
728 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
729 Link *link = userdata;
733 assert(link->network);
734 assert(link->manager);
736 if (link->state == LINK_STATE_FAILED)
740 case DHCP_EVENT_NO_LEASE:
741 log_debug_link(link, "IP address in use.");
743 case DHCP_EVENT_EXPIRED:
744 case DHCP_EVENT_STOP:
745 case DHCP_EVENT_IP_CHANGE:
746 if (link->network->dhcp_critical) {
747 log_error_link(link, "DHCPv4 connection considered system critical, "
748 "ignoring request to reconfigure it.");
752 if (link->dhcp_lease) {
753 r = dhcp_lease_lost(link);
755 link_enter_failed(link);
760 if (event == DHCP_EVENT_IP_CHANGE) {
761 r = dhcp_lease_acquired(client, link);
763 link_enter_failed(link);
768 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
769 r = sd_ipv4ll_start (link->ipv4ll);
771 link_enter_failed(link);
777 case DHCP_EVENT_IP_ACQUIRE:
778 r = dhcp_lease_acquired(client, link);
780 link_enter_failed(link);
784 r = sd_ipv4ll_stop(link->ipv4ll);
786 link_enter_failed(link);
793 log_warning_link(link, "DHCP error: %s", strerror(-event));
795 log_warning_link(link, "DHCP unknown event: %d", event);
802 static int ipv4ll_address_lost(sd_ipv4ll *ll, Link *link) {
809 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
811 _cleanup_address_free_ Address *address = NULL;
812 _cleanup_route_free_ Route *route = NULL;
814 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
815 ADDRESS_FMT_VAL(addr));
817 r = address_new_dynamic(&address);
819 log_error_link(link, "Could not allocate address: %s", strerror(-r));
823 address->family = AF_INET;
824 address->in_addr.in = addr;
825 address->prefixlen = 16;
826 address->scope = RT_SCOPE_LINK;
828 address_drop(address, link, &address_drop_handler);
830 r = route_new_dynamic(&route);
832 log_error_link(link, "Could not allocate route: %s",
837 route->family = AF_INET;
838 route->scope = RT_SCOPE_LINK;
841 route_drop(route, link, &route_drop_handler);
847 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
848 struct in_addr address;
854 r = sd_ipv4ll_get_address(ll, &address);
858 log_struct_link(LOG_INFO, link,
859 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
861 ADDRESS_FMT_VAL(address),
864 link_enter_set_addresses(link);
869 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
870 Link *link = userdata;
874 assert(link->network);
875 assert(link->manager);
878 case IPV4LL_EVENT_STOP:
879 case IPV4LL_EVENT_CONFLICT:
880 r = ipv4ll_address_lost(ll, link);
882 link_enter_failed(link);
886 case IPV4LL_EVENT_BIND:
887 r = ipv4ll_address_claimed(ll, link);
889 link_enter_failed(link);
895 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
897 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
902 static int link_acquire_conf(Link *link) {
906 assert(link->network);
907 assert(link->manager);
908 assert(link->manager->event);
910 if (link->network->ipv4ll) {
911 assert(link->ipv4ll);
913 log_debug_link(link, "acquiring IPv4 link-local address");
915 r = sd_ipv4ll_start(link->ipv4ll);
920 if (link->network->dhcp) {
921 assert(link->dhcp_client);
923 log_debug_link(link, "acquiring DHCPv4 lease");
925 r = sd_dhcp_client_start(link->dhcp_client);
933 static int link_update_flags(Link *link, unsigned flags) {
937 assert(link->network);
939 if (link->state == LINK_STATE_FAILED)
942 if (link->flags == flags)
945 log_debug_link(link, "link status updated: %#.8x -> %#.8x",
948 if ((link->flags & IFF_UP) != (flags & IFF_UP))
950 "link is %s", flags & IFF_UP ? "up": "down");
952 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
953 if (flags & IFF_LOWER_UP) {
954 log_info_link(link, "carrier on");
956 if (link->network->dhcp || link->network->ipv4ll) {
957 r = link_acquire_conf(link);
959 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
960 link_enter_failed(link);
965 log_info_link(link, "carrier off");
967 if (link->network->dhcp) {
968 r = sd_dhcp_client_stop(link->dhcp_client);
970 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
971 link_enter_failed(link);
976 if (link->network->ipv4ll) {
977 r = sd_ipv4ll_stop(link->ipv4ll);
979 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
980 link_enter_failed(link);
992 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
993 Link *link = userdata;
998 if (link->state == LINK_STATE_FAILED)
1001 r = sd_rtnl_message_get_errno(m);
1003 link_update_flags(link, link->flags | IFF_UP);
1005 log_struct_link(LOG_WARNING, link,
1006 "MESSAGE=%s: could not bring up interface: %s",
1007 link->ifname, strerror(-r),
1013 static int link_up(Link *link) {
1014 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1018 assert(link->manager);
1019 assert(link->manager->rtnl);
1021 log_debug_link(link, "bringing link up");
1023 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1024 RTM_SETLINK, link->ifindex);
1026 log_error_link(link, "Could not allocate RTM_SETLINK message");
1030 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1032 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1036 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1038 log_error_link(link,
1039 "Could not send rtnetlink message: %s", strerror(-r));
1046 static int link_enslaved(Link *link) {
1050 assert(link->state == LINK_STATE_ENSLAVING);
1051 assert(link->network);
1055 link_enter_failed(link);
1059 if (!link->network->dhcp && !link->network->ipv4ll)
1060 return link_enter_set_addresses(link);
1065 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1066 Link *link = userdata;
1070 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1071 assert(link->network);
1075 if (link->state == LINK_STATE_FAILED)
1078 r = sd_rtnl_message_get_errno(m);
1080 log_struct_link(LOG_ERR, link,
1081 "MESSAGE=%s: could not enslave: %s",
1082 link->ifname, strerror(-r),
1085 link_enter_failed(link);
1089 log_debug_link(link, "enslaved");
1091 if (link->enslaving == 0)
1092 link_enslaved(link);
1097 static int link_enter_enslave(Link *link) {
1098 NetDev *vlan, *macvlan;
1103 assert(link->network);
1104 assert(link->state == _LINK_STATE_INVALID);
1106 link->state = LINK_STATE_ENSLAVING;
1110 if (!link->network->bridge && !link->network->bond &&
1111 hashmap_isempty(link->network->vlans) &&
1112 hashmap_isempty(link->network->macvlans))
1113 return link_enslaved(link);
1115 if (link->network->bridge) {
1116 log_struct_link(LOG_DEBUG, link,
1117 "MESSAGE=%s: enslaving by '%s'",
1118 link->ifname, link->network->bridge->name,
1119 NETDEV(link->network->bridge),
1122 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1124 log_struct_link(LOG_WARNING, link,
1125 "MESSAGE=%s: could not enslave by '%s': %s",
1126 link->ifname, link->network->bridge->name, strerror(-r),
1127 NETDEV(link->network->bridge),
1129 link_enter_failed(link);
1136 if (link->network->bond) {
1137 log_struct_link(LOG_DEBUG, link,
1138 "MESSAGE=%s: enslaving by '%s'",
1139 link->ifname, link->network->bond->name,
1140 NETDEV(link->network->bond),
1143 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1145 log_struct_link(LOG_WARNING, link,
1146 "MESSAGE=%s: could not enslave by '%s': %s",
1147 link->ifname, link->network->bond->name, strerror(-r),
1148 NETDEV(link->network->bond),
1150 link_enter_failed(link);
1157 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1158 log_struct_link(LOG_DEBUG, link,
1159 "MESSAGE=%s: enslaving by '%s'",
1160 link->ifname, vlan->name, NETDEV(vlan), NULL);
1162 r = netdev_enslave(vlan, link, &enslave_handler);
1164 log_struct_link(LOG_WARNING, link,
1165 "MESSAGE=%s: could not enslave by '%s': %s",
1166 link->ifname, vlan->name, strerror(-r),
1167 NETDEV(vlan), NULL);
1168 link_enter_failed(link);
1175 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1176 log_struct_link(LOG_DEBUG, link,
1177 "MESSAGE=%s: enslaving by '%s'",
1178 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1180 r = netdev_enslave(macvlan, link, &enslave_handler);
1182 log_struct_link(LOG_WARNING, link,
1183 "MESSAGE=%s: could not enslave by '%s': %s",
1184 link->ifname, macvlan->name, strerror(-r),
1185 NETDEV(macvlan), NULL);
1186 link_enter_failed(link);
1196 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1198 Link *link = userdata;
1203 if (link->state == LINK_STATE_FAILED)
1206 r = sd_rtnl_message_get_errno(m);
1208 log_struct_link(LOG_ERR, link,
1209 "MESSAGE=%s: could not get state: %s",
1210 link->ifname, strerror(-r),
1213 link_enter_failed(link);
1217 link_update(link, m);
1222 static int link_getlink(Link *link) {
1223 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1227 assert(link->manager);
1228 assert(link->manager->rtnl);
1230 log_debug_link(link, "requesting link status");
1232 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1233 RTM_GETLINK, link->ifindex);
1235 log_error_link(link, "Could not allocate RTM_GETLINK message");
1239 r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1242 log_error_link(link,
1243 "Could not send rtnetlink message: %s", strerror(-r));
1250 static int link_configure(Link *link) {
1254 assert(link->state == _LINK_STATE_INVALID);
1256 r = link_getlink(link);
1260 return link_enter_enslave(link);
1263 int link_add(Manager *m, struct udev_device *device, Link **ret) {
1271 r = link_new(m, device, &link);
1277 r = network_get(m, device, &network);
1279 return r == -ENOENT ? 0 : r;
1281 r = network_apply(m, network, link);
1285 if (link->network->ipv4ll) {
1286 r = sd_ipv4ll_new(&link->ipv4ll);
1290 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1294 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1298 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1303 if (link->network->dhcp) {
1304 r = sd_dhcp_client_new(&link->dhcp_client);
1308 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1312 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1316 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1320 if (link->network->dhcp_mtu) {
1321 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1327 r = link_configure(link);
1334 int link_update(Link *link, sd_rtnl_message *m) {
1336 struct ether_addr mac;
1340 assert(link->network);
1343 if (link->state == LINK_STATE_FAILED)
1346 if (link->network->dhcp && link->network->dhcp_mtu &&
1347 !link->original_mtu) {
1348 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1350 log_debug_link(link, "saved original MTU: %"
1351 PRIu16, link->original_mtu);
1354 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1355 if (r >= 0 && memcmp(&link->mac.ether_addr_octet, &mac.ether_addr_octet, ETH_ALEN)) {
1357 memcpy(&link->mac.ether_addr_octet, &mac.ether_addr_octet, ETH_ALEN);
1359 log_debug_link(link, "MAC address: "
1360 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1361 mac.ether_addr_octet[0],
1362 mac.ether_addr_octet[1],
1363 mac.ether_addr_octet[2],
1364 mac.ether_addr_octet[3],
1365 mac.ether_addr_octet[4],
1366 mac.ether_addr_octet[5]);
1369 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1371 log_warning_link(link, "Could not update MAC "
1372 "address in IPv4LL client: %s",
1378 if (link->dhcp_client) {
1379 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1381 log_warning_link(link, "Could not update MAC "
1382 "address in DHCP client: %s",
1389 r = sd_rtnl_message_link_get_flags(m, &flags);
1391 log_warning_link(link, "Could not get link flags");
1395 return link_update_flags(link, flags);
1398 int link_save(Link *link) {
1399 _cleanup_free_ char *temp_path = NULL;
1400 _cleanup_fclose_ FILE *f = NULL;
1404 assert(link->state_file);
1406 r = fopen_temporary(link->state_file, &f, &temp_path);
1410 fchmod(fileno(f), 0644);
1413 "# This is private data. Do not parse.\n"
1415 link_state_to_string(link->state));
1417 if (link->dhcp_lease) {
1420 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1425 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1429 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1434 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1436 unlink(link->state_file);
1442 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1447 static const char* const link_state_table[_LINK_STATE_MAX] = {
1448 [LINK_STATE_ENSLAVING] = "configuring",
1449 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1450 [LINK_STATE_SETTING_ROUTES] = "configuring",
1451 [LINK_STATE_CONFIGURED] = "configured",
1452 [LINK_STATE_FAILED] = "failed",
1455 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);