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->network->dhcp_critical) {
447 log_warning_link(link, "DHCPv4 connection considered system critical, "
448 "ignoring request to reconfigure it down.");
452 if (link->dhcp_address) {
453 address_drop(link->dhcp_address, link, address_drop_handler);
455 address_free(link->dhcp_address);
456 link->dhcp_address = NULL;
459 if (link->dhcp_route) {
460 route_free(link->dhcp_route);
461 link->dhcp_route = NULL;
464 if (link->network->dhcp_mtu) {
467 r = sd_dhcp_client_get_mtu(client, &mtu);
468 if (r >= 0 && link->original_mtu != mtu) {
469 r = link_set_mtu(link, link->original_mtu);
471 log_warning_link(link, "DHCP error: could not reset MTU");
472 link_enter_failed(link);
478 if (link->network->dhcp_hostname) {
479 r = set_hostname(link->manager->bus, "");
481 log_error("Failed to reset transient hostname");
485 r = sd_dhcp_client_get_address(client, &address);
487 log_warning_link(link, "DHCP error: no address");
488 link_enter_failed(link);
492 r = sd_dhcp_client_get_netmask(client, &netmask);
494 log_warning_link(link, "DHCP error: no netmask");
495 link_enter_failed(link);
499 prefixlen = sd_dhcp_client_prefixlen(&netmask);
501 log_warning_link(link, "DHCP error: no prefixlen");
502 link_enter_failed(link);
506 r = sd_dhcp_client_get_router(client, &gateway);
508 log_warning_link(link, "DHCP error: no router");
509 link_enter_failed(link);
513 if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
514 _cleanup_address_free_ Address *addr = NULL;
515 _cleanup_route_free_ Route *rt = NULL;
516 struct in_addr *nameservers;
517 size_t nameservers_size;
519 log_struct_link(LOG_INFO, link,
520 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
522 ADDRESS_FMT_VAL(address),
524 ADDRESS_FMT_VAL(gateway),
525 "ADDRESS=%u.%u.%u.%u",
526 ADDRESS_FMT_VAL(address),
529 "GATEWAY=%u.%u.%u.%u",
530 ADDRESS_FMT_VAL(gateway),
533 r = address_new_dynamic(&addr);
535 log_error_link(link, "Could not allocate address");
536 link_enter_failed(link);
540 addr->family = AF_INET;
541 addr->in_addr.in = address;
542 addr->prefixlen = prefixlen;
543 addr->netmask = netmask;
545 r = route_new_dynamic(&rt);
547 log_error_link(link, "Could not allocate route");
548 link_enter_failed(link);
552 rt->family = AF_INET;
553 rt->in_addr.in = gateway;
555 link->dhcp_address = addr;
556 link->dhcp_route = rt;
560 if (link->network->dhcp_dns) {
561 r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
563 r = manager_update_resolv_conf(link->manager);
565 log_error("Failed to update resolv.conf");
569 if (link->network->dhcp_mtu) {
572 r = sd_dhcp_client_get_mtu(client, &mtu);
574 r = link_set_mtu(link, mtu);
576 log_error_link(link, "Failed to set MTU "
581 if (link->network->dhcp_hostname) {
582 const char *hostname;
584 r = sd_dhcp_client_get_hostname(client, &hostname);
586 r = set_hostname(link->manager->bus, hostname);
588 log_error("Failed to set transient hostname "
589 "to '%s'", hostname);
593 link_enter_set_addresses(link);
599 static int link_acquire_conf(Link *link) {
603 assert(link->network);
604 assert(link->network->dhcp);
605 assert(link->manager);
606 assert(link->manager->event);
609 r = sd_dhcp_client_new(&link->dhcp);
613 r = sd_dhcp_client_attach_event(link->dhcp, NULL, 0);
617 r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
621 r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
625 r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
629 if (link->network->dhcp_mtu) {
630 r = sd_dhcp_client_set_request_option(link->dhcp, 26);
636 log_debug_link(link, "acquiring DHCPv4 lease");
638 r = sd_dhcp_client_start(link->dhcp);
645 static int link_update_flags(Link *link, unsigned flags) {
649 assert(link->network);
651 if (link->state == LINK_STATE_FAILED)
654 if (link->flags == flags) {
655 log_debug_link(link, "link status unchanged: %#.8x", flags);
659 if ((link->flags & IFF_UP) != (flags & IFF_UP))
661 "link is %s", flags & IFF_UP ? "up": "down");
663 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
664 if (flags & IFF_LOWER_UP) {
665 log_info_link(link, "carrier on");
667 if (link->network->dhcp) {
668 r = link_acquire_conf(link);
670 log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
671 link_enter_failed(link);
676 log_info_link(link, "carrier off");
678 if (link->network->dhcp) {
679 r = sd_dhcp_client_stop(link->dhcp);
681 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
682 link_enter_failed(link);
690 "link status updated: %#.8x -> %#.8x", link->flags, flags);
697 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
698 Link *link = userdata;
703 if (link->state == LINK_STATE_FAILED)
706 r = sd_rtnl_message_get_errno(m);
708 log_struct_link(LOG_ERR, link,
709 "MESSAGE=%s: could not bring up interface: %s",
710 link->ifname, strerror(-r),
713 link_enter_failed(link);
717 link_update_flags(link, link->flags | IFF_UP);
722 static int link_up(Link *link) {
723 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
727 assert(link->manager);
728 assert(link->manager->rtnl);
730 log_debug_link(link, "bringing link up");
732 r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
734 log_error_link(link, "Could not allocate RTM_SETLINK message");
738 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
740 log_error_link(link, "Could not set link flags: %s", strerror(-r));
744 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
747 "Could not send rtnetlink message: %s", strerror(-r));
754 static int link_enslaved(Link *link) {
758 assert(link->state == LINK_STATE_ENSLAVING);
759 assert(link->network);
763 link_enter_failed(link);
767 if (!link->network->dhcp)
768 return link_enter_set_addresses(link);
773 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
774 Link *link = userdata;
778 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
779 assert(link->network);
783 if (link->state == LINK_STATE_FAILED)
786 r = sd_rtnl_message_get_errno(m);
788 log_struct_link(LOG_ERR, link,
789 "MESSAGE=%s: could not enslave: %s",
790 link->ifname, strerror(-r),
793 link_enter_failed(link);
797 log_debug_link(link, "enslaved");
799 if (link->enslaving == 0)
805 static int link_enter_enslave(Link *link) {
809 assert(link->network);
810 assert(link->state == _LINK_STATE_INVALID);
812 link->state = LINK_STATE_ENSLAVING;
814 if (!link->network->bridge && !link->network->bond && !link->network->vlan)
815 return link_enslaved(link);
817 if (link->network->bridge) {
818 log_struct_link(LOG_DEBUG, link,
819 "MESSAGE=%s: enslaving by '%s'",
820 link->ifname, link->network->bridge->name,
821 NETDEV(link->network->bridge),
824 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
826 log_struct_link(LOG_WARNING, link,
827 "MESSAGE=%s: could not enslave by '%s': %s",
828 link->ifname, link->network->bridge->name, strerror(-r),
829 NETDEV(link->network->bridge),
831 link_enter_failed(link);
838 if (link->network->vlan) {
839 log_struct_link(LOG_DEBUG, link,
840 "MESSAGE=%s: enslaving by '%s'",
841 link->ifname, link->network->vlan->name,
842 NETDEV(link->network->vlan),
845 r = netdev_enslave(link->network->vlan, link, &enslave_handler);
847 log_struct_link(LOG_WARNING, link,
848 "MESSAGE=%s: could not enslave by '%s': %s",
849 link->ifname, link->network->vlan->name,
850 strerror(-r), NETDEV(link->network->vlan),
852 link_enter_failed(link);
862 static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
863 Link *link = userdata;
868 if (link->state == LINK_STATE_FAILED)
871 r = sd_rtnl_message_get_errno(m);
873 log_struct_link(LOG_ERR, link,
874 "MESSAGE=%s: could not get state: %s",
875 link->ifname, strerror(-r),
878 link_enter_failed(link);
882 log_debug_link(link, "got link state");
884 link_update(link, m);
889 static int link_get(Link *link) {
890 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
894 assert(link->manager);
895 assert(link->manager->rtnl);
897 log_debug_link(link, "requesting link status");
899 r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
901 log_error_link(link, "Could not allocate RTM_GETLINK message");
905 r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
908 "Could not send rtnetlink message: %s", strerror(-r));
915 int link_configure(Link *link) {
919 assert(link->network);
920 assert(link->state == _LINK_STATE_INVALID);
924 link_enter_failed(link);
928 return link_enter_enslave(link);
931 int link_update(Link *link, sd_rtnl_message *m) {
940 if (link->state == LINK_STATE_FAILED)
943 r = sd_rtnl_message_link_get_flags(m, &flags);
945 log_warning_link(link, "Could not get link flags");
949 while (sd_rtnl_message_read(m, &type, &data) > 0) {
950 if (type == IFLA_MTU && link->network->dhcp &&
951 link->network->dhcp_mtu && !link->original_mtu) {
952 link->original_mtu = *(uint16_t *) data;
953 log_debug_link(link, "saved original MTU: %" PRIu16,
958 return link_update_flags(link, flags);