]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: json: append route information
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 14 Nov 2021 06:00:06 +0000 (15:00 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 25 Nov 2021 13:35:35 +0000 (22:35 +0900)
src/network/networkd-json.c

index 05f3384851103b3616aeba9cbfb4c7669e5f6e35..ccae1ba60026eb628e116c9516ebce7c84222bcf 100644 (file)
@@ -7,6 +7,7 @@
 #include "networkd-manager.h"
 #include "networkd-network.h"
 #include "networkd-route-util.h"
+#include "networkd-route.h"
 #include "sort-util.h"
 
 static int address_build_json(Address *address, JsonVariant **ret) {
@@ -84,6 +85,104 @@ finalize:
         return r;
 }
 
+static int route_build_json(Route *route, JsonVariant **ret) {
+        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
+        _cleanup_free_ char *scope = NULL, *protocol = NULL, *table = NULL, *flags = NULL, *state = NULL;
+        Manager *manager;
+        int r;
+
+        assert(route);
+        assert(ret);
+
+        manager = route->link ? route->link->manager : route->manager;
+
+        assert(manager);
+
+        r = route_scope_to_string_alloc(route->scope, &scope);
+        if (r < 0)
+                return r;
+
+        r = route_protocol_to_string_alloc(route->protocol, &protocol);
+        if (r < 0)
+                return r;
+
+        r = manager_get_route_table_to_string(manager, route->table, &table);
+        if (r < 0)
+                return r;
+
+        r = route_flags_to_string_alloc(route->flags, &flags);
+        if (r < 0)
+                return r;
+
+        r = network_config_state_to_string_alloc(route->state, &state);
+        if (r < 0)
+                return r;
+
+        r = json_build(&v, JSON_BUILD_OBJECT(
+                                JSON_BUILD_PAIR_INTEGER("Family", route->family),
+                                JSON_BUILD_PAIR_IN_ADDR("Destination", &route->dst, route->family),
+                                JSON_BUILD_PAIR_UNSIGNED("DestinationPrefixLength", route->dst_prefixlen),
+                                JSON_BUILD_PAIR_IN_ADDR_NON_NULL("Gateway", &route->gw, route->gw_family),
+                                JSON_BUILD_PAIR_IN_ADDR_NON_NULL("Source", &route->src, route->family),
+                                JSON_BUILD_PAIR_CONDITION(in_addr_is_set(route->family, &route->src),
+                                                          "SourcePrefixLength", JSON_BUILD_UNSIGNED(route->src_prefixlen)),
+                                JSON_BUILD_PAIR_IN_ADDR_NON_NULL("PreferredSource", &route->prefsrc, route->family),
+                                JSON_BUILD_PAIR_UNSIGNED("Scope", route->scope),
+                                JSON_BUILD_PAIR_STRING("ScopeString", scope),
+                                JSON_BUILD_PAIR_UNSIGNED("Protocol", route->protocol),
+                                JSON_BUILD_PAIR_STRING("ProtocolString", protocol),
+                                JSON_BUILD_PAIR_UNSIGNED("Type", route->type),
+                                JSON_BUILD_PAIR_STRING("TypeString", route_type_to_string(route->type)),
+                                JSON_BUILD_PAIR_UNSIGNED("Priority", route->priority),
+                                JSON_BUILD_PAIR_UNSIGNED("Table", route->table),
+                                JSON_BUILD_PAIR_STRING("TableString", table),
+                                JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("MTU", route->mtu),
+                                JSON_BUILD_PAIR_UNSIGNED("Preference", route->pref),
+                                JSON_BUILD_PAIR_UNSIGNED("Flags", route->flags),
+                                JSON_BUILD_PAIR_STRING("FlagsString", strempty(flags)),
+                                JSON_BUILD_PAIR_FINITE_USEC("LifetimeUSec", route->lifetime_usec),
+                                JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(route->source)),
+                                JSON_BUILD_PAIR_STRING("ConfigState", state),
+                                JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", &route->provider, route->family)));
+        if (r < 0)
+                return r;
+
+        *ret = TAKE_PTR(v);
+        return 0;
+}
+
+static int routes_build_json(Set *routes, JsonVariant **ret) {
+        JsonVariant **elements;
+        Route *route;
+        size_t n = 0;
+        int r;
+
+        assert(ret);
+
+        if (set_isempty(routes)) {
+                *ret = NULL;
+                return 0;
+        }
+
+        elements = new(JsonVariant*, set_size(routes));
+        if (!elements)
+                return -ENOMEM;
+
+        SET_FOREACH(route, routes) {
+                r = route_build_json(route, elements + n);
+                if (r < 0)
+                        goto finalize;
+                n++;
+        }
+
+        r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("Routes", JSON_BUILD_VARIANT_ARRAY(elements, n))));
+
+finalize:
+        json_variant_unref_many(elements, n);
+        free(elements);
+        return r;
+}
+
 static int network_build_json(Network *network, JsonVariant **ret) {
         assert(ret);
 
@@ -178,6 +277,16 @@ int link_build_json(Link *link, JsonVariant **ret) {
         if (r < 0)
                 return r;
 
+        w = json_variant_unref(w);
+
+        r = routes_build_json(link->routes, &w);
+        if (r < 0)
+                return r;
+
+        r = json_variant_merge(&v, w);
+        if (r < 0)
+                return r;
+
         *ret = TAKE_PTR(v);
         return 0;
 }
@@ -225,5 +334,24 @@ finalize:
 }
 
 int manager_build_json(Manager *manager, JsonVariant **ret) {
-        return links_build_json(manager, ret);
+        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL;
+        int r;
+
+        assert(manager);
+        assert(ret);
+
+        r = links_build_json(manager, &v);
+        if (r < 0)
+                return r;
+
+        r = routes_build_json(manager->routes, &w);
+        if (r < 0)
+                return r;
+
+        r = json_variant_merge(&v, w);
+        if (r < 0)
+                return r;
+
+        *ret = TAKE_PTR(v);
+        return 0;
 }