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-netlink.h"
26 #include "sd-daemon.h"
28 #include "conf-parser.h"
29 #include "path-util.h"
30 #include "libudev-private.h"
31 #include "udev-util.h"
32 #include "netlink-util.h"
40 /* use 8 MB for receive socket kernel queue. */
41 #define RCVBUF_SIZE (8*1024*1024)
43 const char* const network_dirs
[] = {
44 "/etc/systemd/network",
45 "/run/systemd/network",
46 "/usr/lib/systemd/network",
48 "/lib/systemd/network",
52 static int setup_default_address_pool(Manager
*m
) {
58 /* Add in the well-known private address ranges. */
60 r
= address_pool_new_from_string(m
, &p
, AF_INET6
, "fc00::", 7);
64 r
= address_pool_new_from_string(m
, &p
, AF_INET
, "192.168.0.0", 16);
68 r
= address_pool_new_from_string(m
, &p
, AF_INET
, "172.16.0.0", 12);
72 r
= address_pool_new_from_string(m
, &p
, AF_INET
, "10.0.0.0", 8);
79 static int on_bus_retry(sd_event_source
*s
, usec_t usec
, void *userdata
) {
80 Manager
*m
= userdata
;
85 m
->bus_retry_event_source
= sd_event_source_unref(m
->bus_retry_event_source
);
87 manager_connect_bus(m
);
92 static int manager_reset_all(Manager
*m
) {
99 HASHMAP_FOREACH(link
, m
->links
, i
) {
100 r
= link_carrier_reset(link
);
102 log_link_warning_errno(link
, r
, "Could not reset carrier: %m");
108 static int match_prepare_for_sleep(sd_bus_message
*message
, void *userdata
, sd_bus_error
*ret_error
) {
109 Manager
*m
= userdata
;
114 r
= sd_bus_message_read(message
, "b", &b
);
116 log_debug_errno(r
, "Failed to parse PrepareForSleep signal: %m");
123 log_debug("Coming back from suspend, resetting all connections...");
125 manager_reset_all(m
);
130 int manager_connect_bus(Manager
*m
) {
135 r
= sd_bus_default_system(&m
->bus
);
137 /* We failed to connect? Yuck, we must be in early
138 * boot. Let's try in 5s again. As soon as we have
139 * kdbus we can stop doing this... */
141 log_debug_errno(r
, "Failed to connect to bus, trying again in 5s: %m");
143 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
);
145 return log_error_errno(r
, "Failed to install bus reconnect time event: %m");
153 r
= sd_bus_add_match(m
->bus
, &m
->prepare_for_sleep_slot
,
155 "sender='org.freedesktop.login1',"
156 "interface='org.freedesktop.login1.Manager',"
157 "member='PrepareForSleep',"
158 "path='/org/freedesktop/login1'",
159 match_prepare_for_sleep
,
162 return log_error_errno(r
, "Failed to add match for PrepareForSleep: %m");
164 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable
, m
);
166 return log_error_errno(r
, "Failed to add manager object vtable: %m");
168 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable
, link_object_find
, m
);
170 return log_error_errno(r
, "Failed to add link object vtable: %m");
172 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/network1/link", link_node_enumerator
, m
);
174 return log_error_errno(r
, "Failed to add link enumerator: %m");
176 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable
, network_object_find
, m
);
178 return log_error_errno(r
, "Failed to add network object vtable: %m");
180 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/network1/network", network_node_enumerator
, m
);
182 return log_error_errno(r
, "Failed to add network enumerator: %m");
184 r
= sd_bus_request_name(m
->bus
, "org.freedesktop.network1", 0);
186 return log_error_errno(r
, "Failed to register name: %m");
188 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
190 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
195 static int manager_udev_process_link(Manager
*m
, struct udev_device
*device
) {
202 if (!streq_ptr(udev_device_get_action(device
), "add"))
205 ifindex
= udev_device_get_ifindex(device
);
207 log_debug("Ignoring udev ADD event for device with invalid ifindex");
211 r
= link_get(m
, ifindex
, &link
);
217 r
= link_initialized(link
, device
);
224 static int manager_dispatch_link_udev(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
225 Manager
*m
= userdata
;
226 struct udev_monitor
*monitor
= m
->udev_monitor
;
227 _cleanup_udev_device_unref_
struct udev_device
*device
= NULL
;
229 device
= udev_monitor_receive_device(monitor
);
233 manager_udev_process_link(m
, device
);
237 static int manager_connect_udev(Manager
*m
) {
240 /* udev does not initialize devices inside containers,
241 * so we rely on them being already initialized before
242 * entering the container */
243 if (detect_container(NULL
) > 0)
246 m
->udev
= udev_new();
250 m
->udev_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev");
251 if (!m
->udev_monitor
)
254 r
= udev_monitor_filter_add_match_subsystem_devtype(m
->udev_monitor
, "net", NULL
);
256 return log_error_errno(r
, "Could not add udev monitor filter: %m");
258 r
= udev_monitor_enable_receiving(m
->udev_monitor
);
260 log_error("Could not enable udev monitor");
264 r
= sd_event_add_io(m
->event
,
265 &m
->udev_event_source
,
266 udev_monitor_get_fd(m
->udev_monitor
),
267 EPOLLIN
, manager_dispatch_link_udev
,
272 r
= sd_event_source_set_description(m
->udev_event_source
, "networkd-udev");
279 static int manager_rtnl_process_link(sd_netlink
*rtnl
, sd_netlink_message
*message
, void *userdata
) {
280 Manager
*m
= userdata
;
282 NetDev
*netdev
= NULL
;
291 if (sd_netlink_message_is_error(message
)) {
292 r
= sd_netlink_message_get_errno(message
);
294 log_warning_errno(r
, "rtnl: Could not receive link: %m");
299 r
= sd_netlink_message_get_type(message
, &type
);
301 log_warning_errno(r
, "rtnl: Could not get message type: %m");
303 } else if (type
!= RTM_NEWLINK
&& type
!= RTM_DELLINK
) {
304 log_warning("rtnl: Received unexpected message type when processing link");
308 r
= sd_rtnl_message_link_get_ifindex(message
, &ifindex
);
310 log_warning_errno(r
, "rtnl: Could not get ifindex from link: %m");
312 } else if (ifindex
<= 0) {
313 log_warning("rtnl: received link message with invalid ifindex: %d", ifindex
);
316 link_get(m
, ifindex
, &link
);
318 r
= sd_netlink_message_read_string(message
, IFLA_IFNAME
, &name
);
320 log_warning_errno(r
, "rtnl: Received link message without ifname: %m");
323 netdev_get(m
, name
, &netdev
);
328 /* link is new, so add it */
329 r
= link_add(m
, message
, &link
);
331 log_warning_errno(r
, "Could not add new link: %m");
337 /* netdev exists, so make sure the ifindex matches */
338 r
= netdev_set_ifindex(netdev
, message
);
340 log_warning_errno(r
, "Could not set ifindex on netdev: %m");
345 r
= link_update(link
, message
);
358 assert_not_reached("Received invalid RTNL message type.");
364 static int systemd_netlink_fd(void) {
365 int n
, fd
, rtnl_fd
= -EINVAL
;
367 n
= sd_listen_fds(true);
371 for (fd
= SD_LISTEN_FDS_START
; fd
< SD_LISTEN_FDS_START
+ n
; fd
++) {
372 if (sd_is_socket(fd
, AF_NETLINK
, SOCK_RAW
, -1) > 0) {
383 static int manager_connect_rtnl(Manager
*m
) {
388 fd
= systemd_netlink_fd();
390 r
= sd_netlink_open(&m
->rtnl
);
392 r
= sd_netlink_open_fd(&m
->rtnl
, fd
);
396 r
= sd_netlink_inc_rcvbuf(m
->rtnl
, RCVBUF_SIZE
);
400 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
404 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, &manager_rtnl_process_link
, m
);
408 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, &manager_rtnl_process_link
, m
);
412 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, &link_rtnl_process_address
, m
);
416 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, &link_rtnl_process_address
, m
);
423 int manager_new(Manager
**ret
) {
424 _cleanup_manager_free_ Manager
*m
= NULL
;
427 m
= new0(Manager
, 1);
431 m
->state_file
= strdup("/run/systemd/netif/state");
435 r
= sd_event_default(&m
->event
);
439 sd_event_set_watchdog(m
->event
, true);
441 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
442 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
444 r
= manager_connect_rtnl(m
);
448 r
= manager_connect_udev(m
);
452 m
->netdevs
= hashmap_new(&string_hash_ops
);
456 LIST_HEAD_INIT(m
->networks
);
458 r
= setup_default_address_pool(m
);
468 void manager_free(Manager
*m
) {
479 udev_monitor_unref(m
->udev_monitor
);
481 sd_bus_unref(m
->bus
);
482 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
483 sd_event_source_unref(m
->udev_event_source
);
484 sd_event_source_unref(m
->bus_retry_event_source
);
485 sd_event_unref(m
->event
);
487 while ((link
= hashmap_first(m
->links
)))
489 hashmap_free(m
->links
);
491 while ((network
= m
->networks
))
492 network_free(network
);
494 hashmap_free(m
->networks_by_name
);
496 while ((netdev
= hashmap_first(m
->netdevs
)))
497 netdev_unref(netdev
);
498 hashmap_free(m
->netdevs
);
500 while ((pool
= m
->address_pools
))
501 address_pool_free(pool
);
503 sd_netlink_unref(m
->rtnl
);
508 static bool manager_check_idle(void *userdata
) {
509 Manager
*m
= userdata
;
515 HASHMAP_FOREACH(link
, m
->links
, i
) {
516 /* we are not woken on udev activity, so let's just wait for the
517 * pending udev event */
518 if (link
->state
== LINK_STATE_PENDING
)
524 /* we are not woken on netork activity, so let's stay around */
525 if (link_lldp_enabled(link
) ||
526 link_ipv4ll_enabled(link
) ||
527 link_dhcp4_server_enabled(link
) ||
528 link_dhcp4_enabled(link
) ||
529 link_dhcp6_enabled(link
))
536 int manager_run(Manager
*m
) {
540 return bus_event_loop_with_idle(
543 "org.freedesktop.network1",
548 /* failed to connect to the bus, so we lose exit-on-idle logic,
549 this should not happen except if dbus is not around at all */
550 return sd_event_loop(m
->event
);
553 int manager_load_config(Manager
*m
) {
556 /* update timestamp */
557 paths_check_timestamp(network_dirs
, &m
->network_dirs_ts_usec
, true);
570 bool manager_should_reload(Manager
*m
) {
571 return paths_check_timestamp(network_dirs
, &m
->network_dirs_ts_usec
, false);
574 int manager_rtnl_enumerate_links(Manager
*m
) {
575 _cleanup_netlink_message_unref_ sd_netlink_message
*req
= NULL
, *reply
= NULL
;
576 sd_netlink_message
*link
;
582 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
586 r
= sd_netlink_message_request_dump(req
, true);
590 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
594 for (link
= reply
; link
; link
= sd_netlink_message_next(link
)) {
597 m
->enumerating
= true;
599 k
= manager_rtnl_process_link(m
->rtnl
, link
, m
);
603 m
->enumerating
= false;
609 int manager_rtnl_enumerate_addresses(Manager
*m
) {
610 _cleanup_netlink_message_unref_ sd_netlink_message
*req
= NULL
, *reply
= NULL
;
611 sd_netlink_message
*addr
;
617 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, 0);
621 r
= sd_netlink_message_request_dump(req
, true);
625 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
629 for (addr
= reply
; addr
; addr
= sd_netlink_message_next(addr
)) {
632 m
->enumerating
= true;
634 k
= link_rtnl_process_address(m
->rtnl
, addr
, m
);
638 m
->enumerating
= false;
644 static int set_put_in_addr(Set
*s
, const struct in_addr
*address
) {
650 r
= in_addr_to_string(AF_INET
, (const union in_addr_union
*) address
, &p
);
654 r
= set_consume(s
, p
);
661 static int set_put_in_addrv(Set
*s
, const struct in_addr
*addresses
, int n
) {
665 assert(n
<= 0 || addresses
);
667 for (i
= 0; i
< n
; i
++) {
668 r
= set_put_in_addr(s
, addresses
+i
);
678 static void print_string_set(FILE *f
, const char *field
, Set
*s
) {
688 SET_FOREACH(p
, s
, i
) {
697 int manager_save(Manager
*m
) {
698 _cleanup_set_free_free_ Set
*dns
= NULL
, *ntp
= NULL
, *domains
= NULL
;
701 _cleanup_free_
char *temp_path
= NULL
;
702 _cleanup_fclose_
FILE *f
= NULL
;
703 LinkOperationalState operstate
= LINK_OPERSTATE_OFF
;
704 const char *operstate_str
;
708 assert(m
->state_file
);
710 /* We add all NTP and DNS server to a set, to filter out duplicates */
711 dns
= set_new(&string_hash_ops
);
715 ntp
= set_new(&string_hash_ops
);
719 domains
= set_new(&string_hash_ops
);
723 HASHMAP_FOREACH(link
, m
->links
, i
) {
724 if (link
->flags
& IFF_LOOPBACK
)
727 if (link
->operstate
> operstate
)
728 operstate
= link
->operstate
;
733 /* First add the static configured entries */
734 r
= set_put_strdupv(dns
, link
->network
->dns
);
738 r
= set_put_strdupv(ntp
, link
->network
->ntp
);
742 r
= set_put_strdupv(domains
, link
->network
->domains
);
746 if (!link
->dhcp_lease
)
749 /* Secondly, add the entries acquired via DHCP */
750 if (link
->network
->dhcp_dns
) {
751 const struct in_addr
*addresses
;
753 r
= sd_dhcp_lease_get_dns(link
->dhcp_lease
, &addresses
);
755 r
= set_put_in_addrv(dns
, addresses
, r
);
758 } else if (r
< 0 && r
!= -ENOENT
)
762 if (link
->network
->dhcp_ntp
) {
763 const struct in_addr
*addresses
;
765 r
= sd_dhcp_lease_get_ntp(link
->dhcp_lease
, &addresses
);
767 r
= set_put_in_addrv(ntp
, addresses
, r
);
770 } else if (r
< 0 && r
!= -ENOENT
)
774 if (link
->network
->dhcp_domains
) {
775 const char *domainname
;
777 r
= sd_dhcp_lease_get_domainname(link
->dhcp_lease
, &domainname
);
779 r
= set_put_strdup(domains
, domainname
);
782 } else if (r
!= -ENOENT
)
787 operstate_str
= link_operstate_to_string(operstate
);
788 assert(operstate_str
);
790 r
= fopen_temporary(m
->state_file
, &f
, &temp_path
);
794 fchmod(fileno(f
), 0644);
797 "# This is private data. Do not parse.\n"
798 "OPER_STATE=%s\n", operstate_str
);
800 print_string_set(f
, "DNS=", dns
);
801 print_string_set(f
, "NTP=", ntp
);
802 print_string_set(f
, "DOMAINS=", domains
);
804 r
= fflush_and_check(f
);
808 if (rename(temp_path
, m
->state_file
) < 0) {
813 if (m
->operational_state
!= operstate
) {
814 m
->operational_state
= operstate
;
815 r
= manager_send_changed(m
, "OperationalState", NULL
);
817 log_error_errno(r
, "Could not emit changed OperationalState: %m");
823 (void) unlink(m
->state_file
);
824 (void) unlink(temp_path
);
826 return log_error_errno(r
, "Failed to save network state to %s: %m", m
->state_file
);
829 int manager_address_pool_acquire(Manager
*m
, int family
, unsigned prefixlen
, union in_addr_union
*found
) {
834 assert(prefixlen
> 0);
837 LIST_FOREACH(address_pools
, p
, m
->address_pools
) {
838 if (p
->family
!= family
)
841 r
= address_pool_acquire(p
, prefixlen
, found
);