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>
27 #include "libudev-private.h"
28 #include "udev-util.h"
32 #include "network-internal.h"
33 #include "conf-parser.h"
35 #include "network-util.h"
36 #include "dhcp-lease-internal.h"
38 static int ipv4ll_address_update(Link *link, bool deprecate);
39 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
41 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
42 _cleanup_link_unref_ Link *link = NULL;
48 assert(manager->links);
52 r = sd_rtnl_message_get_type(message, &type);
55 else if (type != RTM_NEWLINK)
58 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
61 else if (ifindex <= 0)
64 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
73 link->manager = manager;
74 link->state = LINK_STATE_INITIALIZING;
75 link->ifindex = ifindex;
76 link->ifname = strdup(ifname);
80 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
82 log_debug_link(link, "MAC address not found for new device, continuing without");
84 r = asprintf(&link->state_file, "/run/systemd/netif/links/%"PRIu64,
89 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%"PRIu64,
94 r = hashmap_put(manager->links, &link->ifindex, link);
104 static void link_free(Link *link) {
110 while ((address = link->addresses)) {
111 LIST_REMOVE(addresses, link->addresses, address);
112 address_free(address);
115 while ((address = link->pool_addresses)) {
116 LIST_REMOVE(addresses, link->pool_addresses, address);
117 address_free(address);
120 sd_dhcp_client_unref(link->dhcp_client);
121 sd_dhcp_lease_unref(link->dhcp_lease);
123 unlink(link->lease_file);
124 free(link->lease_file);
126 sd_ipv4ll_unref(link->ipv4ll);
127 sd_dhcp6_client_unref(link->dhcp6_client);
128 sd_icmp6_nd_unref(link->icmp6_router_discovery);
131 hashmap_remove(link->manager->links, &link->ifindex);
135 unlink(link->state_file);
136 free(link->state_file);
138 udev_device_unref(link->udev_device);
143 Link *link_unref(Link *link) {
144 if (link && (-- link->n_ref <= 0))
150 Link *link_ref(Link *link) {
152 assert_se(++ link->n_ref >= 2);
157 int link_get(Manager *m, int ifindex, Link **ret) {
166 ifindex_64 = ifindex;
167 link = hashmap_get(m->links, &ifindex_64);
176 void link_drop(Link *link) {
177 if (!link || link->state == LINK_STATE_LINGER)
180 link->state = LINK_STATE_LINGER;
182 log_debug_link(link, "link removed");
189 static void link_enter_unmanaged(Link *link) {
192 log_debug_link(link, "unmanaged");
194 link->state = LINK_STATE_UNMANAGED;
199 static int link_stop_clients(Link *link) {
203 assert(link->manager);
204 assert(link->manager->event);
209 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
210 assert(link->dhcp_client);
212 k = sd_dhcp_client_stop(link->dhcp_client);
214 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
219 if (link->network->ipv4ll) {
220 assert(link->ipv4ll);
222 k = sd_ipv4ll_stop(link->ipv4ll);
224 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
229 if (link->network->dhcp_server) {
230 assert(link->dhcp_server);
232 k = sd_dhcp_server_stop(link->dhcp_server);
234 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
239 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
240 assert(link->icmp6_router_discovery);
242 if (link->dhcp6_client) {
243 k = sd_dhcp6_client_stop(link->dhcp6_client);
245 log_warning_link(link, "Could not stop DHCPv6 client: %s", strerror(-r));
250 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
252 log_warning_link(link, "Could not stop ICMPv6 router discovery: %s", strerror(-r));
260 static void link_enter_failed(Link *link) {
263 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
266 log_warning_link(link, "failed");
268 link->state = LINK_STATE_FAILED;
270 link_stop_clients(link);
275 static Address* link_find_dhcp_server_address(Link *link) {
279 assert(link->network);
281 /* The the first statically configured address if there is any */
282 LIST_FOREACH(addresses, address, link->network->static_addresses) {
284 if (address->family != AF_INET)
287 if (in_addr_null(address->family, &address->in_addr))
293 /* If that didn't work, find a suitable address we got from the pool */
294 LIST_FOREACH(addresses, address, link->pool_addresses) {
295 if (address->family != AF_INET)
304 static int link_enter_configured(Link *link) {
308 assert(link->network);
309 assert(link->state == LINK_STATE_SETTING_ROUTES);
311 if (link->network->dhcp_server &&
312 !sd_dhcp_server_is_running(link->dhcp_server)) {
313 struct in_addr pool_start;
316 address = link_find_dhcp_server_address(link);
318 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
319 link_enter_failed(link);
323 log_debug_link(link, "offering DHCPv4 leases");
325 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in);
329 /* offer 32 addresses starting from the address following the server address */
330 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
331 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
337 r = sd_dhcp_server_set_router(link->dhcp_server,
338 &main_address->in_addr.in);
342 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
343 main_address->prefixlen);
348 r = sd_dhcp_server_start(link->dhcp_server);
350 log_warning_link(link, "could not start DHCPv4 server "
351 "instance: %s", strerror(-r));
353 link_enter_failed(link);
359 log_info_link(link, "link configured");
361 link->state = LINK_STATE_CONFIGURED;
368 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
369 _cleanup_link_unref_ Link *link = userdata;
372 assert(link->route_messages > 0);
373 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
374 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
377 link->route_messages --;
379 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER))
382 r = sd_rtnl_message_get_errno(m);
383 if (r < 0 && r != -EEXIST)
384 log_struct_link(LOG_WARNING, link,
385 "MESSAGE=%-*s: could not set route: %s",
387 link->ifname, strerror(-r),
391 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
393 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
394 log_debug_link(link, "routes set");
395 link_enter_configured(link);
401 static int link_set_dhcp_routes(Link *link) {
402 struct sd_dhcp_route *static_routes;
403 size_t static_routes_size;
409 r = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes, &static_routes_size);
412 log_warning_link(link, "DHCP error: could not get routes: %s", strerror(-r));
416 for (i = 0; i < static_routes_size; i++) {
417 _cleanup_route_free_ Route *route = NULL;
419 r = route_new_dynamic(&route);
421 log_error_link(link, "Could not allocate route: %s",
426 route->family = AF_INET;
427 route->in_addr.in = static_routes[i].gw_addr;
428 route->dst_addr.in = static_routes[i].dst_addr;
429 route->dst_prefixlen = static_routes[i].dst_prefixlen;
430 route->metrics = DHCP_ROUTE_METRIC;
432 r = route_configure(route, link, &route_handler);
434 log_warning_link(link,
435 "could not set host route: %s", strerror(-r));
439 link->route_messages ++;
445 static int link_enter_set_routes(Link *link) {
450 assert(link->network);
451 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
453 link->state = LINK_STATE_SETTING_ROUTES;
455 if (!link->network->static_routes && !link->dhcp_lease &&
456 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
457 return link_enter_configured(link);
459 log_debug_link(link, "setting routes");
461 LIST_FOREACH(routes, rt, link->network->static_routes) {
462 r = route_configure(rt, link, &route_handler);
464 log_warning_link(link,
465 "could not set routes: %s", strerror(-r));
466 link_enter_failed(link);
470 link->route_messages ++;
473 if (link->ipv4ll && !link->dhcp_lease) {
474 _cleanup_route_free_ Route *route = NULL;
477 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
478 if (r < 0 && r != -ENOENT) {
479 log_warning_link(link, "IPV4LL error: no address: %s",
485 r = route_new_dynamic(&route);
487 log_error_link(link, "Could not allocate route: %s",
492 route->family = AF_INET;
493 route->scope = RT_SCOPE_LINK;
494 route->metrics = IPV4LL_ROUTE_METRIC;
496 r = route_configure(route, link, &route_handler);
498 log_warning_link(link,
499 "could not set routes: %s", strerror(-r));
500 link_enter_failed(link);
504 link->route_messages ++;
508 if (link->dhcp_lease) {
509 _cleanup_route_free_ Route *route = NULL;
510 _cleanup_route_free_ Route *route_gw = NULL;
511 struct in_addr gateway;
513 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
514 if (r < 0 && r != -ENOENT) {
515 log_warning_link(link, "DHCP error: could not get gateway: %s",
521 r = route_new_dynamic(&route);
523 log_error_link(link, "Could not allocate route: %s",
528 r = route_new_dynamic(&route_gw);
530 log_error_link(link, "Could not allocate route: %s",
535 /* The dhcp netmask may mask out the gateway. Add an explicit
536 * route for the gw host so that we can route no matter the
537 * netmask or existing kernel route tables. */
538 route_gw->family = AF_INET;
539 route_gw->dst_addr.in = gateway;
540 route_gw->dst_prefixlen = 32;
541 route_gw->scope = RT_SCOPE_LINK;
542 route_gw->metrics = DHCP_ROUTE_METRIC;
544 r = route_configure(route_gw, link, &route_handler);
546 log_warning_link(link,
547 "could not set host route: %s", strerror(-r));
551 link->route_messages ++;
553 route->family = AF_INET;
554 route->in_addr.in = gateway;
555 route->metrics = DHCP_ROUTE_METRIC;
557 r = route_configure(route, link, &route_handler);
559 log_warning_link(link,
560 "could not set routes: %s", strerror(-r));
561 link_enter_failed(link);
565 link->route_messages ++;
568 if (link->network->dhcp_routes)
569 link_set_dhcp_routes(link);
572 if (link->route_messages == 0) {
573 link_enter_configured(link);
579 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
580 _cleanup_link_unref_ Link *link = userdata;
585 assert(link->ifname);
587 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
590 r = sd_rtnl_message_get_errno(m);
591 if (r < 0 && r != -ESRCH)
592 log_struct_link(LOG_WARNING, link,
593 "MESSAGE=%-*s: could not drop route: %s",
595 link->ifname, strerror(-r),
602 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
603 _cleanup_link_unref_ Link *link = userdata;
609 assert(link->manager);
611 for (; m; m = sd_rtnl_message_next(m)) {
612 r = sd_rtnl_message_get_errno(m);
614 log_debug_link(link, "getting address failed: %s", strerror(-r));
618 r = link_rtnl_process_address(rtnl, m, link->manager);
620 log_warning_link(link, "could not process address: %s", strerror(-r));
626 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
627 _cleanup_link_unref_ Link *link = userdata;
633 assert(link->ifname);
634 assert(link->addr_messages > 0);
635 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
636 LINK_STATE_FAILED, LINK_STATE_LINGER));
638 link->addr_messages --;
640 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
643 r = sd_rtnl_message_get_errno(m);
644 if (r < 0 && r != -EEXIST)
645 log_struct_link(LOG_WARNING, link,
646 "MESSAGE=%-*s: could not set address: %s",
648 link->ifname, strerror(-r),
652 /* calling handler directly so take a ref */
654 link_get_address_handler(rtnl, m, link);
657 if (link->addr_messages == 0) {
658 log_debug_link(link, "addresses set");
659 link_enter_set_routes(link);
665 static int link_enter_set_addresses(Link *link) {
668 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
671 assert(link->network);
672 assert(link->state != _LINK_STATE_INVALID);
674 link->state = LINK_STATE_SETTING_ADDRESSES;
676 if (!link->network->static_addresses && !link->dhcp_lease &&
677 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
678 return link_enter_set_routes(link);
680 log_debug_link(link, "setting addresses");
682 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
683 r = address_configure(ad, link, &address_handler);
685 log_warning_link(link,
686 "could not set addresses: %s", strerror(-r));
687 link_enter_failed(link);
691 link->addr_messages ++;
694 if (link->ipv4ll && !link->dhcp_lease) {
695 _cleanup_address_free_ Address *ll_addr = NULL;
698 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
699 if (r < 0 && r != -ENOENT) {
700 log_warning_link(link, "IPV4LL error: no address: %s",
706 r = address_new_dynamic(&ll_addr);
708 log_error_link(link, "Could not allocate address: %s", strerror(-r));
712 ll_addr->family = AF_INET;
713 ll_addr->in_addr.in = addr;
714 ll_addr->prefixlen = 16;
715 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
716 ll_addr->scope = RT_SCOPE_LINK;
718 r = address_configure(ll_addr, link, &address_handler);
720 log_warning_link(link,
721 "could not set addresses: %s", strerror(-r));
722 link_enter_failed(link);
726 link->addr_messages ++;
730 if (link->dhcp_lease) {
731 _cleanup_address_free_ Address *address = NULL;
733 struct in_addr netmask;
736 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
738 log_warning_link(link, "DHCP error: no address: %s",
743 if (!link->network->dhcp_critical) {
744 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
747 log_warning_link(link, "DHCP error: no lifetime: %s",
753 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
755 log_warning_link(link, "DHCP error: no netmask: %s",
760 prefixlen = net_netmask_to_prefixlen(&netmask);
762 r = address_new_dynamic(&address);
764 log_error_link(link, "Could not allocate address: %s",
769 address->family = AF_INET;
770 address->in_addr.in = addr;
771 address->cinfo.ifa_prefered = lifetime;
772 address->cinfo.ifa_valid = lifetime;
773 address->prefixlen = prefixlen;
774 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
776 /* use update rather than configure so that we will update the lifetime
777 of an existing address if it has already been configured */
778 r = address_update(address, link, &address_handler);
780 log_warning_link(link,
781 "could not set addresses: %s", strerror(-r));
782 link_enter_failed(link);
786 link->addr_messages ++;
792 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
793 _cleanup_link_unref_ Link *link = userdata;
798 assert(link->ifname);
800 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
803 r = sd_rtnl_message_get_errno(m);
804 if (r < 0 && r != -ENOENT)
805 log_struct_link(LOG_WARNING, link,
806 "MESSAGE=%-*s: could not update address: %s",
808 link->ifname, strerror(-r),
815 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
816 _cleanup_link_unref_ Link *link = userdata;
821 assert(link->ifname);
823 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
826 r = sd_rtnl_message_get_errno(m);
827 if (r < 0 && r != -EADDRNOTAVAIL)
828 log_struct_link(LOG_WARNING, link,
829 "MESSAGE=%-*s: could not drop address: %s",
831 link->ifname, strerror(-r),
838 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
839 _cleanup_link_unref_ Link *link = userdata;
844 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
847 r = sd_bus_message_get_errno(m);
849 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
854 static int link_set_hostname(Link *link, const char *hostname) {
855 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
859 assert(link->manager);
862 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
864 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
865 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
869 r = sd_bus_message_new_method_call(
872 "org.freedesktop.hostname1",
873 "/org/freedesktop/hostname1",
874 "org.freedesktop.hostname1",
879 r = sd_bus_message_append(m, "sb", hostname, false);
883 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
885 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
894 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
895 _cleanup_link_unref_ Link *link = userdata;
900 assert(link->ifname);
902 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
905 r = sd_rtnl_message_get_errno(m);
907 log_struct_link(LOG_WARNING, link,
908 "MESSAGE=%-*s: could not set MTU: %s",
909 IFNAMSIZ, link->ifname, strerror(-r),
916 static int link_set_mtu(Link *link, uint32_t mtu) {
917 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
921 assert(link->manager);
922 assert(link->manager->rtnl);
924 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
926 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
927 RTM_SETLINK, link->ifindex);
929 log_error_link(link, "Could not allocate RTM_SETLINK message");
933 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
935 log_error_link(link, "Could not append MTU: %s", strerror(-r));
939 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
942 "Could not send rtnetlink message: %s", strerror(-r));
951 static int dhcp_lease_lost(Link *link) {
952 _cleanup_address_free_ Address *address = NULL;
954 struct in_addr netmask;
955 struct in_addr gateway;
961 assert(link->dhcp_lease);
963 log_warning_link(link, "DHCP lease lost");
965 if (link->network->dhcp_routes) {
966 struct sd_dhcp_route *routes;
969 r = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes, &routes_size);
971 for (i = 0; i < routes_size; i++) {
972 _cleanup_route_free_ Route *route = NULL;
974 r = route_new_dynamic(&route);
976 route->family = AF_INET;
977 route->in_addr.in = routes[i].gw_addr;
978 route->dst_addr.in = routes[i].dst_addr;
979 route->dst_prefixlen = routes[i].dst_prefixlen;
981 route_drop(route, link, &route_drop_handler);
987 r = address_new_dynamic(&address);
989 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
991 _cleanup_route_free_ Route *route_gw = NULL;
992 _cleanup_route_free_ Route *route = NULL;
994 r = route_new_dynamic(&route_gw);
996 route_gw->family = AF_INET;
997 route_gw->dst_addr.in = gateway;
998 route_gw->dst_prefixlen = 32;
999 route_gw->scope = RT_SCOPE_LINK;
1001 route_drop(route_gw, link, &route_drop_handler);
1004 r = route_new_dynamic(&route);
1006 route->family = AF_INET;
1007 route->in_addr.in = gateway;
1009 route_drop(route, link, &route_drop_handler);
1013 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
1014 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
1015 prefixlen = net_netmask_to_prefixlen(&netmask);
1017 address->family = AF_INET;
1018 address->in_addr.in = addr;
1019 address->prefixlen = prefixlen;
1021 address_drop(address, link, &address_drop_handler);
1024 if (link->network->dhcp_mtu) {
1027 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
1028 if (r >= 0 && link->original_mtu != mtu) {
1029 r = link_set_mtu(link, link->original_mtu);
1031 log_warning_link(link, "DHCP error: could not reset MTU");
1032 link_enter_failed(link);
1038 if (link->network->dhcp_hostname) {
1039 const char *hostname = NULL;
1041 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
1042 if (r >= 0 && hostname) {
1043 r = link_set_hostname(link, "");
1045 log_error_link(link, "Failed to reset transient hostname");
1049 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
1054 static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
1055 sd_dhcp_lease *lease;
1058 r = sd_dhcp_client_get_lease(client, &lease);
1060 log_warning_link(link, "DHCP error: no lease %s",
1065 sd_dhcp_lease_unref(link->dhcp_lease);
1066 link->dhcp_lease = lease;
1068 link_enter_set_addresses(link);
1073 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1074 sd_dhcp_lease *lease;
1075 struct in_addr address;
1076 struct in_addr netmask;
1077 struct in_addr gateway;
1084 r = sd_dhcp_client_get_lease(client, &lease);
1086 log_warning_link(link, "DHCP error: no lease: %s",
1091 r = sd_dhcp_lease_get_address(lease, &address);
1093 log_warning_link(link, "DHCP error: no address: %s",
1098 r = sd_dhcp_lease_get_netmask(lease, &netmask);
1100 log_warning_link(link, "DHCP error: no netmask: %s",
1105 prefixlen = net_netmask_to_prefixlen(&netmask);
1107 r = sd_dhcp_lease_get_router(lease, &gateway);
1108 if (r < 0 && r != -ENOENT) {
1109 log_warning_link(link, "DHCP error: could not get gateway: %s",
1115 log_struct_link(LOG_INFO, link,
1116 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
1119 ADDRESS_FMT_VAL(address),
1121 ADDRESS_FMT_VAL(gateway),
1122 "ADDRESS=%u.%u.%u.%u",
1123 ADDRESS_FMT_VAL(address),
1126 "GATEWAY=%u.%u.%u.%u",
1127 ADDRESS_FMT_VAL(gateway),
1130 log_struct_link(LOG_INFO, link,
1131 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1134 ADDRESS_FMT_VAL(address),
1136 "ADDRESS=%u.%u.%u.%u",
1137 ADDRESS_FMT_VAL(address),
1142 link->dhcp_lease = lease;
1144 if (link->network->dhcp_mtu) {
1147 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1149 r = link_set_mtu(link, mtu);
1151 log_error_link(link, "Failed to set MTU "
1152 "to %" PRIu16, mtu);
1156 if (link->network->dhcp_hostname) {
1157 const char *hostname;
1159 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1161 r = link_set_hostname(link, hostname);
1163 log_error_link(link, "Failed to set transient hostname "
1164 "to '%s'", hostname);
1168 link_enter_set_addresses(link);
1173 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1174 Link *link = userdata;
1178 assert(link->network);
1179 assert(link->manager);
1181 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1185 case DHCP_EVENT_NO_LEASE:
1186 log_debug_link(link, "IP address in use.");
1188 case DHCP_EVENT_EXPIRED:
1189 case DHCP_EVENT_STOP:
1190 case DHCP_EVENT_IP_CHANGE:
1191 if (link->network->dhcp_critical) {
1192 log_error_link(link, "DHCPv4 connection considered system critical, "
1193 "ignoring request to reconfigure it.");
1197 if (link->dhcp_lease) {
1198 r = dhcp_lease_lost(link);
1200 link_enter_failed(link);
1205 if (event == DHCP_EVENT_IP_CHANGE) {
1206 r = dhcp_lease_acquired(client, link);
1208 link_enter_failed(link);
1213 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1214 if (!sd_ipv4ll_is_running(link->ipv4ll))
1215 r = sd_ipv4ll_start(link->ipv4ll);
1216 else if (ipv4ll_is_bound(link->ipv4ll))
1217 r = ipv4ll_address_update(link, false);
1219 link_enter_failed(link);
1225 case DHCP_EVENT_RENEW:
1226 r = dhcp_lease_renew(client, link);
1228 link_enter_failed(link);
1232 case DHCP_EVENT_IP_ACQUIRE:
1233 r = dhcp_lease_acquired(client, link);
1235 link_enter_failed(link);
1239 if (ipv4ll_is_bound(link->ipv4ll))
1240 r = ipv4ll_address_update(link, true);
1242 r = sd_ipv4ll_stop(link->ipv4ll);
1244 link_enter_failed(link);
1251 log_warning_link(link, "DHCP error: client failed: %s", strerror(-event));
1253 log_warning_link(link, "DHCP unknown event: %d", event);
1260 static int ipv4ll_address_update(Link *link, bool deprecate) {
1262 struct in_addr addr;
1266 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1268 _cleanup_address_free_ Address *address = NULL;
1270 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1271 deprecate ? "deprecate" : "approve",
1272 ADDRESS_FMT_VAL(addr));
1274 r = address_new_dynamic(&address);
1276 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1280 address->family = AF_INET;
1281 address->in_addr.in = addr;
1282 address->prefixlen = 16;
1283 address->scope = RT_SCOPE_LINK;
1284 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1285 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1287 address_update(address, link, &address_update_handler);
1294 static int ipv4ll_address_lost(Link *link) {
1296 struct in_addr addr;
1300 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1302 _cleanup_address_free_ Address *address = NULL;
1303 _cleanup_route_free_ Route *route = NULL;
1305 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1306 ADDRESS_FMT_VAL(addr));
1308 r = address_new_dynamic(&address);
1310 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1314 address->family = AF_INET;
1315 address->in_addr.in = addr;
1316 address->prefixlen = 16;
1317 address->scope = RT_SCOPE_LINK;
1319 address_drop(address, link, &address_drop_handler);
1321 r = route_new_dynamic(&route);
1323 log_error_link(link, "Could not allocate route: %s",
1328 route->family = AF_INET;
1329 route->scope = RT_SCOPE_LINK;
1330 route->metrics = 99;
1332 route_drop(route, link, &route_drop_handler);
1338 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1340 struct in_addr addr;
1344 r = sd_ipv4ll_get_address(ll, &addr);
1350 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1351 struct in_addr address;
1357 r = sd_ipv4ll_get_address(ll, &address);
1361 log_struct_link(LOG_INFO, link,
1362 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1365 ADDRESS_FMT_VAL(address),
1368 link_enter_set_addresses(link);
1373 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1374 Link *link = userdata;
1378 assert(link->network);
1379 assert(link->manager);
1381 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1385 case IPV4LL_EVENT_STOP:
1386 case IPV4LL_EVENT_CONFLICT:
1387 r = ipv4ll_address_lost(link);
1389 link_enter_failed(link);
1393 case IPV4LL_EVENT_BIND:
1394 r = ipv4ll_address_claimed(ll, link);
1396 link_enter_failed(link);
1402 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1404 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1409 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1410 Link *link = userdata;
1413 assert(link->network);
1414 assert(link->manager);
1416 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1420 case DHCP6_EVENT_STOP:
1421 case DHCP6_EVENT_RESEND_EXPIRE:
1422 case DHCP6_EVENT_RETRANS_MAX:
1423 case DHCP6_EVENT_IP_ACQUIRE:
1424 log_debug_link(link, "DHCPv6 event %d", event);
1430 log_warning_link(link, "DHCPv6 error: %s",
1433 log_warning_link(link, "DHCPv6 unknown event: %d",
1439 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1440 Link *link = userdata;
1444 assert(link->network);
1445 assert(link->manager);
1447 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1451 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1452 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1455 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1456 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1461 log_warning_link(link, "ICMPv6 error: %s",
1464 log_warning_link(link, "ICMPv6 unknown event: %d",
1470 if (link->dhcp6_client)
1473 r = sd_dhcp6_client_new(&link->dhcp6_client);
1477 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1479 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1483 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1485 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1489 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1491 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1495 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1498 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1502 r = sd_dhcp6_client_start(link->dhcp6_client);
1504 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1507 static int link_acquire_conf(Link *link) {
1511 assert(link->network);
1512 assert(link->manager);
1513 assert(link->manager->event);
1515 if (link->network->ipv4ll) {
1516 assert(link->ipv4ll);
1518 log_debug_link(link, "acquiring IPv4 link-local address");
1520 r = sd_ipv4ll_start(link->ipv4ll);
1522 log_warning_link(link, "could not acquire IPv4 "
1523 "link-local address");
1528 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1529 assert(link->dhcp_client);
1531 log_debug_link(link, "acquiring DHCPv4 lease");
1533 r = sd_dhcp_client_start(link->dhcp_client);
1535 log_warning_link(link, "could not acquire DHCPv4 "
1541 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1542 assert(link->icmp6_router_discovery);
1544 log_debug_link(link, "discovering IPv6 routers");
1546 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1548 log_warning_link(link, "could not start IPv6 router discovery");
1556 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1557 /* see Documentation/networking/operstates.txt in the kernel sources */
1559 if (operstate == IF_OPER_UP)
1562 if (operstate == IF_OPER_UNKNOWN)
1563 /* operstate may not be implemented, so fall back to flags */
1564 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1570 #define FLAG_STRING(string, flag, old, new) \
1571 (((old ^ new) & flag) \
1572 ? ((old & flag) ? (" -" string) : (" +" string)) \
1575 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1576 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1578 bool carrier_gained = false, carrier_lost = false;
1583 r = sd_rtnl_message_link_get_flags(m, &flags);
1585 log_warning_link(link, "Could not get link flags");
1589 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1591 /* if we got a message without operstate, take it to mean
1592 the state was unchanged */
1593 operstate = link->kernel_operstate;
1595 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1598 if (link->flags != flags) {
1599 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1600 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1601 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1602 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1603 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1604 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1605 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1606 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1607 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1608 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1609 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1610 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1611 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1612 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1613 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1614 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1615 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1616 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1617 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1618 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1620 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1621 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1622 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1623 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1624 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1625 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1626 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1627 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1629 /* link flags are currently at most 18 bits, let's align to printing 20 */
1630 if (unknown_flags_added)
1631 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1632 unknown_flags_added);
1634 if (unknown_flags_removed)
1635 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1636 unknown_flags_removed);
1639 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1640 link_has_carrier(flags, operstate);
1641 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1642 !link_has_carrier(flags, operstate);
1644 link->flags = flags;
1645 link->kernel_operstate = operstate;
1649 if (link->state == LINK_STATE_FAILED ||
1650 link->state == LINK_STATE_UNMANAGED)
1653 if (carrier_gained) {
1654 log_info_link(link, "gained carrier");
1656 if (link->network) {
1657 r = link_acquire_conf(link);
1659 link_enter_failed(link);
1663 } else if (carrier_lost) {
1664 log_info_link(link, "lost carrier");
1666 r = link_stop_clients(link);
1668 link_enter_failed(link);
1676 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1677 _cleanup_link_unref_ Link *link = userdata;
1682 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1685 r = sd_rtnl_message_get_errno(m);
1687 /* we warn but don't fail the link, as it may
1688 be brought up later */
1689 log_struct_link(LOG_WARNING, link,
1690 "MESSAGE=%-*s: could not bring up interface: %s",
1692 link->ifname, strerror(-r),
1700 static int link_up(Link *link) {
1701 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1705 assert(link->manager);
1706 assert(link->manager->rtnl);
1708 log_debug_link(link, "bringing link up");
1710 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1711 RTM_SETLINK, link->ifindex);
1713 log_error_link(link, "Could not allocate RTM_SETLINK message");
1717 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1719 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1723 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1725 log_error_link(link,
1726 "Could not send rtnetlink message: %s", strerror(-r));
1735 static int link_enslaved(Link *link) {
1739 assert(link->state == LINK_STATE_ENSLAVING);
1740 assert(link->network);
1742 log_debug_link(link, "enslaved");
1744 if (!(link->flags & IFF_UP)) {
1747 link_enter_failed(link);
1752 return link_enter_set_addresses(link);
1755 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1756 _cleanup_link_unref_ Link *link = userdata;
1760 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1761 LINK_STATE_LINGER));
1762 assert(link->network);
1766 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1769 r = sd_rtnl_message_get_errno(m);
1770 if (r < 0 && r != -EEXIST) {
1771 log_struct_link(LOG_ERR, link,
1772 "MESSAGE=%-*s: could not enslave: %s",
1774 link->ifname, strerror(-r),
1777 link_enter_failed(link);
1781 if (link->enslaving <= 0)
1782 link_enslaved(link);
1787 static int link_enter_enslave(Link *link) {
1788 NetDev *vlan, *macvlan, *vxlan;
1793 assert(link->network);
1794 assert(link->state == LINK_STATE_INITIALIZING);
1796 link->state = LINK_STATE_ENSLAVING;
1800 if (!link->network->bridge &&
1801 !link->network->bond &&
1802 !link->network->tunnel &&
1803 hashmap_isempty(link->network->vlans) &&
1804 hashmap_isempty(link->network->macvlans) &&
1805 hashmap_isempty(link->network->vxlans))
1806 return link_enslaved(link);
1808 if (link->network->bond) {
1809 log_struct_link(LOG_DEBUG, link,
1810 "MESSAGE=%-*s: enslaving by '%s'",
1812 link->ifname, link->network->bond->ifname,
1813 NETDEV(link->network->bond),
1816 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1818 log_struct_link(LOG_WARNING, link,
1819 "MESSAGE=%-*s: could not enslave by '%s': %s",
1821 link->ifname, link->network->bond->ifname, strerror(-r),
1822 NETDEV(link->network->bond),
1824 link_enter_failed(link);
1831 if (link->network->bridge) {
1832 log_struct_link(LOG_DEBUG, link,
1833 "MESSAGE=%-*s: enslaving by '%s'",
1835 link->ifname, link->network->bridge->ifname,
1836 NETDEV(link->network->bridge),
1839 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1841 log_struct_link(LOG_WARNING, link,
1842 "MESSAGE=%-*s: could not enslave by '%s': %s",
1844 link->ifname, link->network->bridge->ifname, strerror(-r),
1845 NETDEV(link->network->bridge),
1847 link_enter_failed(link);
1854 if (link->network->tunnel) {
1855 log_struct_link(LOG_DEBUG, link,
1856 "MESSAGE=%-*s: enslaving by '%s'",
1858 link->ifname, link->network->tunnel->ifname,
1859 NETDEV(link->network->tunnel),
1862 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1864 log_struct_link(LOG_WARNING, link,
1865 "MESSAGE=%-*s: could not enslave by '%s': %s",
1867 link->ifname, link->network->tunnel->ifname, strerror(-r),
1868 NETDEV(link->network->tunnel),
1870 link_enter_failed(link);
1877 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1878 log_struct_link(LOG_DEBUG, link,
1879 "MESSAGE=%-*s: enslaving by '%s'",
1881 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1883 r = netdev_enslave(vlan, link, &enslave_handler);
1885 log_struct_link(LOG_WARNING, link,
1886 "MESSAGE=%-*s: could not enslave by '%s': %s",
1888 link->ifname, vlan->ifname, strerror(-r),
1889 NETDEV(vlan), NULL);
1890 link_enter_failed(link);
1897 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1898 log_struct_link(LOG_DEBUG, link,
1899 "MESSAGE=%-*s: enslaving by '%s'",
1901 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1903 r = netdev_enslave(macvlan, link, &enslave_handler);
1905 log_struct_link(LOG_WARNING, link,
1906 "MESSAGE=%-*s: could not enslave by '%s': %s",
1908 link->ifname, macvlan->ifname, strerror(-r),
1909 NETDEV(macvlan), NULL);
1910 link_enter_failed(link);
1917 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1918 log_struct_link(LOG_DEBUG, link,
1919 "MESSAGE=%*s: enslaving by '%s'",
1921 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1923 r = netdev_enslave(vxlan, link, &enslave_handler);
1925 log_struct_link(LOG_WARNING, link,
1926 "MESSAGE=%*s: could not enslave by '%s': %s",
1928 link->ifname, vxlan->ifname, strerror(-r),
1929 NETDEV(vxlan), NULL);
1930 link_enter_failed(link);
1940 static int link_configure(Link *link) {
1944 assert(link->state == LINK_STATE_INITIALIZING);
1946 if (link->network->ipv4ll) {
1949 r = sd_ipv4ll_new(&link->ipv4ll);
1953 if (link->udev_device) {
1954 r = net_get_unique_predictable_data(link->udev_device, seed);
1956 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1962 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1966 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1970 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1974 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1979 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1980 r = sd_dhcp_client_new(&link->dhcp_client);
1984 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1988 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1992 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1996 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
2000 if (link->network->dhcp_mtu) {
2001 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
2006 if (link->network->dhcp_routes) {
2007 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
2010 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
2015 if (link->network->dhcp_sendhost) {
2016 _cleanup_free_ char *hostname = gethostname_malloc();
2020 if (!is_localhost(hostname)) {
2021 r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname);
2028 if (link->network->dhcp_server) {
2029 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2033 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2038 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
2039 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
2043 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
2048 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
2053 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
2058 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
2059 icmp6_router_handler, link);
2064 if (link_has_carrier(link->flags, link->kernel_operstate)) {
2065 r = link_acquire_conf(link);
2070 return link_enter_enslave(link);
2073 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2074 _cleanup_link_unref_ Link *link = userdata;
2079 assert(link->ifname);
2080 assert(link->manager);
2082 if (link->state != LINK_STATE_INITIALIZING)
2085 log_debug_link(link, "link state is up-to-date");
2087 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
2089 link_enter_unmanaged(link);
2094 r = network_apply(link->manager, network, link);
2098 r = link_configure(link);
2105 int link_initialized(Link *link, struct udev_device *device) {
2106 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2110 assert(link->manager);
2111 assert(link->manager->rtnl);
2114 if (link->state != LINK_STATE_INITIALIZING)
2117 log_debug_link(link, "udev initialized link");
2119 link->udev_device = udev_device_ref(device);
2121 /* udev has initialized the link, but we don't know if we have yet processed
2122 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
2123 we know that the pending NEWLINKs have already been processed and that we
2126 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
2130 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
2139 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
2140 Manager *m = userdata;
2143 _cleanup_address_free_ Address *address = NULL;
2145 char buf[INET6_ADDRSTRLEN];
2146 bool address_dropped = false;
2153 r = sd_rtnl_message_get_type(message, &type);
2155 log_warning("rtnl: could not get message type");
2159 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2160 if (r < 0 || ifindex <= 0) {
2161 log_warning("rtnl: received address message without valid ifindex, ignoring");
2164 r = link_get(m, ifindex, &link);
2165 if (r < 0 || !link) {
2166 log_warning("rtnl: received address for a nonexistent link, ignoring");
2171 r = address_new_dynamic(&address);
2175 r = sd_rtnl_message_addr_get_family(message, &address->family);
2176 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
2177 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
2181 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2183 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2187 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2189 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
2193 switch (address->family) {
2195 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2197 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2204 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2206 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2213 assert_not_reached("invalid address family");
2216 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
2217 log_warning_link(link, "could not print address");
2221 LIST_FOREACH(addresses, ad, link->addresses) {
2222 if (address_equal(ad, address)) {
2223 LIST_REMOVE(addresses, link->addresses, ad);
2227 address_dropped = true;
2235 if (!address_dropped)
2236 log_debug_link(link, "added address: %s/%u", buf,
2237 address->prefixlen);
2239 log_debug_link(link, "updated address: %s/%u", buf,
2240 address->prefixlen);
2242 LIST_PREPEND(addresses, link->addresses, address);
2249 if (address_dropped) {
2250 log_debug_link(link, "removed address: %s/%u", buf,
2251 address->prefixlen);
2255 log_warning_link(link, "removing non-existent address: %s/%u",
2256 buf, address->prefixlen);
2260 assert_not_reached("Received invalid RTNL message type");
2266 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2268 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2269 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2270 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2278 r = link_new(m, message, ret);
2284 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2286 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2290 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2296 if (detect_container(NULL) <= 0) {
2297 /* not in a container, udev will be around */
2298 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2299 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2301 log_warning_link(link, "could not find udev device");
2305 if (udev_device_get_is_initialized(device) <= 0) {
2307 log_debug_link(link, "udev initializing link...");
2311 r = link_initialized(link, device);
2315 /* we are calling a callback directly, so must take a ref */
2318 r = link_initialized_and_synced(m->rtnl, NULL, link);
2326 int link_update(Link *link, sd_rtnl_message *m) {
2327 struct ether_addr mac;
2332 assert(link->ifname);
2335 if (link->state == LINK_STATE_LINGER) {
2337 log_info_link(link, "link readded");
2338 link->state = LINK_STATE_ENSLAVING;
2341 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2342 if (r >= 0 && !streq(ifname, link->ifname)) {
2343 log_info_link(link, "renamed to %s", ifname);
2346 link->ifname = strdup(ifname);
2351 if (!link->original_mtu) {
2352 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2354 log_debug_link(link, "saved original MTU: %"
2355 PRIu16, link->original_mtu);
2358 /* The kernel may broadcast NEWLINK messages without the MAC address
2359 set, simply ignore them. */
2360 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2362 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2364 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2366 log_debug_link(link, "MAC address: "
2367 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2368 mac.ether_addr_octet[0],
2369 mac.ether_addr_octet[1],
2370 mac.ether_addr_octet[2],
2371 mac.ether_addr_octet[3],
2372 mac.ether_addr_octet[4],
2373 mac.ether_addr_octet[5]);
2376 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2378 log_warning_link(link, "Could not update MAC "
2379 "address in IPv4LL client: %s",
2385 if (link->dhcp_client) {
2386 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2388 log_warning_link(link, "Could not update MAC "
2389 "address in DHCP client: %s",
2395 if (link->dhcp6_client) {
2396 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2399 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2407 return link_update_flags(link, m);
2410 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2419 fprintf(f, "%s=", key);
2421 LIST_FOREACH(addresses, ad, address) {
2422 char buf[INET6_ADDRSTRLEN];
2424 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2425 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2431 static void link_update_operstate(Link *link) {
2435 if (link->kernel_operstate == IF_OPER_DORMANT)
2436 link->operstate = LINK_OPERSTATE_DORMANT;
2437 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2439 uint8_t scope = RT_SCOPE_NOWHERE;
2441 /* if we have carrier, check what addresses we have */
2442 LIST_FOREACH(addresses, address, link->addresses) {
2443 if (address->scope < scope)
2444 scope = address->scope;
2447 if (scope < RT_SCOPE_SITE)
2448 /* universally accessible addresses found */
2449 link->operstate = LINK_OPERSTATE_ROUTABLE;
2450 else if (scope < RT_SCOPE_HOST)
2451 /* only link or site local addresses found */
2452 link->operstate = LINK_OPERSTATE_DEGRADED;
2454 /* no useful addresses found */
2455 link->operstate = LINK_OPERSTATE_CARRIER;
2457 link->operstate = LINK_OPERSTATE_UNKNOWN;
2460 int link_save(Link *link) {
2461 _cleanup_free_ char *temp_path = NULL;
2462 _cleanup_fclose_ FILE *f = NULL;
2463 const char *admin_state, *oper_state;
2467 assert(link->state_file);
2468 assert(link->lease_file);
2469 assert(link->manager);
2471 link_update_operstate(link);
2473 r = manager_save(link->manager);
2477 if (link->state == LINK_STATE_LINGER) {
2478 unlink(link->state_file);
2482 admin_state = link_state_to_string(link->state);
2483 assert(admin_state);
2485 oper_state = link_operstate_to_string(link->operstate);
2488 r = fopen_temporary(link->state_file, &f, &temp_path);
2492 fchmod(fileno(f), 0644);
2495 "# This is private data. Do not parse.\n"
2499 admin_state, oper_state, link->flags);
2501 if (link->network) {
2502 serialize_addresses(f, "DNS", link->network->dns);
2503 serialize_addresses(f, "NTP", link->network->ntp);
2506 if (link->dhcp_lease) {
2507 assert(link->network);
2509 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2516 "DHCP_USE_NTP=%s\n",
2518 yes_no(link->network->dhcp_dns),
2519 yes_no(link->network->dhcp_ntp));
2521 unlink(link->lease_file);
2525 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2527 unlink(link->state_file);
2533 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2538 static const char* const link_state_table[_LINK_STATE_MAX] = {
2539 [LINK_STATE_INITIALIZING] = "initializing",
2540 [LINK_STATE_ENSLAVING] = "configuring",
2541 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2542 [LINK_STATE_SETTING_ROUTES] = "configuring",
2543 [LINK_STATE_CONFIGURED] = "configured",
2544 [LINK_STATE_UNMANAGED] = "unmanaged",
2545 [LINK_STATE_FAILED] = "failed",
2546 [LINK_STATE_LINGER] = "linger",
2549 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2551 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2552 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2553 [LINK_OPERSTATE_DORMANT] = "dormant",
2554 [LINK_OPERSTATE_CARRIER] = "carrier",
2555 [LINK_OPERSTATE_DEGRADED] = "degraded",
2556 [LINK_OPERSTATE_ROUTABLE] = "routable",
2559 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
2561 static const char* const dhcp_support_table[_DHCP_SUPPORT_MAX] = {
2562 [DHCP_SUPPORT_NONE] = "none",
2563 [DHCP_SUPPORT_BOTH] = "both",
2564 [DHCP_SUPPORT_V4] = "v4",
2565 [DHCP_SUPPORT_V6] = "v6",
2568 DEFINE_STRING_TABLE_LOOKUP(dhcp_support, DHCPSupport);
2570 int config_parse_dhcp(
2572 const char *filename,
2574 const char *section,
2575 unsigned section_line,
2582 DHCPSupport *dhcp = data;
2590 /* Our enum shall be a superset of booleans, hence first try
2591 * to parse as boolean, and then as enum */
2593 k = parse_boolean(rvalue);
2595 *dhcp = DHCP_SUPPORT_BOTH;
2597 *dhcp = DHCP_SUPPORT_NONE;
2601 s = dhcp_support_from_string(rvalue);
2603 log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse DHCP option, ignoring: %s", rvalue);