From 90867f6a3a7274632de83867492468798a8b1616 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 19 Feb 2020 07:40:42 +0100 Subject: [PATCH 1/3] network: introduce bus method forcerenew for DHCP server --- src/network/networkd-link-bus.c | 30 ++++++++++++++++++++++++++++++ src/network/networkd-link-bus.h | 1 + src/network/networkd-manager-bus.c | 5 +++++ 3 files changed, 36 insertions(+) diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index efb72b60e7..62f84faee3 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -572,6 +572,35 @@ int bus_link_method_revert_dns(sd_bus_message *message, void *userdata, sd_bus_e return sd_bus_reply_method_return(message, NULL); } +int bus_link_method_force_renew(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Link *l = userdata; + int r; + + assert(l); + + if (!l->network) + return sd_bus_error_setf(error, BUS_ERROR_UNMANAGED_INTERFACE, + "Interface %s is not managed by systemd-networkd", + l->ifname); + + r = bus_verify_polkit_async(message, CAP_NET_ADMIN, + "org.freedesktop.network1.forcerenew", + NULL, true, UID_INVALID, + &l->manager->polkit_registry, error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Polkit will call us back */ + + if (l->dhcp_server) { + r = sd_dhcp_server_forcerenew(l->dhcp_server); + if (r < 0) + return r; + } + + return sd_bus_reply_method_return(message, NULL); +} + int bus_link_method_renew(sd_bus_message *message, void *userdata, sd_bus_error *error) { Link *l = userdata; int r; @@ -651,6 +680,7 @@ const sd_bus_vtable link_vtable[] = { SD_BUS_METHOD("RevertNTP", NULL, NULL, bus_link_method_revert_ntp, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("RevertDNS", NULL, NULL, bus_link_method_revert_dns, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Renew", NULL, NULL, bus_link_method_renew, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ForceRenew", NULL, NULL, bus_link_method_force_renew, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Reconfigure", NULL, NULL, bus_link_method_reconfigure, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END diff --git a/src/network/networkd-link-bus.h b/src/network/networkd-link-bus.h index 09e4ad68a1..afe0197dbd 100644 --- a/src/network/networkd-link-bus.h +++ b/src/network/networkd-link-bus.h @@ -31,4 +31,5 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v int bus_link_method_revert_ntp(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_link_method_revert_dns(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_link_method_renew(sd_bus_message *message, void *userdata, sd_bus_error *error); +int bus_link_method_force_renew(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c index b7279a582c..e956c5ed9a 100644 --- a/src/network/networkd-manager-bus.c +++ b/src/network/networkd-manager-bus.c @@ -191,6 +191,10 @@ 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_force_renew_link(sd_bus_message *message, void *userdata, sd_bus_error *error) { + return call_link_method(userdata, message, bus_link_method_force_renew, error); +} + static int bus_method_reconfigure_link(sd_bus_message *message, void *userdata, sd_bus_error *error) { return call_link_method(userdata, message, bus_link_method_reconfigure, error); } @@ -249,6 +253,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("ForceRenewLink", "i", NULL, bus_method_force_renew_link, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ReconfigureLink", "i", NULL, bus_method_reconfigure_link, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Reload", NULL, NULL, bus_method_reload, SD_BUS_VTABLE_UNPRIVILEGED), From a32c7a4615fc79bcb2f2c74ee6b23906773edd74 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 19 Feb 2020 07:41:36 +0100 Subject: [PATCH 2/3] network: Add policy in polkit DHCP server forcenenew --- src/network/org.freedesktop.network1.policy | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/network/org.freedesktop.network1.policy b/src/network/org.freedesktop.network1.policy index 9b1895e657..50b0ef0814 100644 --- a/src/network/org.freedesktop.network1.policy +++ b/src/network/org.freedesktop.network1.policy @@ -139,6 +139,17 @@ unix-user:systemd-network + + DHCP server sends force renew message + Authentication is required to send force renew message. + + auth_admin + auth_admin + auth_admin_keep + + unix-user:systemd-network + + Renew dynamic addresses Authentication is required to renew dynamic addresses. From 3efdd6af2ce9da44620f081dc44f556deef7f44f Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 19 Feb 2020 07:42:26 +0100 Subject: [PATCH 3/3] network: Add support in networkctl for DHCP server forcerenew --- man/networkctl.xml | 8 ++++++++ src/network/networkctl.c | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/man/networkctl.xml b/man/networkctl.xml index 52876f3776..4906f7a330 100644 --- a/man/networkctl.xml +++ b/man/networkctl.xml @@ -267,6 +267,14 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR) Takes interface name or index number. + + + forcerenew + + Send a FORCERENEW message to all connected clients, triggering DHCP reconfiguration. + Takes interface name or index number. + + reconfigure diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 078cf1f0cf..931ad82cc1 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -1964,6 +1964,48 @@ static int link_renew(int argc, char *argv[], void *userdata) { return k; } +static int link_force_renew_one(sd_bus *bus, int index, const char *name) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + + r = sd_bus_call_method( + bus, + "org.freedesktop.network1", + "/org/freedesktop/network1", + "org.freedesktop.network1.Manager", + "ForceRenewLink", + &error, + NULL, + "i", index); + if (r < 0) + return log_error_errno(r, "Failed to force renew dynamic configuration of interface %s: %s", + name, bus_error_message(&error, r)); + + return 0; +} + +static int link_force_renew(int argc, char *argv[], void *userdata) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + int index, i, k = 0, r; + + r = sd_bus_open_system(&bus); + if (r < 0) + return log_error_errno(r, "Failed to connect system bus: %m"); + + for (i = 1; i < argc; i++) { + index = resolve_interface_or_warn(&rtnl, argv[i]); + if (index < 0) + return index; + + r = link_force_renew_one(bus, index, argv[i]); + if (r < 0 && k >= 0) + k = r; + } + + return k; +} + static int verb_reload(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; @@ -2050,6 +2092,7 @@ static int help(void) { " label Show current address label entries in the kernel\n" " delete DEVICES... Delete virtual netdevs\n" " renew DEVICES... Renew dynamic configurations\n" + " forcerenew DEVICES... Trigger DHCP reconfiguration of all connected clients\n" " reconfigure DEVICES... Reconfigure interfaces\n" " reload Reload .network and .netdev files\n" "\nOptions:\n" @@ -2151,6 +2194,7 @@ static int networkctl_main(int argc, char *argv[]) { { "label", VERB_ANY, VERB_ANY, 0, list_address_labels }, { "delete", 2, VERB_ANY, 0, link_delete }, { "renew", 2, VERB_ANY, 0, link_renew }, + { "forcerenew", 2, VERB_ANY, 0, link_force_renew }, { "reconfigure", 2, VERB_ANY, 0, verb_reconfigure }, { "reload", 1, 1, 0, verb_reload }, {}