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 bool link_dhcp6_enabled(Link *link) {
39 if (link->flags & IFF_LOOPBACK)
45 return IN_SET(link->network->dhcp, DHCP_SUPPORT_V6, DHCP_SUPPORT_BOTH);
48 static bool link_dhcp4_enabled(Link *link) {
49 if (link->flags & IFF_LOOPBACK)
55 return IN_SET(link->network->dhcp, DHCP_SUPPORT_V4, DHCP_SUPPORT_BOTH);
58 static bool link_dhcp4_server_enabled(Link *link) {
59 if (link->flags & IFF_LOOPBACK)
65 return link->network->dhcp_server;
68 static bool link_ipv4ll_enabled(Link *link) {
69 if (link->flags & IFF_LOOPBACK)
75 return link->network->ipv4ll;
78 #define FLAG_STRING(string, flag, old, new) \
79 (((old ^ new) & flag) \
80 ? ((old & flag) ? (" -" string) : (" +" string)) \
83 static int link_update_flags(Link *link, sd_rtnl_message *m) {
84 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
90 r = sd_rtnl_message_link_get_flags(m, &flags);
92 log_link_warning(link, "Could not get link flags");
96 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
98 /* if we got a message without operstate, take it to mean
99 the state was unchanged */
100 operstate = link->kernel_operstate;
102 if ((link->flags == flags) && (link->kernel_operstate == operstate))
105 if (link->flags != flags) {
106 log_link_debug(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
107 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
108 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
109 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
110 FLAG_STRING("UP", IFF_UP, link->flags, flags),
111 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
112 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
113 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
114 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
115 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
116 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
117 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
118 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
119 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
120 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
121 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
122 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
123 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
124 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
125 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
127 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
128 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
129 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
130 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
131 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
132 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
133 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
134 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
136 /* link flags are currently at most 18 bits, let's align to
138 if (unknown_flags_added)
140 "unknown link flags gained: %#.5x (ignoring)",
141 unknown_flags_added);
143 if (unknown_flags_removed)
145 "unknown link flags lost: %#.5x (ignoring)",
146 unknown_flags_removed);
150 link->kernel_operstate = operstate;
157 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
158 _cleanup_link_unref_ Link *link = NULL;
167 r = sd_rtnl_message_get_type(message, &type);
170 else if (type != RTM_NEWLINK)
173 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
176 else if (ifindex <= 0)
179 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
183 link = new0(Link, 1);
188 link->manager = manager;
189 link->state = LINK_STATE_PENDING;
190 link->ifindex = ifindex;
191 link->ifname = strdup(ifname);
195 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
197 log_link_debug(link, "MAC address not found for new device, continuing without");
199 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
204 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
209 r = hashmap_ensure_allocated(&manager->links, NULL);
213 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
217 r = link_update_flags(link, message);
227 static void link_free(Link *link) {
233 while ((address = link->addresses)) {
234 LIST_REMOVE(addresses, link->addresses, address);
235 address_free(address);
238 while ((address = link->pool_addresses)) {
239 LIST_REMOVE(addresses, link->pool_addresses, address);
240 address_free(address);
243 sd_dhcp_client_unref(link->dhcp_client);
244 sd_dhcp_lease_unref(link->dhcp_lease);
246 unlink(link->lease_file);
247 free(link->lease_file);
249 sd_ipv4ll_unref(link->ipv4ll);
250 sd_dhcp6_client_unref(link->dhcp6_client);
251 sd_icmp6_nd_unref(link->icmp6_router_discovery);
254 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
258 unlink(link->state_file);
259 free(link->state_file);
261 udev_device_unref(link->udev_device);
266 Link *link_unref(Link *link) {
267 if (link && (-- link->n_ref <= 0))
273 Link *link_ref(Link *link) {
275 assert_se(++ link->n_ref >= 2);
280 int link_get(Manager *m, int ifindex, Link **ret) {
287 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
296 void link_drop(Link *link) {
297 if (!link || link->state == LINK_STATE_LINGER)
300 link->state = LINK_STATE_LINGER;
302 log_link_debug(link, "link removed");
309 static void link_enter_unmanaged(Link *link) {
312 log_link_debug(link, "unmanaged");
314 link->state = LINK_STATE_UNMANAGED;
319 static int link_stop_clients(Link *link) {
323 assert(link->manager);
324 assert(link->manager->event);
329 if (link->dhcp_client) {
330 k = sd_dhcp_client_stop(link->dhcp_client);
332 log_link_warning(link, "Could not stop DHCPv4 client: %s",
339 k = sd_ipv4ll_stop(link->ipv4ll);
341 log_link_warning(link, "Could not stop IPv4 link-local: %s",
347 if(link->icmp6_router_discovery) {
349 if (link->dhcp6_client) {
350 k = sd_dhcp6_client_stop(link->dhcp6_client);
352 log_link_warning(link, "Could not stop DHCPv6 client: %s",
358 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
360 log_link_warning(link,
361 "Could not stop ICMPv6 router discovery: %s",
370 void link_enter_failed(Link *link) {
373 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
376 log_link_warning(link, "failed");
378 link->state = LINK_STATE_FAILED;
380 link_stop_clients(link);
385 static Address* link_find_dhcp_server_address(Link *link) {
389 assert(link->network);
391 /* The the first statically configured address if there is any */
392 LIST_FOREACH(addresses, address, link->network->static_addresses) {
394 if (address->family != AF_INET)
397 if (in_addr_is_null(address->family, &address->in_addr))
403 /* If that didn't work, find a suitable address we got from the pool */
404 LIST_FOREACH(addresses, address, link->pool_addresses) {
405 if (address->family != AF_INET)
414 static int link_enter_configured(Link *link) {
418 assert(link->network);
419 assert(link->state == LINK_STATE_SETTING_ROUTES);
421 if (link_dhcp4_server_enabled(link) &&
422 !sd_dhcp_server_is_running(link->dhcp_server)) {
423 struct in_addr pool_start;
426 address = link_find_dhcp_server_address(link);
428 log_link_warning(link,
429 "Failed to find suitable address for DHCPv4 server instance.");
430 link_enter_failed(link);
434 log_link_debug(link, "offering DHCPv4 leases");
436 r = sd_dhcp_server_set_address(link->dhcp_server,
437 &address->in_addr.in,
442 /* offer 32 addresses starting from the address following the server address */
443 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
444 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
450 r = sd_dhcp_server_set_router(link->dhcp_server,
451 &main_address->in_addr.in);
455 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
456 main_address->prefixlen);
461 r = sd_dhcp_server_start(link->dhcp_server);
463 log_link_warning(link, "could not start DHCPv4 server "
464 "instance: %s", strerror(-r));
466 link_enter_failed(link);
472 log_link_info(link, "link configured");
474 link->state = LINK_STATE_CONFIGURED;
481 void link_client_handler(Link *link) {
483 assert(link->network);
485 if (!link->static_configured)
488 if (link_ipv4ll_enabled(link))
489 if (!link->ipv4ll_address ||
493 if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
496 if (link->state != LINK_STATE_CONFIGURED)
497 link_enter_configured(link);
502 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
503 _cleanup_link_unref_ Link *link = userdata;
506 assert(link->link_messages > 0);
507 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
508 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
511 link->link_messages --;
513 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
516 r = sd_rtnl_message_get_errno(m);
517 if (r < 0 && r != -EEXIST)
518 log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
520 if (link->link_messages == 0) {
521 log_link_debug(link, "routes set");
522 link->static_configured = true;
523 link_client_handler(link);
529 static int link_enter_set_routes(Link *link) {
534 assert(link->network);
535 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
537 link->state = LINK_STATE_SETTING_ROUTES;
539 LIST_FOREACH(routes, rt, link->network->static_routes) {
540 r = route_configure(rt, link, &route_handler);
542 log_link_warning(link,
543 "could not set routes: %s",
545 link_enter_failed(link);
549 link->link_messages ++;
552 if (link->link_messages == 0) {
553 link->static_configured = true;
554 link_client_handler(link);
556 log_link_debug(link, "setting routes");
561 int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
562 _cleanup_link_unref_ Link *link = userdata;
567 assert(link->ifname);
569 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
572 r = sd_rtnl_message_get_errno(m);
573 if (r < 0 && r != -ESRCH)
574 log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
579 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
580 _cleanup_link_unref_ Link *link = userdata;
586 assert(link->ifname);
587 assert(link->link_messages > 0);
588 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
589 LINK_STATE_FAILED, LINK_STATE_LINGER));
591 link->link_messages --;
593 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
596 r = sd_rtnl_message_get_errno(m);
597 if (r < 0 && r != -EEXIST)
598 log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
600 link_rtnl_process_address(rtnl, m, link->manager);
602 if (link->link_messages == 0) {
603 log_link_debug(link, "addresses set");
604 link_enter_set_routes(link);
610 static int link_enter_set_addresses(Link *link) {
615 assert(link->network);
616 assert(link->state != _LINK_STATE_INVALID);
618 link->state = LINK_STATE_SETTING_ADDRESSES;
620 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
621 r = address_configure(ad, link, &address_handler);
623 log_link_warning(link,
624 "could not set addresses: %s",
626 link_enter_failed(link);
630 link->link_messages ++;
633 if (link->link_messages == 0) {
634 link_enter_set_routes(link);
636 log_link_debug(link, "setting addresses");
641 int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
642 _cleanup_link_unref_ Link *link = userdata;
647 assert(link->ifname);
649 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
652 r = sd_rtnl_message_get_errno(m);
653 if (r < 0 && r != -EADDRNOTAVAIL)
654 log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
659 static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
660 _cleanup_link_unref_ Link *link = userdata;
663 log_link_debug(link, "set link");
665 r = sd_rtnl_message_get_errno(m);
666 if (r < 0 && r != -EEXIST) {
667 log_link_struct(link, LOG_ERR,
668 "MESSAGE=%-*s: could not join netdev: %s",
670 link->ifname, strerror(-r),
673 link_enter_failed(link);
680 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
681 sd_bus_error *ret_error) {
682 _cleanup_link_unref_ Link *link = userdata;
687 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
690 r = sd_bus_message_get_errno(m);
692 log_link_warning(link, "Could not set hostname: %s",
698 int link_set_hostname(Link *link, const char *hostname) {
699 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
703 assert(link->manager);
706 log_link_debug(link, "Setting transient hostname: '%s'", hostname);
708 if (!link->manager->bus) {
709 /* TODO: replace by assert when we can rely on kdbus */
711 "Not connected to system bus, ignoring transient hostname.");
715 r = sd_bus_message_new_method_call(
718 "org.freedesktop.hostname1",
719 "/org/freedesktop/hostname1",
720 "org.freedesktop.hostname1",
725 r = sd_bus_message_append(m, "sb", hostname, false);
729 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
732 log_link_error(link, "Could not set transient hostname: %s",
742 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
743 _cleanup_link_unref_ Link *link = userdata;
748 assert(link->ifname);
750 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
753 r = sd_rtnl_message_get_errno(m);
755 log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
760 int link_set_mtu(Link *link, uint32_t mtu) {
761 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
765 assert(link->manager);
766 assert(link->manager->rtnl);
768 log_link_debug(link, "setting MTU: %" PRIu32, mtu);
770 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
771 RTM_SETLINK, link->ifindex);
773 log_link_error(link, "Could not allocate RTM_SETLINK message");
777 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
779 log_link_error(link, "Could not append MTU: %s", strerror(-r));
783 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
787 "Could not send rtnetlink message: %s",
797 static int link_set_bridge(Link *link) {
798 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
802 assert(link->network);
804 if(link->network->cost == 0)
807 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
808 RTM_SETLINK, link->ifindex);
810 log_link_error(link, "Could not allocate RTM_SETLINK message");
814 r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
817 "Could not set message family %s", strerror(-r));
821 r = sd_rtnl_message_open_container(req, IFLA_PROTINFO);
824 "Could not append IFLA_PROTINFO attribute: %s",
829 if(link->network->cost != 0) {
830 r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
833 "Could not append IFLA_BRPORT_COST attribute: %s",
839 r = sd_rtnl_message_close_container(req);
842 "Could not append IFLA_LINKINFO attribute: %s",
847 r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
850 "Could not send rtnetlink message: %s",
860 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
861 Link *link = userdata;
864 assert(link->network);
865 assert(link->manager);
867 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
871 case DHCP6_EVENT_STOP:
872 case DHCP6_EVENT_RESEND_EXPIRE:
873 case DHCP6_EVENT_RETRANS_MAX:
874 case DHCP6_EVENT_IP_ACQUIRE:
875 log_link_debug(link, "DHCPv6 event %d", event);
881 log_link_warning(link, "DHCPv6 error: %s",
884 log_link_warning(link, "DHCPv6 unknown event: %d",
890 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
891 Link *link = userdata;
895 assert(link->network);
896 assert(link->manager);
898 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
902 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
903 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
906 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
907 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
912 log_link_warning(link, "ICMPv6 error: %s",
915 log_link_warning(link, "ICMPv6 unknown event: %d",
921 if (link->dhcp6_client)
924 r = sd_dhcp6_client_new(&link->dhcp6_client);
928 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
930 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
934 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
935 (const uint8_t *) &link->mac,
936 sizeof (link->mac), ARPHRD_ETHER);
938 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
942 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
944 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
948 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
951 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
955 r = sd_dhcp6_client_start(link->dhcp6_client);
957 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
960 static int link_acquire_conf(Link *link) {
964 assert(link->network);
965 assert(link->manager);
966 assert(link->manager->event);
968 if (link_ipv4ll_enabled(link)) {
969 assert(link->ipv4ll);
971 log_link_debug(link, "acquiring IPv4 link-local address");
973 r = sd_ipv4ll_start(link->ipv4ll);
975 log_link_warning(link, "could not acquire IPv4 "
976 "link-local address");
981 if (link_dhcp4_enabled(link)) {
982 assert(link->dhcp_client);
984 log_link_debug(link, "acquiring DHCPv4 lease");
986 r = sd_dhcp_client_start(link->dhcp_client);
988 log_link_warning(link, "could not acquire DHCPv4 "
994 if (link_dhcp6_enabled(link)) {
995 assert(link->icmp6_router_discovery);
997 log_link_debug(link, "discovering IPv6 routers");
999 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1001 log_link_warning(link,
1002 "could not start IPv6 router discovery");
1010 bool link_has_carrier(Link *link) {
1011 /* see Documentation/networking/operstates.txt in the kernel sources */
1013 if (link->kernel_operstate == IF_OPER_UP)
1016 if (link->kernel_operstate == IF_OPER_UNKNOWN)
1017 /* operstate may not be implemented, so fall back to flags */
1018 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
1024 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1025 _cleanup_link_unref_ Link *link = userdata;
1030 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1033 r = sd_rtnl_message_get_errno(m);
1035 /* we warn but don't fail the link, as it may
1036 be brought up later */
1037 log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
1043 static int link_up(Link *link) {
1044 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1048 assert(link->network);
1049 assert(link->manager);
1050 assert(link->manager->rtnl);
1052 log_link_debug(link, "bringing link up");
1054 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1055 RTM_SETLINK, link->ifindex);
1057 log_link_error(link, "Could not allocate RTM_SETLINK message");
1061 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1063 log_link_error(link, "Could not set link flags: %s",
1068 if (link->network->mac) {
1069 r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
1071 log_link_error(link, "Could not set MAC address: %s", strerror(-r));
1076 if (link->network->mtu) {
1077 r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu);
1079 log_link_error(link, "Could not set MTU: %s", strerror(-r));
1084 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1087 log_link_error(link,
1088 "Could not send rtnetlink message: %s",
1098 static int link_joined(Link *link) {
1102 assert(link->network);
1104 if (!(link->flags & IFF_UP)) {
1107 link_enter_failed(link);
1112 if(link->network->bridge) {
1113 r = link_set_bridge(link);
1115 log_link_error(link,
1116 "Could not set bridge message: %s",
1121 return link_enter_set_addresses(link);
1124 static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1126 _cleanup_link_unref_ Link *link = userdata;
1130 assert(link->network);
1134 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1137 r = sd_rtnl_message_get_errno(m);
1138 if (r < 0 && r != -EEXIST) {
1139 log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
1140 link_enter_failed(link);
1143 log_link_debug(link, "joined netdev");
1145 if (link->enslaving <= 0)
1151 static int link_enter_join_netdev(Link *link) {
1157 assert(link->network);
1158 assert(link->state == LINK_STATE_PENDING);
1160 link->state = LINK_STATE_ENSLAVING;
1164 if (!link->network->bridge &&
1165 !link->network->bond &&
1166 hashmap_isempty(link->network->stacked_netdevs))
1167 return link_joined(link);
1169 if (link->network->bond) {
1170 log_link_struct(link, LOG_DEBUG,
1171 "MESSAGE=%-*s: enslaving by '%s'",
1173 link->ifname, link->network->bond->ifname,
1174 NETDEVIF(link->network->bond),
1177 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1179 log_link_struct(link, LOG_WARNING,
1180 "MESSAGE=%-*s: could not join netdev '%s': %s",
1182 link->ifname, link->network->bond->ifname,
1184 NETDEVIF(link->network->bond),
1186 link_enter_failed(link);
1193 if (link->network->bridge) {
1194 log_link_struct(link, LOG_DEBUG,
1195 "MESSAGE=%-*s: enslaving by '%s'",
1197 link->ifname, link->network->bridge->ifname,
1198 NETDEVIF(link->network->bridge),
1201 r = netdev_join(link->network->bridge, link,
1202 &netdev_join_handler);
1204 log_link_struct(link, LOG_WARNING,
1205 "MESSAGE=%-*s: could not join netdev '%s': %s",
1207 link->ifname, link->network->bridge->ifname,
1209 NETDEVIF(link->network->bridge),
1211 link_enter_failed(link);
1218 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1219 log_link_struct(link, LOG_DEBUG,
1220 "MESSAGE=%-*s: enslaving by '%s'",
1222 link->ifname, netdev->ifname, NETDEVIF(netdev),
1225 r = netdev_join(netdev, link, &netdev_join_handler);
1227 log_link_struct(link, LOG_WARNING,
1228 "MESSAGE=%-*s: could not join netdev '%s': %s",
1230 link->ifname, netdev->ifname,
1232 NETDEVIF(netdev), NULL);
1233 link_enter_failed(link);
1243 static int link_configure(Link *link) {
1247 assert(link->network);
1248 assert(link->state == LINK_STATE_PENDING);
1250 if (link_ipv4ll_enabled(link)) {
1251 r = ipv4ll_configure(link);
1256 if (link_dhcp4_enabled(link)) {
1257 r = dhcp4_configure(link);
1262 if (link_dhcp4_server_enabled(link)) {
1263 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1267 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1272 if (link_dhcp6_enabled(link)) {
1273 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1277 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1282 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1287 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1292 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1293 icmp6_router_handler, link);
1298 if (link_has_carrier(link)) {
1299 r = link_acquire_conf(link);
1304 return link_enter_join_netdev(link);
1307 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1309 _cleanup_link_unref_ Link *link = userdata;
1314 assert(link->ifname);
1315 assert(link->manager);
1317 if (link->state != LINK_STATE_PENDING)
1320 log_link_debug(link, "link state is up-to-date");
1322 r = network_get(link->manager, link->udev_device, link->ifname,
1323 &link->mac, &network);
1325 link_enter_unmanaged(link);
1330 if (link->flags & IFF_LOOPBACK) {
1331 if (network->ipv4ll)
1332 log_link_debug(link, "ignoring IPv4LL for loopback link");
1334 if (network->dhcp != DHCP_SUPPORT_NONE)
1335 log_link_debug(link, "ignoring DHCP clients for loopback link");
1337 if (network->dhcp_server)
1338 log_link_debug(link, "ignoring DHCP server for loopback link");
1341 r = network_apply(link->manager, network, link);
1345 r = link_configure(link);
1352 int link_initialized(Link *link, struct udev_device *device) {
1353 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1357 assert(link->manager);
1358 assert(link->manager->rtnl);
1361 if (link->state != LINK_STATE_PENDING)
1364 if (link->udev_device)
1367 log_link_debug(link, "udev initialized link");
1369 link->udev_device = udev_device_ref(device);
1371 /* udev has initialized the link, but we don't know if we have yet
1372 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1373 * when it returns we know that the pending NEWLINKs have already been
1374 * processed and that we are up-to-date */
1376 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1381 r = sd_rtnl_call_async(link->manager->rtnl, req,
1382 link_initialized_and_synced, link, 0, NULL);
1391 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1392 Manager *m = userdata;
1395 _cleanup_address_free_ Address *address = NULL;
1397 char buf[INET6_ADDRSTRLEN];
1398 char valid_buf[FORMAT_TIMESPAN_MAX];
1399 const char *valid_str = NULL;
1400 bool address_dropped = false;
1407 if (sd_rtnl_message_is_error(message)) {
1408 r = sd_rtnl_message_get_errno(message);
1410 log_warning_errno(r, "rtnl: failed to receive address: %m");
1415 r = sd_rtnl_message_get_type(message, &type);
1417 log_warning("rtnl: could not get message type");
1421 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1423 log_warning_errno(r, "rtnl: could not get ifindex: %m");
1425 } else if (ifindex <= 0) {
1426 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
1429 r = link_get(m, ifindex, &link);
1430 if (r < 0 || !link) {
1431 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
1436 r = address_new_dynamic(&address);
1440 r = sd_rtnl_message_addr_get_family(message, &address->family);
1441 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1442 log_link_warning(link,
1443 "rtnl: received address with invalid family, ignoring");
1447 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1449 log_link_warning(link,
1450 "rtnl: received address with invalid prefixlen, ignoring");
1454 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1456 log_link_warning(link,
1457 "rtnl: received address with invalid scope, ignoring");
1461 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1463 log_link_warning(link,
1464 "rtnl: received address with invalid flags, ignoring");
1468 switch (address->family) {
1470 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
1471 &address->in_addr.in);
1473 log_link_warning(link,
1474 "rtnl: received address without valid address, ignoring");
1481 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
1482 &address->in_addr.in6);
1484 log_link_warning(link,
1485 "rtnl: received address without valid address, ignoring");
1492 assert_not_reached("invalid address family");
1495 if (!inet_ntop(address->family, &address->in_addr, buf,
1496 INET6_ADDRSTRLEN)) {
1497 log_link_warning(link, "could not print address");
1501 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO,
1504 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1507 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1508 address->cinfo.ifa_valid * USEC_PER_SEC,
1512 LIST_FOREACH(addresses, ad, link->addresses) {
1513 if (address_equal(ad, address)) {
1514 LIST_REMOVE(addresses, link->addresses, ad);
1518 address_dropped = true;
1526 if (!address_dropped)
1527 log_link_debug(link, "added address: %s/%u (valid for %s)",
1528 buf, address->prefixlen, valid_str);
1530 log_link_debug(link, "updated address: %s/%u (valid for %s)",
1531 buf, address->prefixlen, valid_str);
1533 LIST_PREPEND(addresses, link->addresses, address);
1540 if (address_dropped) {
1541 log_link_debug(link, "removed address: %s/%u (valid for %s)",
1542 buf, address->prefixlen, valid_str);
1546 log_link_warning(link,
1547 "removing non-existent address: %s/%u (valid for %s)",
1548 buf, address->prefixlen, valid_str);
1552 assert_not_reached("Received invalid RTNL message type");
1558 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1560 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1561 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1562 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1570 r = link_new(m, message, ret);
1576 log_link_debug(link, "link %d added", link->ifindex);
1578 if (detect_container(NULL) <= 0) {
1579 /* not in a container, udev will be around */
1580 sprintf(ifindex_str, "n%d", link->ifindex);
1581 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1583 log_link_warning(link,
1584 "could not find udev device: %m");
1588 if (udev_device_get_is_initialized(device) <= 0) {
1590 log_link_debug(link, "link pending udev initialization...");
1594 r = link_initialized(link, device);
1598 /* we are calling a callback directly, so must take a ref */
1601 r = link_initialized_and_synced(m->rtnl, NULL, link);
1609 int link_update(Link *link, sd_rtnl_message *m) {
1610 struct ether_addr mac;
1613 bool had_carrier, carrier_gained, carrier_lost;
1617 assert(link->ifname);
1620 if (link->state == LINK_STATE_LINGER) {
1622 log_link_info(link, "link readded");
1623 link->state = LINK_STATE_ENSLAVING;
1626 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1627 if (r >= 0 && !streq(ifname, link->ifname)) {
1628 log_link_info(link, "renamed to %s", ifname);
1631 link->ifname = strdup(ifname);
1636 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1637 if (r >= 0 && mtu > 0) {
1639 if (!link->original_mtu) {
1640 link->original_mtu = mtu;
1641 log_link_debug(link, "saved original MTU: %"
1642 PRIu32, link->original_mtu);
1645 if (link->dhcp_client) {
1646 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1649 log_link_warning(link,
1650 "Could not update MTU in DHCP client: %s",
1657 /* The kernel may broadcast NEWLINK messages without the MAC address
1658 set, simply ignore them. */
1659 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1661 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1664 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1667 log_link_debug(link, "MAC address: "
1668 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1669 mac.ether_addr_octet[0],
1670 mac.ether_addr_octet[1],
1671 mac.ether_addr_octet[2],
1672 mac.ether_addr_octet[3],
1673 mac.ether_addr_octet[4],
1674 mac.ether_addr_octet[5]);
1677 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1679 log_link_warning(link,
1680 "Could not update MAC address in IPv4LL client: %s",
1686 if (link->dhcp_client) {
1687 r = sd_dhcp_client_set_mac(link->dhcp_client,
1688 (const uint8_t *) &link->mac,
1692 log_link_warning(link,
1693 "Could not update MAC address in DHCP client: %s",
1699 if (link->dhcp6_client) {
1700 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
1701 (const uint8_t *) &link->mac,
1705 log_link_warning(link,
1706 "Could not update MAC address in DHCPv6 client: %s",
1714 had_carrier = link_has_carrier(link);
1716 r = link_update_flags(link, m);
1720 carrier_gained = !had_carrier && link_has_carrier(link);
1721 carrier_lost = had_carrier && !link_has_carrier(link);
1723 if (carrier_gained) {
1724 log_link_info(link, "gained carrier");
1726 if (link->network) {
1727 r = link_acquire_conf(link);
1729 link_enter_failed(link);
1733 } else if (carrier_lost) {
1734 log_link_info(link, "lost carrier");
1736 r = link_stop_clients(link);
1738 link_enter_failed(link);
1746 static void link_update_operstate(Link *link) {
1750 if (link->kernel_operstate == IF_OPER_DORMANT)
1751 link->operstate = LINK_OPERSTATE_DORMANT;
1752 else if (link_has_carrier(link)) {
1754 uint8_t scope = RT_SCOPE_NOWHERE;
1756 /* if we have carrier, check what addresses we have */
1757 LIST_FOREACH(addresses, address, link->addresses) {
1758 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1761 if (address->scope < scope)
1762 scope = address->scope;
1765 if (scope < RT_SCOPE_SITE)
1766 /* universally accessible addresses found */
1767 link->operstate = LINK_OPERSTATE_ROUTABLE;
1768 else if (scope < RT_SCOPE_HOST)
1769 /* only link or site local addresses found */
1770 link->operstate = LINK_OPERSTATE_DEGRADED;
1772 /* no useful addresses found */
1773 link->operstate = LINK_OPERSTATE_CARRIER;
1774 } else if (link->flags & IFF_UP)
1775 link->operstate = LINK_OPERSTATE_NO_CARRIER;
1777 link->operstate = LINK_OPERSTATE_OFF;
1780 int link_save(Link *link) {
1781 _cleanup_free_ char *temp_path = NULL;
1782 _cleanup_fclose_ FILE *f = NULL;
1783 const char *admin_state, *oper_state;
1787 assert(link->state_file);
1788 assert(link->lease_file);
1789 assert(link->manager);
1791 link_update_operstate(link);
1793 r = manager_save(link->manager);
1797 if (link->state == LINK_STATE_LINGER) {
1798 unlink(link->state_file);
1802 admin_state = link_state_to_string(link->state);
1803 assert(admin_state);
1805 oper_state = link_operstate_to_string(link->operstate);
1808 r = fopen_temporary(link->state_file, &f, &temp_path);
1812 fchmod(fileno(f), 0644);
1815 "# This is private data. Do not parse.\n"
1818 admin_state, oper_state);
1820 if (link->network) {
1821 char **address, **domain;
1824 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
1828 STRV_FOREACH(address, link->network->dns) {
1835 if (link->network->dhcp_dns &&
1837 const struct in_addr *addresses;
1839 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1843 serialize_in_addrs(f, addresses, r);
1851 STRV_FOREACH(address, link->network->ntp) {
1858 if (link->network->dhcp_ntp &&
1860 const struct in_addr *addresses;
1862 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1866 serialize_in_addrs(f, addresses, r);
1872 fprintf(f, "DOMAINS=");
1874 STRV_FOREACH(domain, link->network->domains) {
1881 if (link->network->dhcp_domains &&
1883 const char *domainname;
1885 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1889 fputs(domainname, f);
1895 fprintf(f, "WILDCARD_DOMAIN=%s\n",
1896 yes_no(link->network->wildcard_domain));
1898 fprintf(f, "LLMNR=%s\n",
1899 llmnr_support_to_string(link->network->llmnr));
1902 if (link->dhcp_lease) {
1903 assert(link->network);
1905 r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
1913 unlink(link->lease_file);
1915 r = fflush_and_check(f);
1919 if (rename(temp_path, link->state_file) < 0) {
1926 log_link_error(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
1927 unlink(link->state_file);
1932 static const char* const link_state_table[_LINK_STATE_MAX] = {
1933 [LINK_STATE_PENDING] = "pending",
1934 [LINK_STATE_ENSLAVING] = "configuring",
1935 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1936 [LINK_STATE_SETTING_ROUTES] = "configuring",
1937 [LINK_STATE_CONFIGURED] = "configured",
1938 [LINK_STATE_UNMANAGED] = "unmanaged",
1939 [LINK_STATE_FAILED] = "failed",
1940 [LINK_STATE_LINGER] = "linger",
1943 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
1945 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
1946 [LINK_OPERSTATE_OFF] = "off",
1947 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
1948 [LINK_OPERSTATE_DORMANT] = "dormant",
1949 [LINK_OPERSTATE_CARRIER] = "carrier",
1950 [LINK_OPERSTATE_DEGRADED] = "degraded",
1951 [LINK_OPERSTATE_ROUTABLE] = "routable",
1954 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);