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_PENDING;
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 if (link->state != LINK_STATE_CONFIGURED)
384 link_enter_configured(link);
389 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
390 _cleanup_link_unref_ Link *link = userdata;
393 assert(link->link_messages > 0);
394 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
395 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
398 link->link_messages --;
400 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
403 r = sd_rtnl_message_get_errno(m);
404 if (r < 0 && r != -EEXIST)
405 log_struct_link(LOG_WARNING, link,
406 "MESSAGE=%-*s: could not set route: %s",
408 link->ifname, strerror(-r),
412 if (link->link_messages == 0) {
413 log_debug_link(link, "routes set");
414 link->static_configured = true;
415 link_client_handler(link);
421 static int link_enter_set_routes(Link *link) {
426 assert(link->network);
427 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
429 link->state = LINK_STATE_SETTING_ROUTES;
431 LIST_FOREACH(routes, rt, link->network->static_routes) {
432 r = route_configure(rt, link, &route_handler);
434 log_warning_link(link,
435 "could not set routes: %s",
437 link_enter_failed(link);
441 link->link_messages ++;
444 if (link->link_messages == 0) {
445 link->static_configured = true;
446 link_client_handler(link);
448 log_debug_link(link, "setting routes");
453 int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
454 _cleanup_link_unref_ Link *link = userdata;
459 assert(link->ifname);
461 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
464 r = sd_rtnl_message_get_errno(m);
465 if (r < 0 && r != -ESRCH)
466 log_struct_link(LOG_WARNING, link,
467 "MESSAGE=%-*s: could not drop route: %s",
469 link->ifname, strerror(-r),
476 int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
477 _cleanup_link_unref_ Link *link = userdata;
483 assert(link->manager);
485 for (; m; m = sd_rtnl_message_next(m)) {
486 r = sd_rtnl_message_get_errno(m);
488 log_debug_link(link, "getting address failed: %s",
493 r = link_rtnl_process_address(rtnl, m, link->manager);
495 log_warning_link(link, "could not process address: %s",
502 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
503 _cleanup_link_unref_ Link *link = userdata;
509 assert(link->ifname);
510 assert(link->link_messages > 0);
511 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
512 LINK_STATE_FAILED, LINK_STATE_LINGER));
514 link->link_messages --;
516 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
519 r = sd_rtnl_message_get_errno(m);
520 if (r < 0 && r != -EEXIST)
521 log_struct_link(LOG_WARNING, link,
522 "MESSAGE=%-*s: could not set address: %s",
524 link->ifname, strerror(-r),
528 /* calling handler directly so take a ref */
530 link_get_address_handler(rtnl, m, link);
533 if (link->link_messages == 0) {
534 log_debug_link(link, "addresses set");
535 link_enter_set_routes(link);
541 static int link_enter_set_addresses(Link *link) {
546 assert(link->network);
547 assert(link->state != _LINK_STATE_INVALID);
549 link->state = LINK_STATE_SETTING_ADDRESSES;
551 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
552 r = address_configure(ad, link, &address_handler);
554 log_warning_link(link,
555 "could not set addresses: %s",
557 link_enter_failed(link);
561 link->link_messages ++;
564 if (link->link_messages == 0) {
565 link_enter_set_routes(link);
567 log_debug_link(link, "setting addresses");
572 int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
573 _cleanup_link_unref_ Link *link = userdata;
578 assert(link->ifname);
580 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
583 r = sd_rtnl_message_get_errno(m);
584 if (r < 0 && r != -EADDRNOTAVAIL)
585 log_struct_link(LOG_WARNING, link,
586 "MESSAGE=%-*s: could not drop address: %s",
588 link->ifname, strerror(-r),
595 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
596 sd_bus_error *ret_error) {
597 _cleanup_link_unref_ Link *link = userdata;
602 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
605 r = sd_bus_message_get_errno(m);
609 log_warning_link(link, "Could not set hostname: %s",
615 int link_set_hostname(Link *link, const char *hostname) {
616 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
620 assert(link->manager);
623 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
625 if (!link->manager->bus) {
626 /* TODO: replace by assert when we can rely on kdbus */
628 "Not connected to system bus, ignoring transient hostname.");
632 r = sd_bus_message_new_method_call(
635 "org.freedesktop.hostname1",
636 "/org/freedesktop/hostname1",
637 "org.freedesktop.hostname1",
642 r = sd_bus_message_append(m, "sb", hostname, false);
646 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
649 log_error_link(link, "Could not set transient hostname: %s",
659 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
660 _cleanup_link_unref_ Link *link = userdata;
665 assert(link->ifname);
667 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
670 r = sd_rtnl_message_get_errno(m);
672 log_struct_link(LOG_WARNING, link,
673 "MESSAGE=%-*s: could not set MTU: %s",
674 IFNAMSIZ, link->ifname, strerror(-r),
681 int link_set_mtu(Link *link, uint32_t mtu) {
682 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
686 assert(link->manager);
687 assert(link->manager->rtnl);
689 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
691 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
692 RTM_SETLINK, link->ifindex);
694 log_error_link(link, "Could not allocate RTM_SETLINK message");
698 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
700 log_error_link(link, "Could not append MTU: %s", strerror(-r));
704 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
708 "Could not send rtnetlink message: %s",
718 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
719 Link *link = userdata;
722 assert(link->network);
723 assert(link->manager);
725 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
729 case DHCP6_EVENT_STOP:
730 case DHCP6_EVENT_RESEND_EXPIRE:
731 case DHCP6_EVENT_RETRANS_MAX:
732 case DHCP6_EVENT_IP_ACQUIRE:
733 log_debug_link(link, "DHCPv6 event %d", event);
739 log_warning_link(link, "DHCPv6 error: %s",
742 log_warning_link(link, "DHCPv6 unknown event: %d",
748 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
749 Link *link = userdata;
753 assert(link->network);
754 assert(link->manager);
756 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
760 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
761 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
764 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
765 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
770 log_warning_link(link, "ICMPv6 error: %s",
773 log_warning_link(link, "ICMPv6 unknown event: %d",
779 if (link->dhcp6_client)
782 r = sd_dhcp6_client_new(&link->dhcp6_client);
786 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
788 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
792 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
794 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
798 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
800 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
804 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
807 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
811 r = sd_dhcp6_client_start(link->dhcp6_client);
813 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
816 static int link_acquire_conf(Link *link) {
820 assert(link->network);
821 assert(link->manager);
822 assert(link->manager->event);
824 if (link->network->ipv4ll) {
825 assert(link->ipv4ll);
827 log_debug_link(link, "acquiring IPv4 link-local address");
829 r = sd_ipv4ll_start(link->ipv4ll);
831 log_warning_link(link, "could not acquire IPv4 "
832 "link-local address");
837 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
838 assert(link->dhcp_client);
840 log_debug_link(link, "acquiring DHCPv4 lease");
842 r = sd_dhcp_client_start(link->dhcp_client);
844 log_warning_link(link, "could not acquire DHCPv4 "
850 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
851 assert(link->icmp6_router_discovery);
853 log_debug_link(link, "discovering IPv6 routers");
855 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
857 log_warning_link(link,
858 "could not start IPv6 router discovery");
866 bool link_has_carrier(Link *link) {
867 /* see Documentation/networking/operstates.txt in the kernel sources */
869 if (link->kernel_operstate == IF_OPER_UP)
872 if (link->kernel_operstate == IF_OPER_UNKNOWN)
873 /* operstate may not be implemented, so fall back to flags */
874 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
880 #define FLAG_STRING(string, flag, old, new) \
881 (((old ^ new) & flag) \
882 ? ((old & flag) ? (" -" string) : (" +" string)) \
885 static int link_update_flags(Link *link, sd_rtnl_message *m) {
886 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
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);
952 link->kernel_operstate = operstate;
959 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
960 _cleanup_link_unref_ Link *link = userdata;
965 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
968 r = sd_rtnl_message_get_errno(m);
970 /* we warn but don't fail the link, as it may
971 be brought up later */
972 log_struct_link(LOG_WARNING, link,
973 "MESSAGE=%-*s: could not bring up interface: %s",
975 link->ifname, strerror(-r),
983 static int link_up(Link *link) {
984 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
988 assert(link->manager);
989 assert(link->manager->rtnl);
991 log_debug_link(link, "bringing link up");
993 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
994 RTM_SETLINK, link->ifindex);
996 log_error_link(link, "Could not allocate RTM_SETLINK message");
1000 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1002 log_error_link(link, "Could not set link flags: %s",
1007 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1010 log_error_link(link,
1011 "Could not send rtnetlink message: %s",
1021 static int link_joined(Link *link) {
1025 assert(link->network);
1027 if (!(link->flags & IFF_UP)) {
1030 link_enter_failed(link);
1035 return link_enter_set_addresses(link);
1038 static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1040 _cleanup_link_unref_ Link *link = userdata;
1044 assert(link->network);
1048 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1051 r = sd_rtnl_message_get_errno(m);
1052 if (r < 0 && r != -EEXIST) {
1053 log_struct_link(LOG_ERR, link,
1054 "MESSAGE=%-*s: could not join netdev: %s",
1056 link->ifname, strerror(-r),
1059 link_enter_failed(link);
1062 log_debug_link(link, "joined netdev");
1064 if (link->enslaving <= 0)
1070 static int link_enter_join_netdev(Link *link) {
1076 assert(link->network);
1077 assert(link->state == LINK_STATE_PENDING);
1079 link->state = LINK_STATE_ENSLAVING;
1083 if (!link->network->bridge &&
1084 !link->network->bond &&
1085 hashmap_isempty(link->network->stacked_netdevs))
1086 return link_joined(link);
1088 if (link->network->bond) {
1089 log_struct_link(LOG_DEBUG, link,
1090 "MESSAGE=%-*s: enslaving by '%s'",
1092 link->ifname, link->network->bond->ifname,
1093 NETDEVIF(link->network->bond),
1096 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1098 log_struct_link(LOG_WARNING, link,
1099 "MESSAGE=%-*s: could not join netdev '%s': %s",
1101 link->ifname, link->network->bond->ifname,
1103 NETDEVIF(link->network->bond),
1105 link_enter_failed(link);
1112 if (link->network->bridge) {
1113 log_struct_link(LOG_DEBUG, link,
1114 "MESSAGE=%-*s: enslaving by '%s'",
1116 link->ifname, link->network->bridge->ifname,
1117 NETDEVIF(link->network->bridge),
1120 r = netdev_join(link->network->bridge, link,
1121 &netdev_join_handler);
1123 log_struct_link(LOG_WARNING, link,
1124 "MESSAGE=%-*s: could not join netdev '%s': %s",
1126 link->ifname, link->network->bridge->ifname,
1128 NETDEVIF(link->network->bridge),
1130 link_enter_failed(link);
1137 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1138 log_struct_link(LOG_DEBUG, link,
1139 "MESSAGE=%-*s: enslaving by '%s'",
1141 link->ifname, netdev->ifname, NETDEVIF(netdev),
1144 r = netdev_join(netdev, link, &netdev_join_handler);
1146 log_struct_link(LOG_WARNING, link,
1147 "MESSAGE=%-*s: could not join netdev '%s': %s",
1149 link->ifname, netdev->ifname,
1151 NETDEVIF(netdev), NULL);
1152 link_enter_failed(link);
1162 static int link_configure(Link *link) {
1166 assert(link->network);
1167 assert(link->state == LINK_STATE_PENDING);
1169 if (link->network->ipv4ll) {
1170 r = ipv4ll_configure(link);
1175 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1176 r = dhcp4_configure(link);
1181 if (link->network->dhcp_server) {
1182 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1186 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1191 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1192 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1196 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1201 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1206 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1211 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1212 icmp6_router_handler, link);
1217 if (link_has_carrier(link)) {
1218 r = link_acquire_conf(link);
1223 return link_enter_join_netdev(link);
1226 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1228 _cleanup_link_unref_ Link *link = userdata;
1233 assert(link->ifname);
1234 assert(link->manager);
1236 if (link->state != LINK_STATE_PENDING)
1239 log_debug_link(link, "link state is up-to-date");
1241 r = network_get(link->manager, link->udev_device, link->ifname,
1242 &link->mac, &network);
1244 link_enter_unmanaged(link);
1249 r = network_apply(link->manager, network, link);
1253 r = link_configure(link);
1260 int link_initialized(Link *link, struct udev_device *device) {
1261 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1265 assert(link->manager);
1266 assert(link->manager->rtnl);
1269 if (link->state != LINK_STATE_PENDING)
1272 if (link->udev_device)
1275 log_debug_link(link, "udev initialized link");
1277 link->udev_device = udev_device_ref(device);
1279 /* udev has initialized the link, but we don't know if we have yet
1280 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1281 * when it returns we know that the pending NEWLINKs have already been
1282 * processed and that we are up-to-date */
1284 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1289 r = sd_rtnl_call_async(link->manager->rtnl, req,
1290 link_initialized_and_synced, link, 0, NULL);
1299 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
1301 Manager *m = userdata;
1304 _cleanup_address_free_ Address *address = NULL;
1306 char buf[INET6_ADDRSTRLEN];
1307 char valid_buf[FORMAT_TIMESPAN_MAX];
1308 const char *valid_str = NULL;
1309 bool address_dropped = false;
1316 r = sd_rtnl_message_get_type(message, &type);
1318 log_warning("rtnl: could not get message type");
1322 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1323 if (r < 0 || ifindex <= 0) {
1324 log_warning("rtnl: received address message without valid ifindex, ignoring");
1327 r = link_get(m, ifindex, &link);
1328 if (r < 0 || !link) {
1329 log_warning("rtnl: received address for a nonexistent link, ignoring");
1334 r = address_new_dynamic(&address);
1338 r = sd_rtnl_message_addr_get_family(message, &address->family);
1339 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1340 log_warning_link(link,
1341 "rtnl: received address with invalid family, ignoring");
1345 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1347 log_warning_link(link,
1348 "rtnl: received address with invalid prefixlen, ignoring");
1352 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1354 log_warning_link(link,
1355 "rtnl: received address with invalid scope, ignoring");
1359 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1361 log_warning_link(link,
1362 "rtnl: received address with invalid flags, ignoring");
1366 switch (address->family) {
1368 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
1369 &address->in_addr.in);
1371 log_warning_link(link,
1372 "rtnl: received address without valid address, ignoring");
1379 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
1380 &address->in_addr.in6);
1382 log_warning_link(link,
1383 "rtnl: received address without valid address, ignoring");
1390 assert_not_reached("invalid address family");
1393 if (!inet_ntop(address->family, &address->in_addr, buf,
1394 INET6_ADDRSTRLEN)) {
1395 log_warning_link(link, "could not print address");
1399 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO,
1402 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1405 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1406 address->cinfo.ifa_valid * USEC_PER_SEC,
1410 LIST_FOREACH(addresses, ad, link->addresses) {
1411 if (address_equal(ad, address)) {
1412 LIST_REMOVE(addresses, link->addresses, ad);
1416 address_dropped = true;
1424 if (!address_dropped)
1425 log_debug_link(link, "added address: %s/%u (valid for %s)",
1426 buf, address->prefixlen,
1429 log_debug_link(link, "updated address: %s/%u (valid for %s)",
1430 buf, address->prefixlen,
1433 LIST_PREPEND(addresses, link->addresses, address);
1440 if (address_dropped) {
1441 log_debug_link(link, "removed address: %s/%u (valid for %s)",
1442 buf, address->prefixlen,
1447 log_warning_link(link,
1448 "removing non-existent address: %s/%u (valid for %s)",
1449 buf, address->prefixlen,
1454 assert_not_reached("Received invalid RTNL message type");
1460 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1462 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1463 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1464 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1472 r = link_new(m, message, ret);
1478 log_debug_link(link, "link %d added", link->ifindex);
1480 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
1485 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
1492 if (detect_container(NULL) <= 0) {
1493 /* not in a container, udev will be around */
1494 sprintf(ifindex_str, "n%d", link->ifindex);
1495 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1497 log_warning_link(link,
1498 "could not find udev device: %m");
1502 if (udev_device_get_is_initialized(device) <= 0) {
1504 log_debug_link(link, "link pending udev initialization...");
1508 r = link_initialized(link, device);
1512 /* we are calling a callback directly, so must take a ref */
1515 r = link_initialized_and_synced(m->rtnl, NULL, link);
1523 int link_update(Link *link, sd_rtnl_message *m) {
1524 struct ether_addr mac;
1527 bool had_carrier, carrier_gained, carrier_lost;
1531 assert(link->ifname);
1534 if (link->state == LINK_STATE_LINGER) {
1536 log_info_link(link, "link readded");
1537 link->state = LINK_STATE_ENSLAVING;
1540 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1541 if (r >= 0 && !streq(ifname, link->ifname)) {
1542 log_info_link(link, "renamed to %s", ifname);
1545 link->ifname = strdup(ifname);
1550 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1551 if (r >= 0 && mtu > 0) {
1553 if (!link->original_mtu) {
1554 link->original_mtu = mtu;
1555 log_debug_link(link, "saved original MTU: %"
1556 PRIu32, link->original_mtu);
1559 if (link->dhcp_client) {
1560 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1563 log_warning_link(link,
1564 "Could not update MTU in DHCP client: %s",
1571 /* The kernel may broadcast NEWLINK messages without the MAC address
1572 set, simply ignore them. */
1573 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1575 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1578 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1581 log_debug_link(link, "MAC address: "
1582 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1583 mac.ether_addr_octet[0],
1584 mac.ether_addr_octet[1],
1585 mac.ether_addr_octet[2],
1586 mac.ether_addr_octet[3],
1587 mac.ether_addr_octet[4],
1588 mac.ether_addr_octet[5]);
1591 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1593 log_warning_link(link,
1594 "Could not update MAC address in IPv4LL client: %s",
1600 if (link->dhcp_client) {
1601 r = sd_dhcp_client_set_mac(link->dhcp_client,
1604 log_warning_link(link,
1605 "Could not update MAC address in DHCP client: %s",
1611 if (link->dhcp6_client) {
1612 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
1615 log_warning_link(link,
1616 "Could not update MAC address in DHCPv6 client: %s",
1624 had_carrier = link_has_carrier(link);
1626 r = link_update_flags(link, m);
1630 carrier_gained = !had_carrier && link_has_carrier(link);
1631 carrier_lost = had_carrier && !link_has_carrier(link);
1633 if (carrier_gained) {
1634 log_info_link(link, "gained carrier");
1636 if (link->network) {
1637 r = link_acquire_conf(link);
1639 link_enter_failed(link);
1643 } else if (carrier_lost) {
1644 log_info_link(link, "lost carrier");
1646 r = link_stop_clients(link);
1648 link_enter_failed(link);
1656 static void link_update_operstate(Link *link) {
1660 if (link->kernel_operstate == IF_OPER_DORMANT)
1661 link->operstate = LINK_OPERSTATE_DORMANT;
1662 else if (link_has_carrier(link)) {
1664 uint8_t scope = RT_SCOPE_NOWHERE;
1666 /* if we have carrier, check what addresses we have */
1667 LIST_FOREACH(addresses, address, link->addresses) {
1668 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1671 if (address->scope < scope)
1672 scope = address->scope;
1675 if (scope < RT_SCOPE_SITE)
1676 /* universally accessible addresses found */
1677 link->operstate = LINK_OPERSTATE_ROUTABLE;
1678 else if (scope < RT_SCOPE_HOST)
1679 /* only link or site local addresses found */
1680 link->operstate = LINK_OPERSTATE_DEGRADED;
1682 /* no useful addresses found */
1683 link->operstate = LINK_OPERSTATE_CARRIER;
1684 } else if (link->flags & IFF_UP)
1685 link->operstate = LINK_OPERSTATE_NO_CARRIER;
1687 link->operstate = LINK_OPERSTATE_OFF;
1690 int link_save(Link *link) {
1691 _cleanup_free_ char *temp_path = NULL;
1692 _cleanup_fclose_ FILE *f = NULL;
1693 const char *admin_state, *oper_state;
1697 assert(link->state_file);
1698 assert(link->lease_file);
1699 assert(link->manager);
1701 link_update_operstate(link);
1703 r = manager_save(link->manager);
1707 if (link->state == LINK_STATE_LINGER) {
1708 unlink(link->state_file);
1712 admin_state = link_state_to_string(link->state);
1713 assert(admin_state);
1715 oper_state = link_operstate_to_string(link->operstate);
1718 r = fopen_temporary(link->state_file, &f, &temp_path);
1722 fchmod(fileno(f), 0644);
1725 "# This is private data. Do not parse.\n"
1728 admin_state, oper_state);
1730 if (link->network) {
1731 char **address, **domain;
1736 STRV_FOREACH(address, link->network->dns) {
1743 if (link->network->dhcp_dns &&
1745 const struct in_addr *addresses;
1747 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1751 serialize_in_addrs(f, addresses, r);
1759 STRV_FOREACH(address, link->network->ntp) {
1766 if (link->network->dhcp_ntp &&
1768 const struct in_addr *addresses;
1770 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1774 serialize_in_addrs(f, addresses, r);
1780 fprintf(f, "DOMAINS=");
1782 STRV_FOREACH(domain, link->network->domains) {
1789 if (link->network->dhcp_domains &&
1791 const char *domainname;
1793 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1797 fputs(domainname, f);
1803 fprintf(f, "WILDCARD_DOMAIN=%s\n",
1804 yes_no(link->network->wildcard_domain));
1806 fprintf(f, "LLMNR=%s\n",
1807 llmnr_support_to_string(link->network->llmnr));
1810 if (link->dhcp_lease) {
1811 assert(link->network);
1813 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
1821 unlink(link->lease_file);
1823 r = fflush_and_check(f);
1827 if (rename(temp_path, link->state_file) < 0) {
1834 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
1835 unlink(link->state_file);
1840 static const char* const link_state_table[_LINK_STATE_MAX] = {
1841 [LINK_STATE_PENDING] = "pending",
1842 [LINK_STATE_ENSLAVING] = "configuring",
1843 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1844 [LINK_STATE_SETTING_ROUTES] = "configuring",
1845 [LINK_STATE_CONFIGURED] = "configured",
1846 [LINK_STATE_UNMANAGED] = "unmanaged",
1847 [LINK_STATE_FAILED] = "failed",
1848 [LINK_STATE_LINGER] = "linger",
1851 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
1853 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
1854 [LINK_OPERSTATE_OFF] = "off",
1855 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
1856 [LINK_OPERSTATE_DORMANT] = "dormant",
1857 [LINK_OPERSTATE_CARRIER] = "carrier",
1858 [LINK_OPERSTATE_DEGRADED] = "degraded",
1859 [LINK_OPERSTATE_ROUTABLE] = "routable",
1862 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);