1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <netinet/ether.h>
26 #include "libudev-private.h"
27 #include "udev-util.h"
31 #include "network-internal.h"
33 #include "dhcp-lease-internal.h"
35 static int ipv4ll_address_update(Link *link, bool deprecate);
36 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
38 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
39 _cleanup_link_free_ Link *link = NULL;
45 assert(manager->links);
49 r = sd_rtnl_message_get_type(message, &type);
52 else if (type != RTM_NEWLINK)
55 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
58 else if (ifindex <= 0)
61 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
69 link->manager = manager;
70 link->state = LINK_STATE_INITIALIZING;
71 link->ifindex = ifindex;
72 link->ifname = strdup(ifname);
76 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
81 r = hashmap_put(manager->links, &link->ifindex, link);
91 void link_free(Link *link) {
95 assert(link->manager);
97 sd_dhcp_client_unref(link->dhcp_client);
98 sd_dhcp_lease_unref(link->dhcp_lease);
100 sd_ipv4ll_unref(link->ipv4ll);
102 hashmap_remove(link->manager->links, &link->ifindex);
105 free(link->state_file);
107 udev_device_unref(link->udev_device);
112 int link_get(Manager *m, int ifindex, Link **ret) {
121 ifindex_64 = ifindex;
122 link = hashmap_get(m->links, &ifindex_64);
131 static int link_enter_configured(Link *link) {
133 assert(link->state == LINK_STATE_SETTING_ROUTES);
135 log_info_link(link, "link configured");
137 link->state = LINK_STATE_CONFIGURED;
144 static void link_enter_unmanaged(Link *link) {
147 log_info_link(link, "unmanaged");
149 link->state = LINK_STATE_UNMANAGED;
154 static int link_stop_clients(Link *link) {
158 assert(link->manager);
159 assert(link->manager->event);
164 if (link->network->dhcp) {
165 assert(link->dhcp_client);
167 k = sd_dhcp_client_stop(link->dhcp_client);
169 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
174 if (link->network->ipv4ll) {
175 assert(link->ipv4ll);
177 k = sd_ipv4ll_stop(link->ipv4ll);
179 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
187 static void link_enter_failed(Link *link) {
190 if (link->state == LINK_STATE_FAILED)
193 log_warning_link(link, "failed");
195 link->state = LINK_STATE_FAILED;
197 link_stop_clients(link);
202 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
203 Link *link = userdata;
206 assert(link->route_messages > 0);
207 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
208 link->state == LINK_STATE_SETTING_ROUTES ||
209 link->state == LINK_STATE_FAILED);
211 link->route_messages --;
213 if (link->state == LINK_STATE_FAILED)
216 r = sd_rtnl_message_get_errno(m);
217 if (r < 0 && r != -EEXIST)
218 log_struct_link(LOG_WARNING, link,
219 "MESSAGE=%s: could not set route: %s",
220 link->ifname, strerror(-r),
224 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
226 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
227 log_debug_link(link, "routes set");
228 link_enter_configured(link);
234 static int link_enter_set_routes(Link *link) {
239 assert(link->network);
240 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
242 link->state = LINK_STATE_SETTING_ROUTES;
244 if (!link->network->static_routes && !link->dhcp_lease &&
245 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
246 return link_enter_configured(link);
248 log_debug_link(link, "setting routes");
250 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
251 r = route_configure(rt, link, &route_handler);
253 log_warning_link(link,
254 "could not set routes: %s", strerror(-r));
255 link_enter_failed(link);
259 link->route_messages ++;
262 if (link->ipv4ll && !link->dhcp_lease) {
263 _cleanup_route_free_ Route *route = NULL;
266 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
267 if (r < 0 && r != -ENOENT) {
268 log_warning_link(link, "IPV4LL error: no address: %s",
274 r = route_new_dynamic(&route);
276 log_error_link(link, "Could not allocate route: %s",
281 route->family = AF_INET;
282 route->scope = RT_SCOPE_LINK;
285 r = route_configure(route, link, &route_handler);
287 log_warning_link(link,
288 "could not set routes: %s", strerror(-r));
289 link_enter_failed(link);
293 link->route_messages ++;
297 if (link->dhcp_lease) {
298 _cleanup_route_free_ Route *route = NULL;
299 _cleanup_route_free_ Route *route_gw = NULL;
300 struct in_addr gateway;
302 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
304 log_warning_link(link, "DHCP error: no router: %s",
309 r = route_new_dynamic(&route);
311 log_error_link(link, "Could not allocate route: %s",
316 r = route_new_dynamic(&route_gw);
318 log_error_link(link, "Could not allocate route: %s",
323 /* The dhcp netmask may mask out the gateway. Add an explicit
324 * route for the gw host so that we can route no matter the
325 * netmask or existing kernel route tables. */
326 route_gw->family = AF_INET;
327 route_gw->dst_addr.in = gateway;
328 route_gw->dst_prefixlen = 32;
329 route_gw->scope = RT_SCOPE_LINK;
331 r = route_configure(route_gw, link, &route_handler);
333 log_warning_link(link,
334 "could not set host route: %s", strerror(-r));
338 link->route_messages ++;
340 route->family = AF_INET;
341 route->in_addr.in = gateway;
343 r = route_configure(route, link, &route_handler);
345 log_warning_link(link,
346 "could not set routes: %s", strerror(-r));
347 link_enter_failed(link);
351 link->route_messages ++;
357 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
358 Link *link = userdata;
363 assert(link->ifname);
365 if (link->state == LINK_STATE_FAILED)
368 r = sd_rtnl_message_get_errno(m);
369 if (r < 0 && r != -ENOENT)
370 log_struct_link(LOG_WARNING, link,
371 "MESSAGE=%s: could not drop route: %s",
372 link->ifname, strerror(-r),
379 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
380 Link *link = userdata;
385 assert(link->ifname);
386 assert(link->addr_messages > 0);
387 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
389 link->addr_messages --;
391 if (link->state == LINK_STATE_FAILED)
394 r = sd_rtnl_message_get_errno(m);
395 if (r < 0 && r != -EEXIST)
396 log_struct_link(LOG_WARNING, link,
397 "MESSAGE=%s: could not set address: %s",
398 link->ifname, strerror(-r),
402 if (link->addr_messages == 0) {
403 log_debug_link(link, "addresses set");
404 link_enter_set_routes(link);
410 static int link_enter_set_addresses(Link *link) {
415 assert(link->network);
416 assert(link->state != _LINK_STATE_INVALID);
418 link->state = LINK_STATE_SETTING_ADDRESSES;
420 if (!link->network->static_addresses && !link->dhcp_lease &&
421 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
422 return link_enter_set_routes(link);
424 log_debug_link(link, "setting addresses");
426 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
427 r = address_configure(ad, link, &address_handler);
429 log_warning_link(link,
430 "could not set addresses: %s", strerror(-r));
431 link_enter_failed(link);
435 link->addr_messages ++;
438 if (link->ipv4ll && !link->dhcp_lease) {
439 _cleanup_address_free_ Address *ll_addr = NULL;
442 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
443 if (r < 0 && r != -ENOENT) {
444 log_warning_link(link, "IPV4LL error: no address: %s",
450 r = address_new_dynamic(&ll_addr);
452 log_error_link(link, "Could not allocate address: %s", strerror(-r));
456 ll_addr->family = AF_INET;
457 ll_addr->in_addr.in = addr;
458 ll_addr->prefixlen = 16;
459 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
460 ll_addr->scope = RT_SCOPE_LINK;
462 r = address_configure(ll_addr, link, &address_handler);
464 log_warning_link(link,
465 "could not set addresses: %s", strerror(-r));
466 link_enter_failed(link);
470 link->addr_messages ++;
474 if (link->dhcp_lease) {
475 _cleanup_address_free_ Address *address = NULL;
477 struct in_addr netmask;
480 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
482 log_warning_link(link, "DHCP error: no address: %s",
487 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
489 log_warning_link(link, "DHCP error: no netmask: %s",
494 prefixlen = net_netmask_to_prefixlen(&netmask);
496 r = address_new_dynamic(&address);
498 log_error_link(link, "Could not allocate address: %s",
503 address->family = AF_INET;
504 address->in_addr.in = addr;
505 address->prefixlen = prefixlen;
506 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
508 r = address_configure(address, link, &address_handler);
510 log_warning_link(link,
511 "could not set addresses: %s", strerror(-r));
512 link_enter_failed(link);
516 link->addr_messages ++;
522 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
523 Link *link = userdata;
528 assert(link->ifname);
530 if (link->state == LINK_STATE_FAILED)
533 r = sd_rtnl_message_get_errno(m);
534 if (r < 0 && r != -ENOENT)
535 log_struct_link(LOG_WARNING, link,
536 "MESSAGE=%s: could not update address: %s",
537 link->ifname, strerror(-r),
544 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
545 Link *link = userdata;
550 assert(link->ifname);
552 if (link->state == LINK_STATE_FAILED)
555 r = sd_rtnl_message_get_errno(m);
556 if (r < 0 && r != -ENOENT)
557 log_struct_link(LOG_WARNING, link,
558 "MESSAGE=%s: could not drop address: %s",
559 link->ifname, strerror(-r),
566 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
569 r = sd_bus_message_get_errno(m);
571 log_warning("Could not set hostname: %s", strerror(-r));
576 static int set_hostname(sd_bus *bus, const char *hostname) {
577 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
582 log_debug("Setting transient hostname: '%s'", hostname);
584 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
585 log_info("Not connected to system bus, ignoring transient hostname.");
589 r = sd_bus_message_new_method_call(
592 "org.freedesktop.hostname1",
593 "/org/freedesktop/hostname1",
594 "org.freedesktop.hostname1",
599 r = sd_bus_message_append(m, "sb", hostname, false);
603 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
605 log_error("Could not set transient hostname: %s", strerror(-r));
610 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
611 Link *link = userdata;
616 assert(link->ifname);
618 if (link->state == LINK_STATE_FAILED)
621 r = sd_rtnl_message_get_errno(m);
623 log_struct_link(LOG_WARNING, link,
624 "MESSAGE=%s: could not set MTU: %s",
625 link->ifname, strerror(-r),
632 static int link_set_mtu(Link *link, uint32_t mtu) {
633 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
637 assert(link->manager);
638 assert(link->manager->rtnl);
640 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
642 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
643 RTM_SETLINK, link->ifindex);
645 log_error_link(link, "Could not allocate RTM_SETLINK message");
649 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
651 log_error_link(link, "Could not append MTU: %s", strerror(-r));
655 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
658 "Could not send rtnetlink message: %s", strerror(-r));
665 static int dhcp_lease_lost(Link *link) {
666 _cleanup_address_free_ Address *address = NULL;
667 _cleanup_route_free_ Route *route_gw = NULL;
668 _cleanup_route_free_ Route *route = NULL;
670 struct in_addr netmask;
671 struct in_addr gateway;
676 assert(link->dhcp_lease);
678 log_warning_link(link, "DHCP lease lost");
680 r = address_new_dynamic(&address);
682 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
683 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
684 sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
685 prefixlen = net_netmask_to_prefixlen(&netmask);
687 r = route_new_dynamic(&route_gw);
689 route_gw->family = AF_INET;
690 route_gw->dst_addr.in = gateway;
691 route_gw->dst_prefixlen = 32;
692 route_gw->scope = RT_SCOPE_LINK;
694 route_drop(route_gw, link, &route_drop_handler);
697 r = route_new_dynamic(&route);
699 route->family = AF_INET;
700 route->in_addr.in = gateway;
702 route_drop(route, link, &route_drop_handler);
705 address->family = AF_INET;
706 address->in_addr.in = addr;
707 address->prefixlen = prefixlen;
709 address_drop(address, link, &address_drop_handler);
712 if (link->network->dhcp_mtu) {
715 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
716 if (r >= 0 && link->original_mtu != mtu) {
717 r = link_set_mtu(link, link->original_mtu);
719 log_warning_link(link, "DHCP error: could not reset MTU");
720 link_enter_failed(link);
726 if (link->network->dhcp_hostname) {
727 const char *hostname = NULL;
729 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
730 if (r >= 0 && hostname) {
731 r = set_hostname(link->manager->bus, "");
733 log_error("Failed to reset transient hostname");
737 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
742 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
743 sd_dhcp_lease *lease;
744 struct in_addr address;
745 struct in_addr netmask;
746 struct in_addr gateway;
748 struct in_addr *nameservers;
749 size_t nameservers_size;
755 r = sd_dhcp_client_get_lease(client, &lease);
757 log_warning_link(link, "DHCP error: no lease: %s",
762 r = sd_dhcp_lease_get_address(lease, &address);
764 log_warning_link(link, "DHCP error: no address: %s",
769 r = sd_dhcp_lease_get_netmask(lease, &netmask);
771 log_warning_link(link, "DHCP error: no netmask: %s",
776 prefixlen = net_netmask_to_prefixlen(&netmask);
778 r = sd_dhcp_lease_get_router(lease, &gateway);
780 log_warning_link(link, "DHCP error: no router: %s",
785 log_struct_link(LOG_INFO, link,
786 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
788 ADDRESS_FMT_VAL(address),
790 ADDRESS_FMT_VAL(gateway),
791 "ADDRESS=%u.%u.%u.%u",
792 ADDRESS_FMT_VAL(address),
795 "GATEWAY=%u.%u.%u.%u",
796 ADDRESS_FMT_VAL(gateway),
799 link->dhcp_lease = lease;
801 if (link->network->dhcp_dns) {
802 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
804 r = manager_update_resolv_conf(link->manager);
806 log_error("Failed to update resolv.conf");
810 if (link->network->dhcp_mtu) {
813 r = sd_dhcp_lease_get_mtu(lease, &mtu);
815 r = link_set_mtu(link, mtu);
817 log_error_link(link, "Failed to set MTU "
822 if (link->network->dhcp_hostname) {
823 const char *hostname;
825 r = sd_dhcp_lease_get_hostname(lease, &hostname);
827 r = set_hostname(link->manager->bus, hostname);
829 log_error("Failed to set transient hostname "
830 "to '%s'", hostname);
834 link_enter_set_addresses(link);
839 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
840 Link *link = userdata;
844 assert(link->network);
845 assert(link->manager);
847 if (link->state == LINK_STATE_FAILED)
851 case DHCP_EVENT_NO_LEASE:
852 log_debug_link(link, "IP address in use.");
854 case DHCP_EVENT_EXPIRED:
855 case DHCP_EVENT_STOP:
856 case DHCP_EVENT_IP_CHANGE:
857 if (link->network->dhcp_critical) {
858 log_error_link(link, "DHCPv4 connection considered system critical, "
859 "ignoring request to reconfigure it.");
863 if (link->dhcp_lease) {
864 r = dhcp_lease_lost(link);
866 link_enter_failed(link);
871 if (event == DHCP_EVENT_IP_CHANGE) {
872 r = dhcp_lease_acquired(client, link);
874 link_enter_failed(link);
879 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
880 if (!sd_ipv4ll_is_running(link->ipv4ll))
881 r = sd_ipv4ll_start(link->ipv4ll);
882 else if (ipv4ll_is_bound(link->ipv4ll))
883 r = ipv4ll_address_update(link, false);
885 link_enter_failed(link);
891 case DHCP_EVENT_IP_ACQUIRE:
892 r = dhcp_lease_acquired(client, link);
894 link_enter_failed(link);
898 if (ipv4ll_is_bound(link->ipv4ll))
899 r = ipv4ll_address_update(link, true);
901 r = sd_ipv4ll_stop(link->ipv4ll);
903 link_enter_failed(link);
910 log_warning_link(link, "DHCP error: %s", strerror(-event));
912 log_warning_link(link, "DHCP unknown event: %d", event);
919 static int ipv4ll_address_update(Link *link, bool deprecate) {
925 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
927 _cleanup_address_free_ Address *address = NULL;
929 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
930 deprecate ? "deprecate" : "approve",
931 ADDRESS_FMT_VAL(addr));
933 r = address_new_dynamic(&address);
935 log_error_link(link, "Could not allocate address: %s", strerror(-r));
939 address->family = AF_INET;
940 address->in_addr.in = addr;
941 address->prefixlen = 16;
942 address->scope = RT_SCOPE_LINK;
943 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
944 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
946 address_update(address, link, &address_update_handler);
953 static int ipv4ll_address_lost(Link *link) {
959 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
961 _cleanup_address_free_ Address *address = NULL;
962 _cleanup_route_free_ Route *route = NULL;
964 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
965 ADDRESS_FMT_VAL(addr));
967 r = address_new_dynamic(&address);
969 log_error_link(link, "Could not allocate address: %s", strerror(-r));
973 address->family = AF_INET;
974 address->in_addr.in = addr;
975 address->prefixlen = 16;
976 address->scope = RT_SCOPE_LINK;
978 address_drop(address, link, &address_drop_handler);
980 r = route_new_dynamic(&route);
982 log_error_link(link, "Could not allocate route: %s",
987 route->family = AF_INET;
988 route->scope = RT_SCOPE_LINK;
991 route_drop(route, link, &route_drop_handler);
997 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1003 r = sd_ipv4ll_get_address(ll, &addr);
1009 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1010 struct in_addr address;
1016 r = sd_ipv4ll_get_address(ll, &address);
1020 log_struct_link(LOG_INFO, link,
1021 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1023 ADDRESS_FMT_VAL(address),
1026 link_enter_set_addresses(link);
1031 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1032 Link *link = userdata;
1036 assert(link->network);
1037 assert(link->manager);
1040 case IPV4LL_EVENT_STOP:
1041 case IPV4LL_EVENT_CONFLICT:
1042 r = ipv4ll_address_lost(link);
1044 link_enter_failed(link);
1048 case IPV4LL_EVENT_BIND:
1049 r = ipv4ll_address_claimed(ll, link);
1051 link_enter_failed(link);
1057 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1059 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1064 static int link_acquire_conf(Link *link) {
1068 assert(link->network);
1069 assert(link->manager);
1070 assert(link->manager->event);
1072 if (link->network->ipv4ll) {
1073 assert(link->ipv4ll);
1075 log_debug_link(link, "acquiring IPv4 link-local address");
1077 r = sd_ipv4ll_start(link->ipv4ll);
1082 if (link->network->dhcp) {
1083 assert(link->dhcp_client);
1085 log_debug_link(link, "acquiring DHCPv4 lease");
1087 r = sd_dhcp_client_start(link->dhcp_client);
1095 static int link_update_flags(Link *link, unsigned flags) {
1096 unsigned flags_added, flags_removed, generic_flags;
1097 bool carrier_gained, carrier_lost;
1102 if (link->state == LINK_STATE_FAILED)
1105 if (link->flags == flags)
1108 flags_added = (link->flags ^ flags) & flags;
1109 flags_removed = (link->flags ^ flags) & link->flags;
1110 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1111 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1112 IFF_NOARP | IFF_MASTER | IFF_SLAVE);
1114 /* consider link to have carrier when LOWER_UP and !DORMANT
1116 TODO: use proper operstates once we start supporting 802.1X
1118 see Documentation/networking/operstates.txt in the kernel sources
1120 carrier_gained = (((flags_added & IFF_LOWER_UP) && !(flags & IFF_DORMANT)) ||
1121 ((flags_removed & IFF_DORMANT) && (flags & IFF_LOWER_UP)));
1122 carrier_lost = ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT)) &&
1123 ((flags_removed & IFF_LOWER_UP) || (flags_added & IFF_DORMANT));
1125 link->flags = flags;
1128 /* not currently managing this link
1129 we track state changes, but don't log them
1130 they will be logged if and when a network is
1134 if (flags_added & IFF_UP)
1135 log_info_link(link, "link is up");
1136 else if (flags_removed & IFF_UP)
1137 log_info_link(link, "link is down");
1139 if (flags_added & IFF_LOWER_UP)
1140 log_debug_link(link, "link is lower up");
1141 else if (flags_removed & IFF_LOWER_UP)
1142 log_debug_link(link, "link is lower down");
1144 if (flags_added & IFF_DORMANT)
1145 log_debug_link(link, "link is dormant");
1146 else if (flags_removed & IFF_DORMANT)
1147 log_debug_link(link, "link is not dormant");
1149 if (flags_added & IFF_DEBUG)
1150 log_debug_link(link, "debugging enabled in the kernel");
1151 else if (flags_removed & IFF_DEBUG)
1152 log_debug_link(link, "debugging disabled in the kernel");
1154 if (flags_added & IFF_MULTICAST)
1155 log_debug_link(link, "multicast enabled");
1156 else if (flags_removed & IFF_MULTICAST)
1157 log_debug_link(link, "multicast disabled");
1159 if (flags_added & IFF_BROADCAST)
1160 log_debug_link(link, "broadcast enabled");
1161 else if (flags_removed & IFF_BROADCAST)
1162 log_debug_link(link, "broadcast disabled");
1164 if (flags_added & IFF_PROMISC)
1165 log_debug_link(link, "promiscuous mode enabled");
1166 else if (flags_removed & IFF_PROMISC)
1167 log_debug_link(link, "promiscuous mode disabled");
1169 if (flags_added & IFF_NOARP)
1170 log_debug_link(link, "ARP protocol disabled");
1171 else if (flags_removed & IFF_NOARP)
1172 log_debug_link(link, "ARP protocol enabled");
1174 if (flags_added & IFF_MASTER)
1175 log_debug_link(link, "link is master");
1176 else if (flags_removed & IFF_MASTER)
1177 log_debug_link(link, "link is no longer master");
1179 if (flags_added & IFF_SLAVE)
1180 log_debug_link(link, "link is slave");
1181 else if (flags_removed & IFF_SLAVE)
1182 log_debug_link(link, "link is no longer slave");
1184 /* link flags are currently at most 18 bits, let's default to printing 20 */
1185 if (flags_added & generic_flags)
1186 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1187 flags_added & generic_flags);
1189 if (flags_removed & generic_flags)
1190 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1191 flags_removed & generic_flags);
1193 if (carrier_gained) {
1194 log_info_link(link, "gained carrier");
1196 if (link->network->dhcp || link->network->ipv4ll) {
1197 r = link_acquire_conf(link);
1199 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
1200 link_enter_failed(link);
1204 } else if (carrier_lost) {
1205 log_info_link(link, "lost carrier");
1207 if (link->network->dhcp) {
1208 r = sd_dhcp_client_stop(link->dhcp_client);
1210 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
1211 link_enter_failed(link);
1216 if (link->network->ipv4ll) {
1217 r = sd_ipv4ll_stop(link->ipv4ll);
1219 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
1220 link_enter_failed(link);
1229 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1230 Link *link = userdata;
1235 if (link->state == LINK_STATE_FAILED)
1238 r = sd_rtnl_message_get_errno(m);
1240 link_update_flags(link, link->flags | IFF_UP);
1242 log_struct_link(LOG_WARNING, link,
1243 "MESSAGE=%s: could not bring up interface: %s",
1244 link->ifname, strerror(-r),
1250 static int link_up(Link *link) {
1251 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1255 assert(link->manager);
1256 assert(link->manager->rtnl);
1258 log_debug_link(link, "bringing link up");
1260 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1261 RTM_SETLINK, link->ifindex);
1263 log_error_link(link, "Could not allocate RTM_SETLINK message");
1267 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1269 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1273 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1275 log_error_link(link,
1276 "Could not send rtnetlink message: %s", strerror(-r));
1283 static int link_enslaved(Link *link) {
1287 assert(link->state == LINK_STATE_ENSLAVING);
1288 assert(link->network);
1290 if (!(link->flags & IFF_UP)) {
1293 link_enter_failed(link);
1298 if (!link->network->dhcp && !link->network->ipv4ll)
1299 return link_enter_set_addresses(link);
1304 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1305 Link *link = userdata;
1309 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1310 assert(link->network);
1314 if (link->state == LINK_STATE_FAILED)
1317 r = sd_rtnl_message_get_errno(m);
1319 log_struct_link(LOG_ERR, link,
1320 "MESSAGE=%s: could not enslave: %s",
1321 link->ifname, strerror(-r),
1324 link_enter_failed(link);
1328 log_debug_link(link, "enslaved");
1330 if (link->enslaving == 0)
1331 link_enslaved(link);
1336 static int link_enter_enslave(Link *link) {
1337 NetDev *vlan, *macvlan;
1342 assert(link->network);
1343 assert(link->state == LINK_STATE_INITIALIZING);
1345 link->state = LINK_STATE_ENSLAVING;
1349 if (!link->network->bridge && !link->network->bond &&
1350 hashmap_isempty(link->network->vlans) &&
1351 hashmap_isempty(link->network->macvlans))
1352 return link_enslaved(link);
1354 if (link->network->bridge) {
1355 log_struct_link(LOG_DEBUG, link,
1356 "MESSAGE=%s: enslaving by '%s'",
1357 link->ifname, link->network->bridge->name,
1358 NETDEV(link->network->bridge),
1361 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1363 log_struct_link(LOG_WARNING, link,
1364 "MESSAGE=%s: could not enslave by '%s': %s",
1365 link->ifname, link->network->bridge->name, strerror(-r),
1366 NETDEV(link->network->bridge),
1368 link_enter_failed(link);
1375 if (link->network->bond) {
1376 log_struct_link(LOG_DEBUG, link,
1377 "MESSAGE=%s: enslaving by '%s'",
1378 link->ifname, link->network->bond->name,
1379 NETDEV(link->network->bond),
1382 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1384 log_struct_link(LOG_WARNING, link,
1385 "MESSAGE=%s: could not enslave by '%s': %s",
1386 link->ifname, link->network->bond->name, strerror(-r),
1387 NETDEV(link->network->bond),
1389 link_enter_failed(link);
1396 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1397 log_struct_link(LOG_DEBUG, link,
1398 "MESSAGE=%s: enslaving by '%s'",
1399 link->ifname, vlan->name, NETDEV(vlan), NULL);
1401 r = netdev_enslave(vlan, link, &enslave_handler);
1403 log_struct_link(LOG_WARNING, link,
1404 "MESSAGE=%s: could not enslave by '%s': %s",
1405 link->ifname, vlan->name, strerror(-r),
1406 NETDEV(vlan), NULL);
1407 link_enter_failed(link);
1414 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1415 log_struct_link(LOG_DEBUG, link,
1416 "MESSAGE=%s: enslaving by '%s'",
1417 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1419 r = netdev_enslave(macvlan, link, &enslave_handler);
1421 log_struct_link(LOG_WARNING, link,
1422 "MESSAGE=%s: could not enslave by '%s': %s",
1423 link->ifname, macvlan->name, strerror(-r),
1424 NETDEV(macvlan), NULL);
1425 link_enter_failed(link);
1435 static int link_configure(Link *link) {
1439 assert(link->state == LINK_STATE_INITIALIZING);
1441 if (link->network->ipv4ll) {
1443 r = sd_ipv4ll_new(&link->ipv4ll);
1447 if (link->udev_device) {
1448 r = net_get_unique_predictable_data(link->udev_device, seed);
1450 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1456 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1460 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1464 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1468 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1473 if (link->network->dhcp) {
1474 r = sd_dhcp_client_new(&link->dhcp_client);
1478 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1482 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1486 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1490 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1494 if (link->network->dhcp_mtu) {
1495 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1501 return link_enter_enslave(link);
1504 int link_initialized(Link *link, struct udev_device *device) {
1510 assert(link->ifname);
1511 assert(link->manager);
1513 if (link->state != LINK_STATE_INITIALIZING)
1517 link->udev_device = udev_device_ref(device);
1519 log_debug_link(link, "link initialized");
1521 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1523 link_enter_unmanaged(link);
1528 r = network_apply(link->manager, network, link);
1532 r = link_configure(link);
1536 /* re-trigger all state updates */
1537 flags = link->flags;
1539 r = link_update_flags(link, flags);
1546 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1548 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1549 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1556 r = link_new(m, message, ret);
1562 log_info_link(link, "link added");
1564 if (detect_container(NULL) <= 0) {
1565 /* not in a container, udev will be around */
1566 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1567 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1569 log_warning_link(link, "could not find udev device");
1573 if (udev_device_get_is_initialized(device) <= 0)
1578 r = link_initialized(link, device);
1585 int link_update(Link *link, sd_rtnl_message *m) {
1587 struct ether_addr mac;
1592 assert(link->ifname);
1595 if (link->state == LINK_STATE_FAILED || link->state == LINK_STATE_UNMANAGED)
1598 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1599 if (r >= 0 && !streq(ifname, link->ifname)) {
1600 log_info_link(link, "renamed to %s", ifname);
1603 link->ifname = strdup(ifname);
1608 if (!link->original_mtu) {
1609 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1611 log_debug_link(link, "saved original MTU: %"
1612 PRIu16, link->original_mtu);
1615 /* The kernel may broadcast NEWLINK messages without the MAC address
1616 set, simply ignore them. */
1617 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1619 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1621 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1623 log_debug_link(link, "MAC address: "
1624 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1625 mac.ether_addr_octet[0],
1626 mac.ether_addr_octet[1],
1627 mac.ether_addr_octet[2],
1628 mac.ether_addr_octet[3],
1629 mac.ether_addr_octet[4],
1630 mac.ether_addr_octet[5]);
1633 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1635 log_warning_link(link, "Could not update MAC "
1636 "address in IPv4LL client: %s",
1642 if (link->dhcp_client) {
1643 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1645 log_warning_link(link, "Could not update MAC "
1646 "address in DHCP client: %s",
1654 r = sd_rtnl_message_link_get_flags(m, &flags);
1656 log_warning_link(link, "Could not get link flags");
1660 return link_update_flags(link, flags);
1663 int link_save(Link *link) {
1664 _cleanup_free_ char *temp_path = NULL;
1665 _cleanup_fclose_ FILE *f = NULL;
1670 assert(link->state_file);
1672 state = link_state_to_string(link->state);
1675 r = fopen_temporary(link->state_file, &f, &temp_path);
1679 fchmod(fileno(f), 0644);
1682 "# This is private data. Do not parse.\n"
1683 "STATE=%s\n", state);
1685 if (link->dhcp_lease) {
1686 _cleanup_free_ char *lease_file = NULL;
1688 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1693 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1697 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1702 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1704 unlink(link->state_file);
1710 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1715 static const char* const link_state_table[_LINK_STATE_MAX] = {
1716 [LINK_STATE_INITIALIZING] = "configuring",
1717 [LINK_STATE_ENSLAVING] = "configuring",
1718 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1719 [LINK_STATE_SETTING_ROUTES] = "configuring",
1720 [LINK_STATE_CONFIGURED] = "configured",
1721 [LINK_STATE_UNMANAGED] = "unmanaged",
1722 [LINK_STATE_FAILED] = "failed",
1725 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);