diff options
Diffstat (limited to 'src/network/networkd-manager.c')
-rw-r--r-- | src/network/networkd-manager.c | 138 |
1 files changed, 91 insertions, 47 deletions
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index c09dcfb..4ec4550 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -23,6 +23,7 @@ #include "device-private.h" #include "device-util.h" #include "dns-domain.h" +#include "env-util.h" #include "fd-util.h" #include "fileio.h" #include "firewall-util.h" @@ -36,8 +37,9 @@ #include "networkd-dhcp-server-bus.h" #include "networkd-dhcp6.h" #include "networkd-link-bus.h" -#include "networkd-manager-bus.h" #include "networkd-manager.h" +#include "networkd-manager-bus.h" +#include "networkd-manager-varlink.h" #include "networkd-neighbor.h" #include "networkd-network-bus.h" #include "networkd-nexthop.h" @@ -163,7 +165,6 @@ static int manager_connect_bus(Manager *m) { static int manager_process_uevent(sd_device_monitor *monitor, sd_device *device, void *userdata) { Manager *m = ASSERT_PTR(userdata); sd_device_action_t action; - const char *s; int r; assert(device); @@ -172,20 +173,12 @@ static int manager_process_uevent(sd_device_monitor *monitor, sd_device *device, if (r < 0) return log_device_warning_errno(device, r, "Failed to get udev action, ignoring: %m"); - r = sd_device_get_subsystem(device, &s); - if (r < 0) - return log_device_warning_errno(device, r, "Failed to get subsystem, ignoring: %m"); - - if (streq(s, "net")) + if (device_in_subsystem(device, "net")) r = manager_udev_process_link(m, device, action); - else if (streq(s, "ieee80211")) + else if (device_in_subsystem(device, "ieee80211")) r = manager_udev_process_wiphy(m, device, action); - else if (streq(s, "rfkill")) + else if (device_in_subsystem(device, "rfkill")) r = manager_udev_process_rfkill(m, device, action); - else { - log_device_debug(device, "Received device with unexpected subsystem \"%s\", ignoring.", s); - return 0; - } if (r < 0) log_device_warning_errno(device, r, "Failed to process \"%s\" uevent, ignoring: %m", device_action_to_string(action)); @@ -429,24 +422,13 @@ static int manager_connect_rtnl(Manager *m, int fd) { return manager_setup_rtnl_filter(m); } -static int manager_dirty_handler(sd_event_source *s, void *userdata) { - Manager *m = ASSERT_PTR(userdata); - Link *link; - int r; - - if (m->dirty) { - r = manager_save(m); - if (r < 0) - log_warning_errno(r, "Failed to update state file %s, ignoring: %m", m->state_file); - } - - SET_FOREACH(link, m->dirty_links) { - r = link_save_and_clean(link); - if (r < 0) - log_link_warning_errno(link, r, "Failed to update link state file %s, ignoring: %m", link->state_file); - } +static int manager_post_handler(sd_event_source *s, void *userdata) { + Manager *manager = ASSERT_PTR(userdata); - return 1; + (void) manager_process_remove_requests(manager); + (void) manager_process_requests(manager); + (void) manager_clean_all(manager); + return 0; } static int signal_terminate_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { @@ -472,7 +454,7 @@ static int signal_restart_callback(sd_event_source *s, const struct signalfd_sig static int signal_reload_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { Manager *m = ASSERT_PTR(userdata); - manager_reload(m); + (void) manager_reload(m, /* message = */ NULL); return 0; } @@ -522,11 +504,7 @@ int manager_setup(Manager *m) { if (r < 0) log_debug_errno(r, "Failed allocate memory pressure event source, ignoring: %m"); - r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m); - if (r < 0) - return r; - - r = sd_event_add_post(m->event, NULL, manager_process_requests, m); + r = sd_event_add_post(m->event, NULL, manager_post_handler, m); if (r < 0) return r; @@ -545,6 +523,10 @@ int manager_setup(Manager *m) { if (m->test_mode) return 0; + r = manager_connect_varlink(m); + if (r < 0) + return r; + r = manager_connect_bus(m); if (r < 0) return r; @@ -576,6 +558,29 @@ int manager_setup(Manager *m) { return 0; } +static int persistent_storage_open(void) { + _cleanup_close_ int fd = -EBADF; + int r; + + r = getenv_bool("SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY"); + if (r < 0 && r != -ENXIO) + return log_debug_errno(r, "Failed to parse $SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY environment variable, ignoring: %m"); + if (r <= 0) + return -EBADF; + + fd = open("/var/lib/systemd/network/", O_CLOEXEC | O_DIRECTORY); + if (fd < 0) + return log_debug_errno(errno, "Failed to open /var/lib/systemd/network/, ignoring: %m"); + + r = fd_is_read_only_fs(fd); + if (r < 0) + return log_debug_errno(r, "Failed to check if /var/lib/systemd/network/ is writable: %m"); + if (r > 0) + return log_debug_errno(SYNTHETIC_ERRNO(EROFS), "The directory /var/lib/systemd/network/ is on read-only filesystem."); + + return TAKE_FD(fd); +} + int manager_new(Manager **ret, bool test_mode) { _cleanup_(manager_freep) Manager *m = NULL; @@ -591,10 +596,17 @@ int manager_new(Manager **ret, bool test_mode) { .online_state = _LINK_ONLINE_STATE_INVALID, .manage_foreign_routes = true, .manage_foreign_rules = true, + .manage_foreign_nexthops = true, .ethtool_fd = -EBADF, + .persistent_storage_fd = persistent_storage_open(), + .dhcp_use_domains = _USE_DOMAINS_INVALID, + .dhcp6_use_domains = _USE_DOMAINS_INVALID, + .ndisc_use_domains = _USE_DOMAINS_INVALID, .dhcp_duid.type = DUID_TYPE_EN, .dhcp6_duid.type = DUID_TYPE_EN, .duid_product_uuid.type = DUID_TYPE_UUID, + .dhcp_server_persist_leases = true, + .ip_forwarding = { -1, -1, }, }; *ret = TAKE_PTR(m); @@ -613,6 +625,7 @@ Manager* manager_free(Manager *m) { (void) link_stop_engines(link, true); m->request_queue = ordered_set_free(m->request_queue); + m->remove_request_queue = ordered_set_free(m->remove_request_queue); m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref); m->new_wlan_ifindices = set_free(m->new_wlan_ifindices); @@ -648,21 +661,23 @@ Manager* manager_free(Manager *m) { * set_free() must be called after the above sd_netlink_unref(). */ m->routes = set_free(m->routes); - m->nexthops = set_free(m->nexthops); m->nexthops_by_id = hashmap_free(m->nexthops_by_id); + m->nexthop_ids = set_free(m->nexthop_ids); sd_event_source_unref(m->speed_meter_event_source); sd_event_unref(m->event); sd_device_monitor_unref(m->device_monitor); - bus_verify_polkit_async_registry_free(m->polkit_registry); + manager_varlink_done(m); + hashmap_free(m->polkit_registry); sd_bus_flush_close_unref(m->bus); free(m->dynamic_timezone); free(m->dynamic_hostname); safe_close(m->ethtool_fd); + safe_close(m->persistent_storage_fd); m->fw_ctx = fw_ctx_free(m->fw_ctx); @@ -675,6 +690,8 @@ int manager_start(Manager *m) { assert(m); + manager_set_sysctl(m); + r = manager_start_speed_meter(m); if (r < 0) return log_error_errno(r, "Failed to initialize speed meter: %m"); @@ -708,7 +725,15 @@ int manager_load_config(Manager *m) { if (r < 0) return r; - return manager_build_dhcp_pd_subnet_ids(m); + r = manager_build_dhcp_pd_subnet_ids(m); + if (r < 0) + return r; + + r = manager_build_nexthop_ids(m); + if (r < 0) + return r; + + return 0; } int manager_enumerate_internal( @@ -752,6 +777,20 @@ static int manager_enumerate_links(Manager *m) { if (r < 0) return r; + r = manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link); + if (r < 0) + return r; + + req = sd_netlink_message_unref(req); + + r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0); + if (r < 0) + return r; + + r = sd_rtnl_message_link_set_family(req, AF_BRIDGE); + if (r < 0) + return r; + return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link); } @@ -853,6 +892,9 @@ static int manager_enumerate_nexthop(Manager *m) { assert(m); assert(m->rtnl); + if (!m->manage_foreign_nexthops) + return 0; + r = sd_rtnl_message_new_nexthop(m->rtnl, &req, RTM_GETNEXTHOP, 0, 0); if (r < 0) return r; @@ -1076,16 +1118,13 @@ int manager_set_timezone(Manager *m, const char *tz) { return 0; } -int manager_reload(Manager *m) { +int manager_reload(Manager *m, sd_bus_message *message) { Link *link; int r; assert(m); - (void) sd_notifyf(/* unset= */ false, - "RELOADING=1\n" - "STATUS=Reloading configuration...\n" - "MONOTONIC_USEC=" USEC_FMT, now(CLOCK_MONOTONIC)); + (void) notify_reloading(); r = netdev_load(m, /* reload= */ true); if (r < 0) @@ -1096,9 +1135,14 @@ int manager_reload(Manager *m) { goto finish; HASHMAP_FOREACH(link, m->links_by_index) { - r = link_reconfigure(link, /* force = */ false); - if (r < 0) - goto finish; + if (message) + r = link_reconfigure_on_bus_method_reload(link, message); + else + r = link_reconfigure(link, /* force = */ false); + if (r < 0) { + log_link_warning_errno(link, r, "Failed to reconfigure the interface: %m"); + link_enter_failed(link); + } } r = 0; |