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"
27 #include "udev-util.h"
31 #include "network-internal.h"
33 #include "dhcp-lease-internal.h"
35 static int ipv4ll_address_update(Link *link, bool deprecate);
36 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
38 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
39 _cleanup_link_free_ Link *link = NULL;
45 assert(manager->links);
49 r = sd_rtnl_message_get_type(message, &type);
52 else if (type != RTM_NEWLINK)
55 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
58 else if (ifindex <= 0)
61 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
69 link->manager = manager;
70 link->state = LINK_STATE_INITIALIZING;
71 link->ifindex = ifindex;
72 link->ifname = strdup(ifname);
76 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
81 r = hashmap_put(manager->links, &link->ifindex, link);
91 void link_free(Link *link) {
95 assert(link->manager);
97 sd_dhcp_client_unref(link->dhcp_client);
98 sd_dhcp_lease_unref(link->dhcp_lease);
100 sd_ipv4ll_unref(link->ipv4ll);
102 hashmap_remove(link->manager->links, &link->ifindex);
105 free(link->state_file);
107 udev_device_unref(link->udev_device);
112 int link_get(Manager *m, int ifindex, Link **ret) {
121 ifindex_64 = ifindex;
122 link = hashmap_get(m->links, &ifindex_64);
131 static int link_enter_configured(Link *link) {
133 assert(link->state == LINK_STATE_SETTING_ROUTES);
135 log_info_link(link, "link configured");
137 link->state = LINK_STATE_CONFIGURED;
144 static void link_enter_unmanaged(Link *link) {
147 log_debug_link(link, "unmanaged");
149 link->state = LINK_STATE_UNMANAGED;
154 static int link_stop_clients(Link *link) {
158 assert(link->manager);
159 assert(link->manager->event);
164 if (link->network->dhcp) {
165 assert(link->dhcp_client);
167 k = sd_dhcp_client_stop(link->dhcp_client);
169 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
174 if (link->network->ipv4ll) {
175 assert(link->ipv4ll);
177 k = sd_ipv4ll_stop(link->ipv4ll);
179 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
187 static void link_enter_failed(Link *link) {
190 if (link->state == LINK_STATE_FAILED)
193 log_warning_link(link, "failed");
195 link->state = LINK_STATE_FAILED;
197 link_stop_clients(link);
202 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
203 Link *link = userdata;
206 assert(link->route_messages > 0);
207 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
208 link->state == LINK_STATE_SETTING_ROUTES ||
209 link->state == LINK_STATE_FAILED);
211 link->route_messages --;
213 if (link->state == LINK_STATE_FAILED)
216 r = sd_rtnl_message_get_errno(m);
217 if (r < 0 && r != -EEXIST)
218 log_struct_link(LOG_WARNING, link,
219 "MESSAGE=%s: could not set route: %s",
220 link->ifname, strerror(-r),
224 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
226 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
227 log_debug_link(link, "routes set");
228 link_enter_configured(link);
234 static int link_enter_set_routes(Link *link) {
239 assert(link->network);
240 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
242 link->state = LINK_STATE_SETTING_ROUTES;
244 if (!link->network->static_routes && !link->dhcp_lease &&
245 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
246 return link_enter_configured(link);
248 log_debug_link(link, "setting routes");
250 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
251 r = route_configure(rt, link, &route_handler);
253 log_warning_link(link,
254 "could not set routes: %s", strerror(-r));
255 link_enter_failed(link);
259 link->route_messages ++;
262 if (link->ipv4ll && !link->dhcp_lease) {
263 _cleanup_route_free_ Route *route = NULL;
266 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
267 if (r < 0 && r != -ENOENT) {
268 log_warning_link(link, "IPV4LL error: no address: %s",
274 r = route_new_dynamic(&route);
276 log_error_link(link, "Could not allocate route: %s",
281 route->family = AF_INET;
282 route->scope = RT_SCOPE_LINK;
285 r = route_configure(route, link, &route_handler);
287 log_warning_link(link,
288 "could not set routes: %s", strerror(-r));
289 link_enter_failed(link);
293 link->route_messages ++;
297 if (link->dhcp_lease) {
298 _cleanup_route_free_ Route *route = NULL;
299 _cleanup_route_free_ Route *route_gw = NULL;
300 struct in_addr gateway;
302 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
304 log_warning_link(link, "DHCP error: no router: %s",
309 r = route_new_dynamic(&route);
311 log_error_link(link, "Could not allocate route: %s",
316 r = route_new_dynamic(&route_gw);
318 log_error_link(link, "Could not allocate route: %s",
323 /* The dhcp netmask may mask out the gateway. Add an explicit
324 * route for the gw host so that we can route no matter the
325 * netmask or existing kernel route tables. */
326 route_gw->family = AF_INET;
327 route_gw->dst_addr.in = gateway;
328 route_gw->dst_prefixlen = 32;
329 route_gw->scope = RT_SCOPE_LINK;
331 r = route_configure(route_gw, link, &route_handler);
333 log_warning_link(link,
334 "could not set host route: %s", strerror(-r));
338 link->route_messages ++;
340 route->family = AF_INET;
341 route->in_addr.in = gateway;
343 r = route_configure(route, link, &route_handler);
345 log_warning_link(link,
346 "could not set routes: %s", strerror(-r));
347 link_enter_failed(link);
351 link->route_messages ++;
357 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
358 Link *link = userdata;
363 assert(link->ifname);
365 if (link->state == LINK_STATE_FAILED)
368 r = sd_rtnl_message_get_errno(m);
369 if (r < 0 && r != -ENOENT)
370 log_struct_link(LOG_WARNING, link,
371 "MESSAGE=%s: could not drop route: %s",
372 link->ifname, strerror(-r),
379 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
380 Link *link = userdata;
385 assert(link->ifname);
386 assert(link->addr_messages > 0);
387 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
389 link->addr_messages --;
391 if (link->state == LINK_STATE_FAILED)
394 r = sd_rtnl_message_get_errno(m);
395 if (r < 0 && r != -EEXIST)
396 log_struct_link(LOG_WARNING, link,
397 "MESSAGE=%s: could not set address: %s",
398 link->ifname, strerror(-r),
402 if (link->addr_messages == 0) {
403 log_debug_link(link, "addresses set");
404 link_enter_set_routes(link);
410 static int link_enter_set_addresses(Link *link) {
415 assert(link->network);
416 assert(link->state != _LINK_STATE_INVALID);
418 link->state = LINK_STATE_SETTING_ADDRESSES;
420 if (!link->network->static_addresses && !link->dhcp_lease &&
421 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
422 return link_enter_set_routes(link);
424 log_debug_link(link, "setting addresses");
426 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
427 r = address_configure(ad, link, &address_handler);
429 log_warning_link(link,
430 "could not set addresses: %s", strerror(-r));
431 link_enter_failed(link);
435 link->addr_messages ++;
438 if (link->ipv4ll && !link->dhcp_lease) {
439 _cleanup_address_free_ Address *ll_addr = NULL;
442 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
443 if (r < 0 && r != -ENOENT) {
444 log_warning_link(link, "IPV4LL error: no address: %s",
450 r = address_new_dynamic(&ll_addr);
452 log_error_link(link, "Could not allocate address: %s", strerror(-r));
456 ll_addr->family = AF_INET;
457 ll_addr->in_addr.in = addr;
458 ll_addr->prefixlen = 16;
459 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
460 ll_addr->scope = RT_SCOPE_LINK;
462 r = address_configure(ll_addr, link, &address_handler);
464 log_warning_link(link,
465 "could not set addresses: %s", strerror(-r));
466 link_enter_failed(link);
470 link->addr_messages ++;
474 if (link->dhcp_lease) {
475 _cleanup_address_free_ Address *address = NULL;
477 struct in_addr netmask;
480 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
482 log_warning_link(link, "DHCP error: no address: %s",
487 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
489 log_warning_link(link, "DHCP error: no netmask: %s",
494 prefixlen = net_netmask_to_prefixlen(&netmask);
496 r = address_new_dynamic(&address);
498 log_error_link(link, "Could not allocate address: %s",
503 address->family = AF_INET;
504 address->in_addr.in = addr;
505 address->prefixlen = prefixlen;
506 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
508 r = address_configure(address, link, &address_handler);
510 log_warning_link(link,
511 "could not set addresses: %s", strerror(-r));
512 link_enter_failed(link);
516 link->addr_messages ++;
522 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
523 Link *link = userdata;
528 assert(link->ifname);
530 if (link->state == LINK_STATE_FAILED)
533 r = sd_rtnl_message_get_errno(m);
534 if (r < 0 && r != -ENOENT)
535 log_struct_link(LOG_WARNING, link,
536 "MESSAGE=%s: could not update address: %s",
537 link->ifname, strerror(-r),
544 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
545 Link *link = userdata;
550 assert(link->ifname);
552 if (link->state == LINK_STATE_FAILED)
555 r = sd_rtnl_message_get_errno(m);
556 if (r < 0 && r != -ENOENT)
557 log_struct_link(LOG_WARNING, link,
558 "MESSAGE=%s: could not drop address: %s",
559 link->ifname, strerror(-r),
566 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
569 r = sd_bus_message_get_errno(m);
571 log_warning("Could not set hostname: %s", strerror(-r));
576 static int set_hostname(sd_bus *bus, const char *hostname) {
577 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
582 log_debug("Setting transient hostname: '%s'", hostname);
584 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
585 log_info("Not connected to system bus, ignoring transient hostname.");
589 r = sd_bus_message_new_method_call(
592 "org.freedesktop.hostname1",
593 "/org/freedesktop/hostname1",
594 "org.freedesktop.hostname1",
599 r = sd_bus_message_append(m, "sb", hostname, false);
603 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
605 log_error("Could not set transient hostname: %s", strerror(-r));
610 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
611 Link *link = userdata;
616 assert(link->ifname);
618 if (link->state == LINK_STATE_FAILED)
621 r = sd_rtnl_message_get_errno(m);
623 log_struct_link(LOG_WARNING, link,
624 "MESSAGE=%s: could not set MTU: %s",
625 link->ifname, strerror(-r),
632 static int link_set_mtu(Link *link, uint32_t mtu) {
633 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
637 assert(link->manager);
638 assert(link->manager->rtnl);
640 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
642 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
643 RTM_SETLINK, link->ifindex);
645 log_error_link(link, "Could not allocate RTM_SETLINK message");
649 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
651 log_error_link(link, "Could not append MTU: %s", strerror(-r));
655 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
658 "Could not send rtnetlink message: %s", strerror(-r));
665 static int dhcp_lease_lost(Link *link) {
666 _cleanup_address_free_ Address *address = NULL;
667 _cleanup_route_free_ Route *route_gw = NULL;
668 _cleanup_route_free_ Route *route = NULL;
670 struct in_addr netmask;
671 struct in_addr gateway;
676 assert(link->dhcp_lease);
678 log_warning_link(link, "DHCP lease lost");
680 r = address_new_dynamic(&address);
682 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
683 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
684 sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
685 prefixlen = net_netmask_to_prefixlen(&netmask);
687 r = route_new_dynamic(&route_gw);
689 route_gw->family = AF_INET;
690 route_gw->dst_addr.in = gateway;
691 route_gw->dst_prefixlen = 32;
692 route_gw->scope = RT_SCOPE_LINK;
694 route_drop(route_gw, link, &route_drop_handler);
697 r = route_new_dynamic(&route);
699 route->family = AF_INET;
700 route->in_addr.in = gateway;
702 route_drop(route, link, &route_drop_handler);
705 address->family = AF_INET;
706 address->in_addr.in = addr;
707 address->prefixlen = prefixlen;
709 address_drop(address, link, &address_drop_handler);
712 if (link->network->dhcp_mtu) {
715 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
716 if (r >= 0 && link->original_mtu != mtu) {
717 r = link_set_mtu(link, link->original_mtu);
719 log_warning_link(link, "DHCP error: could not reset MTU");
720 link_enter_failed(link);
726 if (link->network->dhcp_hostname) {
727 const char *hostname = NULL;
729 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
730 if (r >= 0 && hostname) {
731 r = set_hostname(link->manager->bus, "");
733 log_error("Failed to reset transient hostname");
737 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
742 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
743 sd_dhcp_lease *lease;
744 struct in_addr address;
745 struct in_addr netmask;
746 struct in_addr gateway;
748 struct in_addr *nameservers;
749 size_t nameservers_size;
755 r = sd_dhcp_client_get_lease(client, &lease);
757 log_warning_link(link, "DHCP error: no lease: %s",
762 r = sd_dhcp_lease_get_address(lease, &address);
764 log_warning_link(link, "DHCP error: no address: %s",
769 r = sd_dhcp_lease_get_netmask(lease, &netmask);
771 log_warning_link(link, "DHCP error: no netmask: %s",
776 prefixlen = net_netmask_to_prefixlen(&netmask);
778 r = sd_dhcp_lease_get_router(lease, &gateway);
780 log_warning_link(link, "DHCP error: no router: %s",
785 log_struct_link(LOG_INFO, link,
786 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
788 ADDRESS_FMT_VAL(address),
790 ADDRESS_FMT_VAL(gateway),
791 "ADDRESS=%u.%u.%u.%u",
792 ADDRESS_FMT_VAL(address),
795 "GATEWAY=%u.%u.%u.%u",
796 ADDRESS_FMT_VAL(gateway),
799 link->dhcp_lease = lease;
801 if (link->network->dhcp_dns) {
802 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
804 r = manager_update_resolv_conf(link->manager);
806 log_error("Failed to update resolv.conf");
810 if (link->network->dhcp_mtu) {
813 r = sd_dhcp_lease_get_mtu(lease, &mtu);
815 r = link_set_mtu(link, mtu);
817 log_error_link(link, "Failed to set MTU "
822 if (link->network->dhcp_hostname) {
823 const char *hostname;
825 r = sd_dhcp_lease_get_hostname(lease, &hostname);
827 r = set_hostname(link->manager->bus, hostname);
829 log_error("Failed to set transient hostname "
830 "to '%s'", hostname);
834 link_enter_set_addresses(link);
839 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
840 Link *link = userdata;
844 assert(link->network);
845 assert(link->manager);
847 if (link->state == LINK_STATE_FAILED)
851 case DHCP_EVENT_NO_LEASE:
852 log_debug_link(link, "IP address in use.");
854 case DHCP_EVENT_EXPIRED:
855 case DHCP_EVENT_STOP:
856 case DHCP_EVENT_IP_CHANGE:
857 if (link->network->dhcp_critical) {
858 log_error_link(link, "DHCPv4 connection considered system critical, "
859 "ignoring request to reconfigure it.");
863 if (link->dhcp_lease) {
864 r = dhcp_lease_lost(link);
866 link_enter_failed(link);
871 if (event == DHCP_EVENT_IP_CHANGE) {
872 r = dhcp_lease_acquired(client, link);
874 link_enter_failed(link);
879 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
880 if (!sd_ipv4ll_is_running(link->ipv4ll))
881 r = sd_ipv4ll_start(link->ipv4ll);
882 else if (ipv4ll_is_bound(link->ipv4ll))
883 r = ipv4ll_address_update(link, false);
885 link_enter_failed(link);
891 case DHCP_EVENT_IP_ACQUIRE:
892 r = dhcp_lease_acquired(client, link);
894 link_enter_failed(link);
898 if (ipv4ll_is_bound(link->ipv4ll))
899 r = ipv4ll_address_update(link, true);
901 r = sd_ipv4ll_stop(link->ipv4ll);
903 link_enter_failed(link);
910 log_warning_link(link, "DHCP error: %s", strerror(-event));
912 log_warning_link(link, "DHCP unknown event: %d", event);
919 static int ipv4ll_address_update(Link *link, bool deprecate) {
925 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
927 _cleanup_address_free_ Address *address = NULL;
929 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
930 deprecate ? "deprecate" : "approve",
931 ADDRESS_FMT_VAL(addr));
933 r = address_new_dynamic(&address);
935 log_error_link(link, "Could not allocate address: %s", strerror(-r));
939 address->family = AF_INET;
940 address->in_addr.in = addr;
941 address->prefixlen = 16;
942 address->scope = RT_SCOPE_LINK;
943 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
944 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
946 address_update(address, link, &address_update_handler);
953 static int ipv4ll_address_lost(Link *link) {
959 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
961 _cleanup_address_free_ Address *address = NULL;
962 _cleanup_route_free_ Route *route = NULL;
964 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
965 ADDRESS_FMT_VAL(addr));
967 r = address_new_dynamic(&address);
969 log_error_link(link, "Could not allocate address: %s", strerror(-r));
973 address->family = AF_INET;
974 address->in_addr.in = addr;
975 address->prefixlen = 16;
976 address->scope = RT_SCOPE_LINK;
978 address_drop(address, link, &address_drop_handler);
980 r = route_new_dynamic(&route);
982 log_error_link(link, "Could not allocate route: %s",
987 route->family = AF_INET;
988 route->scope = RT_SCOPE_LINK;
991 route_drop(route, link, &route_drop_handler);
997 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1003 r = sd_ipv4ll_get_address(ll, &addr);
1009 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1010 struct in_addr address;
1016 r = sd_ipv4ll_get_address(ll, &address);
1020 log_struct_link(LOG_INFO, link,
1021 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1023 ADDRESS_FMT_VAL(address),
1026 link_enter_set_addresses(link);
1031 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1032 Link *link = userdata;
1036 assert(link->network);
1037 assert(link->manager);
1040 case IPV4LL_EVENT_STOP:
1041 case IPV4LL_EVENT_CONFLICT:
1042 r = ipv4ll_address_lost(link);
1044 link_enter_failed(link);
1048 case IPV4LL_EVENT_BIND:
1049 r = ipv4ll_address_claimed(ll, link);
1051 link_enter_failed(link);
1057 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1059 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1064 static int link_acquire_conf(Link *link) {
1068 assert(link->network);
1069 assert(link->manager);
1070 assert(link->manager->event);
1072 if (link->network->ipv4ll) {
1073 assert(link->ipv4ll);
1075 log_debug_link(link, "acquiring IPv4 link-local address");
1077 r = sd_ipv4ll_start(link->ipv4ll);
1079 log_warning_link(link, "could not acquire IPv4 "
1080 "link-local address");
1085 if (link->network->dhcp) {
1086 assert(link->dhcp_client);
1088 log_debug_link(link, "acquiring DHCPv4 lease");
1090 r = sd_dhcp_client_start(link->dhcp_client);
1092 log_warning_link(link, "could not acquire DHCPv4 "
1101 static bool link_has_carrier(unsigned flags, uint8_t operstate) {
1102 /* see Documentation/networking/operstates.txt in the kernel sources */
1104 if (operstate == IF_OPER_UP)
1107 if (operstate == IF_OPER_UNKNOWN)
1108 /* operstate may not be implemented, so fall back to flags */
1109 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1115 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1116 unsigned flags, flags_added, flags_removed, generic_flags;
1118 bool carrier_gained = false, carrier_lost = false;
1123 if (link->state == LINK_STATE_FAILED)
1126 r = sd_rtnl_message_link_get_flags(m, &flags);
1128 log_warning_link(link, "Could not get link flags");
1132 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1134 /* if we got a message without operstate, take it to mean
1135 the state was unchanged */
1136 operstate = link->operstate;
1138 if ((link->flags == flags) && (link->operstate == operstate))
1141 flags_added = (link->flags ^ flags) & flags;
1142 flags_removed = (link->flags ^ flags) & link->flags;
1143 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1144 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1145 IFF_NOARP | IFF_MASTER | IFF_SLAVE);
1147 if (flags_added & IFF_UP)
1148 log_debug_link(link, "link is up");
1149 else if (flags_removed & IFF_UP)
1150 log_debug_link(link, "link is down");
1152 if (flags_added & IFF_LOWER_UP)
1153 log_debug_link(link, "link is lower up");
1154 else if (flags_removed & IFF_LOWER_UP)
1155 log_debug_link(link, "link is lower down");
1157 if (flags_added & IFF_DORMANT)
1158 log_debug_link(link, "link is dormant");
1159 else if (flags_removed & IFF_DORMANT)
1160 log_debug_link(link, "link is not dormant");
1162 if (flags_added & IFF_DEBUG)
1163 log_debug_link(link, "debugging enabled in the kernel");
1164 else if (flags_removed & IFF_DEBUG)
1165 log_debug_link(link, "debugging disabled in the kernel");
1167 if (flags_added & IFF_MULTICAST)
1168 log_debug_link(link, "multicast enabled");
1169 else if (flags_removed & IFF_MULTICAST)
1170 log_debug_link(link, "multicast disabled");
1172 if (flags_added & IFF_BROADCAST)
1173 log_debug_link(link, "broadcast enabled");
1174 else if (flags_removed & IFF_BROADCAST)
1175 log_debug_link(link, "broadcast disabled");
1177 if (flags_added & IFF_PROMISC)
1178 log_debug_link(link, "promiscuous mode enabled");
1179 else if (flags_removed & IFF_PROMISC)
1180 log_debug_link(link, "promiscuous mode disabled");
1182 if (flags_added & IFF_NOARP)
1183 log_debug_link(link, "ARP protocol disabled");
1184 else if (flags_removed & IFF_NOARP)
1185 log_debug_link(link, "ARP protocol enabled");
1187 if (flags_added & IFF_MASTER)
1188 log_debug_link(link, "link is master");
1189 else if (flags_removed & IFF_MASTER)
1190 log_debug_link(link, "link is no longer master");
1192 if (flags_added & IFF_SLAVE)
1193 log_debug_link(link, "link is slave");
1194 else if (flags_removed & IFF_SLAVE)
1195 log_debug_link(link, "link is no longer slave");
1197 /* link flags are currently at most 18 bits, let's default to printing 20 */
1198 if (flags_added & generic_flags)
1199 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1200 flags_added & generic_flags);
1202 if (flags_removed & generic_flags)
1203 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1204 flags_removed & generic_flags);
1206 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1207 link_has_carrier(flags, operstate);
1208 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1209 !link_has_carrier(flags, operstate);
1211 link->flags = flags;
1212 link->operstate = operstate;
1214 if (carrier_gained) {
1215 log_info_link(link, "gained carrier");
1217 if (link->network) {
1218 r = link_acquire_conf(link);
1220 link_enter_failed(link);
1224 } else if (carrier_lost) {
1225 log_info_link(link, "lost carrier");
1227 r = link_stop_clients(link);
1229 link_enter_failed(link);
1237 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1238 Link *link = userdata;
1243 if (link->state == LINK_STATE_FAILED)
1246 r = sd_rtnl_message_get_errno(m);
1248 log_struct_link(LOG_WARNING, link,
1249 "MESSAGE=%s: could not bring up interface: %s",
1250 link->ifname, strerror(-r),
1253 link_enter_failed(link);
1259 static int link_up(Link *link) {
1260 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1264 assert(link->manager);
1265 assert(link->manager->rtnl);
1267 log_debug_link(link, "bringing link up");
1269 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1270 RTM_SETLINK, link->ifindex);
1272 log_error_link(link, "Could not allocate RTM_SETLINK message");
1276 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1278 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1282 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1284 log_error_link(link,
1285 "Could not send rtnetlink message: %s", strerror(-r));
1292 static int link_enslaved(Link *link) {
1296 assert(link->state == LINK_STATE_ENSLAVING);
1297 assert(link->network);
1299 if (!(link->flags & IFF_UP)) {
1302 link_enter_failed(link);
1307 if (!link->network->dhcp && !link->network->ipv4ll)
1308 return link_enter_set_addresses(link);
1313 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1314 Link *link = userdata;
1318 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1319 assert(link->network);
1323 if (link->state == LINK_STATE_FAILED)
1326 r = sd_rtnl_message_get_errno(m);
1328 log_struct_link(LOG_ERR, link,
1329 "MESSAGE=%s: could not enslave: %s",
1330 link->ifname, strerror(-r),
1333 link_enter_failed(link);
1337 log_debug_link(link, "enslaved");
1339 if (link->enslaving == 0)
1340 link_enslaved(link);
1345 static int link_enter_enslave(Link *link) {
1346 NetDev *vlan, *macvlan;
1351 assert(link->network);
1352 assert(link->state == LINK_STATE_INITIALIZING);
1354 link->state = LINK_STATE_ENSLAVING;
1358 if (!link->network->bridge && !link->network->bond &&
1359 hashmap_isempty(link->network->vlans) &&
1360 hashmap_isempty(link->network->macvlans))
1361 return link_enslaved(link);
1363 if (link->network->bridge) {
1364 log_struct_link(LOG_DEBUG, link,
1365 "MESSAGE=%s: enslaving by '%s'",
1366 link->ifname, link->network->bridge->name,
1367 NETDEV(link->network->bridge),
1370 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1372 log_struct_link(LOG_WARNING, link,
1373 "MESSAGE=%s: could not enslave by '%s': %s",
1374 link->ifname, link->network->bridge->name, strerror(-r),
1375 NETDEV(link->network->bridge),
1377 link_enter_failed(link);
1384 if (link->network->bond) {
1385 log_struct_link(LOG_DEBUG, link,
1386 "MESSAGE=%s: enslaving by '%s'",
1387 link->ifname, link->network->bond->name,
1388 NETDEV(link->network->bond),
1391 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1393 log_struct_link(LOG_WARNING, link,
1394 "MESSAGE=%s: could not enslave by '%s': %s",
1395 link->ifname, link->network->bond->name, strerror(-r),
1396 NETDEV(link->network->bond),
1398 link_enter_failed(link);
1405 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1406 log_struct_link(LOG_DEBUG, link,
1407 "MESSAGE=%s: enslaving by '%s'",
1408 link->ifname, vlan->name, NETDEV(vlan), NULL);
1410 r = netdev_enslave(vlan, link, &enslave_handler);
1412 log_struct_link(LOG_WARNING, link,
1413 "MESSAGE=%s: could not enslave by '%s': %s",
1414 link->ifname, vlan->name, strerror(-r),
1415 NETDEV(vlan), NULL);
1416 link_enter_failed(link);
1423 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1424 log_struct_link(LOG_DEBUG, link,
1425 "MESSAGE=%s: enslaving by '%s'",
1426 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1428 r = netdev_enslave(macvlan, link, &enslave_handler);
1430 log_struct_link(LOG_WARNING, link,
1431 "MESSAGE=%s: could not enslave by '%s': %s",
1432 link->ifname, macvlan->name, strerror(-r),
1433 NETDEV(macvlan), NULL);
1434 link_enter_failed(link);
1444 static int link_configure(Link *link) {
1448 assert(link->state == LINK_STATE_INITIALIZING);
1450 if (link->network->ipv4ll) {
1453 r = sd_ipv4ll_new(&link->ipv4ll);
1457 if (link->udev_device) {
1458 r = net_get_unique_predictable_data(link->udev_device, seed);
1460 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1466 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1470 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1474 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1478 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1483 if (link->network->dhcp) {
1484 r = sd_dhcp_client_new(&link->dhcp_client);
1488 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1492 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1496 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1500 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1504 if (link->network->dhcp_mtu) {
1505 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1511 if (link_has_carrier(link->flags, link->operstate))
1512 r = link_acquire_conf(link);
1516 return link_enter_enslave(link);
1519 int link_initialized(Link *link, struct udev_device *device) {
1524 assert(link->ifname);
1525 assert(link->manager);
1527 if (link->state != LINK_STATE_INITIALIZING)
1531 link->udev_device = udev_device_ref(device);
1533 log_debug_link(link, "link initialized");
1535 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1537 link_enter_unmanaged(link);
1542 r = network_apply(link->manager, network, link);
1546 r = link_configure(link);
1553 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1555 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1556 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1563 r = link_new(m, message, ret);
1569 log_debug_link(link, "link added");
1571 if (detect_container(NULL) <= 0) {
1572 /* not in a container, udev will be around */
1573 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1574 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1576 log_warning_link(link, "could not find udev device");
1580 if (udev_device_get_is_initialized(device) <= 0)
1585 r = link_initialized(link, device);
1592 int link_update(Link *link, sd_rtnl_message *m) {
1593 struct ether_addr mac;
1598 assert(link->ifname);
1601 if (link->state == LINK_STATE_FAILED || link->state == LINK_STATE_UNMANAGED)
1604 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1605 if (r >= 0 && !streq(ifname, link->ifname)) {
1606 log_info_link(link, "renamed to %s", ifname);
1609 link->ifname = strdup(ifname);
1614 if (!link->original_mtu) {
1615 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1617 log_debug_link(link, "saved original MTU: %"
1618 PRIu16, link->original_mtu);
1621 /* The kernel may broadcast NEWLINK messages without the MAC address
1622 set, simply ignore them. */
1623 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1625 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1627 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1629 log_debug_link(link, "MAC address: "
1630 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1631 mac.ether_addr_octet[0],
1632 mac.ether_addr_octet[1],
1633 mac.ether_addr_octet[2],
1634 mac.ether_addr_octet[3],
1635 mac.ether_addr_octet[4],
1636 mac.ether_addr_octet[5]);
1639 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1641 log_warning_link(link, "Could not update MAC "
1642 "address in IPv4LL client: %s",
1648 if (link->dhcp_client) {
1649 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1651 log_warning_link(link, "Could not update MAC "
1652 "address in DHCP client: %s",
1660 return link_update_flags(link, m);
1663 int link_save(Link *link) {
1664 _cleanup_free_ char *temp_path = NULL;
1665 _cleanup_fclose_ FILE *f = NULL;
1670 assert(link->state_file);
1672 state = link_state_to_string(link->state);
1675 r = fopen_temporary(link->state_file, &f, &temp_path);
1679 fchmod(fileno(f), 0644);
1682 "# This is private data. Do not parse.\n"
1683 "STATE=%s\n", state);
1685 if (link->dhcp_lease) {
1686 _cleanup_free_ char *lease_file = NULL;
1688 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1693 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1697 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1702 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1704 unlink(link->state_file);
1710 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1715 static const char* const link_state_table[_LINK_STATE_MAX] = {
1716 [LINK_STATE_INITIALIZING] = "configuring",
1717 [LINK_STATE_ENSLAVING] = "configuring",
1718 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1719 [LINK_STATE_SETTING_ROUTES] = "configuring",
1720 [LINK_STATE_CONFIGURED] = "configured",
1721 [LINK_STATE_UNMANAGED] = "unmanaged",
1722 [LINK_STATE_FAILED] = "failed",
1725 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);