1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <netinet/ether.h>
26 #include "libudev-private.h"
30 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
31 _cleanup_link_free_ Link *link = NULL;
33 struct ether_addr *mac_addr;
44 link->manager = manager;
45 link->state = _LINK_STATE_INVALID;
47 link->ifindex = udev_device_get_ifindex(device);
48 if (link->ifindex <= 0)
51 mac = udev_device_get_sysattr_value(device, "address");
53 mac_addr = ether_aton(mac);
55 memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
58 ifname = udev_device_get_sysname(device);
59 link->ifname = strdup(ifname);
61 r = hashmap_put(manager->links, &link->ifindex, link);
71 void link_free(Link *link) {
75 assert(link->manager);
78 sd_dhcp_client_free(link->dhcp);
80 route_free(link->dhcp_route);
81 link->dhcp_route = NULL;
83 address_free(link->dhcp_address);
84 link->dhcp_address = NULL;
86 hashmap_remove(link->manager->links, &link->ifindex);
93 int link_add(Manager *m, struct udev_device *device, Link **ret) {
103 ifindex = udev_device_get_ifindex(device);
104 link = hashmap_get(m->links, &ifindex);
110 r = link_new(m, device, &link);
116 kind = netdev_kind_from_string(udev_device_get_devtype(device));
117 if (kind != _NETDEV_KIND_INVALID) {
118 r = netdev_set_link(m, kind, link);
119 if (r < 0 && r != -ENOENT)
123 r = network_get(m, device, &network);
125 return r == -ENOENT ? 0 : r;
127 r = network_apply(m, network, link);
134 static int link_enter_configured(Link *link) {
136 assert(link->state == LINK_STATE_SETTING_ROUTES);
138 log_info_link(link, "link configured");
140 link->state = LINK_STATE_CONFIGURED;
145 static void link_enter_failed(Link *link) {
148 log_warning_link(link, "failed");
150 link->state = LINK_STATE_FAILED;
153 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
154 Link *link = userdata;
157 assert(link->route_messages > 0);
158 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
159 link->state == LINK_STATE_SETTING_ROUTES ||
160 link->state == LINK_STATE_FAILED);
162 link->route_messages --;
164 if (link->state == LINK_STATE_FAILED)
167 r = sd_rtnl_message_get_errno(m);
168 if (r < 0 && r != -EEXIST)
169 log_struct_link(LOG_WARNING, link,
170 "MESSAGE=%s: could not set route: %s",
171 link->ifname, strerror(-r),
175 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
177 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
178 log_debug_link(link, "routes set");
179 link_enter_configured(link);
185 static int link_enter_set_routes(Link *link) {
190 assert(link->network);
191 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
193 link->state = LINK_STATE_SETTING_ROUTES;
195 if (!link->network->static_routes && !link->dhcp_route)
196 return link_enter_configured(link);
198 log_debug_link(link, "setting routes");
200 LIST_FOREACH(static_routes, route, link->network->static_routes) {
201 r = route_configure(route, link, &route_handler);
203 log_warning_link(link,
204 "could not set routes: %s", strerror(-r));
205 link_enter_failed(link);
209 link->route_messages ++;
212 if (link->dhcp_route) {
213 r = route_configure(link->dhcp_route, link, &route_handler);
215 log_warning_link(link,
216 "could not set routes: %s", strerror(-r));
217 link_enter_failed(link);
221 link->route_messages ++;
227 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
228 Link *link = userdata;
233 assert(link->ifname);
234 assert(link->addr_messages > 0);
235 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
237 link->addr_messages --;
239 if (link->state == LINK_STATE_FAILED)
242 r = sd_rtnl_message_get_errno(m);
243 if (r < 0 && r != -EEXIST)
244 log_struct_link(LOG_WARNING, link,
245 "MESSAGE=%s: could not set address: %s",
246 link->ifname, strerror(-r),
250 if (link->addr_messages == 0) {
251 log_debug_link(link, "addresses set");
252 link_enter_set_routes(link);
258 static int link_enter_set_addresses(Link *link) {
263 assert(link->network);
264 assert(link->state != _LINK_STATE_INVALID);
266 link->state = LINK_STATE_SETTING_ADDRESSES;
268 if (!link->network->static_addresses && !link->dhcp_address)
269 return link_enter_set_routes(link);
271 log_debug_link(link, "setting addresses");
273 LIST_FOREACH(static_addresses, address, link->network->static_addresses) {
274 r = address_configure(address, link, &address_handler);
276 log_warning_link(link,
277 "could not set addresses: %s", strerror(-r));
278 link_enter_failed(link);
282 link->addr_messages ++;
285 if (link->dhcp_address) {
286 r = address_configure(link->dhcp_address, link, &address_handler);
288 log_warning_link(link,
289 "could not set addresses: %s", strerror(-r));
290 link_enter_failed(link);
294 link->addr_messages ++;
300 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
301 Link *link = userdata;
306 assert(link->ifname);
308 if (link->state == LINK_STATE_FAILED)
311 r = sd_rtnl_message_get_errno(m);
312 if (r < 0 && r != -ENOENT)
313 log_struct_link(LOG_WARNING, link,
314 "MESSAGE=%s: could not drop address: %s",
315 link->ifname, strerror(-r),
322 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
325 r = sd_bus_message_get_errno(m);
327 log_warning("Could not set hostname: %s", strerror(-r));
332 static int set_hostname(sd_bus *bus, const char *hostname) {
333 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
338 log_debug("Setting transient hostname: '%s'", hostname);
340 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
341 log_info("Not connected to system bus, ignoring transient hostname.");
345 r = sd_bus_message_new_method_call(
347 "org.freedesktop.hostname1",
348 "/org/freedesktop/hostname1",
349 "org.freedesktop.hostname1",
355 r = sd_bus_message_append(m, "sb", hostname, false);
359 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
361 log_error("Could not set transient hostname: %s", strerror(-r));
366 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
367 Link *link = userdata;
372 assert(link->ifname);
374 if (link->state == LINK_STATE_FAILED)
377 r = sd_rtnl_message_get_errno(m);
379 log_struct_link(LOG_WARNING, link,
380 "MESSAGE=%s: could not set MTU: %s",
381 link->ifname, strerror(-r),
388 static int link_set_mtu(Link *link, uint32_t mtu) {
389 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
393 assert(link->manager);
394 assert(link->manager->rtnl);
396 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
398 r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
400 log_error_link(link, "Could not allocate RTM_SETLINK message");
404 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
406 log_error_link(link, "Could not append MTU: %s", strerror(-r));
410 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
413 "Could not send rtnetlink message: %s", strerror(-r));
420 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
421 Link *link = userdata;
422 struct in_addr address;
423 struct in_addr netmask;
424 struct in_addr gateway;
429 assert(link->network);
430 assert(link->manager);
432 if (link->state == LINK_STATE_FAILED)
436 log_warning_link(link, "DHCP error: %s", strerror(-event));
437 link_enter_failed(link);
441 if (event == DHCP_EVENT_NO_LEASE)
442 log_debug_link(link, "IP address in use.");
444 if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_EXPIRED ||
445 event == DHCP_EVENT_STOP) {
446 if (link->dhcp_address) {
447 address_drop(link->dhcp_address, link, address_drop_handler);
449 address_free(link->dhcp_address);
450 link->dhcp_address = NULL;
453 if (link->dhcp_route) {
454 route_free(link->dhcp_route);
455 link->dhcp_route = NULL;
458 if (link->network->dhcp_mtu) {
461 r = sd_dhcp_client_get_mtu(client, &mtu);
462 if (r >= 0 && link->original_mtu != mtu) {
463 r = link_set_mtu(link, link->original_mtu);
465 log_warning_link(link, "DHCP error: could not reset MTU");
466 link_enter_failed(link);
472 if (link->network->dhcp_hostname) {
473 r = set_hostname(link->manager->bus, "");
475 log_error("Failed to reset transient hostname");
479 r = sd_dhcp_client_get_address(client, &address);
481 log_warning_link(link, "DHCP error: no address");
482 link_enter_failed(link);
486 r = sd_dhcp_client_get_netmask(client, &netmask);
488 log_warning_link(link, "DHCP error: no netmask");
489 link_enter_failed(link);
493 prefixlen = sd_dhcp_client_prefixlen(&netmask);
495 log_warning_link(link, "DHCP error: no prefixlen");
496 link_enter_failed(link);
500 r = sd_dhcp_client_get_router(client, &gateway);
502 log_warning_link(link, "DHCP error: no router");
503 link_enter_failed(link);
507 if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
508 _cleanup_address_free_ Address *addr = NULL;
509 _cleanup_route_free_ Route *rt = NULL;
510 struct in_addr *nameservers;
511 size_t nameservers_size;
513 log_struct_link(LOG_INFO, link,
514 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
516 ADDRESS_FMT_VAL(address),
518 ADDRESS_FMT_VAL(gateway),
519 "ADDRESS=%u.%u.%u.%u",
520 ADDRESS_FMT_VAL(address),
523 "GATEWAY=%u.%u.%u.%u",
524 ADDRESS_FMT_VAL(gateway),
527 r = address_new_dynamic(&addr);
529 log_error_link(link, "Could not allocate address");
530 link_enter_failed(link);
534 addr->family = AF_INET;
535 addr->in_addr.in = address;
536 addr->prefixlen = prefixlen;
537 addr->netmask = netmask;
539 r = route_new_dynamic(&rt);
541 log_error_link(link, "Could not allocate route");
542 link_enter_failed(link);
546 rt->family = AF_INET;
547 rt->in_addr.in = gateway;
549 link->dhcp_address = addr;
550 link->dhcp_route = rt;
554 if (link->network->dhcp_dns) {
555 r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
557 r = manager_update_resolv_conf(link->manager);
559 log_error("Failed to update resolv.conf");
563 if (link->network->dhcp_mtu) {
566 r = sd_dhcp_client_get_mtu(client, &mtu);
568 r = link_set_mtu(link, mtu);
570 log_error_link(link, "Failed to set MTU "
575 if (link->network->dhcp_hostname) {
576 const char *hostname;
578 r = sd_dhcp_client_get_hostname(client, &hostname);
580 r = set_hostname(link->manager->bus, hostname);
582 log_error("Failed to set transient hostname "
583 "to '%s'", hostname);
587 link_enter_set_addresses(link);
593 static int link_acquire_conf(Link *link) {
597 assert(link->network);
598 assert(link->network->dhcp);
599 assert(link->manager);
600 assert(link->manager->event);
603 r = sd_dhcp_client_new(&link->dhcp);
607 r = sd_dhcp_client_attach_event(link->dhcp, NULL, 0);
611 r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
615 r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
619 r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
623 if (link->network->dhcp_mtu) {
624 r = sd_dhcp_client_set_request_option(link->dhcp, 26);
630 log_debug_link(link, "acquiring DHCPv4 lease");
632 r = sd_dhcp_client_start(link->dhcp);
639 static int link_update_flags(Link *link, unsigned flags) {
643 assert(link->network);
645 if (link->state == LINK_STATE_FAILED)
648 if (link->flags == flags) {
649 log_debug_link(link, "link status unchanged: %#.8x", flags);
653 if ((link->flags & IFF_UP) != (flags & IFF_UP))
655 "link is %s", flags & IFF_UP ? "up": "down");
657 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
658 if (flags & IFF_LOWER_UP) {
659 log_info_link(link, "carrier on");
661 if (link->network->dhcp) {
662 r = link_acquire_conf(link);
664 log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
665 link_enter_failed(link);
670 log_info_link(link, "carrier off");
672 if (link->network->dhcp) {
673 r = sd_dhcp_client_stop(link->dhcp);
675 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
676 link_enter_failed(link);
684 "link status updated: %#.8x -> %#.8x", link->flags, flags);
691 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
692 Link *link = userdata;
697 if (link->state == LINK_STATE_FAILED)
700 r = sd_rtnl_message_get_errno(m);
702 log_struct_link(LOG_ERR, link,
703 "MESSAGE=%s: could not bring up interface: %s",
704 link->ifname, strerror(-r),
707 link_enter_failed(link);
711 link_update_flags(link, link->flags | IFF_UP);
716 static int link_up(Link *link) {
717 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
721 assert(link->manager);
722 assert(link->manager->rtnl);
724 log_debug_link(link, "bringing link up");
726 r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
728 log_error_link(link, "Could not allocate RTM_SETLINK message");
732 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
734 log_error_link(link, "Could not set link flags: %s", strerror(-r));
738 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
741 "Could not send rtnetlink message: %s", strerror(-r));
748 static int link_enslaved(Link *link) {
752 assert(link->state == LINK_STATE_ENSLAVING);
753 assert(link->network);
757 link_enter_failed(link);
761 if (!link->network->dhcp)
762 return link_enter_set_addresses(link);
767 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
768 Link *link = userdata;
772 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
773 assert(link->network);
777 if (link->state == LINK_STATE_FAILED)
780 r = sd_rtnl_message_get_errno(m);
782 log_struct_link(LOG_ERR, link,
783 "MESSAGE=%s: could not enslave: %s",
784 link->ifname, strerror(-r),
787 link_enter_failed(link);
791 log_debug_link(link, "enslaved");
793 if (link->enslaving == 0)
799 static int link_enter_enslave(Link *link) {
803 assert(link->network);
804 assert(link->state == _LINK_STATE_INVALID);
806 link->state = LINK_STATE_ENSLAVING;
808 if (!link->network->bridge && !link->network->bond && !link->network->vlan)
809 return link_enslaved(link);
811 if (link->network->bridge) {
812 log_struct_link(LOG_DEBUG, link,
813 "MESSAGE=%s: enslaving by '%s'",
814 link->ifname, link->network->bridge->name,
815 NETDEV(link->network->bridge),
818 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
820 log_struct_link(LOG_WARNING, link,
821 "MESSAGE=%s: could not enslave by '%s': %s",
822 link->ifname, link->network->bridge->name, strerror(-r),
823 NETDEV(link->network->bridge),
825 link_enter_failed(link);
832 if (link->network->vlan) {
833 log_struct_link(LOG_DEBUG, link,
834 "MESSAGE=%s: enslaving by '%s'",
835 link->ifname, link->network->vlan->name,
836 NETDEV(link->network->vlan),
839 r = netdev_enslave(link->network->vlan, link, &enslave_handler);
841 log_struct_link(LOG_WARNING, link,
842 "MESSAGE=%s: could not enslave by '%s': %s",
843 link->ifname, link->network->vlan->name,
844 strerror(-r), NETDEV(link->network->vlan),
846 link_enter_failed(link);
856 static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
857 Link *link = userdata;
862 if (link->state == LINK_STATE_FAILED)
865 r = sd_rtnl_message_get_errno(m);
867 log_struct_link(LOG_ERR, link,
868 "MESSAGE=%s: could not get state: %s",
869 link->ifname, strerror(-r),
872 link_enter_failed(link);
876 log_debug_link(link, "got link state");
878 link_update(link, m);
883 static int link_get(Link *link) {
884 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
888 assert(link->manager);
889 assert(link->manager->rtnl);
891 log_debug_link(link, "requesting link status");
893 r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
895 log_error_link(link, "Could not allocate RTM_GETLINK message");
899 r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
902 "Could not send rtnetlink message: %s", strerror(-r));
909 int link_configure(Link *link) {
913 assert(link->network);
914 assert(link->state == _LINK_STATE_INVALID);
918 link_enter_failed(link);
922 return link_enter_enslave(link);
925 int link_update(Link *link, sd_rtnl_message *m) {
934 if (link->state == LINK_STATE_FAILED)
937 r = sd_rtnl_message_link_get_flags(m, &flags);
939 log_warning_link(link, "Could not get link flags");
943 while (sd_rtnl_message_read(m, &type, &data) > 0) {
944 if (type == IFLA_MTU && link->network->dhcp &&
945 link->network->dhcp_mtu && !link->original_mtu) {
946 link->original_mtu = *(uint16_t *) data;
947 log_debug_link(link, "saved original MTU: %" PRIu16,
952 return link_update_flags(link, flags);