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"
29 #include "network-internal.h"
31 #include "dhcp-lease-internal.h"
33 static int ipv4ll_address_update(Link *link, bool deprecate);
34 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
36 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
37 _cleanup_link_free_ Link *link = NULL;
42 assert(manager->links);
50 link->manager = manager;
51 link->state = _LINK_STATE_INVALID;
53 link->ifindex = udev_device_get_ifindex(device);
54 if (link->ifindex <= 0)
57 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
62 ifname = udev_device_get_sysname(device);
63 link->ifname = strdup(ifname);
65 r = hashmap_put(manager->links, &link->ifindex, link);
69 link->udev_device = udev_device_ref(device);
77 void link_free(Link *link) {
81 assert(link->manager);
83 sd_dhcp_client_unref(link->dhcp_client);
84 sd_dhcp_lease_unref(link->dhcp_lease);
86 sd_ipv4ll_unref(link->ipv4ll);
88 hashmap_remove(link->manager->links, &link->ifindex);
91 free(link->state_file);
93 udev_device_unref(link->udev_device);
98 int link_get(Manager *m, int ifindex, Link **ret) {
107 ifindex_64 = ifindex;
108 link = hashmap_get(m->links, &ifindex_64);
117 static int link_enter_configured(Link *link) {
119 assert(link->state == LINK_STATE_SETTING_ROUTES);
121 log_info_link(link, "link configured");
123 link->state = LINK_STATE_CONFIGURED;
130 static void link_enter_failed(Link *link) {
133 log_warning_link(link, "failed");
135 link->state = LINK_STATE_FAILED;
140 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
141 Link *link = userdata;
144 assert(link->route_messages > 0);
145 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
146 link->state == LINK_STATE_SETTING_ROUTES ||
147 link->state == LINK_STATE_FAILED);
149 link->route_messages --;
151 if (link->state == LINK_STATE_FAILED)
154 r = sd_rtnl_message_get_errno(m);
155 if (r < 0 && r != -EEXIST)
156 log_struct_link(LOG_WARNING, link,
157 "MESSAGE=%s: could not set route: %s",
158 link->ifname, strerror(-r),
162 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
164 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
165 log_debug_link(link, "routes set");
166 link_enter_configured(link);
172 static int link_enter_set_routes(Link *link) {
177 assert(link->network);
178 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
180 link->state = LINK_STATE_SETTING_ROUTES;
182 if (!link->network->static_routes && !link->dhcp_lease &&
183 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
184 return link_enter_configured(link);
186 log_debug_link(link, "setting routes");
188 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
189 r = route_configure(rt, link, &route_handler);
191 log_warning_link(link,
192 "could not set routes: %s", strerror(-r));
193 link_enter_failed(link);
197 link->route_messages ++;
200 if (link->ipv4ll && !link->dhcp_lease) {
201 _cleanup_route_free_ Route *route = NULL;
204 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
205 if (r < 0 && r != -ENOENT) {
206 log_warning_link(link, "IPV4LL error: no address: %s",
212 r = route_new_dynamic(&route);
214 log_error_link(link, "Could not allocate route: %s",
219 route->family = AF_INET;
220 route->scope = RT_SCOPE_LINK;
223 r = route_configure(route, link, &route_handler);
225 log_warning_link(link,
226 "could not set routes: %s", strerror(-r));
227 link_enter_failed(link);
231 link->route_messages ++;
235 if (link->dhcp_lease) {
236 _cleanup_route_free_ Route *route = NULL;
237 _cleanup_route_free_ Route *route_gw = NULL;
238 struct in_addr gateway;
240 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
242 log_warning_link(link, "DHCP error: no router: %s",
247 r = route_new_dynamic(&route);
249 log_error_link(link, "Could not allocate route: %s",
254 r = route_new_dynamic(&route_gw);
256 log_error_link(link, "Could not allocate route: %s",
261 /* The dhcp netmask may mask out the gateway. Add an explicit
262 * route for the gw host so that we can route no matter the
263 * netmask or existing kernel route tables. */
264 route_gw->family = AF_INET;
265 route_gw->dst_addr.in = gateway;
266 route_gw->dst_prefixlen = 32;
267 route_gw->scope = RT_SCOPE_LINK;
269 r = route_configure(route_gw, link, &route_handler);
271 log_warning_link(link,
272 "could not set host route: %s", strerror(-r));
276 link->route_messages ++;
278 route->family = AF_INET;
279 route->in_addr.in = gateway;
281 r = route_configure(route, link, &route_handler);
283 log_warning_link(link,
284 "could not set routes: %s", strerror(-r));
285 link_enter_failed(link);
289 link->route_messages ++;
295 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
296 Link *link = userdata;
301 assert(link->ifname);
303 if (link->state == LINK_STATE_FAILED)
306 r = sd_rtnl_message_get_errno(m);
307 if (r < 0 && r != -ENOENT)
308 log_struct_link(LOG_WARNING, link,
309 "MESSAGE=%s: could not drop route: %s",
310 link->ifname, strerror(-r),
317 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
318 Link *link = userdata;
323 assert(link->ifname);
324 assert(link->addr_messages > 0);
325 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
327 link->addr_messages --;
329 if (link->state == LINK_STATE_FAILED)
332 r = sd_rtnl_message_get_errno(m);
333 if (r < 0 && r != -EEXIST)
334 log_struct_link(LOG_WARNING, link,
335 "MESSAGE=%s: could not set address: %s",
336 link->ifname, strerror(-r),
340 if (link->addr_messages == 0) {
341 log_debug_link(link, "addresses set");
342 link_enter_set_routes(link);
348 static int link_enter_set_addresses(Link *link) {
353 assert(link->network);
354 assert(link->state != _LINK_STATE_INVALID);
356 link->state = LINK_STATE_SETTING_ADDRESSES;
358 if (!link->network->static_addresses && !link->dhcp_lease &&
359 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
360 return link_enter_set_routes(link);
362 log_debug_link(link, "setting addresses");
364 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
365 r = address_configure(ad, link, &address_handler);
367 log_warning_link(link,
368 "could not set addresses: %s", strerror(-r));
369 link_enter_failed(link);
373 link->addr_messages ++;
376 if (link->ipv4ll && !link->dhcp_lease) {
377 _cleanup_address_free_ Address *ll_addr = NULL;
380 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
381 if (r < 0 && r != -ENOENT) {
382 log_warning_link(link, "IPV4LL error: no address: %s",
388 r = address_new_dynamic(&ll_addr);
390 log_error_link(link, "Could not allocate address: %s", strerror(-r));
394 ll_addr->family = AF_INET;
395 ll_addr->in_addr.in = addr;
396 ll_addr->prefixlen = 16;
397 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
398 ll_addr->scope = RT_SCOPE_LINK;
400 r = address_configure(ll_addr, link, &address_handler);
402 log_warning_link(link,
403 "could not set addresses: %s", strerror(-r));
404 link_enter_failed(link);
408 link->addr_messages ++;
412 if (link->dhcp_lease) {
413 _cleanup_address_free_ Address *address = NULL;
415 struct in_addr netmask;
418 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
420 log_warning_link(link, "DHCP error: no address: %s",
425 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
427 log_warning_link(link, "DHCP error: no netmask: %s",
432 prefixlen = net_netmask_to_prefixlen(&netmask);
434 r = address_new_dynamic(&address);
436 log_error_link(link, "Could not allocate address: %s",
441 address->family = AF_INET;
442 address->in_addr.in = addr;
443 address->prefixlen = prefixlen;
444 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
446 r = address_configure(address, link, &address_handler);
448 log_warning_link(link,
449 "could not set addresses: %s", strerror(-r));
450 link_enter_failed(link);
454 link->addr_messages ++;
460 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
461 Link *link = userdata;
466 assert(link->ifname);
468 if (link->state == LINK_STATE_FAILED)
471 r = sd_rtnl_message_get_errno(m);
472 if (r < 0 && r != -ENOENT)
473 log_struct_link(LOG_WARNING, link,
474 "MESSAGE=%s: could not update address: %s",
475 link->ifname, strerror(-r),
482 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
483 Link *link = userdata;
488 assert(link->ifname);
490 if (link->state == LINK_STATE_FAILED)
493 r = sd_rtnl_message_get_errno(m);
494 if (r < 0 && r != -ENOENT)
495 log_struct_link(LOG_WARNING, link,
496 "MESSAGE=%s: could not drop address: %s",
497 link->ifname, strerror(-r),
504 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
507 r = sd_bus_message_get_errno(m);
509 log_warning("Could not set hostname: %s", strerror(-r));
514 static int set_hostname(sd_bus *bus, const char *hostname) {
515 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
520 log_debug("Setting transient hostname: '%s'", hostname);
522 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
523 log_info("Not connected to system bus, ignoring transient hostname.");
527 r = sd_bus_message_new_method_call(
530 "org.freedesktop.hostname1",
531 "/org/freedesktop/hostname1",
532 "org.freedesktop.hostname1",
537 r = sd_bus_message_append(m, "sb", hostname, false);
541 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
543 log_error("Could not set transient hostname: %s", strerror(-r));
548 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
549 Link *link = userdata;
554 assert(link->ifname);
556 if (link->state == LINK_STATE_FAILED)
559 r = sd_rtnl_message_get_errno(m);
561 log_struct_link(LOG_WARNING, link,
562 "MESSAGE=%s: could not set MTU: %s",
563 link->ifname, strerror(-r),
570 static int link_set_mtu(Link *link, uint32_t mtu) {
571 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
575 assert(link->manager);
576 assert(link->manager->rtnl);
578 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
580 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
581 RTM_SETLINK, link->ifindex);
583 log_error_link(link, "Could not allocate RTM_SETLINK message");
587 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
589 log_error_link(link, "Could not append MTU: %s", strerror(-r));
593 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
596 "Could not send rtnetlink message: %s", strerror(-r));
603 static int dhcp_lease_lost(Link *link) {
604 _cleanup_address_free_ Address *address = NULL;
605 _cleanup_route_free_ Route *route_gw = NULL;
606 _cleanup_route_free_ Route *route = NULL;
608 struct in_addr netmask;
609 struct in_addr gateway;
614 assert(link->dhcp_lease);
616 log_warning_link(link, "DHCP lease lost");
618 r = address_new_dynamic(&address);
620 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
621 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
622 sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
623 prefixlen = net_netmask_to_prefixlen(&netmask);
625 r = route_new_dynamic(&route_gw);
627 route_gw->family = AF_INET;
628 route_gw->dst_addr.in = gateway;
629 route_gw->dst_prefixlen = 32;
630 route_gw->scope = RT_SCOPE_LINK;
632 route_drop(route_gw, link, &route_drop_handler);
635 r = route_new_dynamic(&route);
637 route->family = AF_INET;
638 route->in_addr.in = gateway;
640 route_drop(route, link, &route_drop_handler);
643 address->family = AF_INET;
644 address->in_addr.in = addr;
645 address->prefixlen = prefixlen;
647 address_drop(address, link, &address_drop_handler);
650 if (link->network->dhcp_mtu) {
653 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
654 if (r >= 0 && link->original_mtu != mtu) {
655 r = link_set_mtu(link, link->original_mtu);
657 log_warning_link(link, "DHCP error: could not reset MTU");
658 link_enter_failed(link);
664 if (link->network->dhcp_hostname) {
665 const char *hostname = NULL;
667 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
668 if (r >= 0 && hostname) {
669 r = set_hostname(link->manager->bus, "");
671 log_error("Failed to reset transient hostname");
675 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
680 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
681 sd_dhcp_lease *lease;
682 struct in_addr address;
683 struct in_addr netmask;
684 struct in_addr gateway;
686 struct in_addr *nameservers;
687 size_t nameservers_size;
693 r = sd_dhcp_client_get_lease(client, &lease);
695 log_warning_link(link, "DHCP error: no lease: %s",
700 r = sd_dhcp_lease_get_address(lease, &address);
702 log_warning_link(link, "DHCP error: no address: %s",
707 r = sd_dhcp_lease_get_netmask(lease, &netmask);
709 log_warning_link(link, "DHCP error: no netmask: %s",
714 prefixlen = net_netmask_to_prefixlen(&netmask);
716 r = sd_dhcp_lease_get_router(lease, &gateway);
718 log_warning_link(link, "DHCP error: no router: %s",
723 log_struct_link(LOG_INFO, link,
724 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
726 ADDRESS_FMT_VAL(address),
728 ADDRESS_FMT_VAL(gateway),
729 "ADDRESS=%u.%u.%u.%u",
730 ADDRESS_FMT_VAL(address),
733 "GATEWAY=%u.%u.%u.%u",
734 ADDRESS_FMT_VAL(gateway),
737 link->dhcp_lease = lease;
739 if (link->network->dhcp_dns) {
740 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
742 r = manager_update_resolv_conf(link->manager);
744 log_error("Failed to update resolv.conf");
748 if (link->network->dhcp_mtu) {
751 r = sd_dhcp_lease_get_mtu(lease, &mtu);
753 r = link_set_mtu(link, mtu);
755 log_error_link(link, "Failed to set MTU "
760 if (link->network->dhcp_hostname) {
761 const char *hostname;
763 r = sd_dhcp_lease_get_hostname(lease, &hostname);
765 r = set_hostname(link->manager->bus, hostname);
767 log_error("Failed to set transient hostname "
768 "to '%s'", hostname);
772 link_enter_set_addresses(link);
777 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
778 Link *link = userdata;
782 assert(link->network);
783 assert(link->manager);
785 if (link->state == LINK_STATE_FAILED)
789 case DHCP_EVENT_NO_LEASE:
790 log_debug_link(link, "IP address in use.");
792 case DHCP_EVENT_EXPIRED:
793 case DHCP_EVENT_STOP:
794 case DHCP_EVENT_IP_CHANGE:
795 if (link->network->dhcp_critical) {
796 log_error_link(link, "DHCPv4 connection considered system critical, "
797 "ignoring request to reconfigure it.");
801 if (link->dhcp_lease) {
802 r = dhcp_lease_lost(link);
804 link_enter_failed(link);
809 if (event == DHCP_EVENT_IP_CHANGE) {
810 r = dhcp_lease_acquired(client, link);
812 link_enter_failed(link);
817 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
818 if (!sd_ipv4ll_is_running(link->ipv4ll))
819 r = sd_ipv4ll_start(link->ipv4ll);
820 else if (ipv4ll_is_bound(link->ipv4ll))
821 r = ipv4ll_address_update(link, false);
823 link_enter_failed(link);
829 case DHCP_EVENT_IP_ACQUIRE:
830 r = dhcp_lease_acquired(client, link);
832 link_enter_failed(link);
836 if (ipv4ll_is_bound(link->ipv4ll))
837 r = ipv4ll_address_update(link, true);
839 r = sd_ipv4ll_stop(link->ipv4ll);
841 link_enter_failed(link);
848 log_warning_link(link, "DHCP error: %s", strerror(-event));
850 log_warning_link(link, "DHCP unknown event: %d", event);
857 static int ipv4ll_address_update(Link *link, bool deprecate) {
863 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
865 _cleanup_address_free_ Address *address = NULL;
867 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
868 deprecate ? "deprecate" : "approve",
869 ADDRESS_FMT_VAL(addr));
871 r = address_new_dynamic(&address);
873 log_error_link(link, "Could not allocate address: %s", strerror(-r));
877 address->family = AF_INET;
878 address->in_addr.in = addr;
879 address->prefixlen = 16;
880 address->scope = RT_SCOPE_LINK;
881 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
882 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
884 address_update(address, link, &address_update_handler);
891 static int ipv4ll_address_lost(Link *link) {
897 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
899 _cleanup_address_free_ Address *address = NULL;
900 _cleanup_route_free_ Route *route = NULL;
902 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
903 ADDRESS_FMT_VAL(addr));
905 r = address_new_dynamic(&address);
907 log_error_link(link, "Could not allocate address: %s", strerror(-r));
911 address->family = AF_INET;
912 address->in_addr.in = addr;
913 address->prefixlen = 16;
914 address->scope = RT_SCOPE_LINK;
916 address_drop(address, link, &address_drop_handler);
918 r = route_new_dynamic(&route);
920 log_error_link(link, "Could not allocate route: %s",
925 route->family = AF_INET;
926 route->scope = RT_SCOPE_LINK;
929 route_drop(route, link, &route_drop_handler);
935 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
941 r = sd_ipv4ll_get_address(ll, &addr);
947 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
948 struct in_addr address;
954 r = sd_ipv4ll_get_address(ll, &address);
958 log_struct_link(LOG_INFO, link,
959 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
961 ADDRESS_FMT_VAL(address),
964 link_enter_set_addresses(link);
969 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
970 Link *link = userdata;
974 assert(link->network);
975 assert(link->manager);
978 case IPV4LL_EVENT_STOP:
979 case IPV4LL_EVENT_CONFLICT:
980 r = ipv4ll_address_lost(link);
982 link_enter_failed(link);
986 case IPV4LL_EVENT_BIND:
987 r = ipv4ll_address_claimed(ll, link);
989 link_enter_failed(link);
995 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
997 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1002 static int link_acquire_conf(Link *link) {
1006 assert(link->network);
1007 assert(link->manager);
1008 assert(link->manager->event);
1010 if (link->network->ipv4ll) {
1011 assert(link->ipv4ll);
1013 log_debug_link(link, "acquiring IPv4 link-local address");
1015 r = sd_ipv4ll_start(link->ipv4ll);
1020 if (link->network->dhcp) {
1021 assert(link->dhcp_client);
1023 log_debug_link(link, "acquiring DHCPv4 lease");
1025 r = sd_dhcp_client_start(link->dhcp_client);
1033 static int link_update_flags(Link *link, unsigned flags) {
1034 unsigned flags_added, flags_removed, generic_flags;
1038 assert(link->network);
1040 if (link->state == LINK_STATE_FAILED)
1043 if (link->flags == flags)
1046 flags_added = (link->flags ^ flags) & flags;
1047 flags_removed = (link->flags ^ flags) & link->flags;
1048 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_RUNNING);
1050 if (flags_added & generic_flags)
1051 log_debug_link(link, "link flags gained: %#.8x",
1052 flags_added & generic_flags);
1054 if (flags_removed & generic_flags)
1055 log_debug_link(link, "link flags lost: %#.8x",
1056 flags_removed & generic_flags);
1058 if (flags_added & IFF_UP)
1059 log_info_link(link, "link is up");
1060 else if (flags_removed & IFF_UP)
1061 log_info_link(link, "link is down");
1063 if (flags_added & IFF_LOWER_UP)
1064 log_info_link(link, "carrier on");
1065 else if (flags_removed & IFF_LOWER_UP)
1066 log_info_link(link, "carrier off");
1069 if (flags_added & IFF_RUNNING) {
1070 log_info_link(link, "running");
1072 if (link->network->dhcp || link->network->ipv4ll) {
1073 r = link_acquire_conf(link);
1075 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
1076 link_enter_failed(link);
1080 } else if (flags_removed & IFF_RUNNING) {
1081 log_info_link(link, "not running");
1083 if (link->network->dhcp) {
1084 r = sd_dhcp_client_stop(link->dhcp_client);
1086 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
1087 link_enter_failed(link);
1092 if (link->network->ipv4ll) {
1093 r = sd_ipv4ll_stop(link->ipv4ll);
1095 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
1096 link_enter_failed(link);
1102 link->flags = flags;
1107 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1108 Link *link = userdata;
1113 if (link->state == LINK_STATE_FAILED)
1116 r = sd_rtnl_message_get_errno(m);
1118 link_update_flags(link, link->flags | IFF_UP);
1120 log_struct_link(LOG_WARNING, link,
1121 "MESSAGE=%s: could not bring up interface: %s",
1122 link->ifname, strerror(-r),
1128 static int link_up(Link *link) {
1129 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1133 assert(link->manager);
1134 assert(link->manager->rtnl);
1136 log_debug_link(link, "bringing link up");
1138 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1139 RTM_SETLINK, link->ifindex);
1141 log_error_link(link, "Could not allocate RTM_SETLINK message");
1145 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1147 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1151 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1153 log_error_link(link,
1154 "Could not send rtnetlink message: %s", strerror(-r));
1161 static int link_enslaved(Link *link) {
1165 assert(link->state == LINK_STATE_ENSLAVING);
1166 assert(link->network);
1170 link_enter_failed(link);
1174 if (!link->network->dhcp && !link->network->ipv4ll)
1175 return link_enter_set_addresses(link);
1180 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1181 Link *link = userdata;
1185 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1186 assert(link->network);
1190 if (link->state == LINK_STATE_FAILED)
1193 r = sd_rtnl_message_get_errno(m);
1195 log_struct_link(LOG_ERR, link,
1196 "MESSAGE=%s: could not enslave: %s",
1197 link->ifname, strerror(-r),
1200 link_enter_failed(link);
1204 log_debug_link(link, "enslaved");
1206 if (link->enslaving == 0)
1207 link_enslaved(link);
1212 static int link_enter_enslave(Link *link) {
1213 NetDev *vlan, *macvlan;
1218 assert(link->network);
1219 assert(link->state == _LINK_STATE_INVALID);
1221 link->state = LINK_STATE_ENSLAVING;
1225 if (!link->network->bridge && !link->network->bond &&
1226 hashmap_isempty(link->network->vlans) &&
1227 hashmap_isempty(link->network->macvlans))
1228 return link_enslaved(link);
1230 if (link->network->bridge) {
1231 log_struct_link(LOG_DEBUG, link,
1232 "MESSAGE=%s: enslaving by '%s'",
1233 link->ifname, link->network->bridge->name,
1234 NETDEV(link->network->bridge),
1237 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1239 log_struct_link(LOG_WARNING, link,
1240 "MESSAGE=%s: could not enslave by '%s': %s",
1241 link->ifname, link->network->bridge->name, strerror(-r),
1242 NETDEV(link->network->bridge),
1244 link_enter_failed(link);
1251 if (link->network->bond) {
1252 log_struct_link(LOG_DEBUG, link,
1253 "MESSAGE=%s: enslaving by '%s'",
1254 link->ifname, link->network->bond->name,
1255 NETDEV(link->network->bond),
1258 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1260 log_struct_link(LOG_WARNING, link,
1261 "MESSAGE=%s: could not enslave by '%s': %s",
1262 link->ifname, link->network->bond->name, strerror(-r),
1263 NETDEV(link->network->bond),
1265 link_enter_failed(link);
1272 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1273 log_struct_link(LOG_DEBUG, link,
1274 "MESSAGE=%s: enslaving by '%s'",
1275 link->ifname, vlan->name, NETDEV(vlan), NULL);
1277 r = netdev_enslave(vlan, link, &enslave_handler);
1279 log_struct_link(LOG_WARNING, link,
1280 "MESSAGE=%s: could not enslave by '%s': %s",
1281 link->ifname, vlan->name, strerror(-r),
1282 NETDEV(vlan), NULL);
1283 link_enter_failed(link);
1290 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1291 log_struct_link(LOG_DEBUG, link,
1292 "MESSAGE=%s: enslaving by '%s'",
1293 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1295 r = netdev_enslave(macvlan, link, &enslave_handler);
1297 log_struct_link(LOG_WARNING, link,
1298 "MESSAGE=%s: could not enslave by '%s': %s",
1299 link->ifname, macvlan->name, strerror(-r),
1300 NETDEV(macvlan), NULL);
1301 link_enter_failed(link);
1311 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1313 Link *link = userdata;
1317 assert(link->ifname);
1319 if (link->state == LINK_STATE_FAILED)
1322 r = sd_rtnl_message_get_errno(m);
1324 log_struct_link(LOG_ERR, link,
1325 "MESSAGE=%s: could not get state: %s",
1326 link->ifname, strerror(-r),
1329 link_enter_failed(link);
1333 link_update(link, m);
1338 static int link_getlink(Link *link) {
1339 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1343 assert(link->manager);
1344 assert(link->manager->rtnl);
1346 log_debug_link(link, "requesting link status");
1348 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1349 RTM_GETLINK, link->ifindex);
1351 log_error_link(link, "Could not allocate RTM_GETLINK message");
1355 r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1358 log_error_link(link,
1359 "Could not send rtnetlink message: %s", strerror(-r));
1366 static int link_configure(Link *link) {
1370 assert(link->state == _LINK_STATE_INVALID);
1372 r = link_getlink(link);
1376 return link_enter_enslave(link);
1379 int link_add(Manager *m, struct udev_device *device, Link **ret) {
1387 r = link_new(m, device, &link);
1393 r = network_get(m, device, &network);
1395 return r == -ENOENT ? 0 : r;
1397 r = network_apply(m, network, link);
1401 if (link->network->ipv4ll) {
1403 r = sd_ipv4ll_new(&link->ipv4ll);
1407 r = net_get_unique_predictable_data(link->udev_device, seed);
1409 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1414 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1418 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1422 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1427 if (link->network->dhcp) {
1428 r = sd_dhcp_client_new(&link->dhcp_client);
1432 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1436 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1440 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1444 if (link->network->dhcp_mtu) {
1445 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1451 r = link_configure(link);
1458 int link_update(Link *link, sd_rtnl_message *m) {
1460 struct ether_addr mac;
1464 assert(link->network);
1467 if (link->state == LINK_STATE_FAILED)
1470 if (link->network->dhcp && link->network->dhcp_mtu &&
1471 !link->original_mtu) {
1472 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1474 log_debug_link(link, "saved original MTU: %"
1475 PRIu16, link->original_mtu);
1478 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1480 log_debug_link(link, "Could not get MAC address: %s", strerror(-r));
1482 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1484 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1486 log_debug_link(link, "MAC address: "
1487 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1488 mac.ether_addr_octet[0],
1489 mac.ether_addr_octet[1],
1490 mac.ether_addr_octet[2],
1491 mac.ether_addr_octet[3],
1492 mac.ether_addr_octet[4],
1493 mac.ether_addr_octet[5]);
1496 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1498 log_warning_link(link, "Could not update MAC "
1499 "address in IPv4LL client: %s",
1505 if (link->dhcp_client) {
1506 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1508 log_warning_link(link, "Could not update MAC "
1509 "address in DHCP client: %s",
1517 r = sd_rtnl_message_link_get_flags(m, &flags);
1519 log_warning_link(link, "Could not get link flags");
1523 return link_update_flags(link, flags);
1526 int link_save(Link *link) {
1527 _cleanup_free_ char *temp_path = NULL;
1528 _cleanup_fclose_ FILE *f = NULL;
1533 assert(link->state_file);
1535 state = link_state_to_string(link->state);
1538 r = fopen_temporary(link->state_file, &f, &temp_path);
1542 fchmod(fileno(f), 0644);
1545 "# This is private data. Do not parse.\n"
1546 "STATE=%s\n", state);
1548 if (link->dhcp_lease) {
1549 _cleanup_free_ char *lease_file = NULL;
1551 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1556 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1560 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1565 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1567 unlink(link->state_file);
1573 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1578 static const char* const link_state_table[_LINK_STATE_MAX] = {
1579 [LINK_STATE_ENSLAVING] = "configuring",
1580 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1581 [LINK_STATE_SETTING_ROUTES] = "configuring",
1582 [LINK_STATE_CONFIGURED] = "configured",
1583 [LINK_STATE_FAILED] = "failed",
1586 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);