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>
30 #include "udev-util.h"
31 #include "network-internal.h"
32 #include "networkd-link.h"
33 #include "networkd-netdev.h"
35 bool link_dhcp6_enabled(Link *link) {
36 if (link->flags & IFF_LOOPBACK)
42 return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
45 bool link_dhcp4_enabled(Link *link) {
46 if (link->flags & IFF_LOOPBACK)
52 return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
55 bool link_dhcp4_server_enabled(Link *link) {
56 if (link->flags & IFF_LOOPBACK)
62 return link->network->dhcp_server;
65 bool link_ipv4ll_enabled(Link *link) {
66 if (link->flags & IFF_LOOPBACK)
72 return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
75 bool link_ipv6ll_enabled(Link *link) {
76 if (link->flags & IFF_LOOPBACK)
82 return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
85 bool link_lldp_enabled(Link *link) {
86 if (link->flags & IFF_LOOPBACK)
92 if (link->network->bridge)
95 return link->network->lldp;
98 static bool link_ipv4_forward_enabled(Link *link) {
99 if (link->flags & IFF_LOOPBACK)
105 return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
108 static bool link_ipv6_forward_enabled(Link *link) {
109 if (link->flags & IFF_LOOPBACK)
115 return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
118 #define FLAG_STRING(string, flag, old, new) \
119 (((old ^ new) & flag) \
120 ? ((old & flag) ? (" -" string) : (" +" string)) \
123 static int link_update_flags(Link *link, sd_rtnl_message *m) {
124 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
130 r = sd_rtnl_message_link_get_flags(m, &flags);
132 log_link_warning(link, "Could not get link flags");
136 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
138 /* if we got a message without operstate, take it to mean
139 the state was unchanged */
140 operstate = link->kernel_operstate;
142 if ((link->flags == flags) && (link->kernel_operstate == operstate))
145 if (link->flags != flags) {
146 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",
147 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
148 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
149 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
150 FLAG_STRING("UP", IFF_UP, link->flags, flags),
151 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
152 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
153 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
154 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
155 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
156 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
157 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
158 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
159 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
160 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
161 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
162 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
163 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
164 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
165 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
167 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
168 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
169 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
170 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
171 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
172 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
173 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
174 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
176 /* link flags are currently at most 18 bits, let's align to
178 if (unknown_flags_added)
180 "unknown link flags gained: %#.5x (ignoring)",
181 unknown_flags_added);
183 if (unknown_flags_removed)
185 "unknown link flags lost: %#.5x (ignoring)",
186 unknown_flags_removed);
190 link->kernel_operstate = operstate;
197 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
198 _cleanup_link_unref_ Link *link = NULL;
207 r = sd_rtnl_message_get_type(message, &type);
210 else if (type != RTM_NEWLINK)
213 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
216 else if (ifindex <= 0)
219 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
223 link = new0(Link, 1);
228 link->manager = manager;
229 link->state = LINK_STATE_PENDING;
230 link->ifindex = ifindex;
231 link->ifname = strdup(ifname);
235 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
237 log_link_debug(link, "MAC address not found for new device, continuing without");
239 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
244 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
249 r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d",
255 r = hashmap_ensure_allocated(&manager->links, NULL);
259 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
263 r = link_update_flags(link, message);
273 static void link_free(Link *link) {
281 while ((address = link->addresses)) {
282 LIST_REMOVE(addresses, link->addresses, address);
283 address_free(address);
286 while ((address = link->pool_addresses)) {
287 LIST_REMOVE(addresses, link->pool_addresses, address);
288 address_free(address);
291 sd_dhcp_server_unref(link->dhcp_server);
292 sd_dhcp_client_unref(link->dhcp_client);
293 sd_dhcp_lease_unref(link->dhcp_lease);
295 free(link->lease_file);
297 sd_lldp_free(link->lldp);
299 free(link->lldp_file);
301 sd_ipv4ll_unref(link->ipv4ll);
302 sd_dhcp6_client_unref(link->dhcp6_client);
303 sd_icmp6_nd_unref(link->icmp6_router_discovery);
306 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
310 free(link->state_file);
312 udev_device_unref(link->udev_device);
314 HASHMAP_FOREACH (carrier, link->bound_to_links, i)
315 hashmap_remove(link->bound_to_links, INT_TO_PTR(carrier->ifindex));
316 hashmap_free(link->bound_to_links);
318 HASHMAP_FOREACH (carrier, link->bound_by_links, i)
319 hashmap_remove(link->bound_by_links, INT_TO_PTR(carrier->ifindex));
320 hashmap_free(link->bound_by_links);
325 Link *link_unref(Link *link) {
326 if (link && (-- link->n_ref <= 0))
332 Link *link_ref(Link *link) {
334 assert_se(++ link->n_ref >= 2);
339 int link_get(Manager *m, int ifindex, Link **ret) {
346 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
355 static void link_set_state(Link *link, LinkState state) {
358 if (link->state == state)
363 link_send_changed(link, "AdministrativeState", NULL);
368 static void link_enter_unmanaged(Link *link) {
371 log_link_debug(link, "unmanaged");
373 link_set_state(link, LINK_STATE_UNMANAGED);
378 static int link_stop_clients(Link *link) {
382 assert(link->manager);
383 assert(link->manager->event);
388 if (link->dhcp_client) {
389 k = sd_dhcp_client_stop(link->dhcp_client);
391 log_link_warning(link, "Could not stop DHCPv4 client: %s",
398 k = sd_ipv4ll_stop(link->ipv4ll);
400 log_link_warning(link, "Could not stop IPv4 link-local: %s",
406 if(link->icmp6_router_discovery) {
408 if (link->dhcp6_client) {
409 k = sd_dhcp6_client_stop(link->dhcp6_client);
411 log_link_warning(link, "Could not stop DHCPv6 client: %s",
417 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
419 log_link_warning(link,
420 "Could not stop ICMPv6 router discovery: %s",
428 k = sd_lldp_stop(link->lldp);
430 log_link_warning(link, "Could not stop LLDP : %s",
439 void link_enter_failed(Link *link) {
442 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
445 log_link_warning(link, "failed");
447 link_set_state(link, LINK_STATE_FAILED);
449 link_stop_clients(link);
454 static Address* link_find_dhcp_server_address(Link *link) {
458 assert(link->network);
460 /* The first statically configured address if there is any */
461 LIST_FOREACH(addresses, address, link->network->static_addresses) {
463 if (address->family != AF_INET)
466 if (in_addr_is_null(address->family, &address->in_addr))
472 /* If that didn't work, find a suitable address we got from the pool */
473 LIST_FOREACH(addresses, address, link->pool_addresses) {
474 if (address->family != AF_INET)
483 static int link_enter_configured(Link *link) {
485 assert(link->network);
486 assert(link->state == LINK_STATE_SETTING_ROUTES);
488 log_link_info(link, "link configured");
490 link_set_state(link, LINK_STATE_CONFIGURED);
497 void link_client_handler(Link *link) {
499 assert(link->network);
501 if (!link->static_configured)
504 if (link_ipv4ll_enabled(link))
505 if (!link->ipv4ll_address ||
509 if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
512 if (link->state != LINK_STATE_CONFIGURED)
513 link_enter_configured(link);
518 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
519 _cleanup_link_unref_ Link *link = userdata;
522 assert(link->link_messages > 0);
523 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
524 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
527 link->link_messages --;
529 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
532 r = sd_rtnl_message_get_errno(m);
533 if (r < 0 && r != -EEXIST)
534 log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
536 if (link->link_messages == 0) {
537 log_link_debug(link, "routes set");
538 link->static_configured = true;
539 link_client_handler(link);
545 static int link_enter_set_routes(Link *link) {
550 assert(link->network);
551 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
553 link_set_state(link, LINK_STATE_SETTING_ROUTES);
555 LIST_FOREACH(routes, rt, link->network->static_routes) {
556 r = route_configure(rt, link, &route_handler);
558 log_link_warning(link,
559 "could not set routes: %s",
561 link_enter_failed(link);
565 link->link_messages ++;
568 if (link->link_messages == 0) {
569 link->static_configured = true;
570 link_client_handler(link);
572 log_link_debug(link, "setting routes");
577 int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
578 _cleanup_link_unref_ Link *link = userdata;
583 assert(link->ifname);
585 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
588 r = sd_rtnl_message_get_errno(m);
589 if (r < 0 && r != -ESRCH)
590 log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
595 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
596 _cleanup_link_unref_ Link *link = userdata;
602 assert(link->ifname);
603 assert(link->link_messages > 0);
604 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
605 LINK_STATE_FAILED, LINK_STATE_LINGER));
607 link->link_messages --;
609 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
612 r = sd_rtnl_message_get_errno(m);
613 if (r < 0 && r != -EEXIST)
614 log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
616 link_rtnl_process_address(rtnl, m, link->manager);
618 if (link->link_messages == 0) {
619 log_link_debug(link, "addresses set");
620 link_enter_set_routes(link);
626 static int link_enter_set_addresses(Link *link) {
631 assert(link->network);
632 assert(link->state != _LINK_STATE_INVALID);
634 link_set_state(link, LINK_STATE_SETTING_ADDRESSES);
636 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
637 r = address_configure(ad, link, &address_handler);
639 log_link_warning_errno(link, r, "Could not set addresses: %m");
640 link_enter_failed(link);
644 link->link_messages ++;
647 /* now that we can figure out a default address for the dhcp server,
649 if (link_dhcp4_server_enabled(link)) {
650 struct in_addr pool_start;
653 address = link_find_dhcp_server_address(link);
655 log_link_warning(link,
656 "Failed to find suitable address for DHCPv4 server instance.");
657 link_enter_failed(link);
661 r = sd_dhcp_server_set_address(link->dhcp_server,
662 &address->in_addr.in,
667 /* offer 32 addresses starting from the address following the server address */
668 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
669 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
675 r = sd_dhcp_server_set_router(link->dhcp_server,
676 &main_address->in_addr.in);
680 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
681 main_address->prefixlen);
686 r = sd_dhcp_server_start(link->dhcp_server);
688 log_link_warning(link, "could not start DHCPv4 server "
689 "instance: %s", strerror(-r));
691 link_enter_failed(link);
696 log_link_debug(link, "offering DHCPv4 leases");
699 if (link->link_messages == 0) {
700 link_enter_set_routes(link);
702 log_link_debug(link, "setting addresses");
707 int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
708 _cleanup_link_unref_ Link *link = userdata;
713 assert(link->ifname);
715 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
718 r = sd_rtnl_message_get_errno(m);
719 if (r < 0 && r != -EADDRNOTAVAIL)
720 log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
725 static int link_set_bridge_fdb(Link *const link) {
729 LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
730 r = fdb_entry_configure(link, fdb_entry);
732 log_link_error(link, "Failed to add MAC entry to static MAC table: %s", strerror(-r));
740 static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
741 _cleanup_link_unref_ Link *link = userdata;
744 log_link_debug(link, "set link");
746 r = sd_rtnl_message_get_errno(m);
747 if (r < 0 && r != -EEXIST) {
748 log_link_struct(link, LOG_ERR,
749 "MESSAGE=%-*s: could not join netdev: %s",
751 link->ifname, strerror(-r),
754 link_enter_failed(link);
761 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
762 sd_bus_error *ret_error) {
763 _cleanup_link_unref_ Link *link = userdata;
768 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
771 r = sd_bus_message_get_errno(m);
773 log_link_warning(link, "Could not set hostname: %s",
779 int link_set_hostname(Link *link, const char *hostname) {
780 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
784 assert(link->manager);
787 log_link_debug(link, "Setting transient hostname: '%s'", hostname);
789 if (!link->manager->bus) {
790 /* TODO: replace by assert when we can rely on kdbus */
792 "Not connected to system bus, ignoring transient hostname.");
796 r = sd_bus_message_new_method_call(
799 "org.freedesktop.hostname1",
800 "/org/freedesktop/hostname1",
801 "org.freedesktop.hostname1",
806 r = sd_bus_message_append(m, "sb", hostname, false);
810 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
813 log_link_error(link, "Could not set transient hostname: %s",
823 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
824 _cleanup_link_unref_ Link *link = userdata;
829 assert(link->ifname);
831 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
834 r = sd_rtnl_message_get_errno(m);
836 log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
841 int link_set_mtu(Link *link, uint32_t mtu) {
842 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
846 assert(link->manager);
847 assert(link->manager->rtnl);
849 log_link_debug(link, "setting MTU: %" PRIu32, mtu);
851 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
852 RTM_SETLINK, link->ifindex);
854 log_link_error(link, "Could not allocate RTM_SETLINK message");
858 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
860 log_link_error(link, "Could not append MTU: %s", strerror(-r));
864 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
868 "Could not send rtnetlink message: %s",
878 static int link_set_bridge(Link *link) {
879 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
883 assert(link->network);
885 if(link->network->cost == 0)
888 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
889 RTM_SETLINK, link->ifindex);
891 log_link_error(link, "Could not allocate RTM_SETLINK message");
895 r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
898 "Could not set message family %s", strerror(-r));
902 r = sd_rtnl_message_open_container(req, IFLA_PROTINFO);
905 "Could not append IFLA_PROTINFO attribute: %s",
910 if(link->network->cost != 0) {
911 r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
914 "Could not append IFLA_BRPORT_COST attribute: %s",
920 r = sd_rtnl_message_close_container(req);
923 "Could not append IFLA_LINKINFO attribute: %s",
928 r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
931 "Could not send rtnetlink message: %s",
941 static void lldp_handler(sd_lldp *lldp, int event, void *userdata) {
942 Link *link = userdata;
946 assert(link->network);
947 assert(link->manager);
949 if (event != UPDATE_INFO)
952 r = sd_lldp_save(link->lldp, link->lldp_file);
954 log_link_warning(link, "could not save LLDP");
958 static int link_acquire_conf(Link *link) {
962 assert(link->network);
963 assert(link->manager);
964 assert(link->manager->event);
966 if (link_ipv4ll_enabled(link)) {
967 assert(link->ipv4ll);
969 log_link_debug(link, "acquiring IPv4 link-local address");
971 r = sd_ipv4ll_start(link->ipv4ll);
973 log_link_warning(link, "could not acquire IPv4 "
974 "link-local address");
979 if (link_dhcp4_enabled(link)) {
980 assert(link->dhcp_client);
982 log_link_debug(link, "acquiring DHCPv4 lease");
984 r = sd_dhcp_client_start(link->dhcp_client);
986 log_link_warning(link, "could not acquire DHCPv4 "
992 if (link_dhcp6_enabled(link)) {
993 assert(link->icmp6_router_discovery);
995 log_link_debug(link, "discovering IPv6 routers");
997 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
999 log_link_warning(link,
1000 "could not start IPv6 router discovery");
1005 if (link_lldp_enabled(link)) {
1008 log_link_debug(link, "Starting LLDP");
1010 r = sd_lldp_start(link->lldp);
1012 log_link_warning(link, "could not start LLDP ");
1020 bool link_has_carrier(Link *link) {
1021 /* see Documentation/networking/operstates.txt in the kernel sources */
1023 if (link->kernel_operstate == IF_OPER_UP)
1026 if (link->kernel_operstate == IF_OPER_UNKNOWN)
1027 /* operstate may not be implemented, so fall back to flags */
1028 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
1034 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1035 _cleanup_link_unref_ Link *link = userdata;
1040 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1043 r = sd_rtnl_message_get_errno(m);
1045 /* we warn but don't fail the link, as it may
1046 be brought up later */
1047 log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
1053 static int link_up(Link *link) {
1054 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1055 uint8_t ipv6ll_mode;
1059 assert(link->network);
1060 assert(link->manager);
1061 assert(link->manager->rtnl);
1063 log_link_debug(link, "bringing link up");
1065 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1066 RTM_SETLINK, link->ifindex);
1068 log_link_error(link, "Could not allocate RTM_SETLINK message");
1072 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1074 log_link_error(link, "Could not set link flags: %s",
1079 if (link->network->mac) {
1080 r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
1082 log_link_error(link, "Could not set MAC address: %s", strerror(-r));
1087 if (link->network->mtu) {
1088 r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu);
1090 log_link_error(link, "Could not set MTU: %s", strerror(-r));
1095 r = sd_rtnl_message_open_container(req, IFLA_AF_SPEC);
1097 log_link_error(link, "Could not open IFLA_AF_SPEC container: %s", strerror(-r));
1101 r = sd_rtnl_message_open_container(req, AF_INET6);
1103 log_link_error(link, "Could not open AF_INET6 container: %s", strerror(-r));
1107 ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE;
1108 r = sd_rtnl_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
1110 log_link_error(link, "Could not append IFLA_INET6_ADDR_GEN_MODE: %s", strerror(-r));
1114 if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
1115 r = sd_rtnl_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
1117 log_link_error(link, "Could not append IFLA_INET6_TOKEN: %s", strerror(-r));
1122 r = sd_rtnl_message_close_container(req);
1124 log_link_error(link, "Could not close AF_INET6 container: %s", strerror(-r));
1128 r = sd_rtnl_message_close_container(req);
1130 log_link_error(link, "Could not close IFLA_AF_SPEC container: %s", strerror(-r));
1134 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1137 log_link_error(link,
1138 "Could not send rtnetlink message: %s",
1148 static int link_down_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1149 _cleanup_link_unref_ Link *link = userdata;
1154 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1157 r = sd_rtnl_message_get_errno(m);
1159 log_link_warning_errno(link, -r, "%-*s: could not bring down interface: %m", IFNAMSIZ, link->ifname);
1164 static int link_down(Link *link) {
1165 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1169 assert(link->manager);
1170 assert(link->manager->rtnl);
1172 log_link_debug(link, "bringing link down");
1174 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1175 RTM_SETLINK, link->ifindex);
1177 log_link_error(link, "Could not allocate RTM_SETLINK message");
1181 r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
1183 log_link_error(link, "Could not set link flags: %s",
1188 r = sd_rtnl_call_async(link->manager->rtnl, req, link_down_handler, link,
1191 log_link_error(link,
1192 "Could not send rtnetlink message: %s",
1202 static int link_handle_bound_to_list(Link *link) {
1206 bool required_up = false;
1207 bool link_is_up = false;
1211 if (hashmap_isempty(link->bound_to_links))
1214 if (link->flags & IFF_UP)
1217 HASHMAP_FOREACH (l, link->bound_to_links, i)
1218 if (link_has_carrier(l)) {
1223 if (!required_up && link_is_up) {
1224 r = link_down(link);
1227 } else if (required_up && !link_is_up) {
1236 static int link_handle_bound_by_list(Link *link) {
1243 if (hashmap_isempty(link->bound_by_links))
1246 HASHMAP_FOREACH (l, link->bound_by_links, i) {
1247 r = link_handle_bound_to_list(l);
1255 static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
1261 if (link == carrier)
1264 if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
1267 r = hashmap_ensure_allocated(h, NULL);
1271 r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
1278 static int link_new_bound_by_list(Link *link) {
1283 bool list_updated = false;
1286 assert(link->manager);
1290 HASHMAP_FOREACH (carrier, m->links, i) {
1291 if (!carrier->network)
1294 if (strv_isempty(carrier->network->bind_carrier))
1297 if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
1298 r = link_put_carrier(link, carrier, &link->bound_by_links);
1302 list_updated = true;
1309 HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
1310 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
1320 static int link_new_bound_to_list(Link *link) {
1325 bool list_updated = false;
1328 assert(link->manager);
1333 if (strv_isempty(link->network->bind_carrier))
1338 HASHMAP_FOREACH (carrier, m->links, i) {
1339 if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
1340 r = link_put_carrier(link, carrier, &link->bound_to_links);
1344 list_updated = true;
1351 HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
1352 r = link_put_carrier(carrier, link, &carrier->bound_by_links);
1362 static int link_new_carrier_maps(Link *link) {
1365 r = link_new_bound_by_list(link);
1369 r = link_handle_bound_by_list(link);
1373 r = link_new_bound_to_list(link);
1377 r = link_handle_bound_to_list(link);
1384 static void link_free_bound_to_list(Link *link) {
1388 HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
1389 hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
1391 if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
1392 link_save(bound_to);
1398 static void link_free_bound_by_list(Link *link) {
1402 HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
1403 hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
1405 if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
1406 link_save(bound_by);
1407 link_handle_bound_to_list(bound_by);
1414 static void link_free_carrier_maps(Link *link) {
1415 bool list_updated = false;
1419 if (!hashmap_isempty(link->bound_to_links)) {
1420 link_free_bound_to_list(link);
1421 list_updated = true;
1424 if (!hashmap_isempty(link->bound_by_links)) {
1425 link_free_bound_by_list(link);
1426 list_updated = true;
1435 void link_drop(Link *link) {
1436 if (!link || link->state == LINK_STATE_LINGER)
1439 link_set_state(link, LINK_STATE_LINGER);
1441 link_free_carrier_maps(link);
1443 log_link_debug(link, "link removed");
1450 static int link_joined(Link *link) {
1454 assert(link->network);
1456 if (!hashmap_isempty(link->bound_to_links)) {
1457 r = link_handle_bound_to_list(link);
1460 } else if (!(link->flags & IFF_UP)) {
1463 link_enter_failed(link);
1468 if(link->network->bridge) {
1469 r = link_set_bridge(link);
1471 log_link_error(link,
1472 "Could not set bridge message: %s",
1477 return link_enter_set_addresses(link);
1480 static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1482 _cleanup_link_unref_ Link *link = userdata;
1486 assert(link->network);
1490 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1493 r = sd_rtnl_message_get_errno(m);
1494 if (r < 0 && r != -EEXIST) {
1495 log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
1496 link_enter_failed(link);
1499 log_link_debug(link, "joined netdev");
1501 if (link->enslaving <= 0)
1507 static int link_enter_join_netdev(Link *link) {
1513 assert(link->network);
1514 assert(link->state == LINK_STATE_PENDING);
1516 link_set_state(link, LINK_STATE_ENSLAVING);
1520 if (!link->network->bridge &&
1521 !link->network->bond &&
1522 hashmap_isempty(link->network->stacked_netdevs))
1523 return link_joined(link);
1525 if (link->network->bond) {
1526 log_link_struct(link, LOG_DEBUG,
1527 "MESSAGE=%-*s: enslaving by '%s'",
1529 link->ifname, link->network->bond->ifname,
1530 NETDEVIF(link->network->bond),
1533 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1535 log_link_struct(link, LOG_WARNING,
1536 "MESSAGE=%-*s: could not join netdev '%s': %s",
1538 link->ifname, link->network->bond->ifname,
1540 NETDEVIF(link->network->bond),
1542 link_enter_failed(link);
1549 if (link->network->bridge) {
1550 log_link_struct(link, LOG_DEBUG,
1551 "MESSAGE=%-*s: enslaving by '%s'",
1553 link->ifname, link->network->bridge->ifname,
1554 NETDEVIF(link->network->bridge),
1557 r = netdev_join(link->network->bridge, link,
1558 &netdev_join_handler);
1560 log_link_struct(link, LOG_WARNING,
1561 "MESSAGE=%-*s: could not join netdev '%s': %s",
1563 link->ifname, link->network->bridge->ifname,
1565 NETDEVIF(link->network->bridge),
1567 link_enter_failed(link);
1574 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1575 log_link_struct(link, LOG_DEBUG,
1576 "MESSAGE=%-*s: enslaving by '%s'",
1578 link->ifname, netdev->ifname, NETDEVIF(netdev),
1581 r = netdev_join(netdev, link, &netdev_join_handler);
1583 log_link_struct(link, LOG_WARNING,
1584 "MESSAGE=%-*s: could not join netdev '%s': %s",
1586 link->ifname, netdev->ifname,
1588 NETDEVIF(netdev), NULL);
1589 link_enter_failed(link);
1599 static int link_set_ipv4_forward(Link *link) {
1600 const char *p = NULL;
1604 b = link_ipv4_forward_enabled(link);
1606 p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
1607 r = write_string_file_no_create(p, one_zero(b));
1609 log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
1612 _cleanup_free_ char *buf = NULL;
1614 /* If IP forwarding is turned on for this interface,
1615 * then propagate this to the global setting. Given
1616 * that turning this on has side-effects on other
1617 * fields, we'll try to avoid doing this unless
1618 * necessary, hence check the previous value
1619 * first. Note that we never turn this option off
1620 * again, since all interfaces we manage do not do
1621 * forwarding anyway by default, and ownership rules
1622 * of this control are so unclear. */
1624 r = read_one_line_file("/proc/sys/net/ipv4/ip_forward", &buf);
1626 log_link_warning_errno(link, r, "Cannot read /proc/sys/net/ipv4/ip_forward: %m");
1627 else if (!streq(buf, "1")) {
1628 r = write_string_file_no_create("/proc/sys/net/ipv4/ip_forward", "1");
1630 log_link_warning_errno(link, r, "Cannot write /proc/sys/net/ipv4/ip_forward: %m");
1637 static int link_set_ipv6_forward(Link *link) {
1638 const char *p = NULL;
1641 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
1642 r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link)));
1644 log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m");
1649 static int link_configure(Link *link) {
1653 assert(link->network);
1654 assert(link->state == LINK_STATE_PENDING);
1656 r = link_set_bridge_fdb(link);
1660 r = link_set_ipv4_forward(link);
1664 r = link_set_ipv6_forward(link);
1668 if (link_ipv4ll_enabled(link)) {
1669 r = ipv4ll_configure(link);
1674 if (link_dhcp4_enabled(link)) {
1675 r = dhcp4_configure(link);
1680 if (link_dhcp4_server_enabled(link)) {
1681 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1685 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1690 if (link_dhcp6_enabled(link)) {
1691 r = icmp6_configure(link);
1696 if (link_lldp_enabled(link)) {
1697 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
1701 r = sd_lldp_attach_event(link->lldp, NULL, 0);
1705 r = sd_lldp_set_callback(link->lldp,
1706 lldp_handler, link);
1711 if (link_has_carrier(link)) {
1712 r = link_acquire_conf(link);
1717 return link_enter_join_netdev(link);
1720 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1722 _cleanup_link_unref_ Link *link = userdata;
1727 assert(link->ifname);
1728 assert(link->manager);
1730 if (link->state != LINK_STATE_PENDING)
1733 log_link_debug(link, "link state is up-to-date");
1735 r = link_new_bound_by_list(link);
1739 r = link_handle_bound_by_list(link);
1743 r = network_get(link->manager, link->udev_device, link->ifname,
1744 &link->mac, &network);
1746 link_enter_unmanaged(link);
1751 if (link->flags & IFF_LOOPBACK) {
1752 if (network->link_local != ADDRESS_FAMILY_NO)
1753 log_link_debug(link, "ignoring link-local autoconfiguration for loopback link");
1755 if (network->dhcp != ADDRESS_FAMILY_NO)
1756 log_link_debug(link, "ignoring DHCP clients for loopback link");
1758 if (network->dhcp_server)
1759 log_link_debug(link, "ignoring DHCP server for loopback link");
1762 r = network_apply(link->manager, network, link);
1766 r = link_new_bound_to_list(link);
1770 r = link_configure(link);
1777 int link_initialized(Link *link, struct udev_device *device) {
1778 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1782 assert(link->manager);
1783 assert(link->manager->rtnl);
1786 if (link->state != LINK_STATE_PENDING)
1789 if (link->udev_device)
1792 log_link_debug(link, "udev initialized link");
1794 link->udev_device = udev_device_ref(device);
1796 /* udev has initialized the link, but we don't know if we have yet
1797 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1798 * when it returns we know that the pending NEWLINKs have already been
1799 * processed and that we are up-to-date */
1801 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1806 r = sd_rtnl_call_async(link->manager->rtnl, req,
1807 link_initialized_and_synced, link, 0, NULL);
1816 static Address* link_get_equal_address(Link *link, Address *needle) {
1822 LIST_FOREACH(addresses, i, link->addresses)
1823 if (address_equal(i, needle))
1829 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1830 Manager *m = userdata;
1833 _cleanup_address_free_ Address *address = NULL;
1835 char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
1836 const char *valid_str = NULL;
1843 if (sd_rtnl_message_is_error(message)) {
1844 r = sd_rtnl_message_get_errno(message);
1846 log_warning_errno(r, "rtnl: failed to receive address: %m");
1851 r = sd_rtnl_message_get_type(message, &type);
1853 log_warning("rtnl: could not get message type");
1857 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1859 log_warning_errno(r, "rtnl: could not get ifindex: %m");
1861 } else if (ifindex <= 0) {
1862 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
1865 r = link_get(m, ifindex, &link);
1866 if (r < 0 || !link) {
1867 /* when enumerating we might be out of sync, but we will
1868 * get the address again, so just ignore it */
1869 if (!m->enumerating)
1870 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
1875 r = address_new_dynamic(&address);
1879 r = sd_rtnl_message_addr_get_family(message, &address->family);
1880 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1881 log_link_warning(link, "rtnl: received address with invalid family, ignoring");
1885 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1887 log_link_warning(link, "rtnl: received address with invalid prefixlen, ignoring");
1891 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1893 log_link_warning(link, "rtnl: received address with invalid scope, ignoring");
1897 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1899 log_link_warning(link, "rtnl: received address with invalid flags, ignoring");
1903 switch (address->family) {
1905 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1907 log_link_warning(link, "rtnl: received address without valid address, ignoring");
1914 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1916 log_link_warning(link, "rtnl: received address without valid address, ignoring");
1923 assert_not_reached("invalid address family");
1926 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
1927 log_link_warning(link, "could not print address");
1931 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO, &address->cinfo);
1933 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1936 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1937 address->cinfo.ifa_valid * USEC_PER_SEC,
1941 existing = link_get_equal_address(link, address);
1946 log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1949 existing->scope = address->scope;
1950 existing->flags = address->flags;
1951 existing->cinfo = address->cinfo;
1954 log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1956 LIST_PREPEND(addresses, link->addresses, address);
1957 address_establish(address, link);
1969 log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1970 address_release(existing, link);
1971 LIST_REMOVE(addresses, link->addresses, existing);
1972 address_free(existing);
1974 log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1978 assert_not_reached("Received invalid RTNL message type");
1984 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1986 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1987 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1995 r = link_new(m, message, ret);
2001 log_link_debug(link, "link %d added", link->ifindex);
2003 if (detect_container(NULL) <= 0) {
2004 /* not in a container, udev will be around */
2005 sprintf(ifindex_str, "n%d", link->ifindex);
2006 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2008 log_link_warning(link,
2009 "could not find udev device: %m");
2013 if (udev_device_get_is_initialized(device) <= 0) {
2015 log_link_debug(link, "link pending udev initialization...");
2019 r = link_initialized(link, device);
2023 /* we are calling a callback directly, so must take a ref */
2026 r = link_initialized_and_synced(m->rtnl, NULL, link);
2034 static int link_carrier_gained(Link *link) {
2039 if (link->network) {
2040 r = link_acquire_conf(link);
2042 link_enter_failed(link);
2047 r = link_handle_bound_by_list(link);
2054 static int link_carrier_lost(Link *link) {
2059 r = link_stop_clients(link);
2061 link_enter_failed(link);
2065 r = link_handle_bound_by_list(link);
2072 int link_carrier_reset(Link *link) {
2077 if (link_has_carrier(link)) {
2078 r = link_carrier_lost(link);
2082 r = link_carrier_gained(link);
2086 log_link_info(link, "reset carrier");
2093 int link_update(Link *link, sd_rtnl_message *m) {
2094 struct ether_addr mac;
2097 bool had_carrier, carrier_gained, carrier_lost;
2101 assert(link->ifname);
2104 if (link->state == LINK_STATE_LINGER) {
2106 log_link_info(link, "link readded");
2107 link_set_state(link, LINK_STATE_ENSLAVING);
2109 r = link_new_carrier_maps(link);
2114 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2115 if (r >= 0 && !streq(ifname, link->ifname)) {
2116 log_link_info(link, "renamed to %s", ifname);
2118 link_free_carrier_maps(link);
2121 link->ifname = strdup(ifname);
2125 r = link_new_carrier_maps(link);
2130 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
2131 if (r >= 0 && mtu > 0) {
2133 if (!link->original_mtu) {
2134 link->original_mtu = mtu;
2135 log_link_debug(link, "saved original MTU: %"
2136 PRIu32, link->original_mtu);
2139 if (link->dhcp_client) {
2140 r = sd_dhcp_client_set_mtu(link->dhcp_client,
2143 log_link_warning(link,
2144 "Could not update MTU in DHCP client: %s",
2151 /* The kernel may broadcast NEWLINK messages without the MAC address
2152 set, simply ignore them. */
2153 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2155 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
2158 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
2161 log_link_debug(link, "MAC address: "
2162 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2163 mac.ether_addr_octet[0],
2164 mac.ether_addr_octet[1],
2165 mac.ether_addr_octet[2],
2166 mac.ether_addr_octet[3],
2167 mac.ether_addr_octet[4],
2168 mac.ether_addr_octet[5]);
2171 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2173 log_link_warning(link,
2174 "Could not update MAC address in IPv4LL client: %s",
2180 if (link->dhcp_client) {
2181 r = sd_dhcp_client_set_mac(link->dhcp_client,
2182 (const uint8_t *) &link->mac,
2186 log_link_warning(link,
2187 "Could not update MAC address in DHCP client: %s",
2193 if (link->dhcp6_client) {
2194 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2195 (const uint8_t *) &link->mac,
2199 log_link_warning(link,
2200 "Could not update MAC address in DHCPv6 client: %s",
2208 had_carrier = link_has_carrier(link);
2210 r = link_update_flags(link, m);
2214 carrier_gained = !had_carrier && link_has_carrier(link);
2215 carrier_lost = had_carrier && !link_has_carrier(link);
2217 if (carrier_gained) {
2218 log_link_info(link, "gained carrier");
2220 r = link_carrier_gained(link);
2223 } else if (carrier_lost) {
2224 log_link_info(link, "lost carrier");
2226 r = link_carrier_lost(link);
2235 static void link_update_operstate(Link *link) {
2236 LinkOperationalState operstate;
2239 if (link->kernel_operstate == IF_OPER_DORMANT)
2240 operstate = LINK_OPERSTATE_DORMANT;
2241 else if (link_has_carrier(link)) {
2243 uint8_t scope = RT_SCOPE_NOWHERE;
2245 /* if we have carrier, check what addresses we have */
2246 LIST_FOREACH(addresses, address, link->addresses) {
2247 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
2250 if (address->scope < scope)
2251 scope = address->scope;
2254 if (scope < RT_SCOPE_SITE)
2255 /* universally accessible addresses found */
2256 operstate = LINK_OPERSTATE_ROUTABLE;
2257 else if (scope < RT_SCOPE_HOST)
2258 /* only link or site local addresses found */
2259 operstate = LINK_OPERSTATE_DEGRADED;
2261 /* no useful addresses found */
2262 operstate = LINK_OPERSTATE_CARRIER;
2263 } else if (link->flags & IFF_UP)
2264 operstate = LINK_OPERSTATE_NO_CARRIER;
2266 operstate = LINK_OPERSTATE_OFF;
2268 if (link->operstate != operstate) {
2269 link->operstate = operstate;
2270 link_send_changed(link, "OperationalState", NULL);
2274 int link_save(Link *link) {
2275 _cleanup_free_ char *temp_path = NULL;
2276 _cleanup_fclose_ FILE *f = NULL;
2277 const char *admin_state, *oper_state;
2281 assert(link->state_file);
2282 assert(link->lease_file);
2283 assert(link->manager);
2285 link_update_operstate(link);
2287 r = manager_save(link->manager);
2291 if (link->state == LINK_STATE_LINGER) {
2292 unlink(link->state_file);
2296 admin_state = link_state_to_string(link->state);
2297 assert(admin_state);
2299 oper_state = link_operstate_to_string(link->operstate);
2302 r = fopen_temporary(link->state_file, &f, &temp_path);
2306 fchmod(fileno(f), 0644);
2309 "# This is private data. Do not parse.\n"
2312 admin_state, oper_state);
2314 if (link->network) {
2315 char **address, **domain;
2318 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
2322 STRV_FOREACH(address, link->network->dns) {
2329 if (link->network->dhcp_dns &&
2331 const struct in_addr *addresses;
2333 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2337 serialize_in_addrs(f, addresses, r);
2345 STRV_FOREACH(address, link->network->ntp) {
2352 if (link->network->dhcp_ntp &&
2354 const struct in_addr *addresses;
2356 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2360 serialize_in_addrs(f, addresses, r);
2366 fprintf(f, "DOMAINS=");
2368 STRV_FOREACH(domain, link->network->domains) {
2375 if (link->network->dhcp_domains &&
2377 const char *domainname;
2379 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
2383 fputs(domainname, f);
2389 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2390 yes_no(link->network->wildcard_domain));
2392 fprintf(f, "LLMNR=%s\n",
2393 llmnr_support_to_string(link->network->llmnr));
2396 if (!hashmap_isempty(link->bound_to_links)) {
2401 fputs("CARRIER_BOUND_TO=", f);
2402 HASHMAP_FOREACH(carrier, link->bound_to_links, i) {
2405 fputs(carrier->ifname, f);
2412 if (!hashmap_isempty(link->bound_by_links)) {
2417 fputs("CARRIER_BOUND_BY=", f);
2419 HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
2422 fputs(carrier->ifname, f);
2429 if (link->dhcp_lease) {
2430 assert(link->network);
2432 r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
2440 unlink(link->lease_file);
2443 assert(link->network);
2445 r = sd_lldp_save(link->lldp, link->lldp_file);
2453 unlink(link->lldp_file);
2455 r = fflush_and_check(f);
2459 if (rename(temp_path, link->state_file) < 0) {
2466 log_link_error(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2467 unlink(link->state_file);
2472 static const char* const link_state_table[_LINK_STATE_MAX] = {
2473 [LINK_STATE_PENDING] = "pending",
2474 [LINK_STATE_ENSLAVING] = "configuring",
2475 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2476 [LINK_STATE_SETTING_ROUTES] = "configuring",
2477 [LINK_STATE_CONFIGURED] = "configured",
2478 [LINK_STATE_UNMANAGED] = "unmanaged",
2479 [LINK_STATE_FAILED] = "failed",
2480 [LINK_STATE_LINGER] = "linger",
2483 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2485 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2486 [LINK_OPERSTATE_OFF] = "off",
2487 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
2488 [LINK_OPERSTATE_DORMANT] = "dormant",
2489 [LINK_OPERSTATE_CARRIER] = "carrier",
2490 [LINK_OPERSTATE_DEGRADED] = "degraded",
2491 [LINK_OPERSTATE_ROUTABLE] = "routable",
2494 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);