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) {
886 assert(link->ipv4ll);
888 log_debug_link(link, "acquiring IPv4 link-local address");
890 r = sd_ipv4ll_start(link->ipv4ll);
895 if (link->network->dhcp) {
896 assert(link->dhcp_client);
898 log_debug_link(link, "acquiring DHCPv4 lease");
900 r = sd_dhcp_client_start(link->dhcp_client);
908 static int link_update_flags(Link *link, unsigned flags) {
912 assert(link->network);
914 if (link->state == LINK_STATE_FAILED)
917 if (link->flags == flags)
920 log_debug_link(link, "link status updated: %#.8x -> %#.8x",
923 if ((link->flags & IFF_UP) != (flags & IFF_UP))
925 "link is %s", flags & IFF_UP ? "up": "down");
927 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
928 if (flags & IFF_LOWER_UP) {
929 log_info_link(link, "carrier on");
931 if (link->network->dhcp || link->network->ipv4ll) {
932 r = link_acquire_conf(link);
934 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
935 link_enter_failed(link);
940 log_info_link(link, "carrier off");
942 if (link->network->dhcp) {
943 r = sd_dhcp_client_stop(link->dhcp_client);
945 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
946 link_enter_failed(link);
951 if (link->network->ipv4ll) {
952 r = sd_ipv4ll_stop(link->ipv4ll);
954 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
955 link_enter_failed(link);
967 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
968 Link *link = userdata;
973 if (link->state == LINK_STATE_FAILED)
976 r = sd_rtnl_message_get_errno(m);
978 link_update_flags(link, link->flags | IFF_UP);
980 log_struct_link(LOG_WARNING, link,
981 "MESSAGE=%s: could not bring up interface: %s",
982 link->ifname, strerror(-r),
988 static int link_up(Link *link) {
989 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
993 assert(link->manager);
994 assert(link->manager->rtnl);
996 log_debug_link(link, "bringing link up");
998 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
999 RTM_SETLINK, link->ifindex);
1001 log_error_link(link, "Could not allocate RTM_SETLINK message");
1005 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1007 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1011 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1013 log_error_link(link,
1014 "Could not send rtnetlink message: %s", strerror(-r));
1021 static int link_enslaved(Link *link) {
1025 assert(link->state == LINK_STATE_ENSLAVING);
1026 assert(link->network);
1030 link_enter_failed(link);
1034 if (!link->network->dhcp && !link->network->ipv4ll)
1035 return link_enter_set_addresses(link);
1040 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1041 Link *link = userdata;
1045 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1046 assert(link->network);
1050 if (link->state == LINK_STATE_FAILED)
1053 r = sd_rtnl_message_get_errno(m);
1055 log_struct_link(LOG_ERR, link,
1056 "MESSAGE=%s: could not enslave: %s",
1057 link->ifname, strerror(-r),
1060 link_enter_failed(link);
1064 log_debug_link(link, "enslaved");
1066 if (link->enslaving == 0)
1067 link_enslaved(link);
1072 static int link_enter_enslave(Link *link) {
1073 NetDev *vlan, *macvlan;
1078 assert(link->network);
1079 assert(link->state == _LINK_STATE_INVALID);
1081 link->state = LINK_STATE_ENSLAVING;
1085 if (!link->network->bridge && !link->network->bond &&
1086 hashmap_isempty(link->network->vlans) &&
1087 hashmap_isempty(link->network->macvlans))
1088 return link_enslaved(link);
1090 if (link->network->bridge) {
1091 log_struct_link(LOG_DEBUG, link,
1092 "MESSAGE=%s: enslaving by '%s'",
1093 link->ifname, link->network->bridge->name,
1094 NETDEV(link->network->bridge),
1097 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1099 log_struct_link(LOG_WARNING, link,
1100 "MESSAGE=%s: could not enslave by '%s': %s",
1101 link->ifname, link->network->bridge->name, strerror(-r),
1102 NETDEV(link->network->bridge),
1104 link_enter_failed(link);
1111 if (link->network->bond) {
1112 log_struct_link(LOG_DEBUG, link,
1113 "MESSAGE=%s: enslaving by '%s'",
1114 link->ifname, link->network->bond->name,
1115 NETDEV(link->network->bond),
1118 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1120 log_struct_link(LOG_WARNING, link,
1121 "MESSAGE=%s: could not enslave by '%s': %s",
1122 link->ifname, link->network->bond->name, strerror(-r),
1123 NETDEV(link->network->bond),
1125 link_enter_failed(link);
1132 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1133 log_struct_link(LOG_DEBUG, link,
1134 "MESSAGE=%s: enslaving by '%s'",
1135 link->ifname, vlan->name, NETDEV(vlan), NULL);
1137 r = netdev_enslave(vlan, link, &enslave_handler);
1139 log_struct_link(LOG_WARNING, link,
1140 "MESSAGE=%s: could not enslave by '%s': %s",
1141 link->ifname, vlan->name, strerror(-r),
1142 NETDEV(vlan), NULL);
1143 link_enter_failed(link);
1150 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1151 log_struct_link(LOG_DEBUG, link,
1152 "MESSAGE=%s: enslaving by '%s'",
1153 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1155 r = netdev_enslave(macvlan, link, &enslave_handler);
1157 log_struct_link(LOG_WARNING, link,
1158 "MESSAGE=%s: could not enslave by '%s': %s",
1159 link->ifname, macvlan->name, strerror(-r),
1160 NETDEV(macvlan), NULL);
1161 link_enter_failed(link);
1171 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1173 Link *link = userdata;
1178 if (link->state == LINK_STATE_FAILED)
1181 r = sd_rtnl_message_get_errno(m);
1183 log_struct_link(LOG_ERR, link,
1184 "MESSAGE=%s: could not get state: %s",
1185 link->ifname, strerror(-r),
1188 link_enter_failed(link);
1192 link_update(link, m);
1197 static int link_getlink(Link *link) {
1198 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1202 assert(link->manager);
1203 assert(link->manager->rtnl);
1205 log_debug_link(link, "requesting link status");
1207 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1208 RTM_GETLINK, link->ifindex);
1210 log_error_link(link, "Could not allocate RTM_GETLINK message");
1214 r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1217 log_error_link(link,
1218 "Could not send rtnetlink message: %s", strerror(-r));
1225 static int link_configure(Link *link) {
1229 assert(link->state == _LINK_STATE_INVALID);
1231 r = link_getlink(link);
1235 return link_enter_enslave(link);
1238 int link_add(Manager *m, struct udev_device *device, Link **ret) {
1246 r = link_new(m, device, &link);
1252 r = network_get(m, device, &network);
1254 return r == -ENOENT ? 0 : r;
1256 r = network_apply(m, network, link);
1260 if (link->network->ipv4ll) {
1261 r = sd_ipv4ll_new(&link->ipv4ll);
1265 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1269 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1273 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1278 if (link->network->dhcp) {
1279 r = sd_dhcp_client_new(&link->dhcp_client);
1283 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1287 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1291 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1295 if (link->network->dhcp_mtu) {
1296 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1302 r = link_configure(link);
1309 int link_update(Link *link, sd_rtnl_message *m) {
1311 struct ether_addr mac;
1315 assert(link->network);
1318 if (link->state == LINK_STATE_FAILED)
1321 if (link->network->dhcp && link->network->dhcp_mtu &&
1322 !link->original_mtu) {
1323 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1325 log_debug_link(link, "saved original MTU: %"
1326 PRIu16, link->original_mtu);
1329 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1330 if (r >= 0 && memcmp(&link->mac.ether_addr_octet, &mac.ether_addr_octet, ETH_ALEN)) {
1332 memcpy(&link->mac.ether_addr_octet, &mac.ether_addr_octet, ETH_ALEN);
1334 log_debug_link(link, "MAC address: "
1335 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1336 mac.ether_addr_octet[0],
1337 mac.ether_addr_octet[1],
1338 mac.ether_addr_octet[2],
1339 mac.ether_addr_octet[3],
1340 mac.ether_addr_octet[4],
1341 mac.ether_addr_octet[5]);
1344 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1346 log_warning_link(link, "Could not update MAC "
1347 "address in IPv4LL client: %s",
1353 if (link->dhcp_client) {
1354 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1356 log_warning_link(link, "Could not update MAC "
1357 "address in DHCP client: %s",
1364 r = sd_rtnl_message_link_get_flags(m, &flags);
1366 log_warning_link(link, "Could not get link flags");
1370 return link_update_flags(link, flags);
1373 int link_save(Link *link) {
1374 _cleanup_free_ char *temp_path = NULL;
1375 _cleanup_fclose_ FILE *f = NULL;
1379 assert(link->state_file);
1381 r = fopen_temporary(link->state_file, &f, &temp_path);
1385 fchmod(fileno(f), 0644);
1388 "# This is private data. Do not parse.\n"
1390 link_state_to_string(link->state));
1392 if (link->dhcp_lease) {
1395 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1400 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1404 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1409 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1411 unlink(link->state_file);
1417 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1422 static const char* const link_state_table[_LINK_STATE_MAX] = {
1423 [LINK_STATE_ENSLAVING] = "configuring",
1424 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1425 [LINK_STATE_SETTING_ROUTES] = "configuring",
1426 [LINK_STATE_CONFIGURED] = "configured",
1427 [LINK_STATE_FAILED] = "failed",
1430 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);