From e9b0614e1d653a733c76a3246fd800566e3e1561 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 5 Jun 2023 16:48:43 +0000 Subject: [PATCH] ports: Add bus method to export port information as JSON Signed-off-by: Michael Tremer --- Makefile.am | 1 + src/networkd/port-bonding.c | 16 +++++++++++ src/networkd/port-bus.c | 46 +++++++++++++++++++++++++++++++ src/networkd/port-vlan.c | 28 +++++++++++++++++++ src/networkd/port.c | 55 +++++++++++++++++++++++++++++++++++++ src/networkd/port.h | 9 ++++++ 6 files changed, 155 insertions(+) diff --git a/Makefile.am b/Makefile.am index 466ad735..f4c22b48 100644 --- a/Makefile.am +++ b/Makefile.am @@ -319,6 +319,7 @@ dist_networkd_SOURCES = \ src/networkd/daemon-bus.h \ src/networkd/devmon.c \ src/networkd/devmon.h \ + src/networkd/json.h \ src/networkd/link.c \ src/networkd/link.h \ src/networkd/links.c \ diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c index 6bddc430..bbc3fb7a 100644 --- a/src/networkd/port-bonding.c +++ b/src/networkd/port-bonding.c @@ -100,6 +100,19 @@ static int nw_port_bonding_create_link(nw_port* port, sd_netlink_message* m) { return 0; } +static int nw_port_bonding_to_json(nw_port* port, struct json_object* o) { + int r; + + // Add mode + r = json_object_add_string(o, "BondingMode", + nw_port_bonding_mode_to_string(port->bonding.mode)); + if (r < 0) + goto ERROR; + +ERROR: + return r; +} + const nw_port_info_t nw_port_info_bonding = { .kind = "bond", @@ -111,6 +124,9 @@ const nw_port_info_t nw_port_info_bonding = { // Link .create_link = nw_port_bonding_create_link, + + // JSON + .to_json = nw_port_bonding_to_json, }, }; diff --git a/src/networkd/port-bus.c b/src/networkd/port-bus.c index 996be920..41f8ec41 100644 --- a/src/networkd/port-bus.c +++ b/src/networkd/port-bus.c @@ -20,10 +20,12 @@ #include #include +#include #include "address.h" #include "bus.h" #include "daemon.h" +#include "json.h" #include "logging.h" #include "port.h" #include "port-bus.h" @@ -105,6 +107,46 @@ ERROR: return r; } +static int nw_port_bus_describe(sd_bus_message* message, void* data, + sd_bus_error* error) { + sd_bus_message* reply = NULL; + struct json_object* json = NULL; + char* text = NULL; + int r; + + nw_port* port = (nw_port*)data; + + // Export all data to JSON + r = nw_port_to_json(port, &json); + if (r < 0) + goto ERROR; + + // Convert JSON to string + r = json_to_string(json, &text, NULL); + if (r < 0) + goto ERROR; + + // Create a reply message + r = sd_bus_message_new_method_return(message, &reply); + if (r < 0) + goto ERROR; + + r = sd_bus_message_append(reply, "s", text); + if (r < 0) + goto ERROR; + + // Send the reply + r = sd_bus_send(NULL, reply, NULL); + +ERROR: + if (reply) + sd_bus_message_unref(reply); + if (text) + free(text); + + return r; +} + static const sd_bus_vtable port_vtable[] = { SD_BUS_VTABLE_START(0), @@ -112,6 +154,10 @@ static const sd_bus_vtable port_vtable[] = { SD_BUS_PROPERTY("Address", "s", nw_port_bus_get_address, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + // Operations + SD_BUS_METHOD_WITH_ARGS("Describe", SD_BUS_NO_ARGS, SD_BUS_RESULT("s", json), + nw_port_bus_describe, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_VTABLE_END }; diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c index 5e970e91..ac4a5b4a 100644 --- a/src/networkd/port-vlan.c +++ b/src/networkd/port-vlan.c @@ -22,6 +22,7 @@ #include "config.h" #include "daemon.h" +#include "json.h" #include "logging.h" #include "port.h" #include "port-vlan.h" @@ -77,6 +78,30 @@ static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) { return 0; } +static int nw_port_vlan_to_json(nw_port* port, struct json_object* o) { + nw_port* parent = NULL; + int r; + + // Add the VLAN ID + r = json_object_add_int64(o, "VLANId", port->vlan.id); + if (r < 0) + goto ERROR; + + // Fetch the parent + parent = nw_port_get_parent_port(port); + if (parent) { + r = json_object_add_string(o, "VLANParentPort", nw_port_name(parent)); + if (r < 0) + goto ERROR; + } + +ERROR: + if (parent) + nw_port_unref(parent); + + return r; +} + const nw_port_info_t nw_port_info_vlan = { .kind = "vlan", @@ -90,6 +115,9 @@ const nw_port_info_t nw_port_info_vlan = { // Link .create_link = nw_port_vlan_create_link, + + // JSON + .to_json = nw_port_vlan_to_json, }, }; diff --git a/src/networkd/port.c b/src/networkd/port.c index c9440d4f..a7fb826a 100644 --- a/src/networkd/port.c +++ b/src/networkd/port.c @@ -27,6 +27,7 @@ #include "address.h" #include "config.h" +#include "json.h" #include "link.h" #include "logging.h" #include "port.h" @@ -645,3 +646,57 @@ int nw_port_check_type(nw_port* port, const nw_port_type_t type) { errno = ENOTSUP; return -errno; } + +/* + JSON +*/ +int nw_port_to_json(nw_port* port, struct json_object** object) { + char* address = NULL; + int r; + + // Create a new JSON object + struct json_object* o = json_object_new_object(); + if (!o) { + r = -errno; + goto ERROR; + } + + // Add name + r = json_object_add_string(o, "Name", port->name); + if (r < 0) + goto ERROR; + + // Add Type + r = json_object_add_string(o, "Type", NW_PORT_INFO(port)->kind); + if (r < 0) + goto ERROR; + + // Add address + address = nw_address_to_string(&port->address); + if (address) { + r = json_object_add_string(o, "Address", address); + if (r < 0) + goto ERROR; + } + + // Call custom stuff + if (NW_PORT_OPS(port)->to_json) { + r = NW_PORT_OPS(port)->to_json(port, o); + if (r < 0) + goto ERROR; + } + + // Success + r = 0; + + // Return a reference to the created object + *object = json_object_ref(o); + +ERROR: + if (address) + free(address); + if (o) + json_object_unref(o); + + return r; +} diff --git a/src/networkd/port.h b/src/networkd/port.h index 38d19d1c..e16b9572 100644 --- a/src/networkd/port.h +++ b/src/networkd/port.h @@ -21,6 +21,8 @@ #ifndef NETWORKD_PORT_H #define NETWORKD_PORT_H +#include + #include #ifndef IF_NAMESIZE @@ -47,6 +49,7 @@ typedef struct nw_port_info nw_port_info_t; #include "address.h" #include "config.h" #include "daemon.h" +#include "json.h" #include "port-bonding.h" #include "port-vlan.h" @@ -65,6 +68,9 @@ struct nw_port_info { // Link int (*create_link)(nw_port* port, sd_netlink_message* message); int (*destroy_link)(nw_port* port); + + // JSON + int (*to_json)(nw_port* port, struct json_object* object); } ops; }; @@ -132,4 +138,7 @@ const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port); int __nw_port_update_stats(nw_daemon* daemon, nw_port* port, void* data); int nw_port_update_stats(nw_port* port); +// JSON +int nw_port_to_json(nw_port* port, struct json_object** object); + #endif /* NETWORKD_PORT_H */ -- 2.47.2