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 "network-util.h"
34 #include "dhcp-lease-internal.h"
36 static int ipv4ll_address_update(Link *link, bool deprecate);
37 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
39 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
40 _cleanup_link_free_ Link *link = NULL;
46 assert(manager->links);
50 r = sd_rtnl_message_get_type(message, &type);
53 else if (type != RTM_NEWLINK)
56 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
59 else if (ifindex <= 0)
62 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
70 link->manager = manager;
71 link->state = LINK_STATE_INITIALIZING;
72 link->ifindex = ifindex;
73 link->ifname = strdup(ifname);
77 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
82 r = hashmap_put(manager->links, &link->ifindex, link);
92 void link_free(Link *link) {
96 assert(link->manager);
98 sd_dhcp_client_unref(link->dhcp_client);
99 sd_dhcp_lease_unref(link->dhcp_lease);
101 sd_ipv4ll_unref(link->ipv4ll);
103 hashmap_remove(link->manager->links, &link->ifindex);
106 free(link->state_file);
108 udev_device_unref(link->udev_device);
113 int link_get(Manager *m, int ifindex, Link **ret) {
122 ifindex_64 = ifindex;
123 link = hashmap_get(m->links, &ifindex_64);
132 static int link_enter_configured(Link *link) {
134 assert(link->state == LINK_STATE_SETTING_ROUTES);
136 log_info_link(link, "link configured");
138 link->state = LINK_STATE_CONFIGURED;
145 static void link_enter_unmanaged(Link *link) {
148 log_debug_link(link, "unmanaged");
150 link->state = LINK_STATE_UNMANAGED;
155 static int link_stop_clients(Link *link) {
159 assert(link->manager);
160 assert(link->manager->event);
165 if (link->network->dhcp) {
166 assert(link->dhcp_client);
168 k = sd_dhcp_client_stop(link->dhcp_client);
170 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
175 if (link->network->ipv4ll) {
176 assert(link->ipv4ll);
178 k = sd_ipv4ll_stop(link->ipv4ll);
180 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
188 static void link_enter_failed(Link *link) {
191 if (link->state == LINK_STATE_FAILED)
194 log_warning_link(link, "failed");
196 link->state = LINK_STATE_FAILED;
198 link_stop_clients(link);
203 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
204 Link *link = userdata;
207 assert(link->route_messages > 0);
208 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
209 link->state == LINK_STATE_SETTING_ROUTES ||
210 link->state == LINK_STATE_FAILED);
212 link->route_messages --;
214 if (link->state == LINK_STATE_FAILED)
217 r = sd_rtnl_message_get_errno(m);
218 if (r < 0 && r != -EEXIST)
219 log_struct_link(LOG_WARNING, link,
220 "MESSAGE=%s: could not set route: %s",
221 link->ifname, strerror(-r),
225 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
227 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
228 log_debug_link(link, "routes set");
229 link_enter_configured(link);
235 static int link_enter_set_routes(Link *link) {
240 assert(link->network);
241 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
243 link->state = LINK_STATE_SETTING_ROUTES;
245 if (!link->network->static_routes && !link->dhcp_lease &&
246 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
247 return link_enter_configured(link);
249 log_debug_link(link, "setting routes");
251 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
252 r = route_configure(rt, link, &route_handler);
254 log_warning_link(link,
255 "could not set routes: %s", strerror(-r));
256 link_enter_failed(link);
260 link->route_messages ++;
263 if (link->ipv4ll && !link->dhcp_lease) {
264 _cleanup_route_free_ Route *route = NULL;
267 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
268 if (r < 0 && r != -ENOENT) {
269 log_warning_link(link, "IPV4LL error: no address: %s",
275 r = route_new_dynamic(&route);
277 log_error_link(link, "Could not allocate route: %s",
282 route->family = AF_INET;
283 route->scope = RT_SCOPE_LINK;
286 r = route_configure(route, link, &route_handler);
288 log_warning_link(link,
289 "could not set routes: %s", strerror(-r));
290 link_enter_failed(link);
294 link->route_messages ++;
298 if (link->dhcp_lease) {
299 _cleanup_route_free_ Route *route = NULL;
300 _cleanup_route_free_ Route *route_gw = NULL;
301 struct in_addr gateway;
303 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
305 log_warning_link(link, "DHCP error: no router: %s",
310 r = route_new_dynamic(&route);
312 log_error_link(link, "Could not allocate route: %s",
317 r = route_new_dynamic(&route_gw);
319 log_error_link(link, "Could not allocate route: %s",
324 /* The dhcp netmask may mask out the gateway. Add an explicit
325 * route for the gw host so that we can route no matter the
326 * netmask or existing kernel route tables. */
327 route_gw->family = AF_INET;
328 route_gw->dst_addr.in = gateway;
329 route_gw->dst_prefixlen = 32;
330 route_gw->scope = RT_SCOPE_LINK;
332 r = route_configure(route_gw, link, &route_handler);
334 log_warning_link(link,
335 "could not set host route: %s", strerror(-r));
339 link->route_messages ++;
341 route->family = AF_INET;
342 route->in_addr.in = gateway;
344 r = route_configure(route, link, &route_handler);
346 log_warning_link(link,
347 "could not set routes: %s", strerror(-r));
348 link_enter_failed(link);
352 link->route_messages ++;
358 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
359 Link *link = userdata;
364 assert(link->ifname);
366 if (link->state == LINK_STATE_FAILED)
369 r = sd_rtnl_message_get_errno(m);
370 if (r < 0 && r != -ENOENT)
371 log_struct_link(LOG_WARNING, link,
372 "MESSAGE=%s: could not drop route: %s",
373 link->ifname, strerror(-r),
380 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
381 Link *link = userdata;
386 assert(link->ifname);
387 assert(link->addr_messages > 0);
388 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
390 link->addr_messages --;
392 if (link->state == LINK_STATE_FAILED)
395 r = sd_rtnl_message_get_errno(m);
396 if (r < 0 && r != -EEXIST)
397 log_struct_link(LOG_WARNING, link,
398 "MESSAGE=%s: could not set address: %s",
399 link->ifname, strerror(-r),
403 if (link->addr_messages == 0) {
404 log_debug_link(link, "addresses set");
405 link_enter_set_routes(link);
411 static int link_enter_set_addresses(Link *link) {
416 assert(link->network);
417 assert(link->state != _LINK_STATE_INVALID);
419 link->state = LINK_STATE_SETTING_ADDRESSES;
421 if (!link->network->static_addresses && !link->dhcp_lease &&
422 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
423 return link_enter_set_routes(link);
425 log_debug_link(link, "setting addresses");
427 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
428 r = address_configure(ad, link, &address_handler);
430 log_warning_link(link,
431 "could not set addresses: %s", strerror(-r));
432 link_enter_failed(link);
436 link->addr_messages ++;
439 if (link->ipv4ll && !link->dhcp_lease) {
440 _cleanup_address_free_ Address *ll_addr = NULL;
443 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
444 if (r < 0 && r != -ENOENT) {
445 log_warning_link(link, "IPV4LL error: no address: %s",
451 r = address_new_dynamic(&ll_addr);
453 log_error_link(link, "Could not allocate address: %s", strerror(-r));
457 ll_addr->family = AF_INET;
458 ll_addr->in_addr.in = addr;
459 ll_addr->prefixlen = 16;
460 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
461 ll_addr->scope = RT_SCOPE_LINK;
463 r = address_configure(ll_addr, link, &address_handler);
465 log_warning_link(link,
466 "could not set addresses: %s", strerror(-r));
467 link_enter_failed(link);
471 link->addr_messages ++;
475 if (link->dhcp_lease) {
476 _cleanup_address_free_ Address *address = NULL;
478 struct in_addr netmask;
481 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
483 log_warning_link(link, "DHCP error: no address: %s",
488 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
490 log_warning_link(link, "DHCP error: no netmask: %s",
495 prefixlen = net_netmask_to_prefixlen(&netmask);
497 r = address_new_dynamic(&address);
499 log_error_link(link, "Could not allocate address: %s",
504 address->family = AF_INET;
505 address->in_addr.in = addr;
506 address->prefixlen = prefixlen;
507 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
509 r = address_configure(address, link, &address_handler);
511 log_warning_link(link,
512 "could not set addresses: %s", strerror(-r));
513 link_enter_failed(link);
517 link->addr_messages ++;
523 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
524 Link *link = userdata;
529 assert(link->ifname);
531 if (link->state == LINK_STATE_FAILED)
534 r = sd_rtnl_message_get_errno(m);
535 if (r < 0 && r != -ENOENT)
536 log_struct_link(LOG_WARNING, link,
537 "MESSAGE=%s: could not update address: %s",
538 link->ifname, strerror(-r),
545 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
546 Link *link = userdata;
551 assert(link->ifname);
553 if (link->state == LINK_STATE_FAILED)
556 r = sd_rtnl_message_get_errno(m);
557 if (r < 0 && r != -ENOENT)
558 log_struct_link(LOG_WARNING, link,
559 "MESSAGE=%s: could not drop address: %s",
560 link->ifname, strerror(-r),
567 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
570 r = sd_bus_message_get_errno(m);
572 log_warning("Could not set hostname: %s", strerror(-r));
577 static int set_hostname(sd_bus *bus, const char *hostname) {
578 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
583 log_debug("Setting transient hostname: '%s'", hostname);
585 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
586 log_info("Not connected to system bus, ignoring transient hostname.");
590 r = sd_bus_message_new_method_call(
593 "org.freedesktop.hostname1",
594 "/org/freedesktop/hostname1",
595 "org.freedesktop.hostname1",
600 r = sd_bus_message_append(m, "sb", hostname, false);
604 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
606 log_error("Could not set transient hostname: %s", strerror(-r));
611 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
612 Link *link = userdata;
617 assert(link->ifname);
619 if (link->state == LINK_STATE_FAILED)
622 r = sd_rtnl_message_get_errno(m);
624 log_struct_link(LOG_WARNING, link,
625 "MESSAGE=%s: could not set MTU: %s",
626 link->ifname, strerror(-r),
633 static int link_set_mtu(Link *link, uint32_t mtu) {
634 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
638 assert(link->manager);
639 assert(link->manager->rtnl);
641 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
643 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
644 RTM_SETLINK, link->ifindex);
646 log_error_link(link, "Could not allocate RTM_SETLINK message");
650 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
652 log_error_link(link, "Could not append MTU: %s", strerror(-r));
656 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
659 "Could not send rtnetlink message: %s", strerror(-r));
666 static int dhcp_lease_lost(Link *link) {
667 _cleanup_address_free_ Address *address = NULL;
668 _cleanup_route_free_ Route *route_gw = NULL;
669 _cleanup_route_free_ Route *route = NULL;
671 struct in_addr netmask;
672 struct in_addr gateway;
677 assert(link->dhcp_lease);
679 log_warning_link(link, "DHCP lease lost");
681 r = address_new_dynamic(&address);
683 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
684 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
685 sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
686 prefixlen = net_netmask_to_prefixlen(&netmask);
688 r = route_new_dynamic(&route_gw);
690 route_gw->family = AF_INET;
691 route_gw->dst_addr.in = gateway;
692 route_gw->dst_prefixlen = 32;
693 route_gw->scope = RT_SCOPE_LINK;
695 route_drop(route_gw, link, &route_drop_handler);
698 r = route_new_dynamic(&route);
700 route->family = AF_INET;
701 route->in_addr.in = gateway;
703 route_drop(route, link, &route_drop_handler);
706 address->family = AF_INET;
707 address->in_addr.in = addr;
708 address->prefixlen = prefixlen;
710 address_drop(address, link, &address_drop_handler);
713 if (link->network->dhcp_mtu) {
716 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
717 if (r >= 0 && link->original_mtu != mtu) {
718 r = link_set_mtu(link, link->original_mtu);
720 log_warning_link(link, "DHCP error: could not reset MTU");
721 link_enter_failed(link);
727 if (link->network->dhcp_hostname) {
728 const char *hostname = NULL;
730 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
731 if (r >= 0 && hostname) {
732 r = set_hostname(link->manager->bus, "");
734 log_error("Failed to reset transient hostname");
738 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
743 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
744 sd_dhcp_lease *lease;
745 struct in_addr address;
746 struct in_addr netmask;
747 struct in_addr gateway;
749 struct in_addr *nameservers;
750 size_t nameservers_size;
756 r = sd_dhcp_client_get_lease(client, &lease);
758 log_warning_link(link, "DHCP error: no lease: %s",
763 r = sd_dhcp_lease_get_address(lease, &address);
765 log_warning_link(link, "DHCP error: no address: %s",
770 r = sd_dhcp_lease_get_netmask(lease, &netmask);
772 log_warning_link(link, "DHCP error: no netmask: %s",
777 prefixlen = net_netmask_to_prefixlen(&netmask);
779 r = sd_dhcp_lease_get_router(lease, &gateway);
781 log_warning_link(link, "DHCP error: no router: %s",
786 log_struct_link(LOG_INFO, link,
787 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
789 ADDRESS_FMT_VAL(address),
791 ADDRESS_FMT_VAL(gateway),
792 "ADDRESS=%u.%u.%u.%u",
793 ADDRESS_FMT_VAL(address),
796 "GATEWAY=%u.%u.%u.%u",
797 ADDRESS_FMT_VAL(gateway),
800 link->dhcp_lease = lease;
802 if (link->network->dhcp_dns) {
803 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
805 r = manager_update_resolv_conf(link->manager);
807 log_error("Failed to update resolv.conf");
811 if (link->network->dhcp_mtu) {
814 r = sd_dhcp_lease_get_mtu(lease, &mtu);
816 r = link_set_mtu(link, mtu);
818 log_error_link(link, "Failed to set MTU "
823 if (link->network->dhcp_hostname) {
824 const char *hostname;
826 r = sd_dhcp_lease_get_hostname(lease, &hostname);
828 r = set_hostname(link->manager->bus, hostname);
830 log_error("Failed to set transient hostname "
831 "to '%s'", hostname);
835 link_enter_set_addresses(link);
840 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
841 Link *link = userdata;
845 assert(link->network);
846 assert(link->manager);
848 if (link->state == LINK_STATE_FAILED)
852 case DHCP_EVENT_NO_LEASE:
853 log_debug_link(link, "IP address in use.");
855 case DHCP_EVENT_EXPIRED:
856 case DHCP_EVENT_STOP:
857 case DHCP_EVENT_IP_CHANGE:
858 if (link->network->dhcp_critical) {
859 log_error_link(link, "DHCPv4 connection considered system critical, "
860 "ignoring request to reconfigure it.");
864 if (link->dhcp_lease) {
865 r = dhcp_lease_lost(link);
867 link_enter_failed(link);
872 if (event == DHCP_EVENT_IP_CHANGE) {
873 r = dhcp_lease_acquired(client, link);
875 link_enter_failed(link);
880 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
881 if (!sd_ipv4ll_is_running(link->ipv4ll))
882 r = sd_ipv4ll_start(link->ipv4ll);
883 else if (ipv4ll_is_bound(link->ipv4ll))
884 r = ipv4ll_address_update(link, false);
886 link_enter_failed(link);
892 case DHCP_EVENT_IP_ACQUIRE:
893 r = dhcp_lease_acquired(client, link);
895 link_enter_failed(link);
899 if (ipv4ll_is_bound(link->ipv4ll))
900 r = ipv4ll_address_update(link, true);
902 r = sd_ipv4ll_stop(link->ipv4ll);
904 link_enter_failed(link);
911 log_warning_link(link, "DHCP error: %s", strerror(-event));
913 log_warning_link(link, "DHCP unknown event: %d", event);
920 static int ipv4ll_address_update(Link *link, bool deprecate) {
926 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
928 _cleanup_address_free_ Address *address = NULL;
930 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
931 deprecate ? "deprecate" : "approve",
932 ADDRESS_FMT_VAL(addr));
934 r = address_new_dynamic(&address);
936 log_error_link(link, "Could not allocate address: %s", strerror(-r));
940 address->family = AF_INET;
941 address->in_addr.in = addr;
942 address->prefixlen = 16;
943 address->scope = RT_SCOPE_LINK;
944 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
945 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
947 address_update(address, link, &address_update_handler);
954 static int ipv4ll_address_lost(Link *link) {
960 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
962 _cleanup_address_free_ Address *address = NULL;
963 _cleanup_route_free_ Route *route = NULL;
965 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
966 ADDRESS_FMT_VAL(addr));
968 r = address_new_dynamic(&address);
970 log_error_link(link, "Could not allocate address: %s", strerror(-r));
974 address->family = AF_INET;
975 address->in_addr.in = addr;
976 address->prefixlen = 16;
977 address->scope = RT_SCOPE_LINK;
979 address_drop(address, link, &address_drop_handler);
981 r = route_new_dynamic(&route);
983 log_error_link(link, "Could not allocate route: %s",
988 route->family = AF_INET;
989 route->scope = RT_SCOPE_LINK;
992 route_drop(route, link, &route_drop_handler);
998 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1000 struct in_addr addr;
1004 r = sd_ipv4ll_get_address(ll, &addr);
1010 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1011 struct in_addr address;
1017 r = sd_ipv4ll_get_address(ll, &address);
1021 log_struct_link(LOG_INFO, link,
1022 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1024 ADDRESS_FMT_VAL(address),
1027 link_enter_set_addresses(link);
1032 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1033 Link *link = userdata;
1037 assert(link->network);
1038 assert(link->manager);
1041 case IPV4LL_EVENT_STOP:
1042 case IPV4LL_EVENT_CONFLICT:
1043 r = ipv4ll_address_lost(link);
1045 link_enter_failed(link);
1049 case IPV4LL_EVENT_BIND:
1050 r = ipv4ll_address_claimed(ll, link);
1052 link_enter_failed(link);
1058 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1060 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1065 static int link_acquire_conf(Link *link) {
1069 assert(link->network);
1070 assert(link->manager);
1071 assert(link->manager->event);
1073 if (link->network->ipv4ll) {
1074 assert(link->ipv4ll);
1076 log_debug_link(link, "acquiring IPv4 link-local address");
1078 r = sd_ipv4ll_start(link->ipv4ll);
1080 log_warning_link(link, "could not acquire IPv4 "
1081 "link-local address");
1086 if (link->network->dhcp) {
1087 assert(link->dhcp_client);
1089 log_debug_link(link, "acquiring DHCPv4 lease");
1091 r = sd_dhcp_client_start(link->dhcp_client);
1093 log_warning_link(link, "could not acquire DHCPv4 "
1102 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1103 unsigned flags, flags_added, flags_removed, generic_flags;
1105 bool carrier_gained = false, carrier_lost = false;
1110 if (link->state == LINK_STATE_FAILED)
1113 r = sd_rtnl_message_link_get_flags(m, &flags);
1115 log_warning_link(link, "Could not get link flags");
1119 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1121 /* if we got a message without operstate, take it to mean
1122 the state was unchanged */
1123 operstate = link->operstate;
1125 if ((link->flags == flags) && (link->operstate == operstate))
1128 flags_added = (link->flags ^ flags) & flags;
1129 flags_removed = (link->flags ^ flags) & link->flags;
1130 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1131 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
1132 IFF_NOARP | IFF_MASTER | IFF_SLAVE | IFF_RUNNING);
1134 if (flags_added & IFF_UP)
1135 log_debug_link(link, "link is up");
1136 else if (flags_removed & IFF_UP)
1137 log_debug_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 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1194 link_has_carrier(flags, operstate);
1195 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1196 !link_has_carrier(flags, operstate);
1198 link->flags = flags;
1199 link->operstate = operstate;
1201 if (carrier_gained) {
1202 log_info_link(link, "gained carrier");
1204 if (link->network) {
1205 r = link_acquire_conf(link);
1207 link_enter_failed(link);
1211 } else if (carrier_lost) {
1212 log_info_link(link, "lost carrier");
1214 r = link_stop_clients(link);
1216 link_enter_failed(link);
1224 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1225 Link *link = userdata;
1230 if (link->state == LINK_STATE_FAILED)
1233 r = sd_rtnl_message_get_errno(m);
1235 /* we warn but don't fail the link, as it may
1236 be brought up later */
1237 log_struct_link(LOG_WARNING, link,
1238 "MESSAGE=%s: could not bring up interface: %s",
1239 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) {
1441 r = sd_ipv4ll_new(&link->ipv4ll);
1445 if (link->udev_device) {
1446 r = net_get_unique_predictable_data(link->udev_device, seed);
1448 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1454 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1458 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1462 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1466 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1471 if (link->network->dhcp) {
1472 r = sd_dhcp_client_new(&link->dhcp_client);
1476 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1480 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1484 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1488 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1492 if (link->network->dhcp_mtu) {
1493 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1499 if (link_has_carrier(link->flags, link->operstate))
1501 r = link_acquire_conf(link);
1506 return link_enter_enslave(link);
1509 int link_initialized(Link *link, struct udev_device *device) {
1514 assert(link->ifname);
1515 assert(link->manager);
1517 if (link->state != LINK_STATE_INITIALIZING)
1521 link->udev_device = udev_device_ref(device);
1523 log_debug_link(link, "link initialized");
1525 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
1527 link_enter_unmanaged(link);
1532 r = network_apply(link->manager, network, link);
1536 r = link_configure(link);
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_debug_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) {
1583 struct ether_addr mac;
1588 assert(link->ifname);
1591 if (link->state == LINK_STATE_FAILED || link->state == LINK_STATE_UNMANAGED)
1594 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1595 if (r >= 0 && !streq(ifname, link->ifname)) {
1596 log_info_link(link, "renamed to %s", ifname);
1599 link->ifname = strdup(ifname);
1604 if (!link->original_mtu) {
1605 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1607 log_debug_link(link, "saved original MTU: %"
1608 PRIu16, link->original_mtu);
1611 /* The kernel may broadcast NEWLINK messages without the MAC address
1612 set, simply ignore them. */
1613 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1615 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1617 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1619 log_debug_link(link, "MAC address: "
1620 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1621 mac.ether_addr_octet[0],
1622 mac.ether_addr_octet[1],
1623 mac.ether_addr_octet[2],
1624 mac.ether_addr_octet[3],
1625 mac.ether_addr_octet[4],
1626 mac.ether_addr_octet[5]);
1629 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1631 log_warning_link(link, "Could not update MAC "
1632 "address in IPv4LL client: %s",
1638 if (link->dhcp_client) {
1639 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1641 log_warning_link(link, "Could not update MAC "
1642 "address in DHCP client: %s",
1650 return link_update_flags(link, m);
1653 int link_save(Link *link) {
1654 _cleanup_free_ char *temp_path = NULL;
1655 _cleanup_fclose_ FILE *f = NULL;
1660 assert(link->state_file);
1662 state = link_state_to_string(link->state);
1665 r = fopen_temporary(link->state_file, &f, &temp_path);
1669 fchmod(fileno(f), 0644);
1672 "# This is private data. Do not parse.\n"
1673 "STATE=%s\n", state);
1675 if (link->dhcp_lease) {
1676 _cleanup_free_ char *lease_file = NULL;
1678 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1683 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1687 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1692 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1694 unlink(link->state_file);
1700 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1705 static const char* const link_state_table[_LINK_STATE_MAX] = {
1706 [LINK_STATE_INITIALIZING] = "configuring",
1707 [LINK_STATE_ENSLAVING] = "configuring",
1708 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1709 [LINK_STATE_SETTING_ROUTES] = "configuring",
1710 [LINK_STATE_CONFIGURED] = "configured",
1711 [LINK_STATE_UNMANAGED] = "unmanaged",
1712 [LINK_STATE_FAILED] = "failed",
1715 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);