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 <sys/socket.h>
25 #include "sd-daemon.h"
26 #include "sd-netlink.h"
28 #include "alloc-util.h"
30 #include "conf-parser.h"
34 #include "libudev-private.h"
35 #include "local-addresses.h"
36 #include "netlink-util.h"
38 #include "ordered-set.h"
39 #include "path-util.h"
41 #include "udev-util.h"
44 /* use 8 MB for receive socket kernel queue. */
45 #define RCVBUF_SIZE (8*1024*1024)
47 const char* const network_dirs
[] = {
48 "/etc/systemd/network",
49 "/run/systemd/network",
50 "/usr/lib/systemd/network",
52 "/lib/systemd/network",
56 static int setup_default_address_pool(Manager
*m
) {
62 /* Add in the well-known private address ranges. */
64 r
= address_pool_new_from_string(m
, &p
, AF_INET6
, "fc00::", 7);
68 r
= address_pool_new_from_string(m
, &p
, AF_INET
, "192.168.0.0", 16);
72 r
= address_pool_new_from_string(m
, &p
, AF_INET
, "172.16.0.0", 12);
76 r
= address_pool_new_from_string(m
, &p
, AF_INET
, "10.0.0.0", 8);
83 static int on_bus_retry(sd_event_source
*s
, usec_t usec
, void *userdata
) {
84 Manager
*m
= userdata
;
89 m
->bus_retry_event_source
= sd_event_source_unref(m
->bus_retry_event_source
);
91 manager_connect_bus(m
);
96 static int manager_reset_all(Manager
*m
) {
103 HASHMAP_FOREACH(link
, m
->links
, i
) {
104 r
= link_carrier_reset(link
);
106 log_link_warning_errno(link
, r
, "Could not reset carrier: %m");
112 static int match_prepare_for_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*ret_error
) {
113 Manager
*m
= userdata
;
118 r
= sd_bus_message_read(message
, "b", &b
);
120 log_debug_errno(r
, "Failed to parse PrepareForSleep signal: %m");
127 log_debug("Coming back from suspend, resetting all connections...");
129 manager_reset_all(m
);
134 int manager_connect_bus(Manager
*m
) {
139 r
= sd_bus_default_system(&m
->bus
);
141 /* We failed to connect? Yuck, we must be in early
142 * boot. Let's try in 5s again. As soon as we have
143 * kdbus we can stop doing this... */
145 log_debug_errno(r
, "Failed to connect to bus, trying again in 5s: %m");
147 r
= sd_event_add_time(m
->event
, &m
->bus_retry_event_source
, CLOCK_MONOTONIC
, now(CLOCK_MONOTONIC
) + 5*USEC_PER_SEC
, 0, on_bus_retry
, m
);
149 return log_error_errno(r
, "Failed to install bus reconnect time event: %m");
157 r
= sd_bus_add_match(m
->bus
, &m
->prepare_for_sleep_slot
,
159 "sender='org.freedesktop.login1',"
160 "interface='org.freedesktop.login1.Manager',"
161 "member='PrepareForSleep',"
162 "path='/org/freedesktop/login1'",
163 match_prepare_for_sleep
,
166 return log_error_errno(r
, "Failed to add match for PrepareForSleep: %m");
168 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable
, m
);
170 return log_error_errno(r
, "Failed to add manager object vtable: %m");
172 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable
, link_object_find
, m
);
174 return log_error_errno(r
, "Failed to add link object vtable: %m");
176 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/network1/link", link_node_enumerator
, m
);
178 return log_error_errno(r
, "Failed to add link enumerator: %m");
180 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable
, network_object_find
, m
);
182 return log_error_errno(r
, "Failed to add network object vtable: %m");
184 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/network1/network", network_node_enumerator
, m
);
186 return log_error_errno(r
, "Failed to add network enumerator: %m");
188 r
= sd_bus_request_name(m
->bus
, "org.freedesktop.network1", 0);
190 return log_error_errno(r
, "Failed to register name: %m");
192 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
194 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
199 static int manager_udev_process_link(Manager
*m
, struct udev_device
*device
) {
206 if (!streq_ptr(udev_device_get_action(device
), "add"))
209 ifindex
= udev_device_get_ifindex(device
);
211 log_debug("Ignoring udev ADD event for device with invalid ifindex");
215 r
= link_get(m
, ifindex
, &link
);
221 r
= link_initialized(link
, device
);
228 static int manager_dispatch_link_udev(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
229 Manager
*m
= userdata
;
230 struct udev_monitor
*monitor
= m
->udev_monitor
;
231 _cleanup_udev_device_unref_
struct udev_device
*device
= NULL
;
233 device
= udev_monitor_receive_device(monitor
);
237 manager_udev_process_link(m
, device
);
241 static int manager_connect_udev(Manager
*m
) {
244 /* udev does not initialize devices inside containers,
245 * so we rely on them being already initialized before
246 * entering the container */
247 if (detect_container() > 0)
250 m
->udev
= udev_new();
254 m
->udev_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev");
255 if (!m
->udev_monitor
)
258 r
= udev_monitor_filter_add_match_subsystem_devtype(m
->udev_monitor
, "net", NULL
);
260 return log_error_errno(r
, "Could not add udev monitor filter: %m");
262 r
= udev_monitor_enable_receiving(m
->udev_monitor
);
264 log_error("Could not enable udev monitor");
268 r
= sd_event_add_io(m
->event
,
269 &m
->udev_event_source
,
270 udev_monitor_get_fd(m
->udev_monitor
),
271 EPOLLIN
, manager_dispatch_link_udev
,
276 r
= sd_event_source_set_description(m
->udev_event_source
, "networkd-udev");
283 int manager_rtnl_process_route(sd_netlink
*rtnl
, sd_netlink_message
*message
, void *userdata
) {
284 Manager
*m
= userdata
;
287 uint32_t ifindex
, priority
= 0;
288 unsigned char protocol
, scope
, tos
, table
;
290 unsigned char dst_prefixlen
, src_prefixlen
;
291 union in_addr_union dst
= {}, gw
= {}, src
= {}, prefsrc
= {};
299 if (sd_netlink_message_is_error(message
)) {
300 r
= sd_netlink_message_get_errno(message
);
302 log_warning_errno(r
, "rtnl: failed to receive route: %m");
307 r
= sd_netlink_message_get_type(message
, &type
);
309 log_warning_errno(r
, "rtnl: could not get message type: %m");
311 } else if (type
!= RTM_NEWROUTE
&& type
!= RTM_DELROUTE
) {
312 log_warning("rtnl: received unexpected message type when processing route");
316 r
= sd_netlink_message_read_u32(message
, RTA_OIF
, &ifindex
);
318 log_debug("rtnl: received route without ifindex, ignoring");
321 log_warning_errno(r
, "rtnl: could not get ifindex from route, ignoring: %m");
323 } else if (ifindex
<= 0) {
324 log_warning("rtnl: received route message with invalid ifindex, ignoring: %d", ifindex
);
327 r
= link_get(m
, ifindex
, &link
);
328 if (r
< 0 || !link
) {
329 /* when enumerating we might be out of sync, but we will
330 * get the route again, so just ignore it */
332 log_warning("rtnl: received route for nonexistent link (%d), ignoring", ifindex
);
337 r
= sd_rtnl_message_route_get_family(message
, &family
);
338 if (r
< 0 || !IN_SET(family
, AF_INET
, AF_INET6
)) {
339 log_link_warning(link
, "rtnl: received address with invalid family, ignoring.");
343 r
= sd_rtnl_message_route_get_protocol(message
, &protocol
);
345 log_warning_errno(r
, "rtnl: could not get route protocol: %m");
351 r
= sd_netlink_message_read_in_addr(message
, RTA_DST
, &dst
.in
);
352 if (r
< 0 && r
!= -ENODATA
) {
353 log_link_warning_errno(link
, r
, "rtnl: received route without valid destination, ignoring: %m");
357 r
= sd_netlink_message_read_in_addr(message
, RTA_GATEWAY
, &gw
.in
);
358 if (r
< 0 && r
!= -ENODATA
) {
359 log_link_warning_errno(link
, r
, "rtnl: received route with invalid gateway, ignoring: %m");
363 r
= sd_netlink_message_read_in_addr(message
, RTA_SRC
, &src
.in
);
364 if (r
< 0 && r
!= -ENODATA
) {
365 log_link_warning_errno(link
, r
, "rtnl: received route with invalid source, ignoring: %m");
369 r
= sd_netlink_message_read_in_addr(message
, RTA_PREFSRC
, &prefsrc
.in
);
370 if (r
< 0 && r
!= -ENODATA
) {
371 log_link_warning_errno(link
, r
, "rtnl: received route with invalid preferred source, ignoring: %m");
378 r
= sd_netlink_message_read_in6_addr(message
, RTA_DST
, &dst
.in6
);
379 if (r
< 0 && r
!= -ENODATA
) {
380 log_link_warning_errno(link
, r
, "rtnl: received route without valid destination, ignoring: %m");
384 r
= sd_netlink_message_read_in6_addr(message
, RTA_GATEWAY
, &gw
.in6
);
385 if (r
< 0 && r
!= -ENODATA
) {
386 log_link_warning_errno(link
, r
, "rtnl: received route with invalid gateway, ignoring: %m");
390 r
= sd_netlink_message_read_in6_addr(message
, RTA_SRC
, &src
.in6
);
391 if (r
< 0 && r
!= -ENODATA
) {
392 log_link_warning_errno(link
, r
, "rtnl: received route with invalid source, ignoring: %m");
396 r
= sd_netlink_message_read_in6_addr(message
, RTA_PREFSRC
, &prefsrc
.in6
);
397 if (r
< 0 && r
!= -ENODATA
) {
398 log_link_warning_errno(link
, r
, "rtnl: received route with invalid preferred source, ignoring: %m");
405 log_link_debug(link
, "rtnl: ignoring unsupported address family: %d", family
);
409 r
= sd_rtnl_message_route_get_dst_prefixlen(message
, &dst_prefixlen
);
411 log_link_warning_errno(link
, r
, "rtnl: received route with invalid destination prefixlen, ignoring: %m");
415 r
= sd_rtnl_message_route_get_src_prefixlen(message
, &src_prefixlen
);
417 log_link_warning_errno(link
, r
, "rtnl: received route with invalid source prefixlen, ignoring: %m");
421 r
= sd_rtnl_message_route_get_scope(message
, &scope
);
423 log_link_warning_errno(link
, r
, "rtnl: received route with invalid scope, ignoring: %m");
427 r
= sd_rtnl_message_route_get_tos(message
, &tos
);
429 log_link_warning_errno(link
, r
, "rtnl: received route with invalid tos, ignoring: %m");
433 r
= sd_rtnl_message_route_get_table(message
, &table
);
435 log_link_warning_errno(link
, r
, "rtnl: received route with invalid table, ignoring: %m");
439 r
= sd_netlink_message_read_u32(message
, RTA_PRIORITY
, &priority
);
440 if (r
< 0 && r
!= -ENODATA
) {
441 log_link_warning_errno(link
, r
, "rtnl: received route with invalid priority, ignoring: %m");
445 route_get(link
, family
, &dst
, dst_prefixlen
, tos
, priority
, table
, &route
);
450 /* A route appeared that we did not request */
451 r
= route_add_foreign(link
, family
, &dst
, dst_prefixlen
, tos
, priority
, table
, &route
);
456 route_update(route
, &src
, src_prefixlen
, &gw
, &prefsrc
, scope
, protocol
);
467 assert_not_reached("Received invalid RTNL message type");
473 int manager_rtnl_process_address(sd_netlink
*rtnl
, sd_netlink_message
*message
, void *userdata
) {
474 Manager
*m
= userdata
;
479 unsigned char prefixlen
;
481 union in_addr_union in_addr
;
482 struct ifa_cacheinfo cinfo
;
483 Address
*address
= NULL
;
484 char buf
[INET6_ADDRSTRLEN
], valid_buf
[FORMAT_TIMESPAN_MAX
];
485 const char *valid_str
= NULL
;
492 if (sd_netlink_message_is_error(message
)) {
493 r
= sd_netlink_message_get_errno(message
);
495 log_warning_errno(r
, "rtnl: failed to receive address: %m");
500 r
= sd_netlink_message_get_type(message
, &type
);
502 log_warning_errno(r
, "rtnl: could not get message type: %m");
504 } else if (type
!= RTM_NEWADDR
&& type
!= RTM_DELADDR
) {
505 log_warning("rtnl: received unexpected message type when processing address");
509 r
= sd_rtnl_message_addr_get_ifindex(message
, &ifindex
);
511 log_warning_errno(r
, "rtnl: could not get ifindex from address: %m");
513 } else if (ifindex
<= 0) {
514 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex
);
517 r
= link_get(m
, ifindex
, &link
);
518 if (r
< 0 || !link
) {
519 /* when enumerating we might be out of sync, but we will
520 * get the address again, so just ignore it */
522 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex
);
527 r
= sd_rtnl_message_addr_get_family(message
, &family
);
528 if (r
< 0 || !IN_SET(family
, AF_INET
, AF_INET6
)) {
529 log_link_warning(link
, "rtnl: received address with invalid family, ignoring.");
533 r
= sd_rtnl_message_addr_get_prefixlen(message
, &prefixlen
);
535 log_link_warning_errno(link
, r
, "rtnl: received address with invalid prefixlen, ignoring: %m");
539 r
= sd_rtnl_message_addr_get_scope(message
, &scope
);
541 log_link_warning_errno(link
, r
, "rtnl: received address with invalid scope, ignoring: %m");
545 r
= sd_rtnl_message_addr_get_flags(message
, &flags
);
547 log_link_warning_errno(link
, r
, "rtnl: received address with invalid flags, ignoring: %m");
553 r
= sd_netlink_message_read_in_addr(message
, IFA_LOCAL
, &in_addr
.in
);
555 log_link_warning_errno(link
, r
, "rtnl: received address without valid address, ignoring: %m");
562 r
= sd_netlink_message_read_in6_addr(message
, IFA_ADDRESS
, &in_addr
.in6
);
564 log_link_warning_errno(link
, r
, "rtnl: received address without valid address, ignoring: %m");
571 log_link_debug(link
, "rtnl: ignoring unsupported address family: %d", family
);
574 if (!inet_ntop(family
, &in_addr
, buf
, INET6_ADDRSTRLEN
)) {
575 log_link_warning(link
, "Could not print address");
579 r
= sd_netlink_message_read_cache_info(message
, IFA_CACHEINFO
, &cinfo
);
581 if (cinfo
.ifa_valid
!= CACHE_INFO_INFINITY_LIFE_TIME
)
582 valid_str
= format_timespan(valid_buf
, FORMAT_TIMESPAN_MAX
,
583 cinfo
.ifa_valid
* USEC_PER_SEC
,
587 address_get(link
, family
, &in_addr
, prefixlen
, &address
);
592 log_link_debug(link
, "Updating address: %s/%u (valid %s%s)", buf
, prefixlen
,
593 valid_str
? "for " : "forever", valid_str
?: "");
595 /* An address appeared that we did not request */
596 r
= address_add_foreign(link
, family
, &in_addr
, prefixlen
, &address
);
598 log_link_warning_errno(link
, r
, "Failed to add address %s/%u: %m", buf
, prefixlen
);
601 log_link_debug(link
, "Adding address: %s/%u (valid %s%s)", buf
, prefixlen
,
602 valid_str
? "for " : "forever", valid_str
?: "");
605 address_update(address
, flags
, scope
, &cinfo
);
612 log_link_debug(link
, "Removing address: %s/%u (valid %s%s)", buf
, prefixlen
,
613 valid_str
? "for " : "forever", valid_str
?: "");
614 address_drop(address
);
616 log_link_warning(link
, "Removing non-existent address: %s/%u (valid %s%s)", buf
, prefixlen
,
617 valid_str
? "for " : "forever", valid_str
?: "");
621 assert_not_reached("Received invalid RTNL message type");
627 static int manager_rtnl_process_link(sd_netlink
*rtnl
, sd_netlink_message
*message
, void *userdata
) {
628 Manager
*m
= userdata
;
630 NetDev
*netdev
= NULL
;
639 if (sd_netlink_message_is_error(message
)) {
640 r
= sd_netlink_message_get_errno(message
);
642 log_warning_errno(r
, "rtnl: Could not receive link: %m");
647 r
= sd_netlink_message_get_type(message
, &type
);
649 log_warning_errno(r
, "rtnl: Could not get message type: %m");
651 } else if (type
!= RTM_NEWLINK
&& type
!= RTM_DELLINK
) {
652 log_warning("rtnl: Received unexpected message type when processing link");
656 r
= sd_rtnl_message_link_get_ifindex(message
, &ifindex
);
658 log_warning_errno(r
, "rtnl: Could not get ifindex from link: %m");
660 } else if (ifindex
<= 0) {
661 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex
);
665 r
= sd_netlink_message_read_string(message
, IFLA_IFNAME
, &name
);
667 log_warning_errno(r
, "rtnl: Received link message without ifname: %m");
671 (void) link_get(m
, ifindex
, &link
);
672 (void) netdev_get(m
, name
, &netdev
);
677 /* link is new, so add it */
678 r
= link_add(m
, message
, &link
);
680 log_warning_errno(r
, "Could not add new link: %m");
686 /* netdev exists, so make sure the ifindex matches */
687 r
= netdev_set_ifindex(netdev
, message
);
689 log_warning_errno(r
, "Could not set ifindex on netdev: %m");
694 r
= link_update(link
, message
);
707 assert_not_reached("Received invalid RTNL message type.");
713 static int systemd_netlink_fd(void) {
714 int n
, fd
, rtnl_fd
= -EINVAL
;
716 n
= sd_listen_fds(true);
720 for (fd
= SD_LISTEN_FDS_START
; fd
< SD_LISTEN_FDS_START
+ n
; fd
++) {
721 if (sd_is_socket(fd
, AF_NETLINK
, SOCK_RAW
, -1) > 0) {
732 static int manager_connect_rtnl(Manager
*m
) {
737 fd
= systemd_netlink_fd();
739 r
= sd_netlink_open(&m
->rtnl
);
741 r
= sd_netlink_open_fd(&m
->rtnl
, fd
);
745 r
= sd_netlink_inc_rcvbuf(m
->rtnl
, RCVBUF_SIZE
);
749 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
753 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, &manager_rtnl_process_link
, m
);
757 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, &manager_rtnl_process_link
, m
);
761 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, &manager_rtnl_process_address
, m
);
765 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, &manager_rtnl_process_address
, m
);
769 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWROUTE
, &manager_rtnl_process_route
, m
);
773 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELROUTE
, &manager_rtnl_process_route
, m
);
780 static int ordered_set_put_in_addr(OrderedSet
*s
, const struct in_addr
*address
) {
786 r
= in_addr_to_string(AF_INET
, (const union in_addr_union
*) address
, &p
);
790 r
= ordered_set_consume(s
, p
);
797 static int ordered_set_put_in_addrv(OrderedSet
*s
, const struct in_addr
*addresses
, int n
) {
801 assert(n
<= 0 || addresses
);
803 for (i
= 0; i
< n
; i
++) {
804 r
= ordered_set_put_in_addr(s
, addresses
+i
);
814 static void print_string_set(FILE *f
, const char *field
, OrderedSet
*s
) {
819 if (ordered_set_isempty(s
))
824 ORDERED_SET_FOREACH(p
, s
, i
) {
833 static int manager_save(Manager
*m
) {
834 _cleanup_ordered_set_free_free_ OrderedSet
*dns
= NULL
, *ntp
= NULL
, *search_domains
= NULL
, *route_domains
= NULL
;
837 _cleanup_free_
char *temp_path
= NULL
;
838 _cleanup_fclose_
FILE *f
= NULL
;
839 LinkOperationalState operstate
= LINK_OPERSTATE_OFF
;
840 const char *operstate_str
;
844 assert(m
->state_file
);
846 /* We add all NTP and DNS server to a set, to filter out duplicates */
847 dns
= ordered_set_new(&string_hash_ops
);
851 ntp
= ordered_set_new(&string_hash_ops
);
855 search_domains
= ordered_set_new(&string_hash_ops
);
859 route_domains
= ordered_set_new(&string_hash_ops
);
863 HASHMAP_FOREACH(link
, m
->links
, i
) {
864 if (link
->flags
& IFF_LOOPBACK
)
867 if (link
->operstate
> operstate
)
868 operstate
= link
->operstate
;
873 /* First add the static configured entries */
874 r
= ordered_set_put_strdupv(dns
, link
->network
->dns
);
878 r
= ordered_set_put_strdupv(ntp
, link
->network
->ntp
);
882 r
= ordered_set_put_strdupv(search_domains
, link
->network
->search_domains
);
886 r
= ordered_set_put_strdupv(route_domains
, link
->network
->route_domains
);
890 if (!link
->dhcp_lease
)
893 /* Secondly, add the entries acquired via DHCP */
894 if (link
->network
->dhcp_dns
) {
895 const struct in_addr
*addresses
;
897 r
= sd_dhcp_lease_get_dns(link
->dhcp_lease
, &addresses
);
899 r
= ordered_set_put_in_addrv(dns
, addresses
, r
);
902 } else if (r
< 0 && r
!= -ENODATA
)
906 if (link
->network
->dhcp_ntp
) {
907 const struct in_addr
*addresses
;
909 r
= sd_dhcp_lease_get_ntp(link
->dhcp_lease
, &addresses
);
911 r
= ordered_set_put_in_addrv(ntp
, addresses
, r
);
914 } else if (r
< 0 && r
!= -ENODATA
)
918 if (link
->network
->dhcp_domains
) {
919 const char *domainname
;
921 r
= sd_dhcp_lease_get_domainname(link
->dhcp_lease
, &domainname
);
923 r
= ordered_set_put_strdup(search_domains
, domainname
);
926 } else if (r
!= -ENODATA
)
931 operstate_str
= link_operstate_to_string(operstate
);
932 assert(operstate_str
);
934 r
= fopen_temporary(m
->state_file
, &f
, &temp_path
);
938 fchmod(fileno(f
), 0644);
941 "# This is private data. Do not parse.\n"
942 "OPER_STATE=%s\n", operstate_str
);
944 print_string_set(f
, "DNS=", dns
);
945 print_string_set(f
, "NTP=", ntp
);
946 print_string_set(f
, "DOMAINS=", search_domains
);
947 print_string_set(f
, "ROUTE_DOMAINS=", route_domains
);
949 r
= fflush_and_check(f
);
953 if (rename(temp_path
, m
->state_file
) < 0) {
958 if (m
->operational_state
!= operstate
) {
959 m
->operational_state
= operstate
;
960 r
= manager_send_changed(m
, "OperationalState", NULL
);
962 log_error_errno(r
, "Could not emit changed OperationalState: %m");
970 (void) unlink(m
->state_file
);
971 (void) unlink(temp_path
);
973 return log_error_errno(r
, "Failed to save network state to %s: %m", m
->state_file
);
976 static int manager_dirty_handler(sd_event_source
*s
, void *userdata
) {
977 Manager
*m
= userdata
;
987 SET_FOREACH(link
, m
->dirty_links
, i
) {
996 int manager_new(Manager
**ret
) {
997 _cleanup_manager_free_ Manager
*m
= NULL
;
1000 m
= new0(Manager
, 1);
1004 m
->state_file
= strdup("/run/systemd/netif/state");
1008 r
= sd_event_default(&m
->event
);
1012 sd_event_set_watchdog(m
->event
, true);
1014 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
1015 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
1017 r
= sd_event_add_post(m
->event
, NULL
, manager_dirty_handler
, m
);
1021 r
= manager_connect_rtnl(m
);
1025 r
= manager_connect_udev(m
);
1029 m
->netdevs
= hashmap_new(&string_hash_ops
);
1033 LIST_HEAD_INIT(m
->networks
);
1035 r
= setup_default_address_pool(m
);
1045 void manager_free(Manager
*m
) {
1054 free(m
->state_file
);
1056 while ((link
= hashmap_first(m
->links
)))
1058 hashmap_free(m
->links
);
1060 while ((network
= m
->networks
))
1061 network_free(network
);
1063 hashmap_free(m
->networks_by_name
);
1065 while ((netdev
= hashmap_first(m
->netdevs
)))
1066 netdev_unref(netdev
);
1067 hashmap_free(m
->netdevs
);
1069 while ((pool
= m
->address_pools
))
1070 address_pool_free(pool
);
1072 sd_netlink_unref(m
->rtnl
);
1073 sd_event_unref(m
->event
);
1075 sd_event_source_unref(m
->udev_event_source
);
1076 udev_monitor_unref(m
->udev_monitor
);
1077 udev_unref(m
->udev
);
1079 sd_bus_unref(m
->bus
);
1080 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
1081 sd_event_source_unref(m
->bus_retry_event_source
);
1086 static bool manager_check_idle(void *userdata
) {
1087 Manager
*m
= userdata
;
1093 HASHMAP_FOREACH(link
, m
->links
, i
) {
1094 /* we are not woken on udev activity, so let's just wait for the
1095 * pending udev event */
1096 if (link
->state
== LINK_STATE_PENDING
)
1102 /* we are not woken on netork activity, so let's stay around */
1103 if (link_lldp_enabled(link
) ||
1104 link_ipv4ll_enabled(link
) ||
1105 link_dhcp4_server_enabled(link
) ||
1106 link_dhcp4_enabled(link
) ||
1107 link_dhcp6_enabled(link
) ||
1108 link_ipv6_accept_ra_enabled(link
))
1115 int manager_run(Manager
*m
) {
1121 /* The dirty handler will deal with future serialization, but the first one
1122 must be done explicitly. */
1126 HASHMAP_FOREACH(link
, m
->links
, i
)
1130 return bus_event_loop_with_idle(
1133 "org.freedesktop.network1",
1138 /* failed to connect to the bus, so we lose exit-on-idle logic,
1139 this should not happen except if dbus is not around at all */
1140 return sd_event_loop(m
->event
);
1143 int manager_load_config(Manager
*m
) {
1146 /* update timestamp */
1147 paths_check_timestamp(network_dirs
, &m
->network_dirs_ts_usec
, true);
1153 r
= network_load(m
);
1160 bool manager_should_reload(Manager
*m
) {
1161 return paths_check_timestamp(network_dirs
, &m
->network_dirs_ts_usec
, false);
1164 int manager_rtnl_enumerate_links(Manager
*m
) {
1165 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
1166 sd_netlink_message
*link
;
1172 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
1176 r
= sd_netlink_message_request_dump(req
, true);
1180 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
1184 for (link
= reply
; link
; link
= sd_netlink_message_next(link
)) {
1187 m
->enumerating
= true;
1189 k
= manager_rtnl_process_link(m
->rtnl
, link
, m
);
1193 m
->enumerating
= false;
1199 int manager_rtnl_enumerate_addresses(Manager
*m
) {
1200 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
1201 sd_netlink_message
*addr
;
1207 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, 0);
1211 r
= sd_netlink_message_request_dump(req
, true);
1215 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
1219 for (addr
= reply
; addr
; addr
= sd_netlink_message_next(addr
)) {
1222 m
->enumerating
= true;
1224 k
= manager_rtnl_process_address(m
->rtnl
, addr
, m
);
1228 m
->enumerating
= false;
1234 int manager_rtnl_enumerate_routes(Manager
*m
) {
1235 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
1236 sd_netlink_message
*route
;
1242 r
= sd_rtnl_message_new_route(m
->rtnl
, &req
, RTM_GETROUTE
, 0, 0);
1246 r
= sd_netlink_message_request_dump(req
, true);
1250 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
1254 for (route
= reply
; route
; route
= sd_netlink_message_next(route
)) {
1257 m
->enumerating
= true;
1259 k
= manager_rtnl_process_route(m
->rtnl
, route
, m
);
1263 m
->enumerating
= false;
1269 int manager_address_pool_acquire(Manager
*m
, int family
, unsigned prefixlen
, union in_addr_union
*found
) {
1274 assert(prefixlen
> 0);
1277 LIST_FOREACH(address_pools
, p
, m
->address_pools
) {
1278 if (p
->family
!= family
)
1281 r
= address_pool_acquire(p
, prefixlen
, found
);
1289 Link
* manager_find_uplink(Manager
*m
, Link
*exclude
) {
1290 _cleanup_free_
struct local_address
*gateways
= NULL
;
1295 /* Looks for a suitable "uplink", via black magic: an
1296 * interface that is up and where the default route with the
1297 * highest priority points to. */
1299 n
= local_gateways(m
->rtnl
, 0, AF_UNSPEC
, &gateways
);
1301 log_warning_errno(n
, "Failed to determine list of default gateways: %m");
1305 for (i
= 0; i
< n
; i
++) {
1308 link
= hashmap_get(m
->links
, INT_TO_PTR(gateways
[i
].ifindex
));
1310 log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
1314 if (link
== exclude
)
1317 if (link
->operstate
< LINK_OPERSTATE_ROUTABLE
)
1326 void manager_dirty(Manager
*manager
) {
1329 /* the serialized state in /run is no longer up-to-date */
1330 manager
->dirty
= true;