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_warning_link(link, "could not set route: %s", strerror(-r));
171 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
173 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
174 log_debug_link(link, "routes set");
175 link_enter_configured(link);
181 static int link_enter_set_routes(Link *link) {
186 assert(link->network);
187 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
189 link->state = LINK_STATE_SETTING_ROUTES;
191 if (!link->network->static_routes && !link->dhcp_route)
192 return link_enter_configured(link);
194 log_debug_link(link, "setting routes");
196 LIST_FOREACH(static_routes, route, link->network->static_routes) {
197 r = route_configure(route, link, &route_handler);
199 log_warning_link(link,
200 "could not set routes: %s", strerror(-r));
201 link_enter_failed(link);
205 link->route_messages ++;
208 if (link->dhcp_route) {
209 r = route_configure(link->dhcp_route, link, &route_handler);
211 log_warning_link(link,
212 "could not set routes: %s", strerror(-r));
213 link_enter_failed(link);
217 link->route_messages ++;
223 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
224 Link *link = userdata;
229 assert(link->ifname);
230 assert(link->addr_messages > 0);
231 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
233 link->addr_messages --;
235 if (link->state == LINK_STATE_FAILED)
238 r = sd_rtnl_message_get_errno(m);
239 if (r < 0 && r != -EEXIST)
240 log_struct_link(LOG_ERR, link,
241 "MESSAGE=%s: could not set address: %s",
242 link->ifname, strerror(-r),
246 if (link->addr_messages == 0) {
247 log_debug_link(link, "addresses set");
248 link_enter_set_routes(link);
254 static int link_enter_set_addresses(Link *link) {
259 assert(link->network);
260 assert(link->state != _LINK_STATE_INVALID);
262 link->state = LINK_STATE_SETTING_ADDRESSES;
264 if (!link->network->static_addresses && !link->dhcp_address)
265 return link_enter_set_routes(link);
267 log_debug_link(link, "setting addresses");
269 LIST_FOREACH(static_addresses, address, link->network->static_addresses) {
270 r = address_configure(address, link, &address_handler);
272 log_warning_link(link,
273 "could not set addresses: %s", strerror(-r));
274 link_enter_failed(link);
278 link->addr_messages ++;
281 if (link->dhcp_address) {
282 r = address_configure(link->dhcp_address, link, &address_handler);
284 log_warning_link(link,
285 "could not set addresses: %s", strerror(-r));
286 link_enter_failed(link);
290 link->addr_messages ++;
296 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
297 Link *link = userdata;
302 assert(link->ifname);
304 if (link->state == LINK_STATE_FAILED)
307 r = sd_rtnl_message_get_errno(m);
308 if (r < 0 && r != -EEXIST)
309 log_warning_link(link, "could not drop address: %s", strerror(-r));
314 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
317 r = sd_bus_message_get_errno(m);
319 log_warning("Could not set hostname: %s", strerror(-r));
324 static int set_hostname(sd_bus *bus, const char *hostname) {
325 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
330 log_debug("Setting transient hostname: '%s'", hostname);
332 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
333 log_info("Not connected to system bus, ignoring transient hostname.");
337 r = sd_bus_message_new_method_call(
339 "org.freedesktop.hostname1",
340 "/org/freedesktop/hostname1",
341 "org.freedesktop.hostname1",
347 r = sd_bus_message_append(m, "sb", hostname, false);
351 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
353 log_error("Could not set transient hostname: %s", strerror(-r));
358 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
359 Link *link = userdata;
364 assert(link->ifname);
366 if (link->state == LINK_STATE_FAILED)
369 r = sd_rtnl_message_get_errno(m);
370 if (r < 0 && r != -EEXIST)
371 log_warning_link(link, "Could not set MTU: %s", strerror(-r));
376 static int link_set_mtu(Link *link, uint32_t mtu) {
377 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
381 assert(link->manager);
382 assert(link->manager->rtnl);
384 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
386 r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
388 log_error_link(link, "Could not allocate RTM_SETLINK message");
392 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
394 log_error_link(link, "Could not append MTU: %s", strerror(-r));
398 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
401 "Could not send rtnetlink message: %s", strerror(-r));
408 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
409 Link *link = userdata;
410 struct in_addr address;
411 struct in_addr netmask;
412 struct in_addr gateway;
417 assert(link->network);
418 assert(link->manager);
420 if (link->state == LINK_STATE_FAILED)
424 log_warning_link(link, "DHCP error: %s", strerror(-event));
425 link_enter_failed(link);
429 if (event == DHCP_EVENT_NO_LEASE)
430 log_debug_link(link, "IP address in use.");
432 if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_EXPIRED ||
433 event == DHCP_EVENT_STOP) {
434 if (link->dhcp_address) {
435 address_drop(link->dhcp_address, link, address_drop_handler);
437 address_free(link->dhcp_address);
438 link->dhcp_address = NULL;
441 if (link->dhcp_route) {
442 route_free(link->dhcp_route);
443 link->dhcp_route = NULL;
446 if (link->network->dhcp_mtu) {
449 r = sd_dhcp_client_get_mtu(client, &mtu);
450 if (r >= 0 && link->original_mtu != mtu) {
451 r = link_set_mtu(link, link->original_mtu);
453 log_warning_link(link, "DHCP error: could not reset MTU");
454 link_enter_failed(link);
460 if (link->network->dhcp_hostname) {
461 r = set_hostname(link->manager->bus, "");
463 log_error("Failed to reset transient hostname");
467 r = sd_dhcp_client_get_address(client, &address);
469 log_warning_link(link, "DHCP error: no address");
470 link_enter_failed(link);
474 r = sd_dhcp_client_get_netmask(client, &netmask);
476 log_warning_link(link, "DHCP error: no netmask");
477 link_enter_failed(link);
481 prefixlen = sd_dhcp_client_prefixlen(&netmask);
483 log_warning_link(link, "DHCP error: no prefixlen");
484 link_enter_failed(link);
488 r = sd_dhcp_client_get_router(client, &gateway);
490 log_warning_link(link, "DHCP error: no router");
491 link_enter_failed(link);
495 if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
496 _cleanup_address_free_ Address *addr = NULL;
497 _cleanup_route_free_ Route *rt = NULL;
498 struct in_addr *nameservers;
499 size_t nameservers_size;
501 log_struct_link(LOG_INFO, link,
502 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
504 ADDRESS_FMT_VAL(address),
506 ADDRESS_FMT_VAL(gateway),
507 "ADDRESS=%u.%u.%u.%u",
508 ADDRESS_FMT_VAL(address),
511 "GATEWAY=%u.%u.%u.%u",
512 ADDRESS_FMT_VAL(gateway),
515 r = address_new_dynamic(&addr);
517 log_error_link(link, "Could not allocate address");
518 link_enter_failed(link);
522 addr->family = AF_INET;
523 addr->in_addr.in = address;
524 addr->prefixlen = prefixlen;
525 addr->netmask = netmask;
527 r = route_new_dynamic(&rt);
529 log_error_link(link, "Could not allocate route");
530 link_enter_failed(link);
534 rt->family = AF_INET;
535 rt->in_addr.in = gateway;
537 link->dhcp_address = addr;
538 link->dhcp_route = rt;
542 if (link->network->dhcp_dns) {
543 r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
545 r = manager_update_resolv_conf(link->manager);
547 log_error("Failed to update resolv.conf");
551 if (link->network->dhcp_mtu) {
554 r = sd_dhcp_client_get_mtu(client, &mtu);
556 r = link_set_mtu(link, mtu);
558 log_error_link(link, "Failed to set MTU "
563 if (link->network->dhcp_hostname) {
564 const char *hostname;
566 r = sd_dhcp_client_get_hostname(client, &hostname);
568 r = set_hostname(link->manager->bus, hostname);
570 log_error("Failed to set transient hostname "
571 "to '%s'", hostname);
575 link_enter_set_addresses(link);
581 static int link_acquire_conf(Link *link) {
585 assert(link->network);
586 assert(link->network->dhcp);
587 assert(link->manager);
588 assert(link->manager->event);
591 r = sd_dhcp_client_new(&link->dhcp);
595 r = sd_dhcp_client_attach_event(link->dhcp, NULL, 0);
599 r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
603 r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
607 r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
611 if (link->network->dhcp_mtu) {
612 r = sd_dhcp_client_set_request_option(link->dhcp, 26);
618 log_debug_link(link, "acquiring DHCPv4 lease");
620 r = sd_dhcp_client_start(link->dhcp);
627 static int link_update_flags(Link *link, unsigned flags) {
631 assert(link->network);
633 if (link->state == LINK_STATE_FAILED)
636 if (link->flags == flags) {
637 log_debug_link(link, "link status unchanged: %#.8x", flags);
641 if ((link->flags & IFF_UP) != (flags & IFF_UP))
643 "link is %s", flags & IFF_UP ? "up": "down");
645 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
646 if (flags & IFF_LOWER_UP) {
647 log_info_link(link, "carrier on");
649 if (link->network->dhcp) {
650 r = link_acquire_conf(link);
652 log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
653 link_enter_failed(link);
658 log_info_link(link, "carrier off");
660 if (link->network->dhcp) {
661 r = sd_dhcp_client_stop(link->dhcp);
663 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
664 link_enter_failed(link);
672 "link status updated: %#.8x -> %#.8x", link->flags, flags);
679 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
680 Link *link = userdata;
685 if (link->state == LINK_STATE_FAILED)
688 r = sd_rtnl_message_get_errno(m);
690 log_warning_link(link,
691 "could not bring up interface: %s", strerror(-r));
692 link_enter_failed(link);
695 link_update_flags(link, link->flags | IFF_UP);
700 static int link_up(Link *link) {
701 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
705 assert(link->manager);
706 assert(link->manager->rtnl);
708 log_debug_link(link, "bringing link up");
710 r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
712 log_error_link(link, "Could not allocate RTM_SETLINK message");
716 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
718 log_error_link(link, "Could not set link flags: %s", strerror(-r));
722 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
725 "Could not send rtnetlink message: %s", strerror(-r));
732 static int link_enslaved(Link *link) {
736 assert(link->state == LINK_STATE_ENSLAVING);
737 assert(link->network);
741 link_enter_failed(link);
745 if (!link->network->dhcp)
746 return link_enter_set_addresses(link);
751 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
752 Link *link = userdata;
756 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
757 assert(link->network);
761 if (link->state == LINK_STATE_FAILED)
764 r = sd_rtnl_message_get_errno(m);
766 log_error_link(link, "could not enslave: %s",
768 link_enter_failed(link);
772 log_debug_link(link, "enslaved");
774 if (link->enslaving == 0)
780 static int link_enter_enslave(Link *link) {
784 assert(link->network);
785 assert(link->state == _LINK_STATE_INVALID);
787 link->state = LINK_STATE_ENSLAVING;
789 if (!link->network->bridge && !link->network->bond && !link->network->vlan)
790 return link_enslaved(link);
792 if (link->network->bridge) {
793 log_struct_link(LOG_DEBUG, link,
794 "MESSAGE=%s: enslaving by '%s'",
795 link->network->bridge->name,
796 NETDEV(link->network->bridge),
799 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
801 log_struct_link(LOG_WARNING, link,
802 "MESSAGE=%s: could not enslave by '%s': %s",
803 link->network->bridge->name, strerror(-r),
804 NETDEV(link->network->bridge),
806 link_enter_failed(link);
813 if (link->network->vlan) {
814 log_struct_link(LOG_DEBUG, link,
815 "MESSAGE=%s: enslaving by '%s'",
816 link->network->vlan->name,
817 NETDEV(link->network->vlan),
820 r = netdev_enslave(link->network->vlan, link, &enslave_handler);
822 log_struct_link(LOG_WARNING, link,
823 "MESSAGE=%s: could not enslave by '%s': %s",
824 link->network->vlan->name, strerror(-r),
825 NETDEV(link->network->vlan),
827 link_enter_failed(link);
837 static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
838 Link *link = userdata;
843 if (link->state == LINK_STATE_FAILED)
846 r = sd_rtnl_message_get_errno(m);
848 log_warning_link(link, "could not get state: %s", strerror(-r));
849 link_enter_failed(link);
852 log_debug_link(link, "got link state");
854 link_update(link, m);
859 static int link_get(Link *link) {
860 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
864 assert(link->manager);
865 assert(link->manager->rtnl);
867 log_debug_link(link, "requesting link status");
869 r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
871 log_error_link(link, "Could not allocate RTM_GETLINK message");
875 r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
878 "Could not send rtnetlink message: %s", strerror(-r));
885 int link_configure(Link *link) {
889 assert(link->network);
890 assert(link->state == _LINK_STATE_INVALID);
894 link_enter_failed(link);
898 return link_enter_enslave(link);
901 int link_update(Link *link, sd_rtnl_message *m) {
910 if (link->state == LINK_STATE_FAILED)
913 r = sd_rtnl_message_link_get_flags(m, &flags);
915 log_warning_link(link, "Could not get link flags");
919 while (sd_rtnl_message_read(m, &type, &data) > 0) {
920 if (type == IFLA_MTU && link->network->dhcp &&
921 link->network->dhcp_mtu && !link->original_mtu) {
922 link->original_mtu = *(uint16_t *) data;
923 log_debug_link(link, "saved original MTU: %" PRIu16,
928 return link_update_flags(link, flags);