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 "networkd-link.h"
27 #include "networkd-netdev.h"
28 #include "libudev-private.h"
29 #include "udev-util.h"
33 #include "network-internal.h"
34 #include "conf-parser.h"
36 #include "dhcp-lease-internal.h"
38 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
39 _cleanup_link_unref_ Link *link = NULL;
48 r = sd_rtnl_message_get_type(message, &type);
51 else if (type != RTM_NEWLINK)
54 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
57 else if (ifindex <= 0)
60 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 = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
78 log_debug_link(link, "MAC address not found for new device, continuing without");
80 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
85 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
90 r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
94 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
104 static void link_free(Link *link) {
110 while ((address = link->addresses)) {
111 LIST_REMOVE(addresses, link->addresses, address);
112 address_free(address);
115 while ((address = link->pool_addresses)) {
116 LIST_REMOVE(addresses, link->pool_addresses, address);
117 address_free(address);
120 sd_dhcp_client_unref(link->dhcp_client);
121 sd_dhcp_lease_unref(link->dhcp_lease);
123 unlink(link->lease_file);
124 free(link->lease_file);
126 sd_ipv4ll_unref(link->ipv4ll);
127 sd_dhcp6_client_unref(link->dhcp6_client);
128 sd_icmp6_nd_unref(link->icmp6_router_discovery);
131 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
135 unlink(link->state_file);
136 free(link->state_file);
138 udev_device_unref(link->udev_device);
143 Link *link_unref(Link *link) {
144 if (link && (-- link->n_ref <= 0))
150 Link *link_ref(Link *link) {
152 assert_se(++ link->n_ref >= 2);
157 int link_get(Manager *m, int ifindex, Link **ret) {
164 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
173 void link_drop(Link *link) {
174 if (!link || link->state == LINK_STATE_LINGER)
177 link->state = LINK_STATE_LINGER;
179 log_debug_link(link, "link removed");
186 static void link_enter_unmanaged(Link *link) {
189 log_debug_link(link, "unmanaged");
191 link->state = LINK_STATE_UNMANAGED;
196 static int link_stop_clients(Link *link) {
200 assert(link->manager);
201 assert(link->manager->event);
206 if (link->dhcp_client) {
207 k = sd_dhcp_client_stop(link->dhcp_client);
209 log_warning_link(link, "Could not stop DHCPv4 client: %s",
216 k = sd_ipv4ll_stop(link->ipv4ll);
218 log_warning_link(link, "Could not stop IPv4 link-local: %s",
224 if (link->dhcp_server) {
225 k = sd_dhcp_server_stop(link->dhcp_server);
227 log_warning_link(link, "Could not stop DHCPv4 server: %s",
233 if(link->icmp6_router_discovery) {
235 if (link->dhcp6_client) {
236 k = sd_dhcp6_client_stop(link->dhcp6_client);
238 log_warning_link(link, "Could not stop DHCPv6 client: %s",
244 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
246 log_warning_link(link,
247 "Could not stop ICMPv6 router discovery: %s",
256 void link_enter_failed(Link *link) {
259 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
262 log_warning_link(link, "failed");
264 link->state = LINK_STATE_FAILED;
266 link_stop_clients(link);
271 static Address* link_find_dhcp_server_address(Link *link) {
275 assert(link->network);
277 /* The the first statically configured address if there is any */
278 LIST_FOREACH(addresses, address, link->network->static_addresses) {
280 if (address->family != AF_INET)
283 if (in_addr_is_null(address->family, &address->in_addr))
289 /* If that didn't work, find a suitable address we got from the pool */
290 LIST_FOREACH(addresses, address, link->pool_addresses) {
291 if (address->family != AF_INET)
300 static int link_enter_configured(Link *link) {
304 assert(link->network);
305 assert(link->state == LINK_STATE_SETTING_ROUTES);
307 if (link->network->dhcp_server &&
308 !sd_dhcp_server_is_running(link->dhcp_server)) {
309 struct in_addr pool_start;
312 address = link_find_dhcp_server_address(link);
314 log_warning_link(link,
315 "Failed to find suitable address for DHCPv4 server instance.");
316 link_enter_failed(link);
320 log_debug_link(link, "offering DHCPv4 leases");
322 r = sd_dhcp_server_set_address(link->dhcp_server,
323 &address->in_addr.in,
328 /* offer 32 addresses starting from the address following the server address */
329 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
330 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
336 r = sd_dhcp_server_set_router(link->dhcp_server,
337 &main_address->in_addr.in);
341 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
342 main_address->prefixlen);
347 r = sd_dhcp_server_start(link->dhcp_server);
349 log_warning_link(link, "could not start DHCPv4 server "
350 "instance: %s", strerror(-r));
352 link_enter_failed(link);
358 log_info_link(link, "link configured");
360 link->state = LINK_STATE_CONFIGURED;
367 void link_client_handler(Link *link) {
369 assert(link->network);
371 if (!link->static_configured)
374 if (link->network->ipv4ll)
375 if (!link->ipv4ll_address ||
379 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4))
380 if (!link->dhcp4_configured)
383 link_enter_configured(link);
388 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
389 _cleanup_link_unref_ Link *link = userdata;
392 assert(link->link_messages > 0);
393 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
394 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
397 link->link_messages --;
399 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
402 r = sd_rtnl_message_get_errno(m);
403 if (r < 0 && r != -EEXIST)
404 log_struct_link(LOG_WARNING, link,
405 "MESSAGE=%-*s: could not set route: %s",
407 link->ifname, strerror(-r),
411 if (link->link_messages == 0) {
412 log_debug_link(link, "routes set");
413 link->static_configured = true;
414 link_client_handler(link);
420 static int link_enter_set_routes(Link *link) {
425 assert(link->network);
426 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
428 link->state = LINK_STATE_SETTING_ROUTES;
430 LIST_FOREACH(routes, rt, link->network->static_routes) {
431 r = route_configure(rt, link, &route_handler);
433 log_warning_link(link,
434 "could not set routes: %s",
436 link_enter_failed(link);
440 link->link_messages ++;
443 if (link->link_messages == 0) {
444 link->static_configured = true;
445 link_client_handler(link);
447 log_debug_link(link, "setting routes");
452 int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
453 _cleanup_link_unref_ Link *link = userdata;
458 assert(link->ifname);
460 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
463 r = sd_rtnl_message_get_errno(m);
464 if (r < 0 && r != -ESRCH)
465 log_struct_link(LOG_WARNING, link,
466 "MESSAGE=%-*s: could not drop route: %s",
468 link->ifname, strerror(-r),
475 int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
476 _cleanup_link_unref_ Link *link = userdata;
482 assert(link->manager);
484 for (; m; m = sd_rtnl_message_next(m)) {
485 r = sd_rtnl_message_get_errno(m);
487 log_debug_link(link, "getting address failed: %s",
492 r = link_rtnl_process_address(rtnl, m, link->manager);
494 log_warning_link(link, "could not process address: %s",
501 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
502 _cleanup_link_unref_ Link *link = userdata;
508 assert(link->ifname);
509 assert(link->link_messages > 0);
510 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
511 LINK_STATE_FAILED, LINK_STATE_LINGER));
513 link->link_messages --;
515 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
518 r = sd_rtnl_message_get_errno(m);
519 if (r < 0 && r != -EEXIST)
520 log_struct_link(LOG_WARNING, link,
521 "MESSAGE=%-*s: could not set address: %s",
523 link->ifname, strerror(-r),
527 /* calling handler directly so take a ref */
529 link_get_address_handler(rtnl, m, link);
532 if (link->link_messages == 0) {
533 log_debug_link(link, "addresses set");
534 link_enter_set_routes(link);
540 static int link_enter_set_addresses(Link *link) {
545 assert(link->network);
546 assert(link->state != _LINK_STATE_INVALID);
548 link->state = LINK_STATE_SETTING_ADDRESSES;
550 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
551 r = address_configure(ad, link, &address_handler);
553 log_warning_link(link,
554 "could not set addresses: %s",
556 link_enter_failed(link);
560 link->link_messages ++;
563 if (link->link_messages == 0) {
564 link_enter_set_routes(link);
566 log_debug_link(link, "setting addresses");
571 int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
572 _cleanup_link_unref_ Link *link = userdata;
577 assert(link->ifname);
579 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
582 r = sd_rtnl_message_get_errno(m);
583 if (r < 0 && r != -EADDRNOTAVAIL)
584 log_struct_link(LOG_WARNING, link,
585 "MESSAGE=%-*s: could not drop address: %s",
587 link->ifname, strerror(-r),
594 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
595 sd_bus_error *ret_error) {
596 _cleanup_link_unref_ Link *link = userdata;
601 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
604 r = sd_bus_message_get_errno(m);
608 log_warning_link(link, "Could not set hostname: %s",
614 int link_set_hostname(Link *link, const char *hostname) {
615 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
619 assert(link->manager);
622 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
624 if (!link->manager->bus) {
625 /* TODO: replace by assert when we can rely on kdbus */
627 "Not connected to system bus, ignoring transient hostname.");
631 r = sd_bus_message_new_method_call(
634 "org.freedesktop.hostname1",
635 "/org/freedesktop/hostname1",
636 "org.freedesktop.hostname1",
641 r = sd_bus_message_append(m, "sb", hostname, false);
645 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
648 log_error_link(link, "Could not set transient hostname: %s",
658 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
659 _cleanup_link_unref_ Link *link = userdata;
664 assert(link->ifname);
666 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
669 r = sd_rtnl_message_get_errno(m);
671 log_struct_link(LOG_WARNING, link,
672 "MESSAGE=%-*s: could not set MTU: %s",
673 IFNAMSIZ, link->ifname, strerror(-r),
680 int link_set_mtu(Link *link, uint32_t mtu) {
681 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
685 assert(link->manager);
686 assert(link->manager->rtnl);
688 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
690 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
691 RTM_SETLINK, link->ifindex);
693 log_error_link(link, "Could not allocate RTM_SETLINK message");
697 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
699 log_error_link(link, "Could not append MTU: %s", strerror(-r));
703 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
707 "Could not send rtnetlink message: %s",
717 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
718 Link *link = userdata;
721 assert(link->network);
722 assert(link->manager);
724 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
728 case DHCP6_EVENT_STOP:
729 case DHCP6_EVENT_RESEND_EXPIRE:
730 case DHCP6_EVENT_RETRANS_MAX:
731 case DHCP6_EVENT_IP_ACQUIRE:
732 log_debug_link(link, "DHCPv6 event %d", event);
738 log_warning_link(link, "DHCPv6 error: %s",
741 log_warning_link(link, "DHCPv6 unknown event: %d",
747 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
748 Link *link = userdata;
752 assert(link->network);
753 assert(link->manager);
755 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
759 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
760 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
763 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
764 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
769 log_warning_link(link, "ICMPv6 error: %s",
772 log_warning_link(link, "ICMPv6 unknown event: %d",
778 if (link->dhcp6_client)
781 r = sd_dhcp6_client_new(&link->dhcp6_client);
785 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
787 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
791 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
793 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
797 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
799 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
803 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
806 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
810 r = sd_dhcp6_client_start(link->dhcp6_client);
812 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
815 static int link_acquire_conf(Link *link) {
819 assert(link->network);
820 assert(link->manager);
821 assert(link->manager->event);
823 if (link->network->ipv4ll) {
824 assert(link->ipv4ll);
826 log_debug_link(link, "acquiring IPv4 link-local address");
828 r = sd_ipv4ll_start(link->ipv4ll);
830 log_warning_link(link, "could not acquire IPv4 "
831 "link-local address");
836 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
837 assert(link->dhcp_client);
839 log_debug_link(link, "acquiring DHCPv4 lease");
841 r = sd_dhcp_client_start(link->dhcp_client);
843 log_warning_link(link, "could not acquire DHCPv4 "
849 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
850 assert(link->icmp6_router_discovery);
852 log_debug_link(link, "discovering IPv6 routers");
854 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
856 log_warning_link(link,
857 "could not start IPv6 router discovery");
865 bool link_has_carrier(unsigned flags, uint8_t operstate) {
866 /* see Documentation/networking/operstates.txt in the kernel sources */
868 if (operstate == IF_OPER_UP)
871 if (operstate == IF_OPER_UNKNOWN)
872 /* operstate may not be implemented, so fall back to flags */
873 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
879 #define FLAG_STRING(string, flag, old, new) \
880 (((old ^ new) & flag) \
881 ? ((old & flag) ? (" -" string) : (" +" string)) \
884 static int link_update_flags(Link *link, sd_rtnl_message *m) {
885 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
887 bool carrier_gained = false, carrier_lost = false;
892 r = sd_rtnl_message_link_get_flags(m, &flags);
894 log_warning_link(link, "Could not get link flags");
898 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
900 /* if we got a message without operstate, take it to mean
901 the state was unchanged */
902 operstate = link->kernel_operstate;
904 if ((link->flags == flags) && (link->kernel_operstate == operstate))
907 if (link->flags != flags) {
908 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
909 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
910 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
911 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
912 FLAG_STRING("UP", IFF_UP, link->flags, flags),
913 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
914 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
915 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
916 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
917 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
918 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
919 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
920 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
921 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
922 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
923 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
924 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
925 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
926 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
927 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
929 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
930 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
931 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
932 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
933 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
934 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
935 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
936 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
938 /* link flags are currently at most 18 bits, let's align to
940 if (unknown_flags_added)
942 "unknown link flags gained: %#.5x (ignoring)",
943 unknown_flags_added);
945 if (unknown_flags_removed)
947 "unknown link flags lost: %#.5x (ignoring)",
948 unknown_flags_removed);
951 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
952 link_has_carrier(flags, operstate);
953 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
954 !link_has_carrier(flags, operstate);
957 link->kernel_operstate = operstate;
961 if (link->state == LINK_STATE_FAILED ||
962 link->state == LINK_STATE_UNMANAGED)
965 if (carrier_gained) {
966 log_info_link(link, "gained carrier");
969 r = link_acquire_conf(link);
971 link_enter_failed(link);
975 } else if (carrier_lost) {
976 log_info_link(link, "lost carrier");
978 r = link_stop_clients(link);
980 link_enter_failed(link);
988 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
989 _cleanup_link_unref_ Link *link = userdata;
994 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
997 r = sd_rtnl_message_get_errno(m);
999 /* we warn but don't fail the link, as it may
1000 be brought up later */
1001 log_struct_link(LOG_WARNING, link,
1002 "MESSAGE=%-*s: could not bring up interface: %s",
1004 link->ifname, strerror(-r),
1012 static int link_up(Link *link) {
1013 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1017 assert(link->manager);
1018 assert(link->manager->rtnl);
1020 log_debug_link(link, "bringing link up");
1022 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1023 RTM_SETLINK, link->ifindex);
1025 log_error_link(link, "Could not allocate RTM_SETLINK message");
1029 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1031 log_error_link(link, "Could not set link flags: %s",
1036 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1039 log_error_link(link,
1040 "Could not send rtnetlink message: %s",
1050 static int link_joined(Link *link) {
1054 assert(link->state == LINK_STATE_ENSLAVING);
1055 assert(link->network);
1057 if (!(link->flags & IFF_UP)) {
1060 link_enter_failed(link);
1065 return link_enter_set_addresses(link);
1068 static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1070 _cleanup_link_unref_ Link *link = userdata;
1074 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1075 LINK_STATE_LINGER));
1076 assert(link->network);
1080 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1083 r = sd_rtnl_message_get_errno(m);
1084 if (r < 0 && r != -EEXIST) {
1085 log_struct_link(LOG_ERR, link,
1086 "MESSAGE=%-*s: could not join netdev: %s",
1088 link->ifname, strerror(-r),
1091 link_enter_failed(link);
1094 log_debug_link(link, "joined netdev");
1096 if (link->enslaving <= 0)
1102 static int link_enter_join_netdev(Link *link) {
1108 assert(link->network);
1109 assert(link->state == LINK_STATE_INITIALIZING);
1111 link->state = LINK_STATE_ENSLAVING;
1115 if (!link->network->bridge &&
1116 !link->network->bond &&
1117 hashmap_isempty(link->network->stacked_netdevs))
1118 return link_joined(link);
1120 if (link->network->bond) {
1121 log_struct_link(LOG_DEBUG, link,
1122 "MESSAGE=%-*s: enslaving by '%s'",
1124 link->ifname, link->network->bond->ifname,
1125 NETDEVIF(link->network->bond),
1128 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1130 log_struct_link(LOG_WARNING, link,
1131 "MESSAGE=%-*s: could not join netdev '%s': %s",
1133 link->ifname, link->network->bond->ifname,
1135 NETDEVIF(link->network->bond),
1137 link_enter_failed(link);
1144 if (link->network->bridge) {
1145 log_struct_link(LOG_DEBUG, link,
1146 "MESSAGE=%-*s: enslaving by '%s'",
1148 link->ifname, link->network->bridge->ifname,
1149 NETDEVIF(link->network->bridge),
1152 r = netdev_join(link->network->bridge, link,
1153 &netdev_join_handler);
1155 log_struct_link(LOG_WARNING, link,
1156 "MESSAGE=%-*s: could not join netdev '%s': %s",
1158 link->ifname, link->network->bridge->ifname,
1160 NETDEVIF(link->network->bridge),
1162 link_enter_failed(link);
1169 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1170 log_struct_link(LOG_DEBUG, link,
1171 "MESSAGE=%-*s: enslaving by '%s'",
1173 link->ifname, netdev->ifname, NETDEVIF(netdev),
1176 r = netdev_join(netdev, link, &netdev_join_handler);
1178 log_struct_link(LOG_WARNING, link,
1179 "MESSAGE=%-*s: could not join netdev '%s': %s",
1181 link->ifname, netdev->ifname,
1183 NETDEVIF(netdev), NULL);
1184 link_enter_failed(link);
1194 static int link_configure(Link *link) {
1198 assert(link->network);
1199 assert(link->state == LINK_STATE_INITIALIZING);
1201 if (link->network->ipv4ll) {
1202 r = ipv4ll_configure(link);
1207 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1208 r = dhcp4_configure(link);
1213 if (link->network->dhcp_server) {
1214 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1218 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1223 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1224 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1228 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1233 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1238 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1243 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1244 icmp6_router_handler, link);
1249 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1250 r = link_acquire_conf(link);
1255 return link_enter_join_netdev(link);
1258 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1260 _cleanup_link_unref_ Link *link = userdata;
1265 assert(link->ifname);
1266 assert(link->manager);
1268 if (link->state != LINK_STATE_INITIALIZING)
1271 log_debug_link(link, "link state is up-to-date");
1273 r = network_get(link->manager, link->udev_device, link->ifname,
1274 &link->mac, &network);
1276 link_enter_unmanaged(link);
1281 r = network_apply(link->manager, network, link);
1285 r = link_configure(link);
1292 int link_initialized(Link *link, struct udev_device *device) {
1293 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1297 assert(link->manager);
1298 assert(link->manager->rtnl);
1301 if (link->state != LINK_STATE_INITIALIZING)
1304 if (link->udev_device)
1307 log_debug_link(link, "udev initialized link");
1309 link->udev_device = udev_device_ref(device);
1311 /* udev has initialized the link, but we don't know if we have yet
1312 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1313 * when it returns we know that the pending NEWLINKs have already been
1314 * processed and that we are up-to-date */
1316 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1321 r = sd_rtnl_call_async(link->manager->rtnl, req,
1322 link_initialized_and_synced, link, 0, NULL);
1331 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
1333 Manager *m = userdata;
1336 _cleanup_address_free_ Address *address = NULL;
1338 char buf[INET6_ADDRSTRLEN];
1339 bool address_dropped = false;
1346 r = sd_rtnl_message_get_type(message, &type);
1348 log_warning("rtnl: could not get message type");
1352 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1353 if (r < 0 || ifindex <= 0) {
1354 log_warning("rtnl: received address message without valid ifindex, ignoring");
1357 r = link_get(m, ifindex, &link);
1358 if (r < 0 || !link) {
1359 log_warning("rtnl: received address for a nonexistent link, ignoring");
1364 r = address_new_dynamic(&address);
1368 r = sd_rtnl_message_addr_get_family(message, &address->family);
1369 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1370 log_warning_link(link,
1371 "rtnl: received address with invalid family, ignoring");
1375 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1377 log_warning_link(link,
1378 "rtnl: received address with invalid prefixlen, ignoring");
1382 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1384 log_warning_link(link,
1385 "rtnl: received address with invalid scope, ignoring");
1389 switch (address->family) {
1391 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
1392 &address->in_addr.in);
1394 log_warning_link(link,
1395 "rtnl: received address without valid address, ignoring");
1402 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
1403 &address->in_addr.in6);
1405 log_warning_link(link,
1406 "rtnl: received address without valid address, ignoring");
1413 assert_not_reached("invalid address family");
1416 if (!inet_ntop(address->family, &address->in_addr, buf,
1417 INET6_ADDRSTRLEN)) {
1418 log_warning_link(link, "could not print address");
1422 LIST_FOREACH(addresses, ad, link->addresses) {
1423 if (address_equal(ad, address)) {
1424 LIST_REMOVE(addresses, link->addresses, ad);
1428 address_dropped = true;
1436 if (!address_dropped)
1437 log_debug_link(link, "added address: %s/%u", buf,
1438 address->prefixlen);
1440 log_debug_link(link, "updated address: %s/%u", buf,
1441 address->prefixlen);
1443 LIST_PREPEND(addresses, link->addresses, address);
1450 if (address_dropped) {
1451 log_debug_link(link, "removed address: %s/%u", buf,
1452 address->prefixlen);
1456 log_warning_link(link,
1457 "removing non-existent address: %s/%u",
1458 buf, address->prefixlen);
1462 assert_not_reached("Received invalid RTNL message type");
1468 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1470 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1471 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1472 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1480 r = link_new(m, message, ret);
1486 log_debug_link(link, "link %d added", link->ifindex);
1488 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
1493 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
1500 if (detect_container(NULL) <= 0) {
1501 /* not in a container, udev will be around */
1502 sprintf(ifindex_str, "n%d", link->ifindex);
1503 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1505 log_warning_link(link,
1506 "could not find udev device: %m");
1510 if (udev_device_get_is_initialized(device) <= 0) {
1512 log_debug_link(link, "udev initializing link...");
1516 r = link_initialized(link, device);
1520 /* we are calling a callback directly, so must take a ref */
1523 r = link_initialized_and_synced(m->rtnl, NULL, link);
1531 int link_update(Link *link, sd_rtnl_message *m) {
1532 struct ether_addr mac;
1538 assert(link->ifname);
1541 if (link->state == LINK_STATE_LINGER) {
1543 log_info_link(link, "link readded");
1544 link->state = LINK_STATE_ENSLAVING;
1547 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1548 if (r >= 0 && !streq(ifname, link->ifname)) {
1549 log_info_link(link, "renamed to %s", ifname);
1552 link->ifname = strdup(ifname);
1557 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1558 if (r >= 0 && mtu > 0) {
1560 if (!link->original_mtu) {
1561 link->original_mtu = mtu;
1562 log_debug_link(link, "saved original MTU: %"
1563 PRIu32, link->original_mtu);
1566 if (link->dhcp_client) {
1567 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1570 log_warning_link(link,
1571 "Could not update MTU in DHCP client: %s",
1578 /* The kernel may broadcast NEWLINK messages without the MAC address
1579 set, simply ignore them. */
1580 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1582 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1585 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1588 log_debug_link(link, "MAC address: "
1589 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1590 mac.ether_addr_octet[0],
1591 mac.ether_addr_octet[1],
1592 mac.ether_addr_octet[2],
1593 mac.ether_addr_octet[3],
1594 mac.ether_addr_octet[4],
1595 mac.ether_addr_octet[5]);
1598 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1600 log_warning_link(link,
1601 "Could not update MAC address in IPv4LL client: %s",
1607 if (link->dhcp_client) {
1608 r = sd_dhcp_client_set_mac(link->dhcp_client,
1611 log_warning_link(link,
1612 "Could not update MAC address in DHCP client: %s",
1618 if (link->dhcp6_client) {
1619 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
1622 log_warning_link(link,
1623 "Could not update MAC address in DHCPv6 client: %s",
1631 return link_update_flags(link, m);
1634 static void link_update_operstate(Link *link) {
1638 if (link->kernel_operstate == IF_OPER_DORMANT)
1639 link->operstate = LINK_OPERSTATE_DORMANT;
1640 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
1642 uint8_t scope = RT_SCOPE_NOWHERE;
1644 /* if we have carrier, check what addresses we have */
1645 LIST_FOREACH(addresses, address, link->addresses) {
1646 if (address->scope < scope)
1647 scope = address->scope;
1650 if (scope < RT_SCOPE_SITE)
1651 /* universally accessible addresses found */
1652 link->operstate = LINK_OPERSTATE_ROUTABLE;
1653 else if (scope < RT_SCOPE_HOST)
1654 /* only link or site local addresses found */
1655 link->operstate = LINK_OPERSTATE_DEGRADED;
1657 /* no useful addresses found */
1658 link->operstate = LINK_OPERSTATE_CARRIER;
1659 } else if (link->flags & IFF_UP)
1660 link->operstate = LINK_OPERSTATE_UP;
1662 link->operstate = LINK_OPERSTATE_DOWN;
1665 int link_save(Link *link) {
1666 _cleanup_free_ char *temp_path = NULL;
1667 _cleanup_fclose_ FILE *f = NULL;
1668 const char *admin_state, *oper_state;
1672 assert(link->state_file);
1673 assert(link->lease_file);
1674 assert(link->manager);
1676 link_update_operstate(link);
1678 r = manager_save(link->manager);
1682 if (link->state == LINK_STATE_LINGER) {
1683 unlink(link->state_file);
1687 admin_state = link_state_to_string(link->state);
1688 assert(admin_state);
1690 oper_state = link_operstate_to_string(link->operstate);
1693 r = fopen_temporary(link->state_file, &f, &temp_path);
1697 fchmod(fileno(f), 0644);
1700 "# This is private data. Do not parse.\n"
1703 admin_state, oper_state);
1705 if (link->network) {
1710 if (link->network->dhcp_dns &&
1712 const struct in_addr *addresses;
1714 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1716 serialize_in_addrs(f, addresses, r);
1717 if (link->network->dns)
1722 STRV_FOREACH(address, link->network->dns)
1723 fprintf(f, "%s%s", *address,
1724 (address + 1 ? " " : ""));
1730 if (link->network->dhcp_ntp &&
1732 const struct in_addr *addresses;
1734 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1736 serialize_in_addrs(f, addresses, r);
1737 if (link->network->ntp)
1742 STRV_FOREACH(address, link->network->ntp)
1743 fprintf(f, "%s%s", *address,
1744 (address + 1 ? " " : ""));
1748 fprintf(f, "LLMNR=%s\n",
1749 llmnr_support_to_string(link->network->llmnr));
1752 if (link->dhcp_lease) {
1753 assert(link->network);
1755 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
1763 unlink(link->lease_file);
1765 r = fflush_and_check(f);
1769 if (rename(temp_path, link->state_file) < 0) {
1776 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
1777 unlink(link->state_file);
1782 static const char* const link_state_table[_LINK_STATE_MAX] = {
1783 [LINK_STATE_INITIALIZING] = "initializing",
1784 [LINK_STATE_ENSLAVING] = "configuring",
1785 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1786 [LINK_STATE_SETTING_ROUTES] = "configuring",
1787 [LINK_STATE_CONFIGURED] = "configured",
1788 [LINK_STATE_UNMANAGED] = "unmanaged",
1789 [LINK_STATE_FAILED] = "failed",
1790 [LINK_STATE_LINGER] = "linger",
1793 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
1795 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
1796 [LINK_OPERSTATE_DOWN] = "down",
1797 [LINK_OPERSTATE_UP] = "up",
1798 [LINK_OPERSTATE_DORMANT] = "dormant",
1799 [LINK_OPERSTATE_CARRIER] = "carrier",
1800 [LINK_OPERSTATE_DEGRADED] = "degraded",
1801 [LINK_OPERSTATE_ROUTABLE] = "routable",
1804 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);