mirror of
https://github.com/systemd/systemd.git
synced 2024-12-26 03:22:00 +03:00
network: add Reload() dbus method
This commit is contained in:
parent
6f3ad94590
commit
7f06b3e1b9
@ -23,6 +23,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
|
||||
fflush(f);
|
||||
assert_se(manager_new(&manager) >= 0);
|
||||
(void) network_load_one(manager, network_config);
|
||||
(void) network_load_one(manager, &manager->networks, network_config);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/capability.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-common-errors.h"
|
||||
@ -11,6 +12,7 @@
|
||||
#include "networkd-manager.h"
|
||||
#include "path-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
|
||||
static int method_list_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
@ -187,6 +189,34 @@ static int bus_method_renew_link(sd_bus_message *message, void *userdata, sd_bus
|
||||
return call_link_method(userdata, message, bus_link_method_renew, error);
|
||||
}
|
||||
|
||||
static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
Manager *manager = userdata;
|
||||
Iterator i;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||
"org.freedesktop.network1.reload",
|
||||
NULL, true, UID_INVALID,
|
||||
&manager->polkit_registry, error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Polkit will call us back */
|
||||
|
||||
r = network_reload(manager);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
HASHMAP_FOREACH(link, manager->links, i) {
|
||||
r = link_reconfigure(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
}
|
||||
|
||||
const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
@ -209,6 +239,7 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_METHOD("RevertLinkNTP", "i", NULL, bus_method_revert_link_ntp, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("RevertLinkDNS", "i", NULL, bus_method_revert_link_dns, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("RenewLink", "i", NULL, bus_method_renew_link, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Reload", NULL, NULL, bus_method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
@ -1860,7 +1860,7 @@ int manager_load_config(Manager *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = network_load(m);
|
||||
r = network_load(m, &m->networks);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -314,7 +314,7 @@ int network_verify(Network *network) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int network_load_one(Manager *manager, const char *filename) {
|
||||
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
|
||||
_cleanup_free_ char *fname = NULL, *name = NULL;
|
||||
_cleanup_(network_unrefp) Network *network = NULL;
|
||||
_cleanup_fclose_ FILE *file = NULL;
|
||||
@ -488,36 +488,42 @@ int network_load_one(Manager *manager, const char *filename) {
|
||||
log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
|
||||
network->filename);
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(&manager->networks, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_hashmap_put(manager->networks, network->name, network);
|
||||
if (r < 0)
|
||||
return r;
|
||||
struct stat stats;
|
||||
if (stat(filename, &stats) < 0)
|
||||
return -errno;
|
||||
network->timestamp = timespec_load(&stats.st_mtim);
|
||||
|
||||
if (network_verify(network) < 0)
|
||||
/* Ignore .network files that do not match the conditions. */
|
||||
return 0;
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(networks, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_hashmap_put(*networks, network->name, network);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
network = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int network_load(Manager *manager) {
|
||||
int network_load(Manager *manager, OrderedHashmap **networks) {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
char **f;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
ordered_hashmap_clear_with_destructor(manager->networks, network_unref);
|
||||
ordered_hashmap_clear_with_destructor(*networks, network_unref);
|
||||
|
||||
r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate network files: %m");
|
||||
|
||||
STRV_FOREACH(f, files) {
|
||||
r = network_load_one(manager, *f);
|
||||
r = network_load_one(manager, networks, *f);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to load %s, ignoring: %m", *f);
|
||||
}
|
||||
@ -525,6 +531,48 @@ int network_load(Manager *manager) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int network_reload(Manager *manager) {
|
||||
OrderedHashmap *new_networks = NULL;
|
||||
Network *n, *old;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
r = network_load(manager, &new_networks);
|
||||
if (r < 0)
|
||||
goto failure;
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(n, new_networks, i) {
|
||||
r = network_get_by_name(manager, n->name, &old);
|
||||
if (r < 0)
|
||||
continue; /* The .network file is new. */
|
||||
|
||||
if (n->timestamp != old->timestamp)
|
||||
continue; /* The .network file is modified. */
|
||||
|
||||
if (!streq(n->filename, old->filename))
|
||||
continue;
|
||||
|
||||
r = ordered_hashmap_replace(new_networks, old->name, old);
|
||||
if (r < 0)
|
||||
goto failure;
|
||||
|
||||
network_ref(old);
|
||||
network_unref(n);
|
||||
}
|
||||
|
||||
ordered_hashmap_free_with_destructor(manager->networks, network_unref);
|
||||
manager->networks = new_networks;
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
ordered_hashmap_free_with_destructor(new_networks, network_unref);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static Network *network_free(Network *network) {
|
||||
IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
|
||||
RoutingPolicyRule *rule;
|
||||
@ -615,13 +663,9 @@ static Network *network_free(Network *network) {
|
||||
hashmap_free(network->prefixes_by_section);
|
||||
hashmap_free(network->rules_by_section);
|
||||
|
||||
if (network->manager) {
|
||||
if (network->manager->networks && network->name)
|
||||
ordered_hashmap_remove(network->manager->networks, network->name);
|
||||
|
||||
if (network->manager->duids_requesting_uuid)
|
||||
set_remove(network->manager->duids_requesting_uuid, &network->duid);
|
||||
}
|
||||
if (network->manager &&
|
||||
network->manager->duids_requesting_uuid)
|
||||
set_remove(network->manager->duids_requesting_uuid, &network->duid);
|
||||
|
||||
free(network->name);
|
||||
|
||||
|
@ -54,6 +54,7 @@ struct Network {
|
||||
|
||||
char *filename;
|
||||
char *name;
|
||||
usec_t timestamp;
|
||||
|
||||
unsigned n_ref;
|
||||
|
||||
@ -283,8 +284,9 @@ Network *network_ref(Network *network);
|
||||
Network *network_unref(Network *network);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_unref);
|
||||
|
||||
int network_load(Manager *manager);
|
||||
int network_load_one(Manager *manager, const char *filename);
|
||||
int network_load(Manager *manager, OrderedHashmap **networks);
|
||||
int network_reload(Manager *manager);
|
||||
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename);
|
||||
int network_verify(Network *network);
|
||||
|
||||
int network_get_by_name(Manager *manager, const char *name, Network **ret);
|
||||
|
@ -150,4 +150,15 @@
|
||||
<annotate key="org.freedesktop.policykit.owner">unix-user:systemd-network</annotate>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.network1.reload">
|
||||
<description gettext-domain="systemd">Reload network settings</description>
|
||||
<message gettext-domain="systemd">Authentication is required to reload network settings.</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.owner">unix-user:systemd-network</annotate>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
||||
|
Loading…
Reference in New Issue
Block a user