From f8da534e25dbdde2ec4d4390303cdf6a431643d9 Mon Sep 17 00:00:00 2001 From: pelaufer Date: Sat, 2 Sep 2023 14:52:35 -0600 Subject: [PATCH] Adding dhcp client and dhcp6 client dbus status interface --- src/network/meson.build | 2 + src/network/networkd-dhcp4-bus.c | 78 ++++++++++++++++++++++++++++++ src/network/networkd-dhcp4-bus.h | 10 ++++ src/network/networkd-dhcp4.c | 5 ++ src/network/networkd-dhcp6-bus.c | 76 +++++++++++++++++++++++++++++ src/network/networkd-dhcp6-bus.h | 10 ++++ src/network/networkd-dhcp6.c | 6 +++ src/network/networkd-link-bus.c | 6 +++ src/network/networkd-manager-bus.c | 5 +- 9 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/network/networkd-dhcp4-bus.c create mode 100644 src/network/networkd-dhcp4-bus.h create mode 100644 src/network/networkd-dhcp6-bus.c create mode 100644 src/network/networkd-dhcp6-bus.h diff --git a/src/network/meson.build b/src/network/meson.build index 7d0e5d63457..2ca9eac714b 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -43,7 +43,9 @@ sources = files( 'networkd-dhcp-server-bus.c', 'networkd-dhcp-server-static-lease.c', 'networkd-dhcp-server.c', + 'networkd-dhcp4-bus.c', 'networkd-dhcp4.c', + 'networkd-dhcp6-bus.c', 'networkd-dhcp6.c', 'networkd-ipv4acd.c', 'networkd-ipv4ll.c', diff --git a/src/network/networkd-dhcp4-bus.c b/src/network/networkd-dhcp4-bus.c new file mode 100644 index 00000000000..cb88627d200 --- /dev/null +++ b/src/network/networkd-dhcp4-bus.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "sd-dhcp-client.h" + +#include "alloc-util.h" +#include "bus-common-errors.h" +#include "bus-util.h" +#include "dhcp-client-internal.h" +#include "dhcp-protocol.h" +#include "networkd-dhcp4-bus.h" +#include "networkd-link-bus.h" +#include "networkd-manager.h" +#include "string-table.h" +#include "strv.h" + +static int property_get_dhcp_client_state( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Link *l = ASSERT_PTR(userdata); + sd_dhcp_client *c; + + assert(reply); + + c = l->dhcp_client; + if (!c) + return sd_bus_message_append(reply, "s", "disabled"); + + return sd_bus_message_append(reply, "s", dhcp_state_to_string(dhcp_client_get_state(c))); +} + +static int dhcp_client_emit_changed(Link *link, const char *property, ...) { + _cleanup_free_ char *path = NULL; + char **l; + + assert(link); + + if (sd_bus_is_ready(link->manager->bus) <= 0) + return 0; + + path = link_bus_path(link); + if (!path) + return log_oom(); + + l = strv_from_stdarg_alloca(property); + + return sd_bus_emit_properties_changed_strv( + link->manager->bus, + path, + "org.freedesktop.network1.DHCPv4Client", + l); +} + +int dhcp_client_callback_bus(sd_dhcp_client *c, int event, void *userdata) { + Link *l = ASSERT_PTR(userdata); + + return dhcp_client_emit_changed(l, "State", NULL); +} + +static const sd_bus_vtable dhcp_client_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_PROPERTY("State", "s", property_get_dhcp_client_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation dhcp_client_object = { + "/org/freedesktop/network1/link", + "org.freedesktop.network1.DHCPv4Client", + .fallback_vtables = BUS_FALLBACK_VTABLES({dhcp_client_vtable, link_object_find}), + .node_enumerator = link_node_enumerator, +}; diff --git a/src/network/networkd-dhcp4-bus.h b/src/network/networkd-dhcp4-bus.h new file mode 100644 index 00000000000..482e824c0ac --- /dev/null +++ b/src/network/networkd-dhcp4-bus.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "sd-dhcp-client.h" + +#include "networkd-link-bus.h" + +extern const BusObjectImplementation dhcp_client_object; + +int dhcp_client_callback_bus(sd_dhcp_client *client, int event, void *userdata); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 9dcd37e11c6..f952d6dfbcc 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -13,6 +13,7 @@ #include "network-internal.h" #include "networkd-address.h" #include "networkd-dhcp-prefix-delegation.h" +#include "networkd-dhcp4-bus.h" #include "networkd-dhcp4.h" #include "networkd-ipv4acd.h" #include "networkd-link.h" @@ -1482,6 +1483,10 @@ static int dhcp4_configure(Link *link) { if (r < 0) return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for broadcast: %m"); + r = dhcp_client_set_state_callback(link->dhcp_client, dhcp_client_callback_bus, link); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set state change callback: %m"); + if (link->mtu > 0) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) diff --git a/src/network/networkd-dhcp6-bus.c b/src/network/networkd-dhcp6-bus.c new file mode 100644 index 00000000000..a225877373e --- /dev/null +++ b/src/network/networkd-dhcp6-bus.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "alloc-util.h" +#include "bus-common-errors.h" +#include "bus-util.h" +#include "dhcp6-client-internal.h" +#include "dhcp6-protocol.h" +#include "networkd-dhcp6-bus.h" +#include "networkd-link-bus.h" +#include "networkd-manager.h" +#include "string-table.h" +#include "strv.h" + +static int property_get_dhcp6_client_state( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Link *l = ASSERT_PTR(userdata); + sd_dhcp6_client *c; + + assert(reply); + + c = l->dhcp6_client; + if (!c) + return sd_bus_message_append(reply, "s", "disabled"); + + return sd_bus_message_append(reply, "s", dhcp6_state_to_string(dhcp6_client_get_state(c))); +} + +static int dhcp6_client_emit_changed(Link *link, const char *property, ...) { + _cleanup_free_ char *path = NULL; + char **l; + + assert(link); + + if (sd_bus_is_ready(link->manager->bus) <= 0) + return 0; + + path = link_bus_path(link); + if (!path) + return log_oom(); + + l = strv_from_stdarg_alloca(property); + + return sd_bus_emit_properties_changed_strv( + link->manager->bus, + path, + "org.freedesktop.network1.DHCPv6Client", + l); +} + +void dhcp6_client_callback_bus(sd_dhcp6_client *c, int event, void *userdata) { + Link *l = ASSERT_PTR(userdata); + + dhcp6_client_emit_changed(l, "State", NULL); +} + +static const sd_bus_vtable dhcp6_client_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_PROPERTY("State", "s", property_get_dhcp6_client_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + + SD_BUS_VTABLE_END +}; + +const BusObjectImplementation dhcp6_client_object = { + "/org/freedesktop/network1/link", + "org.freedesktop.network1.DHCPv6Client", + .fallback_vtables = BUS_FALLBACK_VTABLES({dhcp6_client_vtable, link_object_find}), + .node_enumerator = link_node_enumerator, +}; diff --git a/src/network/networkd-dhcp6-bus.h b/src/network/networkd-dhcp6-bus.h new file mode 100644 index 00000000000..76a6b727aa8 --- /dev/null +++ b/src/network/networkd-dhcp6-bus.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "sd-dhcp6-client.h" + +#include "networkd-link-bus.h" + +extern const BusObjectImplementation dhcp6_client_object; + +void dhcp6_client_callback_bus(sd_dhcp6_client *client, int event, void *userdata); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 95b13ca93c6..57e10872116 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -5,11 +5,13 @@ #include "sd-dhcp6-client.h" +#include "dhcp6-client-internal.h" #include "hashmap.h" #include "hostname-setup.h" #include "hostname-util.h" #include "networkd-address.h" #include "networkd-dhcp-prefix-delegation.h" +#include "networkd-dhcp6-bus.h" #include "networkd-dhcp6.h" #include "networkd-link.h" #include "networkd-manager.h" @@ -699,6 +701,10 @@ static int dhcp6_configure(Link *link) { if (r < 0) return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set callback: %m"); + r = dhcp6_client_set_state_callback(client, dhcp6_client_callback_bus, link); + if (r < 0) + return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set state change callback: %m"); + r = sd_dhcp6_client_set_prefix_delegation(client, link->network->dhcp6_use_pd_prefix); if (r < 0) return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to %s requesting prefixes to be delegated: %m", diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index e9c18f0fd01..06749307832 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -862,6 +862,12 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void (!link->dhcp_server || sd_dhcp_server_is_in_relay_mode(link->dhcp_server))) return 0; + if (streq(interface, "org.freedesktop.network1.DHCPv4Client") && !link->dhcp_client) + return 0; + + if (streq(interface, "org.freedesktop.network1.DHCPv6Client") && !link->dhcp6_client) + return 0; + *found = link; return 1; diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c index 67f951df69d..7813a3173a5 100644 --- a/src/network/networkd-manager-bus.c +++ b/src/network/networkd-manager-bus.c @@ -9,6 +9,8 @@ #include "bus-message-util.h" #include "bus-polkit.h" #include "networkd-dhcp-server-bus.h" +#include "networkd-dhcp4-bus.h" +#include "networkd-dhcp6-bus.h" #include "networkd-json.h" #include "networkd-link-bus.h" #include "networkd-link.h" @@ -413,5 +415,6 @@ const BusObjectImplementation manager_object = { "/org/freedesktop/network1", "org.freedesktop.network1.Manager", .vtables = BUS_VTABLES(manager_vtable), - .children = BUS_IMPLEMENTATIONS(&dhcp_server_object, &link_object, &network_object), + .children = BUS_IMPLEMENTATIONS(&dhcp_server_object, &dhcp_client_object, + &dhcp6_client_object, &link_object, &network_object), }; -- 2.39.5