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_STATIC_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;
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_STATIC_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_STATIC_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 address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
603 _cleanup_link_unref_ Link *link = userdata;
608 assert(link->ifname);
609 assert(link->addr_messages > 0);
610 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
611 LINK_STATE_FAILED, LINK_STATE_LINGER));
613 link->addr_messages --;
615 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
618 r = sd_rtnl_message_get_errno(m);
619 if (r < 0 && r != -EEXIST)
620 log_struct_link(LOG_WARNING, link,
621 "MESSAGE=%-*s: could not set address: %s",
623 link->ifname, strerror(-r),
627 if (link->addr_messages == 0) {
628 log_debug_link(link, "addresses set");
629 link_enter_set_routes(link);
635 static int link_enter_set_addresses(Link *link) {
638 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
641 assert(link->network);
642 assert(link->state != _LINK_STATE_INVALID);
644 link->state = LINK_STATE_SETTING_ADDRESSES;
646 if (!link->network->static_addresses && !link->dhcp_lease &&
647 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
648 return link_enter_set_routes(link);
650 log_debug_link(link, "setting addresses");
652 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
653 r = address_configure(ad, link, &address_handler);
655 log_warning_link(link,
656 "could not set addresses: %s", strerror(-r));
657 link_enter_failed(link);
661 link->addr_messages ++;
664 if (link->ipv4ll && !link->dhcp_lease) {
665 _cleanup_address_free_ Address *ll_addr = NULL;
668 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
669 if (r < 0 && r != -ENOENT) {
670 log_warning_link(link, "IPV4LL error: no address: %s",
676 r = address_new_dynamic(&ll_addr);
678 log_error_link(link, "Could not allocate address: %s", strerror(-r));
682 ll_addr->family = AF_INET;
683 ll_addr->in_addr.in = addr;
684 ll_addr->prefixlen = 16;
685 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
686 ll_addr->scope = RT_SCOPE_LINK;
688 r = address_configure(ll_addr, link, &address_handler);
690 log_warning_link(link,
691 "could not set addresses: %s", strerror(-r));
692 link_enter_failed(link);
696 link->addr_messages ++;
700 if (link->dhcp_lease) {
701 _cleanup_address_free_ Address *address = NULL;
703 struct in_addr netmask;
706 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
708 log_warning_link(link, "DHCP error: no address: %s",
713 if (!link->network->dhcp_critical) {
714 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
717 log_warning_link(link, "DHCP error: no lifetime: %s",
723 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
725 log_warning_link(link, "DHCP error: no netmask: %s",
730 prefixlen = net_netmask_to_prefixlen(&netmask);
732 r = address_new_dynamic(&address);
734 log_error_link(link, "Could not allocate address: %s",
739 address->family = AF_INET;
740 address->in_addr.in = addr;
741 address->cinfo.ifa_prefered = lifetime;
742 address->cinfo.ifa_valid = lifetime;
743 address->prefixlen = prefixlen;
744 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
746 /* use update rather than configure so that we will update the lifetime
747 of an existing address if it has already been configured */
748 r = address_update(address, link, &address_handler);
750 log_warning_link(link,
751 "could not set addresses: %s", strerror(-r));
752 link_enter_failed(link);
756 link->addr_messages ++;
762 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
763 _cleanup_link_unref_ Link *link = userdata;
768 assert(link->ifname);
770 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
773 r = sd_rtnl_message_get_errno(m);
774 if (r < 0 && r != -ENOENT)
775 log_struct_link(LOG_WARNING, link,
776 "MESSAGE=%-*s: could not update address: %s",
778 link->ifname, strerror(-r),
785 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
786 _cleanup_link_unref_ Link *link = userdata;
791 assert(link->ifname);
793 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
796 r = sd_rtnl_message_get_errno(m);
797 if (r < 0 && r != -EADDRNOTAVAIL)
798 log_struct_link(LOG_WARNING, link,
799 "MESSAGE=%-*s: could not drop address: %s",
801 link->ifname, strerror(-r),
808 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
809 _cleanup_link_unref_ Link *link = userdata;
814 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
817 r = sd_bus_message_get_errno(m);
819 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
824 static int link_set_hostname(Link *link, const char *hostname) {
825 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
829 assert(link->manager);
832 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
834 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
835 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
839 r = sd_bus_message_new_method_call(
842 "org.freedesktop.hostname1",
843 "/org/freedesktop/hostname1",
844 "org.freedesktop.hostname1",
849 r = sd_bus_message_append(m, "sb", hostname, false);
853 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
855 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
864 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
865 _cleanup_link_unref_ Link *link = userdata;
870 assert(link->ifname);
872 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
875 r = sd_rtnl_message_get_errno(m);
877 log_struct_link(LOG_WARNING, link,
878 "MESSAGE=%-*s: could not set MTU: %s",
879 IFNAMSIZ, link->ifname, strerror(-r),
886 static int link_set_mtu(Link *link, uint32_t mtu) {
887 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
891 assert(link->manager);
892 assert(link->manager->rtnl);
894 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
896 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
897 RTM_SETLINK, link->ifindex);
899 log_error_link(link, "Could not allocate RTM_SETLINK message");
903 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
905 log_error_link(link, "Could not append MTU: %s", strerror(-r));
909 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
912 "Could not send rtnetlink message: %s", strerror(-r));
921 static int dhcp_lease_lost(Link *link) {
922 _cleanup_address_free_ Address *address = NULL;
924 struct in_addr netmask;
925 struct in_addr gateway;
931 assert(link->dhcp_lease);
933 log_warning_link(link, "DHCP lease lost");
935 if (link->network->dhcp_routes) {
936 struct sd_dhcp_route *routes;
939 r = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes, &routes_size);
941 for (i = 0; i < routes_size; i++) {
942 _cleanup_route_free_ Route *route = NULL;
944 r = route_new_dynamic(&route);
946 route->family = AF_INET;
947 route->in_addr.in = routes[i].gw_addr;
948 route->dst_addr.in = routes[i].dst_addr;
949 route->dst_prefixlen = routes[i].dst_prefixlen;
951 route_drop(route, link, &route_drop_handler);
957 r = address_new_dynamic(&address);
959 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
961 _cleanup_route_free_ Route *route_gw = NULL;
962 _cleanup_route_free_ Route *route = NULL;
964 r = route_new_dynamic(&route_gw);
966 route_gw->family = AF_INET;
967 route_gw->dst_addr.in = gateway;
968 route_gw->dst_prefixlen = 32;
969 route_gw->scope = RT_SCOPE_LINK;
971 route_drop(route_gw, link, &route_drop_handler);
974 r = route_new_dynamic(&route);
976 route->family = AF_INET;
977 route->in_addr.in = gateway;
979 route_drop(route, link, &route_drop_handler);
983 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
984 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
985 prefixlen = net_netmask_to_prefixlen(&netmask);
987 address->family = AF_INET;
988 address->in_addr.in = addr;
989 address->prefixlen = prefixlen;
991 address_drop(address, link, &address_drop_handler);
994 if (link->network->dhcp_mtu) {
997 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
998 if (r >= 0 && link->original_mtu != mtu) {
999 r = link_set_mtu(link, link->original_mtu);
1001 log_warning_link(link, "DHCP error: could not reset MTU");
1002 link_enter_failed(link);
1008 if (link->network->dhcp_hostname) {
1009 const char *hostname = NULL;
1011 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
1012 if (r >= 0 && hostname) {
1013 r = link_set_hostname(link, "");
1015 log_error_link(link, "Failed to reset transient hostname");
1019 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
1024 static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
1025 sd_dhcp_lease *lease;
1028 r = sd_dhcp_client_get_lease(client, &lease);
1030 log_warning_link(link, "DHCP error: no lease %s",
1035 sd_dhcp_lease_unref(link->dhcp_lease);
1036 link->dhcp_lease = lease;
1038 link_enter_set_addresses(link);
1043 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1044 sd_dhcp_lease *lease;
1045 struct in_addr address;
1046 struct in_addr netmask;
1047 struct in_addr gateway;
1054 r = sd_dhcp_client_get_lease(client, &lease);
1056 log_warning_link(link, "DHCP error: no lease: %s",
1061 r = sd_dhcp_lease_get_address(lease, &address);
1063 log_warning_link(link, "DHCP error: no address: %s",
1068 r = sd_dhcp_lease_get_netmask(lease, &netmask);
1070 log_warning_link(link, "DHCP error: no netmask: %s",
1075 prefixlen = net_netmask_to_prefixlen(&netmask);
1077 r = sd_dhcp_lease_get_router(lease, &gateway);
1078 if (r < 0 && r != -ENOENT) {
1079 log_warning_link(link, "DHCP error: could not get gateway: %s",
1085 log_struct_link(LOG_INFO, link,
1086 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
1089 ADDRESS_FMT_VAL(address),
1091 ADDRESS_FMT_VAL(gateway),
1092 "ADDRESS=%u.%u.%u.%u",
1093 ADDRESS_FMT_VAL(address),
1096 "GATEWAY=%u.%u.%u.%u",
1097 ADDRESS_FMT_VAL(gateway),
1100 log_struct_link(LOG_INFO, link,
1101 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1104 ADDRESS_FMT_VAL(address),
1106 "ADDRESS=%u.%u.%u.%u",
1107 ADDRESS_FMT_VAL(address),
1112 link->dhcp_lease = lease;
1114 if (link->network->dhcp_mtu) {
1117 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1119 r = link_set_mtu(link, mtu);
1121 log_error_link(link, "Failed to set MTU "
1122 "to %" PRIu16, mtu);
1126 if (link->network->dhcp_hostname) {
1127 const char *hostname;
1129 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1131 r = link_set_hostname(link, hostname);
1133 log_error_link(link, "Failed to set transient hostname "
1134 "to '%s'", hostname);
1138 link_enter_set_addresses(link);
1143 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1144 Link *link = userdata;
1148 assert(link->network);
1149 assert(link->manager);
1151 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1155 case DHCP_EVENT_NO_LEASE:
1156 log_debug_link(link, "IP address in use.");
1158 case DHCP_EVENT_EXPIRED:
1159 case DHCP_EVENT_STOP:
1160 case DHCP_EVENT_IP_CHANGE:
1161 if (link->network->dhcp_critical) {
1162 log_error_link(link, "DHCPv4 connection considered system critical, "
1163 "ignoring request to reconfigure it.");
1167 if (link->dhcp_lease) {
1168 r = dhcp_lease_lost(link);
1170 link_enter_failed(link);
1175 if (event == DHCP_EVENT_IP_CHANGE) {
1176 r = dhcp_lease_acquired(client, link);
1178 link_enter_failed(link);
1183 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1184 if (!sd_ipv4ll_is_running(link->ipv4ll))
1185 r = sd_ipv4ll_start(link->ipv4ll);
1186 else if (ipv4ll_is_bound(link->ipv4ll))
1187 r = ipv4ll_address_update(link, false);
1189 link_enter_failed(link);
1195 case DHCP_EVENT_RENEW:
1196 r = dhcp_lease_renew(client, link);
1198 link_enter_failed(link);
1202 case DHCP_EVENT_IP_ACQUIRE:
1203 r = dhcp_lease_acquired(client, link);
1205 link_enter_failed(link);
1209 if (ipv4ll_is_bound(link->ipv4ll))
1210 r = ipv4ll_address_update(link, true);
1212 r = sd_ipv4ll_stop(link->ipv4ll);
1214 link_enter_failed(link);
1221 log_warning_link(link, "DHCP error: client failed: %s", strerror(-event));
1223 log_warning_link(link, "DHCP unknown event: %d", event);
1230 static int ipv4ll_address_update(Link *link, bool deprecate) {
1232 struct in_addr addr;
1236 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1238 _cleanup_address_free_ Address *address = NULL;
1240 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1241 deprecate ? "deprecate" : "approve",
1242 ADDRESS_FMT_VAL(addr));
1244 r = address_new_dynamic(&address);
1246 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1250 address->family = AF_INET;
1251 address->in_addr.in = addr;
1252 address->prefixlen = 16;
1253 address->scope = RT_SCOPE_LINK;
1254 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1255 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1257 address_update(address, link, &address_update_handler);
1264 static int ipv4ll_address_lost(Link *link) {
1266 struct in_addr addr;
1270 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1272 _cleanup_address_free_ Address *address = NULL;
1273 _cleanup_route_free_ Route *route = NULL;
1275 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1276 ADDRESS_FMT_VAL(addr));
1278 r = address_new_dynamic(&address);
1280 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1284 address->family = AF_INET;
1285 address->in_addr.in = addr;
1286 address->prefixlen = 16;
1287 address->scope = RT_SCOPE_LINK;
1289 address_drop(address, link, &address_drop_handler);
1291 r = route_new_dynamic(&route);
1293 log_error_link(link, "Could not allocate route: %s",
1298 route->family = AF_INET;
1299 route->scope = RT_SCOPE_LINK;
1300 route->metrics = 99;
1302 route_drop(route, link, &route_drop_handler);
1308 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1310 struct in_addr addr;
1314 r = sd_ipv4ll_get_address(ll, &addr);
1320 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1321 struct in_addr address;
1327 r = sd_ipv4ll_get_address(ll, &address);
1331 log_struct_link(LOG_INFO, link,
1332 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1335 ADDRESS_FMT_VAL(address),
1338 link_enter_set_addresses(link);
1343 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1344 Link *link = userdata;
1348 assert(link->network);
1349 assert(link->manager);
1351 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1355 case IPV4LL_EVENT_STOP:
1356 case IPV4LL_EVENT_CONFLICT:
1357 r = ipv4ll_address_lost(link);
1359 link_enter_failed(link);
1363 case IPV4LL_EVENT_BIND:
1364 r = ipv4ll_address_claimed(ll, link);
1366 link_enter_failed(link);
1372 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1374 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1379 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1380 Link *link = userdata;
1383 assert(link->network);
1384 assert(link->manager);
1386 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1390 case DHCP6_EVENT_STOP:
1391 case DHCP6_EVENT_RESEND_EXPIRE:
1392 case DHCP6_EVENT_RETRANS_MAX:
1393 case DHCP6_EVENT_IP_ACQUIRE:
1394 log_debug_link(link, "DHCPv6 event %d", event);
1400 log_warning_link(link, "DHCPv6 error: %s",
1403 log_warning_link(link, "DHCPv6 unknown event: %d",
1409 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1410 Link *link = userdata;
1414 assert(link->network);
1415 assert(link->manager);
1417 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1421 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1422 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1425 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1426 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1431 log_warning_link(link, "ICMPv6 error: %s",
1434 log_warning_link(link, "ICMPv6 unknown event: %d",
1440 if (link->dhcp6_client)
1443 r = sd_dhcp6_client_new(&link->dhcp6_client);
1447 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1449 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1453 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1455 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1459 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1461 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1465 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1468 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1472 r = sd_dhcp6_client_start(link->dhcp6_client);
1474 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1477 static int link_acquire_conf(Link *link) {
1481 assert(link->network);
1482 assert(link->manager);
1483 assert(link->manager->event);
1485 if (link->network->ipv4ll) {
1486 assert(link->ipv4ll);
1488 log_debug_link(link, "acquiring IPv4 link-local address");
1490 r = sd_ipv4ll_start(link->ipv4ll);
1492 log_warning_link(link, "could not acquire IPv4 "
1493 "link-local address");
1498 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1499 assert(link->dhcp_client);
1501 log_debug_link(link, "acquiring DHCPv4 lease");
1503 r = sd_dhcp_client_start(link->dhcp_client);
1505 log_warning_link(link, "could not acquire DHCPv4 "
1511 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1512 assert(link->icmp6_router_discovery);
1514 log_debug_link(link, "discovering IPv6 routers");
1516 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1518 log_warning_link(link, "could not start IPv6 router discovery");
1526 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1527 /* see Documentation/networking/operstates.txt in the kernel sources */
1529 if (operstate == IF_OPER_UP)
1532 if (operstate == IF_OPER_UNKNOWN)
1533 /* operstate may not be implemented, so fall back to flags */
1534 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1540 #define FLAG_STRING(string, flag, old, new) \
1541 (((old ^ new) & flag) \
1542 ? ((old & flag) ? (" -" string) : (" +" string)) \
1545 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1546 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1548 bool carrier_gained = false, carrier_lost = false;
1553 r = sd_rtnl_message_link_get_flags(m, &flags);
1555 log_warning_link(link, "Could not get link flags");
1559 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1561 /* if we got a message without operstate, take it to mean
1562 the state was unchanged */
1563 operstate = link->kernel_operstate;
1565 if ((link->flags == flags) && (link->kernel_operstate == operstate))
1568 if (link->flags != flags) {
1569 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",
1570 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1571 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1572 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1573 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1574 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1575 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1576 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1577 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1578 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1579 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1580 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1581 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1582 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1583 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1584 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1585 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1586 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1587 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1588 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1590 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1591 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1592 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1593 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1594 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1595 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1596 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1597 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1599 /* link flags are currently at most 18 bits, let's align to printing 20 */
1600 if (unknown_flags_added)
1601 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1602 unknown_flags_added);
1604 if (unknown_flags_removed)
1605 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1606 unknown_flags_removed);
1609 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1610 link_has_carrier(flags, operstate);
1611 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1612 !link_has_carrier(flags, operstate);
1614 link->flags = flags;
1615 link->kernel_operstate = operstate;
1619 if (link->state == LINK_STATE_FAILED ||
1620 link->state == LINK_STATE_UNMANAGED)
1623 if (carrier_gained) {
1624 log_info_link(link, "gained carrier");
1626 if (link->network) {
1627 r = link_acquire_conf(link);
1629 link_enter_failed(link);
1633 } else if (carrier_lost) {
1634 log_info_link(link, "lost carrier");
1636 r = link_stop_clients(link);
1638 link_enter_failed(link);
1646 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1647 _cleanup_link_unref_ Link *link = userdata;
1652 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1655 r = sd_rtnl_message_get_errno(m);
1657 /* we warn but don't fail the link, as it may
1658 be brought up later */
1659 log_struct_link(LOG_WARNING, link,
1660 "MESSAGE=%-*s: could not bring up interface: %s",
1662 link->ifname, strerror(-r),
1670 static int link_up(Link *link) {
1671 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1675 assert(link->manager);
1676 assert(link->manager->rtnl);
1678 log_debug_link(link, "bringing link up");
1680 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1681 RTM_SETLINK, link->ifindex);
1683 log_error_link(link, "Could not allocate RTM_SETLINK message");
1687 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1689 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1693 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1695 log_error_link(link,
1696 "Could not send rtnetlink message: %s", strerror(-r));
1705 static int link_enslaved(Link *link) {
1709 assert(link->state == LINK_STATE_ENSLAVING);
1710 assert(link->network);
1712 log_debug_link(link, "enslaved");
1714 if (!(link->flags & IFF_UP)) {
1717 link_enter_failed(link);
1722 return link_enter_set_addresses(link);
1725 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1726 _cleanup_link_unref_ Link *link = userdata;
1730 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1731 LINK_STATE_LINGER));
1732 assert(link->network);
1736 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1739 r = sd_rtnl_message_get_errno(m);
1740 if (r < 0 && r != -EEXIST) {
1741 log_struct_link(LOG_ERR, link,
1742 "MESSAGE=%-*s: could not enslave: %s",
1744 link->ifname, strerror(-r),
1747 link_enter_failed(link);
1751 if (link->enslaving <= 0)
1752 link_enslaved(link);
1757 static int link_enter_enslave(Link *link) {
1758 NetDev *vlan, *macvlan, *vxlan;
1763 assert(link->network);
1764 assert(link->state == LINK_STATE_INITIALIZING);
1766 link->state = LINK_STATE_ENSLAVING;
1770 if (!link->network->bridge &&
1771 !link->network->bond &&
1772 !link->network->tunnel &&
1773 hashmap_isempty(link->network->vlans) &&
1774 hashmap_isempty(link->network->macvlans) &&
1775 hashmap_isempty(link->network->vxlans))
1776 return link_enslaved(link);
1778 if (link->network->bond) {
1779 log_struct_link(LOG_DEBUG, link,
1780 "MESSAGE=%-*s: enslaving by '%s'",
1782 link->ifname, link->network->bond->ifname,
1783 NETDEV(link->network->bond),
1786 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1788 log_struct_link(LOG_WARNING, link,
1789 "MESSAGE=%-*s: could not enslave by '%s': %s",
1791 link->ifname, link->network->bond->ifname, strerror(-r),
1792 NETDEV(link->network->bond),
1794 link_enter_failed(link);
1801 if (link->network->bridge) {
1802 log_struct_link(LOG_DEBUG, link,
1803 "MESSAGE=%-*s: enslaving by '%s'",
1805 link->ifname, link->network->bridge->ifname,
1806 NETDEV(link->network->bridge),
1809 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1811 log_struct_link(LOG_WARNING, link,
1812 "MESSAGE=%-*s: could not enslave by '%s': %s",
1814 link->ifname, link->network->bridge->ifname, strerror(-r),
1815 NETDEV(link->network->bridge),
1817 link_enter_failed(link);
1824 if (link->network->tunnel) {
1825 log_struct_link(LOG_DEBUG, link,
1826 "MESSAGE=%-*s: enslaving by '%s'",
1828 link->ifname, link->network->tunnel->ifname,
1829 NETDEV(link->network->tunnel),
1832 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1834 log_struct_link(LOG_WARNING, link,
1835 "MESSAGE=%-*s: could not enslave by '%s': %s",
1837 link->ifname, link->network->tunnel->ifname, strerror(-r),
1838 NETDEV(link->network->tunnel),
1840 link_enter_failed(link);
1847 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1848 log_struct_link(LOG_DEBUG, link,
1849 "MESSAGE=%-*s: enslaving by '%s'",
1851 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1853 r = netdev_enslave(vlan, link, &enslave_handler);
1855 log_struct_link(LOG_WARNING, link,
1856 "MESSAGE=%-*s: could not enslave by '%s': %s",
1858 link->ifname, vlan->ifname, strerror(-r),
1859 NETDEV(vlan), NULL);
1860 link_enter_failed(link);
1867 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1868 log_struct_link(LOG_DEBUG, link,
1869 "MESSAGE=%-*s: enslaving by '%s'",
1871 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1873 r = netdev_enslave(macvlan, link, &enslave_handler);
1875 log_struct_link(LOG_WARNING, link,
1876 "MESSAGE=%-*s: could not enslave by '%s': %s",
1878 link->ifname, macvlan->ifname, strerror(-r),
1879 NETDEV(macvlan), NULL);
1880 link_enter_failed(link);
1887 HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1888 log_struct_link(LOG_DEBUG, link,
1889 "MESSAGE=%*s: enslaving by '%s'",
1891 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1893 r = netdev_enslave(vxlan, link, &enslave_handler);
1895 log_struct_link(LOG_WARNING, link,
1896 "MESSAGE=%*s: could not enslave by '%s': %s",
1898 link->ifname, vxlan->ifname, strerror(-r),
1899 NETDEV(vxlan), NULL);
1900 link_enter_failed(link);
1910 static int link_configure(Link *link) {
1914 assert(link->state == LINK_STATE_INITIALIZING);
1916 if (link->network->ipv4ll) {
1919 r = sd_ipv4ll_new(&link->ipv4ll);
1923 if (link->udev_device) {
1924 r = net_get_unique_predictable_data(link->udev_device, seed);
1926 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1932 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1936 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1940 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1944 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1949 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1950 r = sd_dhcp_client_new(&link->dhcp_client);
1954 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1958 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1962 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1966 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1970 if (link->network->dhcp_mtu) {
1971 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1976 if (link->network->dhcp_routes) {
1977 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
1980 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
1985 if (link->network->dhcp_sendhost) {
1986 _cleanup_free_ char *hostname = gethostname_malloc();
1990 if (!is_localhost(hostname)) {
1991 r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname);
1998 if (link->network->dhcp_server) {
1999 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2003 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2008 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
2009 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
2013 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
2018 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
2023 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
2028 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
2029 icmp6_router_handler, link);
2034 if (link_has_carrier(link->flags, link->kernel_operstate)) {
2035 r = link_acquire_conf(link);
2040 return link_enter_enslave(link);
2043 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2044 _cleanup_link_unref_ Link *link = userdata;
2049 assert(link->ifname);
2050 assert(link->manager);
2052 if (link->state != LINK_STATE_INITIALIZING)
2055 log_debug_link(link, "link state is up-to-date");
2057 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
2059 link_enter_unmanaged(link);
2064 r = network_apply(link->manager, network, link);
2068 r = link_configure(link);
2075 int link_initialized(Link *link, struct udev_device *device) {
2076 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2080 assert(link->manager);
2081 assert(link->manager->rtnl);
2084 if (link->state != LINK_STATE_INITIALIZING)
2087 log_debug_link(link, "udev initialized link");
2089 link->udev_device = udev_device_ref(device);
2091 /* udev has initialized the link, but we don't know if we have yet processed
2092 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
2093 we know that the pending NEWLINKs have already been processed and that we
2096 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
2100 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
2109 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
2110 Manager *m = userdata;
2113 _cleanup_address_free_ Address *address = NULL;
2115 char buf[INET6_ADDRSTRLEN];
2116 bool address_dropped = false;
2123 r = sd_rtnl_message_get_type(message, &type);
2125 log_warning("rtnl: could not get message type");
2129 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2130 if (r < 0 || ifindex <= 0) {
2131 log_warning("rtnl: received address message without valid ifindex, ignoring");
2134 r = link_get(m, ifindex, &link);
2135 if (r < 0 || !link) {
2136 log_warning("rtnl: received address for a nonexistent link, ignoring");
2141 r = address_new_dynamic(&address);
2145 r = sd_rtnl_message_addr_get_family(message, &address->family);
2146 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
2147 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
2151 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2153 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2157 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2159 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
2163 switch (address->family) {
2165 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2167 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2174 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2176 log_warning_link(link, "rtnl: received address without valid address, ignoring");
2183 assert_not_reached("invalid address family");
2186 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
2187 log_warning_link(link, "could not print address");
2191 LIST_FOREACH(addresses, ad, link->addresses) {
2192 if (address_equal(ad, address)) {
2193 LIST_REMOVE(addresses, link->addresses, ad);
2197 address_dropped = true;
2205 if (!address_dropped)
2206 log_debug_link(link, "added address: %s/%u", buf,
2207 address->prefixlen);
2209 LIST_PREPEND(addresses, link->addresses, address);
2216 if (address_dropped) {
2217 log_debug_link(link, "removed address: %s/%u", buf,
2218 address->prefixlen);
2225 assert_not_reached("Received invalid RTNL message type");
2231 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
2232 _cleanup_link_unref_ Link *link = userdata;
2238 assert(link->manager);
2240 for (; m; m = sd_rtnl_message_next(m)) {
2241 r = sd_rtnl_message_get_errno(m);
2243 log_debug_link(link, "getting address failed: %s", strerror(-r));
2247 r = link_rtnl_process_address(rtnl, m, link->manager);
2249 log_warning_link(link, "could not process address: %s", strerror(-r));
2255 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2257 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2258 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2259 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2267 r = link_new(m, message, ret);
2273 log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2275 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2279 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2285 if (detect_container(NULL) <= 0) {
2286 /* not in a container, udev will be around */
2287 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2288 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2290 log_warning_link(link, "could not find udev device");
2294 if (udev_device_get_is_initialized(device) <= 0) {
2296 log_debug_link(link, "udev initializing link...");
2300 r = link_initialized(link, device);
2304 /* we are calling a callback directly, so must take a ref */
2307 r = link_initialized_and_synced(m->rtnl, NULL, link);
2315 int link_update(Link *link, sd_rtnl_message *m) {
2316 struct ether_addr mac;
2321 assert(link->ifname);
2324 if (link->state == LINK_STATE_LINGER) {
2326 log_info_link(link, "link readded");
2327 link->state = LINK_STATE_ENSLAVING;
2330 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2331 if (r >= 0 && !streq(ifname, link->ifname)) {
2332 log_info_link(link, "renamed to %s", ifname);
2335 link->ifname = strdup(ifname);
2340 if (!link->original_mtu) {
2341 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2343 log_debug_link(link, "saved original MTU: %"
2344 PRIu16, link->original_mtu);
2347 /* The kernel may broadcast NEWLINK messages without the MAC address
2348 set, simply ignore them. */
2349 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2351 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2353 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2355 log_debug_link(link, "MAC address: "
2356 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2357 mac.ether_addr_octet[0],
2358 mac.ether_addr_octet[1],
2359 mac.ether_addr_octet[2],
2360 mac.ether_addr_octet[3],
2361 mac.ether_addr_octet[4],
2362 mac.ether_addr_octet[5]);
2365 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2367 log_warning_link(link, "Could not update MAC "
2368 "address in IPv4LL client: %s",
2374 if (link->dhcp_client) {
2375 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2377 log_warning_link(link, "Could not update MAC "
2378 "address in DHCP client: %s",
2384 if (link->dhcp6_client) {
2385 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2388 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2396 return link_update_flags(link, m);
2399 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2408 fprintf(f, "%s=", key);
2410 LIST_FOREACH(addresses, ad, address) {
2411 char buf[INET6_ADDRSTRLEN];
2413 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2414 fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2420 static void link_update_operstate(Link *link) {
2424 if (link->kernel_operstate == IF_OPER_DORMANT)
2425 link->operstate = LINK_OPERSTATE_DORMANT;
2426 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2428 uint8_t scope = RT_SCOPE_NOWHERE;
2430 /* if we have carrier, check what addresses we have */
2431 LIST_FOREACH(addresses, address, link->addresses) {
2432 if (address->scope < scope)
2433 scope = address->scope;
2436 if (scope < RT_SCOPE_SITE)
2437 /* universally accessible addresses found */
2438 link->operstate = LINK_OPERSTATE_ROUTABLE;
2439 else if (scope < RT_SCOPE_HOST)
2440 /* only link or site local addresses found */
2441 link->operstate = LINK_OPERSTATE_DEGRADED;
2443 /* no useful addresses found */
2444 link->operstate = LINK_OPERSTATE_CARRIER;
2446 link->operstate = LINK_OPERSTATE_UNKNOWN;
2449 int link_save(Link *link) {
2450 _cleanup_free_ char *temp_path = NULL;
2451 _cleanup_fclose_ FILE *f = NULL;
2452 const char *admin_state, *oper_state;
2456 assert(link->state_file);
2457 assert(link->lease_file);
2458 assert(link->manager);
2460 link_update_operstate(link);
2462 r = manager_save(link->manager);
2466 if (link->state == LINK_STATE_LINGER) {
2467 unlink(link->state_file);
2471 admin_state = link_state_to_string(link->state);
2472 assert(admin_state);
2474 oper_state = link_operstate_to_string(link->operstate);
2477 r = fopen_temporary(link->state_file, &f, &temp_path);
2481 fchmod(fileno(f), 0644);
2484 "# This is private data. Do not parse.\n"
2488 admin_state, oper_state, link->flags);
2490 if (link->network) {
2491 serialize_addresses(f, "DNS", link->network->dns);
2492 serialize_addresses(f, "NTP", link->network->ntp);
2495 if (link->dhcp_lease) {
2496 assert(link->network);
2498 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2505 "DHCP_USE_NTP=%s\n",
2507 yes_no(link->network->dhcp_dns),
2508 yes_no(link->network->dhcp_ntp));
2510 unlink(link->lease_file);
2514 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2516 unlink(link->state_file);
2522 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2527 static const char* const link_state_table[_LINK_STATE_MAX] = {
2528 [LINK_STATE_INITIALIZING] = "initializing",
2529 [LINK_STATE_ENSLAVING] = "configuring",
2530 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2531 [LINK_STATE_SETTING_ROUTES] = "configuring",
2532 [LINK_STATE_CONFIGURED] = "configured",
2533 [LINK_STATE_UNMANAGED] = "unmanaged",
2534 [LINK_STATE_FAILED] = "failed",
2535 [LINK_STATE_LINGER] = "linger",
2538 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2540 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2541 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2542 [LINK_OPERSTATE_DORMANT] = "dormant",
2543 [LINK_OPERSTATE_CARRIER] = "carrier",
2544 [LINK_OPERSTATE_DEGRADED] = "degraded",
2545 [LINK_OPERSTATE_ROUTABLE] = "routable",
2548 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
2550 static const char* const dhcp_support_table[_DHCP_SUPPORT_MAX] = {
2551 [DHCP_SUPPORT_NONE] = "none",
2552 [DHCP_SUPPORT_BOTH] = "both",
2553 [DHCP_SUPPORT_V4] = "v4",
2554 [DHCP_SUPPORT_V6] = "v6",
2557 DEFINE_STRING_TABLE_LOOKUP(dhcp_support, DHCPSupport);
2559 int config_parse_dhcp(
2561 const char *filename,
2563 const char *section,
2564 unsigned section_line,
2571 DHCPSupport *dhcp = data;
2579 /* Our enum shall be a superset of booleans, hence first try
2580 * to parse as boolean, and then as enum */
2582 k = parse_boolean(rvalue);
2584 *dhcp = DHCP_SUPPORT_BOTH;
2586 *dhcp = DHCP_SUPPORT_NONE;
2590 s = dhcp_support_from_string(rvalue);
2592 log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse DHCP option, ignoring: %s", rvalue);