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"
29 #include "network-internal.h"
31 #include "dhcp-lease-internal.h"
33 static int ipv4ll_address_update(Link
*link
, bool deprecate
);
34 static bool ipv4ll_is_bound(sd_ipv4ll
*ll
);
36 int link_new(Manager
*manager
, struct udev_device
*device
, Link
**ret
) {
37 _cleanup_link_free_ Link
*link
= NULL
;
42 assert(manager
->links
);
50 link
->manager
= manager
;
51 link
->state
= _LINK_STATE_INVALID
;
53 link
->ifindex
= udev_device_get_ifindex(device
);
54 if (link
->ifindex
<= 0)
57 r
= asprintf(&link
->state_file
, "/run/systemd/network/links/%"PRIu64
,
62 ifname
= udev_device_get_sysname(device
);
63 link
->ifname
= strdup(ifname
);
65 r
= hashmap_put(manager
->links
, &link
->ifindex
, link
);
69 link
->udev_device
= udev_device_ref(device
);
77 void link_free(Link
*link
) {
81 assert(link
->manager
);
83 sd_dhcp_client_unref(link
->dhcp_client
);
84 sd_dhcp_lease_unref(link
->dhcp_lease
);
86 sd_ipv4ll_free(link
->ipv4ll
);
88 hashmap_remove(link
->manager
->links
, &link
->ifindex
);
91 free(link
->state_file
);
93 udev_device_unref(link
->udev_device
);
98 int link_get(Manager
*m
, int ifindex
, Link
**ret
) {
107 ifindex_64
= ifindex
;
108 link
= hashmap_get(m
->links
, &ifindex_64
);
117 static int link_enter_configured(Link
*link
) {
119 assert(link
->state
== LINK_STATE_SETTING_ROUTES
);
121 log_info_link(link
, "link configured");
123 link
->state
= LINK_STATE_CONFIGURED
;
130 static void link_enter_failed(Link
*link
) {
133 log_warning_link(link
, "failed");
135 link
->state
= LINK_STATE_FAILED
;
140 static int route_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
141 Link
*link
= userdata
;
144 assert(link
->route_messages
> 0);
145 assert(link
->state
== LINK_STATE_SETTING_ADDRESSES
||
146 link
->state
== LINK_STATE_SETTING_ROUTES
||
147 link
->state
== LINK_STATE_FAILED
);
149 link
->route_messages
--;
151 if (link
->state
== LINK_STATE_FAILED
)
154 r
= sd_rtnl_message_get_errno(m
);
155 if (r
< 0 && r
!= -EEXIST
)
156 log_struct_link(LOG_WARNING
, link
,
157 "MESSAGE=%s: could not set route: %s",
158 link
->ifname
, strerror(-r
),
162 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
164 if (link
->route_messages
== 0 && link
->state
== LINK_STATE_SETTING_ROUTES
) {
165 log_debug_link(link
, "routes set");
166 link_enter_configured(link
);
172 static int link_enter_set_routes(Link
*link
) {
177 assert(link
->network
);
178 assert(link
->state
== LINK_STATE_SETTING_ADDRESSES
);
180 link
->state
= LINK_STATE_SETTING_ROUTES
;
182 if (!link
->network
->static_routes
&& !link
->dhcp_lease
&&
183 (!link
->ipv4ll
|| ipv4ll_is_bound(link
->ipv4ll
) == false))
184 return link_enter_configured(link
);
186 log_debug_link(link
, "setting routes");
188 LIST_FOREACH(static_routes
, rt
, link
->network
->static_routes
) {
189 r
= route_configure(rt
, link
, &route_handler
);
191 log_warning_link(link
,
192 "could not set routes: %s", strerror(-r
));
193 link_enter_failed(link
);
197 link
->route_messages
++;
200 if (link
->ipv4ll
&& !link
->dhcp_lease
) {
201 _cleanup_route_free_ Route
*route
= NULL
;
204 r
= sd_ipv4ll_get_address(link
->ipv4ll
, &addr
);
205 if (r
< 0 && r
!= -ENOENT
) {
206 log_warning_link(link
, "IPV4LL error: no address: %s",
212 r
= route_new_dynamic(&route
);
214 log_error_link(link
, "Could not allocate route: %s",
219 route
->family
= AF_INET
;
220 route
->scope
= RT_SCOPE_LINK
;
223 r
= route_configure(route
, link
, &route_handler
);
225 log_warning_link(link
,
226 "could not set routes: %s", strerror(-r
));
227 link_enter_failed(link
);
231 link
->route_messages
++;
235 if (link
->dhcp_lease
) {
236 _cleanup_route_free_ Route
*route
= NULL
;
237 _cleanup_route_free_ Route
*route_gw
= NULL
;
238 struct in_addr gateway
;
240 r
= sd_dhcp_lease_get_router(link
->dhcp_lease
, &gateway
);
242 log_warning_link(link
, "DHCP error: no router: %s",
247 r
= route_new_dynamic(&route
);
249 log_error_link(link
, "Could not allocate route: %s",
254 r
= route_new_dynamic(&route_gw
);
256 log_error_link(link
, "Could not allocate route: %s",
261 /* The dhcp netmask may mask out the gateway. Add an explicit
262 * route for the gw host so that we can route no matter the
263 * netmask or existing kernel route tables. */
264 route_gw
->family
= AF_INET
;
265 route_gw
->dst_addr
.in
= gateway
;
266 route_gw
->dst_prefixlen
= 32;
267 route_gw
->scope
= RT_SCOPE_LINK
;
269 r
= route_configure(route_gw
, link
, &route_handler
);
271 log_warning_link(link
,
272 "could not set host route: %s", strerror(-r
));
276 link
->route_messages
++;
278 route
->family
= AF_INET
;
279 route
->in_addr
.in
= gateway
;
281 r
= route_configure(route
, link
, &route_handler
);
283 log_warning_link(link
,
284 "could not set routes: %s", strerror(-r
));
285 link_enter_failed(link
);
289 link
->route_messages
++;
295 static int route_drop_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
296 Link
*link
= userdata
;
301 assert(link
->ifname
);
303 if (link
->state
== LINK_STATE_FAILED
)
306 r
= sd_rtnl_message_get_errno(m
);
307 if (r
< 0 && r
!= -ENOENT
)
308 log_struct_link(LOG_WARNING
, link
,
309 "MESSAGE=%s: could not drop route: %s",
310 link
->ifname
, strerror(-r
),
317 static int address_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
318 Link
*link
= userdata
;
323 assert(link
->ifname
);
324 assert(link
->addr_messages
> 0);
325 assert(link
->state
== LINK_STATE_SETTING_ADDRESSES
|| link
->state
== LINK_STATE_FAILED
);
327 link
->addr_messages
--;
329 if (link
->state
== LINK_STATE_FAILED
)
332 r
= sd_rtnl_message_get_errno(m
);
333 if (r
< 0 && r
!= -EEXIST
)
334 log_struct_link(LOG_WARNING
, link
,
335 "MESSAGE=%s: could not set address: %s",
336 link
->ifname
, strerror(-r
),
340 if (link
->addr_messages
== 0) {
341 log_debug_link(link
, "addresses set");
342 link_enter_set_routes(link
);
348 static int link_enter_set_addresses(Link
*link
) {
353 assert(link
->network
);
354 assert(link
->state
!= _LINK_STATE_INVALID
);
356 link
->state
= LINK_STATE_SETTING_ADDRESSES
;
358 if (!link
->network
->static_addresses
&& !link
->dhcp_lease
&&
359 (!link
->ipv4ll
|| ipv4ll_is_bound(link
->ipv4ll
) == false))
360 return link_enter_set_routes(link
);
362 log_debug_link(link
, "setting addresses");
364 LIST_FOREACH(static_addresses
, ad
, link
->network
->static_addresses
) {
365 r
= address_configure(ad
, link
, &address_handler
);
367 log_warning_link(link
,
368 "could not set addresses: %s", strerror(-r
));
369 link_enter_failed(link
);
373 link
->addr_messages
++;
376 if (link
->ipv4ll
&& !link
->dhcp_lease
) {
377 _cleanup_address_free_ Address
*ll_addr
= NULL
;
380 r
= sd_ipv4ll_get_address(link
->ipv4ll
, &addr
);
381 if (r
< 0 && r
!= -ENOENT
) {
382 log_warning_link(link
, "IPV4LL error: no address: %s",
388 r
= address_new_dynamic(&ll_addr
);
390 log_error_link(link
, "Could not allocate address: %s", strerror(-r
));
394 ll_addr
->family
= AF_INET
;
395 ll_addr
->in_addr
.in
= addr
;
396 ll_addr
->prefixlen
= 16;
397 ll_addr
->broadcast
.s_addr
= ll_addr
->in_addr
.in
.s_addr
| htonl(0xfffffffflu
>> ll_addr
->prefixlen
);
398 ll_addr
->scope
= RT_SCOPE_LINK
;
400 r
= address_configure(ll_addr
, link
, &address_handler
);
402 log_warning_link(link
,
403 "could not set addresses: %s", strerror(-r
));
404 link_enter_failed(link
);
408 link
->addr_messages
++;
412 if (link
->dhcp_lease
) {
413 _cleanup_address_free_ Address
*address
= NULL
;
415 struct in_addr netmask
;
418 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &addr
);
420 log_warning_link(link
, "DHCP error: no address: %s",
425 r
= sd_dhcp_lease_get_netmask(link
->dhcp_lease
, &netmask
);
427 log_warning_link(link
, "DHCP error: no netmask: %s",
432 prefixlen
= net_netmask_to_prefixlen(&netmask
);
434 r
= address_new_dynamic(&address
);
436 log_error_link(link
, "Could not allocate address: %s",
441 address
->family
= AF_INET
;
442 address
->in_addr
.in
= addr
;
443 address
->prefixlen
= prefixlen
;
444 address
->broadcast
.s_addr
= addr
.s_addr
| ~netmask
.s_addr
;
446 r
= address_configure(address
, link
, &address_handler
);
448 log_warning_link(link
,
449 "could not set addresses: %s", strerror(-r
));
450 link_enter_failed(link
);
454 link
->addr_messages
++;
460 static int address_update_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
461 Link
*link
= userdata
;
466 assert(link
->ifname
);
468 if (link
->state
== LINK_STATE_FAILED
)
471 r
= sd_rtnl_message_get_errno(m
);
472 if (r
< 0 && r
!= -ENOENT
)
473 log_struct_link(LOG_WARNING
, link
,
474 "MESSAGE=%s: could not update address: %s",
475 link
->ifname
, strerror(-r
),
482 static int address_drop_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
483 Link
*link
= userdata
;
488 assert(link
->ifname
);
490 if (link
->state
== LINK_STATE_FAILED
)
493 r
= sd_rtnl_message_get_errno(m
);
494 if (r
< 0 && r
!= -ENOENT
)
495 log_struct_link(LOG_WARNING
, link
,
496 "MESSAGE=%s: could not drop address: %s",
497 link
->ifname
, strerror(-r
),
504 static int set_hostname_handler(sd_bus
*bus
, sd_bus_message
*m
, void *userdata
, sd_bus_error
*ret_error
) {
507 r
= sd_bus_message_get_errno(m
);
509 log_warning("Could not set hostname: %s", strerror(-r
));
514 static int set_hostname(sd_bus
*bus
, const char *hostname
) {
515 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
520 log_debug("Setting transient hostname: '%s'", hostname
);
522 if (!bus
) { /* TODO: replace by assert when we can rely on kdbus */
523 log_info("Not connected to system bus, ignoring transient hostname.");
527 r
= sd_bus_message_new_method_call(
530 "org.freedesktop.hostname1",
531 "/org/freedesktop/hostname1",
532 "org.freedesktop.hostname1",
537 r
= sd_bus_message_append(m
, "sb", hostname
, false);
541 r
= sd_bus_call_async(bus
, m
, set_hostname_handler
, NULL
, 0, NULL
);
543 log_error("Could not set transient hostname: %s", strerror(-r
));
548 static int set_mtu_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
549 Link
*link
= userdata
;
554 assert(link
->ifname
);
556 if (link
->state
== LINK_STATE_FAILED
)
559 r
= sd_rtnl_message_get_errno(m
);
561 log_struct_link(LOG_WARNING
, link
,
562 "MESSAGE=%s: could not set MTU: %s",
563 link
->ifname
, strerror(-r
),
570 static int link_set_mtu(Link
*link
, uint32_t mtu
) {
571 _cleanup_rtnl_message_unref_ sd_rtnl_message
*req
= NULL
;
575 assert(link
->manager
);
576 assert(link
->manager
->rtnl
);
578 log_debug_link(link
, "setting MTU: %" PRIu32
, mtu
);
580 r
= sd_rtnl_message_new_link(link
->manager
->rtnl
, &req
,
581 RTM_SETLINK
, link
->ifindex
);
583 log_error_link(link
, "Could not allocate RTM_SETLINK message");
587 r
= sd_rtnl_message_append_u32(req
, IFLA_MTU
, mtu
);
589 log_error_link(link
, "Could not append MTU: %s", strerror(-r
));
593 r
= sd_rtnl_call_async(link
->manager
->rtnl
, req
, set_mtu_handler
, link
, 0, NULL
);
596 "Could not send rtnetlink message: %s", strerror(-r
));
603 static int dhcp_lease_lost(Link
*link
) {
604 _cleanup_address_free_ Address
*address
= NULL
;
605 _cleanup_route_free_ Route
*route_gw
= NULL
;
606 _cleanup_route_free_ Route
*route
= NULL
;
608 struct in_addr netmask
;
609 struct in_addr gateway
;
614 assert(link
->dhcp_lease
);
616 log_warning_link(link
, "DHCP lease lost");
618 r
= address_new_dynamic(&address
);
620 sd_dhcp_lease_get_address(link
->dhcp_lease
, &addr
);
621 sd_dhcp_lease_get_netmask(link
->dhcp_lease
, &netmask
);
622 sd_dhcp_lease_get_router(link
->dhcp_lease
, &gateway
);
623 prefixlen
= net_netmask_to_prefixlen(&netmask
);
625 r
= route_new_dynamic(&route_gw
);
627 route_gw
->family
= AF_INET
;
628 route_gw
->dst_addr
.in
= gateway
;
629 route_gw
->dst_prefixlen
= 32;
630 route_gw
->scope
= RT_SCOPE_LINK
;
632 route_drop(route_gw
, link
, &route_drop_handler
);
635 r
= route_new_dynamic(&route
);
637 route
->family
= AF_INET
;
638 route
->in_addr
.in
= gateway
;
640 route_drop(route
, link
, &route_drop_handler
);
643 address
->family
= AF_INET
;
644 address
->in_addr
.in
= addr
;
645 address
->prefixlen
= prefixlen
;
647 address_drop(address
, link
, &address_drop_handler
);
650 if (link
->network
->dhcp_mtu
) {
653 r
= sd_dhcp_lease_get_mtu(link
->dhcp_lease
, &mtu
);
654 if (r
>= 0 && link
->original_mtu
!= mtu
) {
655 r
= link_set_mtu(link
, link
->original_mtu
);
657 log_warning_link(link
, "DHCP error: could not reset MTU");
658 link_enter_failed(link
);
664 if (link
->network
->dhcp_hostname
) {
665 const char *hostname
= NULL
;
667 r
= sd_dhcp_lease_get_hostname(link
->dhcp_lease
, &hostname
);
668 if (r
>= 0 && hostname
) {
669 r
= set_hostname(link
->manager
->bus
, "");
671 log_error("Failed to reset transient hostname");
675 link
->dhcp_lease
= sd_dhcp_lease_unref(link
->dhcp_lease
);
680 static int dhcp_lease_acquired(sd_dhcp_client
*client
, Link
*link
) {
681 sd_dhcp_lease
*lease
;
682 struct in_addr address
;
683 struct in_addr netmask
;
684 struct in_addr gateway
;
686 struct in_addr
*nameservers
;
687 size_t nameservers_size
;
693 r
= sd_dhcp_client_get_lease(client
, &lease
);
695 log_warning_link(link
, "DHCP error: no lease: %s",
700 r
= sd_dhcp_lease_get_address(lease
, &address
);
702 log_warning_link(link
, "DHCP error: no address: %s",
707 r
= sd_dhcp_lease_get_netmask(lease
, &netmask
);
709 log_warning_link(link
, "DHCP error: no netmask: %s",
714 prefixlen
= net_netmask_to_prefixlen(&netmask
);
716 r
= sd_dhcp_lease_get_router(lease
, &gateway
);
718 log_warning_link(link
, "DHCP error: no router: %s",
723 log_struct_link(LOG_INFO
, link
,
724 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
726 ADDRESS_FMT_VAL(address
),
728 ADDRESS_FMT_VAL(gateway
),
729 "ADDRESS=%u.%u.%u.%u",
730 ADDRESS_FMT_VAL(address
),
733 "GATEWAY=%u.%u.%u.%u",
734 ADDRESS_FMT_VAL(gateway
),
737 link
->dhcp_lease
= lease
;
739 if (link
->network
->dhcp_dns
) {
740 r
= sd_dhcp_lease_get_dns(lease
, &nameservers
, &nameservers_size
);
742 r
= manager_update_resolv_conf(link
->manager
);
744 log_error("Failed to update resolv.conf");
748 if (link
->network
->dhcp_mtu
) {
751 r
= sd_dhcp_lease_get_mtu(lease
, &mtu
);
753 r
= link_set_mtu(link
, mtu
);
755 log_error_link(link
, "Failed to set MTU "
760 if (link
->network
->dhcp_hostname
) {
761 const char *hostname
;
763 r
= sd_dhcp_lease_get_hostname(lease
, &hostname
);
765 r
= set_hostname(link
->manager
->bus
, hostname
);
767 log_error("Failed to set transient hostname "
768 "to '%s'", hostname
);
772 link_enter_set_addresses(link
);
777 static void dhcp_handler(sd_dhcp_client
*client
, int event
, void *userdata
) {
778 Link
*link
= userdata
;
782 assert(link
->network
);
783 assert(link
->manager
);
785 if (link
->state
== LINK_STATE_FAILED
)
789 case DHCP_EVENT_NO_LEASE
:
790 log_debug_link(link
, "IP address in use.");
792 case DHCP_EVENT_EXPIRED
:
793 case DHCP_EVENT_STOP
:
794 case DHCP_EVENT_IP_CHANGE
:
795 if (link
->network
->dhcp_critical
) {
796 log_error_link(link
, "DHCPv4 connection considered system critical, "
797 "ignoring request to reconfigure it.");
801 if (link
->dhcp_lease
) {
802 r
= dhcp_lease_lost(link
);
804 link_enter_failed(link
);
809 if (event
== DHCP_EVENT_IP_CHANGE
) {
810 r
= dhcp_lease_acquired(client
, link
);
812 link_enter_failed(link
);
817 if (event
== DHCP_EVENT_EXPIRED
&& link
->network
->ipv4ll
) {
818 if (!sd_ipv4ll_is_running(link
->ipv4ll
))
819 r
= sd_ipv4ll_start(link
->ipv4ll
);
820 else if (ipv4ll_is_bound(link
->ipv4ll
))
821 r
= ipv4ll_address_update(link
, false);
823 link_enter_failed(link
);
829 case DHCP_EVENT_IP_ACQUIRE
:
830 r
= dhcp_lease_acquired(client
, link
);
832 link_enter_failed(link
);
836 if (ipv4ll_is_bound(link
->ipv4ll
))
837 r
= ipv4ll_address_update(link
, true);
839 r
= sd_ipv4ll_stop(link
->ipv4ll
);
841 link_enter_failed(link
);
848 log_warning_link(link
, "DHCP error: %s", strerror(-event
));
850 log_warning_link(link
, "DHCP unknown event: %d", event
);
857 static int ipv4ll_address_update(Link
*link
, bool deprecate
) {
863 r
= sd_ipv4ll_get_address(link
->ipv4ll
, &addr
);
865 _cleanup_address_free_ Address
*address
= NULL
;
867 log_debug_link(link
, "IPv4 link-local %s %u.%u.%u.%u",
868 deprecate
? "deprecate" : "approve",
869 ADDRESS_FMT_VAL(addr
));
871 r
= address_new_dynamic(&address
);
873 log_error_link(link
, "Could not allocate address: %s", strerror(-r
));
877 address
->family
= AF_INET
;
878 address
->in_addr
.in
= addr
;
879 address
->prefixlen
= 16;
880 address
->scope
= RT_SCOPE_LINK
;
881 address
->cinfo
.ifa_prefered
= deprecate
? 0 : CACHE_INFO_INFINITY_LIFE_TIME
;
882 address
->broadcast
.s_addr
= address
->in_addr
.in
.s_addr
| htonl(0xfffffffflu
>> address
->prefixlen
);
884 address_update(address
, link
, &address_update_handler
);
891 static int ipv4ll_address_lost(Link
*link
) {
897 r
= sd_ipv4ll_get_address(link
->ipv4ll
, &addr
);
899 _cleanup_address_free_ Address
*address
= NULL
;
900 _cleanup_route_free_ Route
*route
= NULL
;
902 log_debug_link(link
, "IPv4 link-local release %u.%u.%u.%u",
903 ADDRESS_FMT_VAL(addr
));
905 r
= address_new_dynamic(&address
);
907 log_error_link(link
, "Could not allocate address: %s", strerror(-r
));
911 address
->family
= AF_INET
;
912 address
->in_addr
.in
= addr
;
913 address
->prefixlen
= 16;
914 address
->scope
= RT_SCOPE_LINK
;
916 address_drop(address
, link
, &address_drop_handler
);
918 r
= route_new_dynamic(&route
);
920 log_error_link(link
, "Could not allocate route: %s",
925 route
->family
= AF_INET
;
926 route
->scope
= RT_SCOPE_LINK
;
929 route_drop(route
, link
, &route_drop_handler
);
935 static bool ipv4ll_is_bound(sd_ipv4ll
*ll
) {
941 r
= sd_ipv4ll_get_address(ll
, &addr
);
947 static int ipv4ll_address_claimed(sd_ipv4ll
*ll
, Link
*link
) {
948 struct in_addr address
;
954 r
= sd_ipv4ll_get_address(ll
, &address
);
958 log_struct_link(LOG_INFO
, link
,
959 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
961 ADDRESS_FMT_VAL(address
),
964 link_enter_set_addresses(link
);
969 static void ipv4ll_handler(sd_ipv4ll
*ll
, int event
, void *userdata
){
970 Link
*link
= userdata
;
974 assert(link
->network
);
975 assert(link
->manager
);
978 case IPV4LL_EVENT_STOP
:
979 case IPV4LL_EVENT_CONFLICT
:
980 r
= ipv4ll_address_lost(link
);
982 link_enter_failed(link
);
986 case IPV4LL_EVENT_BIND
:
987 r
= ipv4ll_address_claimed(ll
, link
);
989 link_enter_failed(link
);
995 log_warning_link(link
, "IPv4 link-local error: %s", strerror(-event
));
997 log_warning_link(link
, "IPv4 link-local unknown event: %d", event
);
1002 static int link_acquire_conf(Link
*link
) {
1006 assert(link
->network
);
1007 assert(link
->manager
);
1008 assert(link
->manager
->event
);
1010 if (link
->network
->ipv4ll
) {
1011 assert(link
->ipv4ll
);
1013 log_debug_link(link
, "acquiring IPv4 link-local address");
1015 r
= sd_ipv4ll_start(link
->ipv4ll
);
1020 if (link
->network
->dhcp
) {
1021 assert(link
->dhcp_client
);
1023 log_debug_link(link
, "acquiring DHCPv4 lease");
1025 r
= sd_dhcp_client_start(link
->dhcp_client
);
1033 static int link_update_flags(Link
*link
, unsigned flags
) {
1037 assert(link
->network
);
1039 if (link
->state
== LINK_STATE_FAILED
)
1042 if (link
->flags
== flags
)
1045 log_debug_link(link
, "link status updated: %#.8x -> %#.8x",
1046 link
->flags
, flags
);
1048 if ((link
->flags
& IFF_UP
) != (flags
& IFF_UP
))
1050 "link is %s", flags
& IFF_UP
? "up": "down");
1052 if ((link
->flags
& IFF_LOWER_UP
) != (flags
& IFF_LOWER_UP
)) {
1053 if (flags
& IFF_LOWER_UP
) {
1054 log_info_link(link
, "carrier on");
1056 if (link
->network
->dhcp
|| link
->network
->ipv4ll
) {
1057 r
= link_acquire_conf(link
);
1059 log_warning_link(link
, "Could not acquire configuration: %s", strerror(-r
));
1060 link_enter_failed(link
);
1065 log_info_link(link
, "carrier off");
1067 if (link
->network
->dhcp
) {
1068 r
= sd_dhcp_client_stop(link
->dhcp_client
);
1070 log_warning_link(link
, "Could not stop DHCPv4 client: %s", strerror(-r
));
1071 link_enter_failed(link
);
1076 if (link
->network
->ipv4ll
) {
1077 r
= sd_ipv4ll_stop(link
->ipv4ll
);
1079 log_warning_link(link
, "Could not stop IPv4 link-local: %s", strerror(-r
));
1080 link_enter_failed(link
);
1087 link
->flags
= flags
;
1092 static int link_up_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
1093 Link
*link
= userdata
;
1098 if (link
->state
== LINK_STATE_FAILED
)
1101 r
= sd_rtnl_message_get_errno(m
);
1103 link_update_flags(link
, link
->flags
| IFF_UP
);
1105 log_struct_link(LOG_WARNING
, link
,
1106 "MESSAGE=%s: could not bring up interface: %s",
1107 link
->ifname
, strerror(-r
),
1113 static int link_up(Link
*link
) {
1114 _cleanup_rtnl_message_unref_ sd_rtnl_message
*req
= NULL
;
1118 assert(link
->manager
);
1119 assert(link
->manager
->rtnl
);
1121 log_debug_link(link
, "bringing link up");
1123 r
= sd_rtnl_message_new_link(link
->manager
->rtnl
, &req
,
1124 RTM_SETLINK
, link
->ifindex
);
1126 log_error_link(link
, "Could not allocate RTM_SETLINK message");
1130 r
= sd_rtnl_message_link_set_flags(req
, IFF_UP
, IFF_UP
);
1132 log_error_link(link
, "Could not set link flags: %s", strerror(-r
));
1136 r
= sd_rtnl_call_async(link
->manager
->rtnl
, req
, link_up_handler
, link
, 0, NULL
);
1138 log_error_link(link
,
1139 "Could not send rtnetlink message: %s", strerror(-r
));
1146 static int link_enslaved(Link
*link
) {
1150 assert(link
->state
== LINK_STATE_ENSLAVING
);
1151 assert(link
->network
);
1155 link_enter_failed(link
);
1159 if (!link
->network
->dhcp
&& !link
->network
->ipv4ll
)
1160 return link_enter_set_addresses(link
);
1165 static int enslave_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
, void *userdata
) {
1166 Link
*link
= userdata
;
1170 assert(link
->state
== LINK_STATE_ENSLAVING
|| link
->state
== LINK_STATE_FAILED
);
1171 assert(link
->network
);
1175 if (link
->state
== LINK_STATE_FAILED
)
1178 r
= sd_rtnl_message_get_errno(m
);
1180 log_struct_link(LOG_ERR
, link
,
1181 "MESSAGE=%s: could not enslave: %s",
1182 link
->ifname
, strerror(-r
),
1185 link_enter_failed(link
);
1189 log_debug_link(link
, "enslaved");
1191 if (link
->enslaving
== 0)
1192 link_enslaved(link
);
1197 static int link_enter_enslave(Link
*link
) {
1198 NetDev
*vlan
, *macvlan
;
1203 assert(link
->network
);
1204 assert(link
->state
== _LINK_STATE_INVALID
);
1206 link
->state
= LINK_STATE_ENSLAVING
;
1210 if (!link
->network
->bridge
&& !link
->network
->bond
&&
1211 hashmap_isempty(link
->network
->vlans
) &&
1212 hashmap_isempty(link
->network
->macvlans
))
1213 return link_enslaved(link
);
1215 if (link
->network
->bridge
) {
1216 log_struct_link(LOG_DEBUG
, link
,
1217 "MESSAGE=%s: enslaving by '%s'",
1218 link
->ifname
, link
->network
->bridge
->name
,
1219 NETDEV(link
->network
->bridge
),
1222 r
= netdev_enslave(link
->network
->bridge
, link
, &enslave_handler
);
1224 log_struct_link(LOG_WARNING
, link
,
1225 "MESSAGE=%s: could not enslave by '%s': %s",
1226 link
->ifname
, link
->network
->bridge
->name
, strerror(-r
),
1227 NETDEV(link
->network
->bridge
),
1229 link_enter_failed(link
);
1236 if (link
->network
->bond
) {
1237 log_struct_link(LOG_DEBUG
, link
,
1238 "MESSAGE=%s: enslaving by '%s'",
1239 link
->ifname
, link
->network
->bond
->name
,
1240 NETDEV(link
->network
->bond
),
1243 r
= netdev_enslave(link
->network
->bond
, link
, &enslave_handler
);
1245 log_struct_link(LOG_WARNING
, link
,
1246 "MESSAGE=%s: could not enslave by '%s': %s",
1247 link
->ifname
, link
->network
->bond
->name
, strerror(-r
),
1248 NETDEV(link
->network
->bond
),
1250 link_enter_failed(link
);
1257 HASHMAP_FOREACH(vlan
, link
->network
->vlans
, i
) {
1258 log_struct_link(LOG_DEBUG
, link
,
1259 "MESSAGE=%s: enslaving by '%s'",
1260 link
->ifname
, vlan
->name
, NETDEV(vlan
), NULL
);
1262 r
= netdev_enslave(vlan
, link
, &enslave_handler
);
1264 log_struct_link(LOG_WARNING
, link
,
1265 "MESSAGE=%s: could not enslave by '%s': %s",
1266 link
->ifname
, vlan
->name
, strerror(-r
),
1267 NETDEV(vlan
), NULL
);
1268 link_enter_failed(link
);
1275 HASHMAP_FOREACH(macvlan
, link
->network
->macvlans
, i
) {
1276 log_struct_link(LOG_DEBUG
, link
,
1277 "MESSAGE=%s: enslaving by '%s'",
1278 link
->ifname
, macvlan
->name
, NETDEV(macvlan
), NULL
);
1280 r
= netdev_enslave(macvlan
, link
, &enslave_handler
);
1282 log_struct_link(LOG_WARNING
, link
,
1283 "MESSAGE=%s: could not enslave by '%s': %s",
1284 link
->ifname
, macvlan
->name
, strerror(-r
),
1285 NETDEV(macvlan
), NULL
);
1286 link_enter_failed(link
);
1296 static int link_getlink_handler(sd_rtnl
*rtnl
, sd_rtnl_message
*m
,
1298 Link
*link
= userdata
;
1302 assert(link
->ifname
);
1304 if (link
->state
== LINK_STATE_FAILED
)
1307 r
= sd_rtnl_message_get_errno(m
);
1309 log_struct_link(LOG_ERR
, link
,
1310 "MESSAGE=%s: could not get state: %s",
1311 link
->ifname
, strerror(-r
),
1314 link_enter_failed(link
);
1318 link_update(link
, m
);
1323 static int link_getlink(Link
*link
) {
1324 _cleanup_rtnl_message_unref_ sd_rtnl_message
*req
= NULL
;
1328 assert(link
->manager
);
1329 assert(link
->manager
->rtnl
);
1331 log_debug_link(link
, "requesting link status");
1333 r
= sd_rtnl_message_new_link(link
->manager
->rtnl
, &req
,
1334 RTM_GETLINK
, link
->ifindex
);
1336 log_error_link(link
, "Could not allocate RTM_GETLINK message");
1340 r
= sd_rtnl_call_async(link
->manager
->rtnl
, req
, link_getlink_handler
,
1343 log_error_link(link
,
1344 "Could not send rtnetlink message: %s", strerror(-r
));
1351 static int link_configure(Link
*link
) {
1355 assert(link
->state
== _LINK_STATE_INVALID
);
1357 r
= link_getlink(link
);
1361 return link_enter_enslave(link
);
1364 int link_add(Manager
*m
, struct udev_device
*device
, Link
**ret
) {
1372 r
= link_new(m
, device
, &link
);
1378 r
= network_get(m
, device
, &network
);
1380 return r
== -ENOENT
? 0 : r
;
1382 r
= network_apply(m
, network
, link
);
1386 if (link
->network
->ipv4ll
) {
1388 r
= sd_ipv4ll_new(&link
->ipv4ll
);
1392 r
= net_get_unique_predictable_data(link
->udev_device
, seed
);
1394 r
= sd_ipv4ll_set_address_seed(link
->ipv4ll
, seed
);
1399 r
= sd_ipv4ll_attach_event(link
->ipv4ll
, NULL
, 0);
1403 r
= sd_ipv4ll_set_index(link
->ipv4ll
, link
->ifindex
);
1407 r
= sd_ipv4ll_set_callback(link
->ipv4ll
, ipv4ll_handler
, link
);
1412 if (link
->network
->dhcp
) {
1413 r
= sd_dhcp_client_new(&link
->dhcp_client
);
1417 r
= sd_dhcp_client_attach_event(link
->dhcp_client
, NULL
, 0);
1421 r
= sd_dhcp_client_set_index(link
->dhcp_client
, link
->ifindex
);
1425 r
= sd_dhcp_client_set_callback(link
->dhcp_client
, dhcp_handler
, link
);
1429 if (link
->network
->dhcp_mtu
) {
1430 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, 26);
1436 r
= link_configure(link
);
1443 int link_update(Link
*link
, sd_rtnl_message
*m
) {
1445 struct ether_addr mac
;
1449 assert(link
->network
);
1452 if (link
->state
== LINK_STATE_FAILED
)
1455 if (link
->network
->dhcp
&& link
->network
->dhcp_mtu
&&
1456 !link
->original_mtu
) {
1457 r
= sd_rtnl_message_read_u16(m
, IFLA_MTU
, &link
->original_mtu
);
1459 log_debug_link(link
, "saved original MTU: %"
1460 PRIu16
, link
->original_mtu
);
1463 r
= sd_rtnl_message_read_ether_addr(m
, IFLA_ADDRESS
, &mac
);
1465 log_debug_link(link
, "Could not get MAC address: %s", strerror(-r
));
1467 if (memcmp(link
->mac
.ether_addr_octet
, mac
.ether_addr_octet
, ETH_ALEN
)) {
1469 memcpy(link
->mac
.ether_addr_octet
, mac
.ether_addr_octet
, ETH_ALEN
);
1471 log_debug_link(link
, "MAC address: "
1472 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1473 mac
.ether_addr_octet
[0],
1474 mac
.ether_addr_octet
[1],
1475 mac
.ether_addr_octet
[2],
1476 mac
.ether_addr_octet
[3],
1477 mac
.ether_addr_octet
[4],
1478 mac
.ether_addr_octet
[5]);
1481 r
= sd_ipv4ll_set_mac(link
->ipv4ll
, &link
->mac
);
1483 log_warning_link(link
, "Could not update MAC "
1484 "address in IPv4LL client: %s",
1490 if (link
->dhcp_client
) {
1491 r
= sd_dhcp_client_set_mac(link
->dhcp_client
, &link
->mac
);
1493 log_warning_link(link
, "Could not update MAC "
1494 "address in DHCP client: %s",
1502 r
= sd_rtnl_message_link_get_flags(m
, &flags
);
1504 log_warning_link(link
, "Could not get link flags");
1508 return link_update_flags(link
, flags
);
1511 int link_save(Link
*link
) {
1512 _cleanup_free_
char *temp_path
= NULL
;
1513 _cleanup_fclose_
FILE *f
= NULL
;
1518 assert(link
->state_file
);
1520 state
= link_state_to_string(link
->state
);
1524 r
= fopen_temporary(link
->state_file
, &f
, &temp_path
);
1528 fchmod(fileno(f
), 0644);
1531 "# This is private data. Do not parse.\n"
1532 "STATE=%s\n", state
);
1534 if (link
->dhcp_lease
) {
1535 _cleanup_free_
char *lease_file
= NULL
;
1537 r
= asprintf(&lease_file
, "/run/systemd/network/leases/%"PRIu64
,
1542 r
= dhcp_lease_save(link
->dhcp_lease
, lease_file
);
1546 fprintf(f
, "DHCP_LEASE=%s\n", lease_file
);
1551 if (ferror(f
) || rename(temp_path
, link
->state_file
) < 0) {
1553 unlink(link
->state_file
);
1559 log_error("Failed to save link data %s: %s", link
->state_file
, strerror(-r
));
1564 static const char* const link_state_table
[_LINK_STATE_MAX
] = {
1565 [LINK_STATE_ENSLAVING
] = "configuring",
1566 [LINK_STATE_SETTING_ADDRESSES
] = "configuring",
1567 [LINK_STATE_SETTING_ROUTES
] = "configuring",
1568 [LINK_STATE_CONFIGURED
] = "configured",
1569 [LINK_STATE_FAILED
] = "failed",
1572 DEFINE_STRING_TABLE_LOOKUP(link_state
, LinkState
);