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 log_warning_link(link, "failed");
192 link->state = LINK_STATE_FAILED;
194 link_stop_clients(link);
199 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
200 Link *link = userdata;
203 assert(link->route_messages > 0);
204 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
205 link->state == LINK_STATE_SETTING_ROUTES ||
206 link->state == LINK_STATE_FAILED);
208 link->route_messages --;
210 if (link->state == LINK_STATE_FAILED)
213 r = sd_rtnl_message_get_errno(m);
214 if (r < 0 && r != -EEXIST)
215 log_struct_link(LOG_WARNING, link,
216 "MESSAGE=%s: could not set route: %s",
217 link->ifname, strerror(-r),
221 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
223 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
224 log_debug_link(link, "routes set");
225 link_enter_configured(link);
231 static int link_enter_set_routes(Link *link) {
236 assert(link->network);
237 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
239 link->state = LINK_STATE_SETTING_ROUTES;
241 if (!link->network->static_routes && !link->dhcp_lease &&
242 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
243 return link_enter_configured(link);
245 log_debug_link(link, "setting routes");
247 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
248 r = route_configure(rt, link, &route_handler);
250 log_warning_link(link,
251 "could not set routes: %s", strerror(-r));
252 link_enter_failed(link);
256 link->route_messages ++;
259 if (link->ipv4ll && !link->dhcp_lease) {
260 _cleanup_route_free_ Route *route = NULL;
263 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
264 if (r < 0 && r != -ENOENT) {
265 log_warning_link(link, "IPV4LL error: no address: %s",
271 r = route_new_dynamic(&route);
273 log_error_link(link, "Could not allocate route: %s",
278 route->family = AF_INET;
279 route->scope = RT_SCOPE_LINK;
282 r = route_configure(route, link, &route_handler);
284 log_warning_link(link,
285 "could not set routes: %s", strerror(-r));
286 link_enter_failed(link);
290 link->route_messages ++;
294 if (link->dhcp_lease) {
295 _cleanup_route_free_ Route *route = NULL;
296 _cleanup_route_free_ Route *route_gw = NULL;
297 struct in_addr gateway;
299 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
301 log_warning_link(link, "DHCP error: no router: %s",
306 r = route_new_dynamic(&route);
308 log_error_link(link, "Could not allocate route: %s",
313 r = route_new_dynamic(&route_gw);
315 log_error_link(link, "Could not allocate route: %s",
320 /* The dhcp netmask may mask out the gateway. Add an explicit
321 * route for the gw host so that we can route no matter the
322 * netmask or existing kernel route tables. */
323 route_gw->family = AF_INET;
324 route_gw->dst_addr.in = gateway;
325 route_gw->dst_prefixlen = 32;
326 route_gw->scope = RT_SCOPE_LINK;
328 r = route_configure(route_gw, link, &route_handler);
330 log_warning_link(link,
331 "could not set host route: %s", strerror(-r));
335 link->route_messages ++;
337 route->family = AF_INET;
338 route->in_addr.in = gateway;
340 r = route_configure(route, link, &route_handler);
342 log_warning_link(link,
343 "could not set routes: %s", strerror(-r));
344 link_enter_failed(link);
348 link->route_messages ++;
354 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
355 Link *link = userdata;
360 assert(link->ifname);
362 if (link->state == LINK_STATE_FAILED)
365 r = sd_rtnl_message_get_errno(m);
366 if (r < 0 && r != -ENOENT)
367 log_struct_link(LOG_WARNING, link,
368 "MESSAGE=%s: could not drop route: %s",
369 link->ifname, strerror(-r),
376 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
377 Link *link = userdata;
382 assert(link->ifname);
383 assert(link->addr_messages > 0);
384 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
386 link->addr_messages --;
388 if (link->state == LINK_STATE_FAILED)
391 r = sd_rtnl_message_get_errno(m);
392 if (r < 0 && r != -EEXIST)
393 log_struct_link(LOG_WARNING, link,
394 "MESSAGE=%s: could not set address: %s",
395 link->ifname, strerror(-r),
399 if (link->addr_messages == 0) {
400 log_debug_link(link, "addresses set");
401 link_enter_set_routes(link);
407 static int link_enter_set_addresses(Link *link) {
412 assert(link->network);
413 assert(link->state != _LINK_STATE_INVALID);
415 link->state = LINK_STATE_SETTING_ADDRESSES;
417 if (!link->network->static_addresses && !link->dhcp_lease &&
418 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
419 return link_enter_set_routes(link);
421 log_debug_link(link, "setting addresses");
423 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
424 r = address_configure(ad, link, &address_handler);
426 log_warning_link(link,
427 "could not set addresses: %s", strerror(-r));
428 link_enter_failed(link);
432 link->addr_messages ++;
435 if (link->ipv4ll && !link->dhcp_lease) {
436 _cleanup_address_free_ Address *ll_addr = NULL;
439 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
440 if (r < 0 && r != -ENOENT) {
441 log_warning_link(link, "IPV4LL error: no address: %s",
447 r = address_new_dynamic(&ll_addr);
449 log_error_link(link, "Could not allocate address: %s", strerror(-r));
453 ll_addr->family = AF_INET;
454 ll_addr->in_addr.in = addr;
455 ll_addr->prefixlen = 16;
456 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
457 ll_addr->scope = RT_SCOPE_LINK;
459 r = address_configure(ll_addr, link, &address_handler);
461 log_warning_link(link,
462 "could not set addresses: %s", strerror(-r));
463 link_enter_failed(link);
467 link->addr_messages ++;
471 if (link->dhcp_lease) {
472 _cleanup_address_free_ Address *address = NULL;
474 struct in_addr netmask;
477 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
479 log_warning_link(link, "DHCP error: no address: %s",
484 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
486 log_warning_link(link, "DHCP error: no netmask: %s",
491 prefixlen = net_netmask_to_prefixlen(&netmask);
493 r = address_new_dynamic(&address);
495 log_error_link(link, "Could not allocate address: %s",
500 address->family = AF_INET;
501 address->in_addr.in = addr;
502 address->prefixlen = prefixlen;
503 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
505 r = address_configure(address, link, &address_handler);
507 log_warning_link(link,
508 "could not set addresses: %s", strerror(-r));
509 link_enter_failed(link);
513 link->addr_messages ++;
519 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
520 Link *link = userdata;
525 assert(link->ifname);
527 if (link->state == LINK_STATE_FAILED)
530 r = sd_rtnl_message_get_errno(m);
531 if (r < 0 && r != -ENOENT)
532 log_struct_link(LOG_WARNING, link,
533 "MESSAGE=%s: could not update address: %s",
534 link->ifname, strerror(-r),
541 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
542 Link *link = userdata;
547 assert(link->ifname);
549 if (link->state == LINK_STATE_FAILED)
552 r = sd_rtnl_message_get_errno(m);
553 if (r < 0 && r != -ENOENT)
554 log_struct_link(LOG_WARNING, link,
555 "MESSAGE=%s: could not drop address: %s",
556 link->ifname, strerror(-r),
563 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
566 r = sd_bus_message_get_errno(m);
568 log_warning("Could not set hostname: %s", strerror(-r));
573 static int set_hostname(sd_bus *bus, const char *hostname) {
574 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
579 log_debug("Setting transient hostname: '%s'", hostname);
581 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
582 log_info("Not connected to system bus, ignoring transient hostname.");
586 r = sd_bus_message_new_method_call(
589 "org.freedesktop.hostname1",
590 "/org/freedesktop/hostname1",
591 "org.freedesktop.hostname1",
596 r = sd_bus_message_append(m, "sb", hostname, false);
600 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
602 log_error("Could not set transient hostname: %s", strerror(-r));
607 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
608 Link *link = userdata;
613 assert(link->ifname);
615 if (link->state == LINK_STATE_FAILED)
618 r = sd_rtnl_message_get_errno(m);
620 log_struct_link(LOG_WARNING, link,
621 "MESSAGE=%s: could not set MTU: %s",
622 link->ifname, strerror(-r),
629 static int link_set_mtu(Link *link, uint32_t mtu) {
630 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
634 assert(link->manager);
635 assert(link->manager->rtnl);
637 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
639 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
640 RTM_SETLINK, link->ifindex);
642 log_error_link(link, "Could not allocate RTM_SETLINK message");
646 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
648 log_error_link(link, "Could not append MTU: %s", strerror(-r));
652 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
655 "Could not send rtnetlink message: %s", strerror(-r));
662 static int dhcp_lease_lost(Link *link) {
663 _cleanup_address_free_ Address *address = NULL;
664 _cleanup_route_free_ Route *route_gw = NULL;
665 _cleanup_route_free_ Route *route = NULL;
667 struct in_addr netmask;
668 struct in_addr gateway;
673 assert(link->dhcp_lease);
675 log_warning_link(link, "DHCP lease lost");
677 r = address_new_dynamic(&address);
679 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
680 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
681 sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
682 prefixlen = net_netmask_to_prefixlen(&netmask);
684 r = route_new_dynamic(&route_gw);
686 route_gw->family = AF_INET;
687 route_gw->dst_addr.in = gateway;
688 route_gw->dst_prefixlen = 32;
689 route_gw->scope = RT_SCOPE_LINK;
691 route_drop(route_gw, link, &route_drop_handler);
694 r = route_new_dynamic(&route);
696 route->family = AF_INET;
697 route->in_addr.in = gateway;
699 route_drop(route, link, &route_drop_handler);
702 address->family = AF_INET;
703 address->in_addr.in = addr;
704 address->prefixlen = prefixlen;
706 address_drop(address, link, &address_drop_handler);
709 if (link->network->dhcp_mtu) {
712 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
713 if (r >= 0 && link->original_mtu != mtu) {
714 r = link_set_mtu(link, link->original_mtu);
716 log_warning_link(link, "DHCP error: could not reset MTU");
717 link_enter_failed(link);
723 if (link->network->dhcp_hostname) {
724 const char *hostname = NULL;
726 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
727 if (r >= 0 && hostname) {
728 r = set_hostname(link->manager->bus, "");
730 log_error("Failed to reset transient hostname");
734 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
739 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
740 sd_dhcp_lease *lease;
741 struct in_addr address;
742 struct in_addr netmask;
743 struct in_addr gateway;
745 struct in_addr *nameservers;
746 size_t nameservers_size;
752 r = sd_dhcp_client_get_lease(client, &lease);
754 log_warning_link(link, "DHCP error: no lease: %s",
759 r = sd_dhcp_lease_get_address(lease, &address);
761 log_warning_link(link, "DHCP error: no address: %s",
766 r = sd_dhcp_lease_get_netmask(lease, &netmask);
768 log_warning_link(link, "DHCP error: no netmask: %s",
773 prefixlen = net_netmask_to_prefixlen(&netmask);
775 r = sd_dhcp_lease_get_router(lease, &gateway);
777 log_warning_link(link, "DHCP error: no router: %s",
782 log_struct_link(LOG_INFO, link,
783 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
785 ADDRESS_FMT_VAL(address),
787 ADDRESS_FMT_VAL(gateway),
788 "ADDRESS=%u.%u.%u.%u",
789 ADDRESS_FMT_VAL(address),
792 "GATEWAY=%u.%u.%u.%u",
793 ADDRESS_FMT_VAL(gateway),
796 link->dhcp_lease = lease;
798 if (link->network->dhcp_dns) {
799 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
801 r = manager_update_resolv_conf(link->manager);
803 log_error("Failed to update resolv.conf");
807 if (link->network->dhcp_mtu) {
810 r = sd_dhcp_lease_get_mtu(lease, &mtu);
812 r = link_set_mtu(link, mtu);
814 log_error_link(link, "Failed to set MTU "
819 if (link->network->dhcp_hostname) {
820 const char *hostname;
822 r = sd_dhcp_lease_get_hostname(lease, &hostname);
824 r = set_hostname(link->manager->bus, hostname);
826 log_error("Failed to set transient hostname "
827 "to '%s'", hostname);
831 link_enter_set_addresses(link);
836 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
837 Link *link = userdata;
841 assert(link->network);
842 assert(link->manager);
844 if (link->state == LINK_STATE_FAILED)
848 case DHCP_EVENT_NO_LEASE:
849 log_debug_link(link, "IP address in use.");
851 case DHCP_EVENT_EXPIRED:
852 case DHCP_EVENT_STOP:
853 case DHCP_EVENT_IP_CHANGE:
854 if (link->network->dhcp_critical) {
855 log_error_link(link, "DHCPv4 connection considered system critical, "
856 "ignoring request to reconfigure it.");
860 if (link->dhcp_lease) {
861 r = dhcp_lease_lost(link);
863 link_enter_failed(link);
868 if (event == DHCP_EVENT_IP_CHANGE) {
869 r = dhcp_lease_acquired(client, link);
871 link_enter_failed(link);
876 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
877 if (!sd_ipv4ll_is_running(link->ipv4ll))
878 r = sd_ipv4ll_start(link->ipv4ll);
879 else if (ipv4ll_is_bound(link->ipv4ll))
880 r = ipv4ll_address_update(link, false);
882 link_enter_failed(link);
888 case DHCP_EVENT_IP_ACQUIRE:
889 r = dhcp_lease_acquired(client, link);
891 link_enter_failed(link);
895 if (ipv4ll_is_bound(link->ipv4ll))
896 r = ipv4ll_address_update(link, true);
898 r = sd_ipv4ll_stop(link->ipv4ll);
900 link_enter_failed(link);
907 log_warning_link(link, "DHCP error: %s", strerror(-event));
909 log_warning_link(link, "DHCP unknown event: %d", event);
916 static int ipv4ll_address_update(Link *link, bool deprecate) {
922 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
924 _cleanup_address_free_ Address *address = NULL;
926 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
927 deprecate ? "deprecate" : "approve",
928 ADDRESS_FMT_VAL(addr));
930 r = address_new_dynamic(&address);
932 log_error_link(link, "Could not allocate address: %s", strerror(-r));
936 address->family = AF_INET;
937 address->in_addr.in = addr;
938 address->prefixlen = 16;
939 address->scope = RT_SCOPE_LINK;
940 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
941 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
943 address_update(address, link, &address_update_handler);
950 static int ipv4ll_address_lost(Link *link) {
956 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
958 _cleanup_address_free_ Address *address = NULL;
959 _cleanup_route_free_ Route *route = NULL;
961 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
962 ADDRESS_FMT_VAL(addr));
964 r = address_new_dynamic(&address);
966 log_error_link(link, "Could not allocate address: %s", strerror(-r));
970 address->family = AF_INET;
971 address->in_addr.in = addr;
972 address->prefixlen = 16;
973 address->scope = RT_SCOPE_LINK;
975 address_drop(address, link, &address_drop_handler);
977 r = route_new_dynamic(&route);
979 log_error_link(link, "Could not allocate route: %s",
984 route->family = AF_INET;
985 route->scope = RT_SCOPE_LINK;
988 route_drop(route, link, &route_drop_handler);
994 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1000 r = sd_ipv4ll_get_address(ll, &addr);
1006 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1007 struct in_addr address;
1013 r = sd_ipv4ll_get_address(ll, &address);
1017 log_struct_link(LOG_INFO, link,
1018 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1020 ADDRESS_FMT_VAL(address),
1023 link_enter_set_addresses(link);
1028 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1029 Link *link = userdata;
1033 assert(link->network);
1034 assert(link->manager);
1037 case IPV4LL_EVENT_STOP:
1038 case IPV4LL_EVENT_CONFLICT:
1039 r = ipv4ll_address_lost(link);
1041 link_enter_failed(link);
1045 case IPV4LL_EVENT_BIND:
1046 r = ipv4ll_address_claimed(ll, link);
1048 link_enter_failed(link);
1054 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1056 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1061 static int link_acquire_conf(Link *link) {
1065 assert(link->network);
1066 assert(link->manager);
1067 assert(link->manager->event);
1069 if (link->network->ipv4ll) {
1070 assert(link->ipv4ll);
1072 log_debug_link(link, "acquiring IPv4 link-local address");
1074 r = sd_ipv4ll_start(link->ipv4ll);
1079 if (link->network->dhcp) {
1080 assert(link->dhcp_client);
1082 log_debug_link(link, "acquiring DHCPv4 lease");
1084 r = sd_dhcp_client_start(link->dhcp_client);
1092 static int link_update_flags(Link *link, unsigned flags) {
1093 unsigned flags_added, flags_removed, generic_flags;
1094 bool carrier_gained, carrier_lost;
1099 if (link->state == LINK_STATE_FAILED)
1102 if (link->flags == flags)
1105 flags_added = (link->flags ^ flags) & flags;
1106 flags_removed = (link->flags ^ flags) & link->flags;
1107 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1108 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1109 IFF_NOARP | IFF_MASTER | IFF_SLAVE);
1111 /* consider link to have carrier when LOWER_UP and !DORMANT
1113 TODO: use proper operstates once we start supporting 802.1X
1115 see Documentation/networking/operstates.txt in the kernel sources
1117 carrier_gained = (((flags_added & IFF_LOWER_UP) && !(flags & IFF_DORMANT)) ||
1118 ((flags_removed & IFF_DORMANT) && (flags & IFF_LOWER_UP)));
1119 carrier_lost = ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT)) &&
1120 ((flags_removed & IFF_LOWER_UP) || (flags_added & IFF_DORMANT));
1122 link->flags = flags;
1125 /* not currently managing this link
1126 we track state changes, but don't log them
1127 they will be logged if and when a network is
1131 if (flags_added & IFF_UP)
1132 log_info_link(link, "link is up");
1133 else if (flags_removed & IFF_UP)
1134 log_info_link(link, "link is down");
1136 if (flags_added & IFF_LOWER_UP)
1137 log_debug_link(link, "link is lower up");
1138 else if (flags_removed & IFF_LOWER_UP)
1139 log_debug_link(link, "link is lower down");
1141 if (flags_added & IFF_DORMANT)
1142 log_debug_link(link, "link is dormant");
1143 else if (flags_removed & IFF_DORMANT)
1144 log_debug_link(link, "link is not dormant");
1146 if (flags_added & IFF_DEBUG)
1147 log_debug_link(link, "debugging enabled in the kernel");
1148 else if (flags_removed & IFF_DEBUG)
1149 log_debug_link(link, "debugging disabled in the kernel");
1151 if (flags_added & IFF_MULTICAST)
1152 log_debug_link(link, "multicast enabled");
1153 else if (flags_removed & IFF_MULTICAST)
1154 log_debug_link(link, "multicast disabled");
1156 if (flags_added & IFF_BROADCAST)
1157 log_debug_link(link, "broadcast enabled");
1158 else if (flags_removed & IFF_BROADCAST)
1159 log_debug_link(link, "broadcast disabled");
1161 if (flags_added & IFF_PROMISC)
1162 log_debug_link(link, "promiscuous mode enabled");
1163 else if (flags_removed & IFF_PROMISC)
1164 log_debug_link(link, "promiscuous mode disabled");
1166 if (flags_added & IFF_NOARP)
1167 log_debug_link(link, "ARP protocol disabled");
1168 else if (flags_removed & IFF_NOARP)
1169 log_debug_link(link, "ARP protocol enabled");
1171 if (flags_added & IFF_MASTER)
1172 log_debug_link(link, "link is master");
1173 else if (flags_removed & IFF_MASTER)
1174 log_debug_link(link, "link is no longer master");
1176 if (flags_added & IFF_SLAVE)
1177 log_debug_link(link, "link is slave");
1178 else if (flags_removed & IFF_SLAVE)
1179 log_debug_link(link, "link is no longer slave");
1181 /* link flags are currently at most 18 bits, let's default to printing 20 */
1182 if (flags_added & generic_flags)
1183 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1184 flags_added & generic_flags);
1186 if (flags_removed & generic_flags)
1187 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1188 flags_removed & generic_flags);
1190 if (carrier_gained) {
1191 log_info_link(link, "gained carrier");
1193 if (link->network->dhcp || link->network->ipv4ll) {
1194 r = link_acquire_conf(link);
1196 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
1197 link_enter_failed(link);
1201 } else if (carrier_lost) {
1202 log_info_link(link, "lost carrier");
1204 if (link->network->dhcp) {
1205 r = sd_dhcp_client_stop(link->dhcp_client);
1207 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
1208 link_enter_failed(link);
1213 if (link->network->ipv4ll) {
1214 r = sd_ipv4ll_stop(link->ipv4ll);
1216 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
1217 link_enter_failed(link);
1226 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1227 Link *link = userdata;
1232 if (link->state == LINK_STATE_FAILED)
1235 r = sd_rtnl_message_get_errno(m);
1237 link_update_flags(link, link->flags | IFF_UP);
1239 log_struct_link(LOG_WARNING, link,
1240 "MESSAGE=%s: could not bring up interface: %s",
1241 link->ifname, strerror(-r),
1247 static int link_up(Link *link) {
1248 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1252 assert(link->manager);
1253 assert(link->manager->rtnl);
1255 log_debug_link(link, "bringing link up");
1257 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1258 RTM_SETLINK, link->ifindex);
1260 log_error_link(link, "Could not allocate RTM_SETLINK message");
1264 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1266 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1270 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1272 log_error_link(link,
1273 "Could not send rtnetlink message: %s", strerror(-r));
1280 static int link_enslaved(Link *link) {
1284 assert(link->state == LINK_STATE_ENSLAVING);
1285 assert(link->network);
1287 if (!(link->flags & IFF_UP)) {
1290 link_enter_failed(link);
1295 if (!link->network->dhcp && !link->network->ipv4ll)
1296 return link_enter_set_addresses(link);
1301 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1302 Link *link = userdata;
1306 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1307 assert(link->network);
1311 if (link->state == LINK_STATE_FAILED)
1314 r = sd_rtnl_message_get_errno(m);
1316 log_struct_link(LOG_ERR, link,
1317 "MESSAGE=%s: could not enslave: %s",
1318 link->ifname, strerror(-r),
1321 link_enter_failed(link);
1325 log_debug_link(link, "enslaved");
1327 if (link->enslaving == 0)
1328 link_enslaved(link);
1333 static int link_enter_enslave(Link *link) {
1334 NetDev *vlan, *macvlan;
1339 assert(link->network);
1340 assert(link->state == LINK_STATE_INITIALIZING);
1342 link->state = LINK_STATE_ENSLAVING;
1346 if (!link->network->bridge && !link->network->bond &&
1347 hashmap_isempty(link->network->vlans) &&
1348 hashmap_isempty(link->network->macvlans))
1349 return link_enslaved(link);
1351 if (link->network->bridge) {
1352 log_struct_link(LOG_DEBUG, link,
1353 "MESSAGE=%s: enslaving by '%s'",
1354 link->ifname, link->network->bridge->name,
1355 NETDEV(link->network->bridge),
1358 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1360 log_struct_link(LOG_WARNING, link,
1361 "MESSAGE=%s: could not enslave by '%s': %s",
1362 link->ifname, link->network->bridge->name, strerror(-r),
1363 NETDEV(link->network->bridge),
1365 link_enter_failed(link);
1372 if (link->network->bond) {
1373 log_struct_link(LOG_DEBUG, link,
1374 "MESSAGE=%s: enslaving by '%s'",
1375 link->ifname, link->network->bond->name,
1376 NETDEV(link->network->bond),
1379 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1381 log_struct_link(LOG_WARNING, link,
1382 "MESSAGE=%s: could not enslave by '%s': %s",
1383 link->ifname, link->network->bond->name, strerror(-r),
1384 NETDEV(link->network->bond),
1386 link_enter_failed(link);
1393 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1394 log_struct_link(LOG_DEBUG, link,
1395 "MESSAGE=%s: enslaving by '%s'",
1396 link->ifname, vlan->name, NETDEV(vlan), NULL);
1398 r = netdev_enslave(vlan, link, &enslave_handler);
1400 log_struct_link(LOG_WARNING, link,
1401 "MESSAGE=%s: could not enslave by '%s': %s",
1402 link->ifname, vlan->name, strerror(-r),
1403 NETDEV(vlan), NULL);
1404 link_enter_failed(link);
1411 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1412 log_struct_link(LOG_DEBUG, link,
1413 "MESSAGE=%s: enslaving by '%s'",
1414 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1416 r = netdev_enslave(macvlan, link, &enslave_handler);
1418 log_struct_link(LOG_WARNING, link,
1419 "MESSAGE=%s: could not enslave by '%s': %s",
1420 link->ifname, macvlan->name, strerror(-r),
1421 NETDEV(macvlan), NULL);
1422 link_enter_failed(link);
1432 static int link_configure(Link *link) {
1436 assert(link->state == LINK_STATE_INITIALIZING);
1438 if (link->network->ipv4ll) {
1440 r = sd_ipv4ll_new(&link->ipv4ll);
1444 if (link->udev_device) {
1445 r = net_get_unique_predictable_data(link->udev_device, seed);
1447 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1453 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1457 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1461 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1465 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1470 if (link->network->dhcp) {
1471 r = sd_dhcp_client_new(&link->dhcp_client);
1475 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1479 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1483 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1487 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1491 if (link->network->dhcp_mtu) {
1492 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1498 return link_enter_enslave(link);
1501 int link_initialized(Link *link, struct udev_device *device) {
1507 assert(link->ifname);
1508 assert(link->manager);
1510 if (link->state != LINK_STATE_INITIALIZING)
1514 link->udev_device = udev_device_ref(device);
1516 log_debug_link(link, "link initialized");
1518 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1520 link_enter_unmanaged(link);
1525 r = network_apply(link->manager, network, link);
1529 r = link_configure(link);
1533 /* re-trigger all state updates */
1534 flags = link->flags;
1536 r = link_update_flags(link, flags);
1543 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1545 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1546 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1553 r = link_new(m, message, ret);
1559 log_info_link(link, "link added");
1561 if (detect_container(NULL) <= 0) {
1562 /* not in a container, udev will be around */
1563 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1564 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1566 log_warning_link(link, "could not find udev device");
1570 if (udev_device_get_is_initialized(device) <= 0)
1575 r = link_initialized(link, device);
1582 int link_update(Link *link, sd_rtnl_message *m) {
1584 struct ether_addr mac;
1589 assert(link->ifname);
1592 if (link->state == LINK_STATE_FAILED || link->state == LINK_STATE_UNMANAGED)
1595 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1596 if (r >= 0 && !streq(ifname, link->ifname)) {
1597 log_info_link(link, "renamed to %s", ifname);
1600 link->ifname = strdup(ifname);
1605 if (!link->original_mtu) {
1606 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1608 log_debug_link(link, "saved original MTU: %"
1609 PRIu16, link->original_mtu);
1612 /* The kernel may broadcast NEWLINK messages without the MAC address
1613 set, simply ignore them. */
1614 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1616 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1618 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1620 log_debug_link(link, "MAC address: "
1621 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1622 mac.ether_addr_octet[0],
1623 mac.ether_addr_octet[1],
1624 mac.ether_addr_octet[2],
1625 mac.ether_addr_octet[3],
1626 mac.ether_addr_octet[4],
1627 mac.ether_addr_octet[5]);
1630 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1632 log_warning_link(link, "Could not update MAC "
1633 "address in IPv4LL client: %s",
1639 if (link->dhcp_client) {
1640 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1642 log_warning_link(link, "Could not update MAC "
1643 "address in DHCP client: %s",
1651 r = sd_rtnl_message_link_get_flags(m, &flags);
1653 log_warning_link(link, "Could not get link flags");
1657 return link_update_flags(link, flags);
1660 int link_save(Link *link) {
1661 _cleanup_free_ char *temp_path = NULL;
1662 _cleanup_fclose_ FILE *f = NULL;
1667 assert(link->state_file);
1669 state = link_state_to_string(link->state);
1672 r = fopen_temporary(link->state_file, &f, &temp_path);
1676 fchmod(fileno(f), 0644);
1679 "# This is private data. Do not parse.\n"
1680 "STATE=%s\n", state);
1682 if (link->dhcp_lease) {
1683 _cleanup_free_ char *lease_file = NULL;
1685 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1690 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1694 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1699 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1701 unlink(link->state_file);
1707 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1712 static const char* const link_state_table[_LINK_STATE_MAX] = {
1713 [LINK_STATE_INITIALIZING] = "configuring",
1714 [LINK_STATE_ENSLAVING] = "configuring",
1715 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1716 [LINK_STATE_SETTING_ROUTES] = "configuring",
1717 [LINK_STATE_CONFIGURED] = "configured",
1718 [LINK_STATE_UNMANAGED] = "unmanaged",
1719 [LINK_STATE_FAILED] = "failed",
1722 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);