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"
31 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
32 _cleanup_link_free_ Link *link = NULL;
34 struct ether_addr *mac_addr;
45 link->manager = manager;
46 link->state = _LINK_STATE_INVALID;
48 link->ifindex = udev_device_get_ifindex(device);
49 if (link->ifindex <= 0)
52 mac = udev_device_get_sysattr_value(device, "address");
54 mac_addr = ether_aton(mac);
56 memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
59 ifname = udev_device_get_sysname(device);
60 link->ifname = strdup(ifname);
62 r = hashmap_put(manager->links, &link->ifindex, link);
72 void link_free(Link *link) {
76 assert(link->manager);
79 sd_dhcp_client_free(link->dhcp);
81 route_free(link->dhcp_route);
82 link->dhcp_route = NULL;
84 address_free(link->dhcp_address);
85 link->dhcp_address = NULL;
87 hashmap_remove(link->manager->links, &link->ifindex);
94 int link_add(Manager *m, struct udev_device *device, Link **ret) {
104 ifindex = udev_device_get_ifindex(device);
105 link = hashmap_get(m->links, &ifindex);
111 r = link_new(m, device, &link);
117 kind = netdev_kind_from_string(udev_device_get_devtype(device));
118 if (kind != _NETDEV_KIND_INVALID) {
119 r = netdev_set_link(m, kind, link);
120 if (r < 0 && r != -ENOENT)
124 r = network_get(m, device, &network);
126 return r == -ENOENT ? 0 : r;
128 r = network_apply(m, network, link);
135 static int link_enter_configured(Link *link) {
137 assert(link->state == LINK_STATE_SETTING_ROUTES);
139 log_info_link(link, "link configured");
141 link->state = LINK_STATE_CONFIGURED;
146 static void link_enter_failed(Link *link) {
149 log_warning_link(link, "failed");
151 link->state = LINK_STATE_FAILED;
154 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
155 Link *link = userdata;
158 assert(link->route_messages > 0);
159 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
160 link->state == LINK_STATE_SETTING_ROUTES ||
161 link->state == LINK_STATE_FAILED);
163 link->route_messages --;
165 if (link->state == LINK_STATE_FAILED)
168 r = sd_rtnl_message_get_errno(m);
169 if (r < 0 && r != -EEXIST)
170 log_struct_link(LOG_WARNING, link,
171 "MESSAGE=%s: could not set route: %s",
172 link->ifname, strerror(-r),
176 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
178 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
179 log_debug_link(link, "routes set");
180 link_enter_configured(link);
186 static int link_enter_set_routes(Link *link) {
191 assert(link->network);
192 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
194 link->state = LINK_STATE_SETTING_ROUTES;
196 if (!link->network->static_routes && !link->dhcp_route)
197 return link_enter_configured(link);
199 log_debug_link(link, "setting routes");
201 LIST_FOREACH(static_routes, route, link->network->static_routes) {
202 r = route_configure(route, link, &route_handler);
204 log_warning_link(link,
205 "could not set routes: %s", strerror(-r));
206 link_enter_failed(link);
210 link->route_messages ++;
213 if (link->dhcp_route) {
214 r = route_configure(link->dhcp_route, link, &route_handler);
216 log_warning_link(link,
217 "could not set routes: %s", strerror(-r));
218 link_enter_failed(link);
222 link->route_messages ++;
228 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
229 Link *link = userdata;
234 assert(link->ifname);
235 assert(link->addr_messages > 0);
236 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
238 link->addr_messages --;
240 if (link->state == LINK_STATE_FAILED)
243 r = sd_rtnl_message_get_errno(m);
244 if (r < 0 && r != -EEXIST)
245 log_struct_link(LOG_WARNING, link,
246 "MESSAGE=%s: could not set address: %s",
247 link->ifname, strerror(-r),
251 if (link->addr_messages == 0) {
252 log_debug_link(link, "addresses set");
253 link_enter_set_routes(link);
259 static int link_enter_set_addresses(Link *link) {
264 assert(link->network);
265 assert(link->state != _LINK_STATE_INVALID);
267 link->state = LINK_STATE_SETTING_ADDRESSES;
269 if (!link->network->static_addresses && !link->dhcp_address)
270 return link_enter_set_routes(link);
272 log_debug_link(link, "setting addresses");
274 LIST_FOREACH(static_addresses, address, link->network->static_addresses) {
275 r = address_configure(address, link, &address_handler);
277 log_warning_link(link,
278 "could not set addresses: %s", strerror(-r));
279 link_enter_failed(link);
283 link->addr_messages ++;
286 if (link->dhcp_address) {
287 r = address_configure(link->dhcp_address, link, &address_handler);
289 log_warning_link(link,
290 "could not set addresses: %s", strerror(-r));
291 link_enter_failed(link);
295 link->addr_messages ++;
301 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
302 Link *link = userdata;
307 assert(link->ifname);
309 if (link->state == LINK_STATE_FAILED)
312 r = sd_rtnl_message_get_errno(m);
313 if (r < 0 && r != -ENOENT)
314 log_struct_link(LOG_WARNING, link,
315 "MESSAGE=%s: could not drop address: %s",
316 link->ifname, strerror(-r),
323 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
326 r = sd_bus_message_get_errno(m);
328 log_warning("Could not set hostname: %s", strerror(-r));
333 static int set_hostname(sd_bus *bus, const char *hostname) {
334 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
339 log_debug("Setting transient hostname: '%s'", hostname);
341 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
342 log_info("Not connected to system bus, ignoring transient hostname.");
346 r = sd_bus_message_new_method_call(
348 "org.freedesktop.hostname1",
349 "/org/freedesktop/hostname1",
350 "org.freedesktop.hostname1",
356 r = sd_bus_message_append(m, "sb", hostname, false);
360 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
362 log_error("Could not set transient hostname: %s", strerror(-r));
367 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
368 Link *link = userdata;
373 assert(link->ifname);
375 if (link->state == LINK_STATE_FAILED)
378 r = sd_rtnl_message_get_errno(m);
380 log_struct_link(LOG_WARNING, link,
381 "MESSAGE=%s: could not set MTU: %s",
382 link->ifname, strerror(-r),
389 static int link_set_mtu(Link *link, uint32_t mtu) {
390 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
394 assert(link->manager);
395 assert(link->manager->rtnl);
397 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
399 r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
401 log_error_link(link, "Could not allocate RTM_SETLINK message");
405 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
407 log_error_link(link, "Could not append MTU: %s", strerror(-r));
411 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
414 "Could not send rtnetlink message: %s", strerror(-r));
421 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
422 Link *link = userdata;
423 struct in_addr address;
424 struct in_addr netmask;
425 struct in_addr gateway;
430 assert(link->network);
431 assert(link->manager);
433 if (link->state == LINK_STATE_FAILED)
437 log_warning_link(link, "DHCP error: %s", strerror(-event));
438 link_enter_failed(link);
442 if (event == DHCP_EVENT_NO_LEASE)
443 log_debug_link(link, "IP address in use.");
445 if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_EXPIRED ||
446 event == DHCP_EVENT_STOP) {
447 if (link->network->dhcp_critical) {
448 log_warning_link(link, "DHCPv4 connection considered system critical, "
449 "ignoring request to reconfigure it down.");
453 if (link->dhcp_address) {
454 address_drop(link->dhcp_address, link, address_drop_handler);
456 address_free(link->dhcp_address);
457 link->dhcp_address = NULL;
460 if (link->dhcp_route) {
461 route_free(link->dhcp_route);
462 link->dhcp_route = NULL;
465 if (link->network->dhcp_mtu) {
468 r = sd_dhcp_client_get_mtu(client, &mtu);
469 if (r >= 0 && link->original_mtu != mtu) {
470 r = link_set_mtu(link, link->original_mtu);
472 log_warning_link(link, "DHCP error: could not reset MTU");
473 link_enter_failed(link);
479 if (link->network->dhcp_hostname) {
480 r = set_hostname(link->manager->bus, "");
482 log_error("Failed to reset transient hostname");
486 r = sd_dhcp_client_get_address(client, &address);
488 log_warning_link(link, "DHCP error: no address");
489 link_enter_failed(link);
493 r = sd_dhcp_client_get_netmask(client, &netmask);
495 log_warning_link(link, "DHCP error: no netmask");
496 link_enter_failed(link);
500 prefixlen = net_netmask_to_prefixlen(&netmask);
502 r = sd_dhcp_client_get_router(client, &gateway);
504 log_warning_link(link, "DHCP error: no router");
505 link_enter_failed(link);
509 if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
510 _cleanup_address_free_ Address *addr = NULL;
511 _cleanup_route_free_ Route *rt = NULL;
512 struct in_addr *nameservers;
513 size_t nameservers_size;
515 log_struct_link(LOG_INFO, link,
516 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
518 ADDRESS_FMT_VAL(address),
520 ADDRESS_FMT_VAL(gateway),
521 "ADDRESS=%u.%u.%u.%u",
522 ADDRESS_FMT_VAL(address),
525 "GATEWAY=%u.%u.%u.%u",
526 ADDRESS_FMT_VAL(gateway),
529 r = address_new_dynamic(&addr);
531 log_error_link(link, "Could not allocate address");
532 link_enter_failed(link);
536 addr->family = AF_INET;
537 addr->in_addr.in = address;
538 addr->prefixlen = prefixlen;
539 addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
541 r = route_new_dynamic(&rt);
543 log_error_link(link, "Could not allocate route");
544 link_enter_failed(link);
548 rt->family = AF_INET;
549 rt->in_addr.in = gateway;
551 link->dhcp_address = addr;
552 link->dhcp_route = rt;
556 if (link->network->dhcp_dns) {
557 r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
559 r = manager_update_resolv_conf(link->manager);
561 log_error("Failed to update resolv.conf");
565 if (link->network->dhcp_mtu) {
568 r = sd_dhcp_client_get_mtu(client, &mtu);
570 r = link_set_mtu(link, mtu);
572 log_error_link(link, "Failed to set MTU "
577 if (link->network->dhcp_hostname) {
578 const char *hostname;
580 r = sd_dhcp_client_get_hostname(client, &hostname);
582 r = set_hostname(link->manager->bus, hostname);
584 log_error("Failed to set transient hostname "
585 "to '%s'", hostname);
589 link_enter_set_addresses(link);
595 static int link_acquire_conf(Link *link) {
599 assert(link->network);
600 assert(link->network->dhcp);
601 assert(link->manager);
602 assert(link->manager->event);
605 r = sd_dhcp_client_new(&link->dhcp);
609 r = sd_dhcp_client_attach_event(link->dhcp, NULL, 0);
613 r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
617 r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
621 r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
625 if (link->network->dhcp_mtu) {
626 r = sd_dhcp_client_set_request_option(link->dhcp, 26);
632 log_debug_link(link, "acquiring DHCPv4 lease");
634 r = sd_dhcp_client_start(link->dhcp);
641 static int link_update_flags(Link *link, unsigned flags) {
645 assert(link->network);
647 if (link->state == LINK_STATE_FAILED)
650 if (link->flags == flags) {
651 log_debug_link(link, "link status unchanged: %#.8x", flags);
655 if ((link->flags & IFF_UP) != (flags & IFF_UP))
657 "link is %s", flags & IFF_UP ? "up": "down");
659 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
660 if (flags & IFF_LOWER_UP) {
661 log_info_link(link, "carrier on");
663 if (link->network->dhcp) {
664 r = link_acquire_conf(link);
666 log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
667 link_enter_failed(link);
672 log_info_link(link, "carrier off");
674 if (link->network->dhcp) {
675 r = sd_dhcp_client_stop(link->dhcp);
677 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
678 link_enter_failed(link);
686 "link status updated: %#.8x -> %#.8x", link->flags, flags);
693 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
694 Link *link = userdata;
699 if (link->state == LINK_STATE_FAILED)
702 r = sd_rtnl_message_get_errno(m);
704 log_struct_link(LOG_ERR, link,
705 "MESSAGE=%s: could not bring up interface: %s",
706 link->ifname, strerror(-r),
709 link_enter_failed(link);
713 link_update_flags(link, link->flags | IFF_UP);
718 static int link_up(Link *link) {
719 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
723 assert(link->manager);
724 assert(link->manager->rtnl);
726 log_debug_link(link, "bringing link up");
728 r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
730 log_error_link(link, "Could not allocate RTM_SETLINK message");
734 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
736 log_error_link(link, "Could not set link flags: %s", strerror(-r));
740 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
743 "Could not send rtnetlink message: %s", strerror(-r));
750 static int link_enslaved(Link *link) {
754 assert(link->state == LINK_STATE_ENSLAVING);
755 assert(link->network);
759 link_enter_failed(link);
763 if (!link->network->dhcp)
764 return link_enter_set_addresses(link);
769 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
770 Link *link = userdata;
774 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
775 assert(link->network);
779 if (link->state == LINK_STATE_FAILED)
782 r = sd_rtnl_message_get_errno(m);
784 log_struct_link(LOG_ERR, link,
785 "MESSAGE=%s: could not enslave: %s",
786 link->ifname, strerror(-r),
789 link_enter_failed(link);
793 log_debug_link(link, "enslaved");
795 if (link->enslaving == 0)
801 static int link_enter_enslave(Link *link) {
805 assert(link->network);
806 assert(link->state == _LINK_STATE_INVALID);
808 link->state = LINK_STATE_ENSLAVING;
810 if (!link->network->bridge && !link->network->bond && !link->network->vlan)
811 return link_enslaved(link);
813 if (link->network->bridge) {
814 log_struct_link(LOG_DEBUG, link,
815 "MESSAGE=%s: enslaving by '%s'",
816 link->ifname, link->network->bridge->name,
817 NETDEV(link->network->bridge),
820 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
822 log_struct_link(LOG_WARNING, link,
823 "MESSAGE=%s: could not enslave by '%s': %s",
824 link->ifname, link->network->bridge->name, strerror(-r),
825 NETDEV(link->network->bridge),
827 link_enter_failed(link);
834 if (link->network->vlan) {
835 log_struct_link(LOG_DEBUG, link,
836 "MESSAGE=%s: enslaving by '%s'",
837 link->ifname, link->network->vlan->name,
838 NETDEV(link->network->vlan),
841 r = netdev_enslave(link->network->vlan, link, &enslave_handler);
843 log_struct_link(LOG_WARNING, link,
844 "MESSAGE=%s: could not enslave by '%s': %s",
845 link->ifname, link->network->vlan->name,
846 strerror(-r), NETDEV(link->network->vlan),
848 link_enter_failed(link);
858 static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
859 Link *link = userdata;
864 if (link->state == LINK_STATE_FAILED)
867 r = sd_rtnl_message_get_errno(m);
869 log_struct_link(LOG_ERR, link,
870 "MESSAGE=%s: could not get state: %s",
871 link->ifname, strerror(-r),
874 link_enter_failed(link);
878 log_debug_link(link, "got link state");
880 link_update(link, m);
885 static int link_get(Link *link) {
886 _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
890 assert(link->manager);
891 assert(link->manager->rtnl);
893 log_debug_link(link, "requesting link status");
895 r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
897 log_error_link(link, "Could not allocate RTM_GETLINK message");
901 r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
904 "Could not send rtnetlink message: %s", strerror(-r));
911 int link_configure(Link *link) {
915 assert(link->network);
916 assert(link->state == _LINK_STATE_INVALID);
920 link_enter_failed(link);
924 return link_enter_enslave(link);
927 int link_update(Link *link, sd_rtnl_message *m) {
936 if (link->state == LINK_STATE_FAILED)
939 r = sd_rtnl_message_link_get_flags(m, &flags);
941 log_warning_link(link, "Could not get link flags");
945 while (sd_rtnl_message_read(m, &type, &data) > 0) {
946 if (type == IFLA_MTU && link->network->dhcp &&
947 link->network->dhcp_mtu && !link->original_mtu) {
948 link->original_mtu = *(uint16_t *) data;
949 log_debug_link(link, "saved original MTU: %" PRIu16,
954 return link_update_flags(link, flags);