summaryrefslogtreecommitdiff
path: root/src/network/networkd-json.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-05-12 22:11:09 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-05-14 09:18:29 +0900
commit54a16efe18289126467c802651dffb9a1c4bf703 (patch)
tree628fe8dd6ae9cd963ff811388c105f6cc105dddd /src/network/networkd-json.c
parent1a3caa49d757ed0b90f86d0f1c3eee55a1588e61 (diff)
downloadsystemd-54a16efe18289126467c802651dffb9a1c4bf703.tar.gz
network: introduce Describe() method for manager and links
Diffstat (limited to 'src/network/networkd-json.c')
-rw-r--r--src/network/networkd-json.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c
new file mode 100644
index 0000000000..7a7fc24ea6
--- /dev/null
+++ b/src/network/networkd-json.c
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "network-util.h"
+#include "networkd-json.h"
+#include "networkd-link.h"
+#include "networkd-manager.h"
+#include "networkd-network.h"
+#include "sort-util.h"
+
+static int network_build_json(Network *network, JsonVariant **ret) {
+ assert(network);
+ assert(ret);
+
+ return json_build(ret, JSON_BUILD_OBJECT(
+ JSON_BUILD_PAIR("NetworkFile", JSON_BUILD_STRING(network->filename))));
+}
+
+static int device_build_json(sd_device *device, JsonVariant **ret) {
+ const char *link = NULL, *path = NULL, *vendor = NULL, *model = NULL;
+
+ assert(device);
+ assert(ret);
+
+ (void) sd_device_get_property_value(device, "ID_NET_LINK_FILE", &link);
+ (void) sd_device_get_property_value(device, "ID_PATH", &path);
+
+ if (sd_device_get_property_value(device, "ID_VENDOR_FROM_DATABASE", &vendor) < 0)
+ (void) sd_device_get_property_value(device, "ID_VENDOR", &vendor);
+
+ if (sd_device_get_property_value(device, "ID_MODEL_FROM_DATABASE", &model) < 0)
+ (void) sd_device_get_property_value(device, "ID_MODEL", &model);
+
+ return json_build(ret, JSON_BUILD_OBJECT(
+ JSON_BUILD_PAIR("LinkFile", JSON_BUILD_STRING(link)),
+ JSON_BUILD_PAIR("Path", JSON_BUILD_STRING(path)),
+ JSON_BUILD_PAIR("Vendor", JSON_BUILD_STRING(vendor)),
+ JSON_BUILD_PAIR("Model", JSON_BUILD_STRING(model))));
+}
+
+int link_build_json(Link *link, JsonVariant **ret) {
+ _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
+ _cleanup_free_ char *type = NULL;
+ int r;
+
+ assert(link);
+ assert(ret);
+
+ r = link_get_type_string(link->sd_device, link->iftype, &type);
+ if (r == -ENOMEM)
+ return r;
+
+ r = json_build(&v, JSON_BUILD_OBJECT(
+ JSON_BUILD_PAIR("Index", JSON_BUILD_INTEGER(link->ifindex)),
+ JSON_BUILD_PAIR("Name", JSON_BUILD_STRING(link->ifname)),
+ JSON_BUILD_PAIR("AlternativeNames", JSON_BUILD_STRV(link->alternative_names)),
+ JSON_BUILD_PAIR("Type", JSON_BUILD_STRING(type)),
+ JSON_BUILD_PAIR("Driver", JSON_BUILD_STRING(link->driver)),
+ JSON_BUILD_PAIR("SetupState", JSON_BUILD_STRING(link_state_to_string(link->state))),
+ JSON_BUILD_PAIR("OperationalState", JSON_BUILD_STRING(link_operstate_to_string(link->operstate))),
+ JSON_BUILD_PAIR("CarrierState", JSON_BUILD_STRING(link_carrier_state_to_string(link->carrier_state))),
+ JSON_BUILD_PAIR("AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->address_state))),
+ JSON_BUILD_PAIR("IPv4AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->ipv4_address_state))),
+ JSON_BUILD_PAIR("IPv6AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->ipv6_address_state)))));
+ if (r < 0)
+ return r;
+
+ if (link->network) {
+ _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
+
+ r = network_build_json(link->network, &w);
+ if (r < 0)
+ return r;
+
+ r = json_variant_merge(&v, w);
+ if (r < 0)
+ return r;
+ }
+
+ if (link->sd_device) {
+ _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
+
+ r = device_build_json(link->sd_device, &w);
+ if (r < 0)
+ return r;
+
+ r = json_variant_merge(&v, w);
+ if (r < 0)
+ return r;
+ }
+
+ *ret = TAKE_PTR(v);
+ return 0;
+}
+
+static int link_json_compare(JsonVariant * const *a, JsonVariant * const *b) {
+ intmax_t index_a, index_b;
+
+ assert(a && *a);
+ assert(b && *b);
+
+ index_a = json_variant_integer(json_variant_by_key(*a, "Index"));
+ index_b = json_variant_integer(json_variant_by_key(*b, "Index"));
+
+ return CMP(index_a, index_b);
+}
+
+int manager_build_json(Manager *manager, JsonVariant **ret) {
+ JsonVariant **elements;
+ Link *link;
+ size_t n = 0;
+ int r;
+
+ assert(manager);
+ assert(ret);
+
+ elements = new(JsonVariant*, hashmap_size(manager->links));
+ if (!elements)
+ return -ENOMEM;
+
+ HASHMAP_FOREACH(link, manager->links) {
+ r = link_build_json(link, elements + n);
+ if (r < 0)
+ goto finalize;
+ n++;
+ }
+
+ typesafe_qsort(elements, n, link_json_compare);
+
+ r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Interfaces", JSON_BUILD_VARIANT_ARRAY(elements, n))));
+
+finalize:
+ json_variant_unref_many(elements, n);
+ free(elements);
+ return r;
+}