summaryrefslogtreecommitdiffstats
path: root/src/network/networkd-json.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-11-14 03:59:44 +0100
committerGitHub <noreply@github.com>2024-11-14 03:59:44 +0100
commitbdc6edbdabfa0c8844d00f9863ec1d81d7804cc5 (patch)
treec62ad9e23c9391ff4a40bbc42da23156e960c4aa /src/network/networkd-json.c
parentnamespace-util: pin pid via pidfd during namespace_open() (diff)
parenttest-network: update KeepConfiguration=dhcp -> dynamic (diff)
downloadsystemd-bdc6edbdabfa0c8844d00f9863ec1d81d7804cc5.tar.xz
systemd-bdc6edbdabfa0c8844d00f9863ec1d81d7804cc5.zip
network: serialize and deserialize current configuration (#34989)
Replaces #34963. Fixes #26602. Fixes #32569.
Diffstat (limited to 'src/network/networkd-json.c')
-rw-r--r--src/network/networkd-json.c191
1 files changed, 123 insertions, 68 deletions
diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c
index fd2b709d9d..460fbe5968 100644
--- a/src/network/networkd-json.c
+++ b/src/network/networkd-json.c
@@ -28,55 +28,78 @@
#include "user-util.h"
#include "wifi-util.h"
-static int address_append_json(Address *address, sd_json_variant **array) {
- _cleanup_free_ char *scope = NULL, *flags = NULL, *state = NULL;
+static int address_append_json(Address *address, bool serializing, sd_json_variant **array) {
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
int r;
assert(address);
assert(array);
- r = route_scope_to_string_alloc(address->scope, &scope);
- if (r < 0)
- return r;
-
- r = address_flags_to_string_alloc(address->flags, address->family, &flags);
- if (r < 0)
- return r;
-
- r = network_config_state_to_string_alloc(address->state, &state);
- if (r < 0)
- return r;
-
- return sd_json_variant_append_arraybo(
- array,
+ r = sd_json_buildo(
+ &v,
SD_JSON_BUILD_PAIR_INTEGER("Family", address->family),
JSON_BUILD_PAIR_IN_ADDR("Address", &address->in_addr, address->family),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("Peer", &address->in_addr_peer, address->family),
- JSON_BUILD_PAIR_IN4_ADDR_NON_NULL("Broadcast", &address->broadcast),
SD_JSON_BUILD_PAIR_UNSIGNED("PrefixLength", address->prefixlen),
- SD_JSON_BUILD_PAIR_UNSIGNED("Scope", address->scope),
- SD_JSON_BUILD_PAIR_STRING("ScopeString", scope),
- SD_JSON_BUILD_PAIR_UNSIGNED("Flags", address->flags),
- SD_JSON_BUILD_PAIR_STRING("FlagsString", flags),
- JSON_BUILD_PAIR_STRING_NON_EMPTY("Label", address->label),
- JSON_BUILD_PAIR_FINITE_USEC("PreferredLifetimeUSec", address->lifetime_preferred_usec),
- JSON_BUILD_PAIR_FINITE_USEC("PreferredLifetimeUsec", address->lifetime_preferred_usec), /* for backward compat */
- JSON_BUILD_PAIR_FINITE_USEC("ValidLifetimeUSec", address->lifetime_valid_usec),
- JSON_BUILD_PAIR_FINITE_USEC("ValidLifetimeUsec", address->lifetime_valid_usec), /* for backward compat */
SD_JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(address->source)),
- SD_JSON_BUILD_PAIR_STRING("ConfigState", state),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", &address->provider, address->family));
+ if (r < 0)
+ return r;
+
+ if (!serializing) {
+ _cleanup_free_ char *scope = NULL, *flags = NULL, *state = NULL;
+
+ r = route_scope_to_string_alloc(address->scope, &scope);
+ if (r < 0)
+ return r;
+
+ r = address_flags_to_string_alloc(address->flags, address->family, &flags);
+ if (r < 0)
+ return r;
+
+ r = network_config_state_to_string_alloc(address->state, &state);
+ if (r < 0)
+ return r;
+
+ r = sd_json_variant_merge_objectbo(
+ &v,
+ JSON_BUILD_PAIR_IN4_ADDR_NON_NULL("Broadcast", &address->broadcast),
+ SD_JSON_BUILD_PAIR_UNSIGNED("Scope", address->scope),
+ SD_JSON_BUILD_PAIR_STRING("ScopeString", scope),
+ SD_JSON_BUILD_PAIR_UNSIGNED("Flags", address->flags),
+ SD_JSON_BUILD_PAIR_STRING("FlagsString", flags),
+ JSON_BUILD_PAIR_STRING_NON_EMPTY("Label", address->label),
+ JSON_BUILD_PAIR_FINITE_USEC("PreferredLifetimeUSec", address->lifetime_preferred_usec),
+ JSON_BUILD_PAIR_FINITE_USEC("PreferredLifetimeUsec", address->lifetime_preferred_usec), /* for backward compat */
+ JSON_BUILD_PAIR_FINITE_USEC("ValidLifetimeUSec", address->lifetime_valid_usec),
+ JSON_BUILD_PAIR_FINITE_USEC("ValidLifetimeUsec", address->lifetime_valid_usec), /* for backward compat */
+ SD_JSON_BUILD_PAIR_STRING("ConfigState", state));
+ if (r < 0)
+ return r;
+ }
+
+ return sd_json_variant_append_array(array, v);
}
-static int addresses_append_json(Set *addresses, sd_json_variant **v) {
+int addresses_append_json(Link *link, bool serializing, sd_json_variant **v) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
Address *address;
int r;
+ assert(link);
assert(v);
- SET_FOREACH(address, addresses) {
- r = address_append_json(address, &array);
+ SET_FOREACH(address, link->addresses) {
+ if (serializing) {
+ if (address->source == NETWORK_CONFIG_SOURCE_FOREIGN)
+ continue;
+ if (!address_is_ready(address))
+ continue;
+
+ log_address_debug(address, "Serializing", link);
+ }
+
+ r = address_append_json(address, serializing, &array);
if (r < 0)
return r;
}
@@ -199,35 +222,15 @@ static int nexthops_append_json(Manager *manager, int ifindex, sd_json_variant *
return json_variant_set_field_non_null(v, "NextHops", array);
}
-static int route_append_json(Route *route, sd_json_variant **array) {
- _cleanup_free_ char *scope = NULL, *protocol = NULL, *table = NULL, *flags = NULL, *state = NULL;
+static int route_append_json(Route *route, bool serializing, sd_json_variant **array) {
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
int r;
assert(route);
assert(array);
- 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(route->manager, route->table, /* append_num = */ false, &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;
-
- return sd_json_variant_append_arraybo(
- array,
+ r = sd_json_buildo(
+ &v,
SD_JSON_BUILD_PAIR_INTEGER("Family", route->family),
JSON_BUILD_PAIR_IN_ADDR("Destination", &route->dst, route->family),
SD_JSON_BUILD_PAIR_UNSIGNED("DestinationPrefixLength", route->dst_prefixlen),
@@ -238,26 +241,67 @@ static int route_append_json(Route *route, sd_json_variant **array) {
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("PreferredSource", &route->prefsrc, route->family),
SD_JSON_BUILD_PAIR_UNSIGNED("TOS", route->tos),
SD_JSON_BUILD_PAIR_UNSIGNED("Scope", route->scope),
- SD_JSON_BUILD_PAIR_STRING("ScopeString", scope),
SD_JSON_BUILD_PAIR_UNSIGNED("Protocol", route->protocol),
- SD_JSON_BUILD_PAIR_STRING("ProtocolString", protocol),
SD_JSON_BUILD_PAIR_UNSIGNED("Type", route->type),
- SD_JSON_BUILD_PAIR_STRING("TypeString", route_type_to_string(route->type)),
SD_JSON_BUILD_PAIR_UNSIGNED("Priority", route->priority),
SD_JSON_BUILD_PAIR_UNSIGNED("Table", route->table),
- SD_JSON_BUILD_PAIR_STRING("TableString", table),
- JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("MTU", route_metric_get(&route->metric, RTAX_MTU)),
- SD_JSON_BUILD_PAIR_UNSIGNED("Preference", route->pref),
SD_JSON_BUILD_PAIR_UNSIGNED("Flags", route->flags),
- SD_JSON_BUILD_PAIR_STRING("FlagsString", strempty(flags)),
- JSON_BUILD_PAIR_FINITE_USEC("LifetimeUSec", route->lifetime_usec),
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("NextHopID", route->nexthop_id),
SD_JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(route->source)),
- SD_JSON_BUILD_PAIR_STRING("ConfigState", state),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", &route->provider, route->family));
+ if (r < 0)
+ return r;
+
+ if (serializing) {
+ r = sd_json_variant_merge_objectbo(
+ &v,
+ SD_JSON_BUILD_PAIR_INTEGER("InterfaceIndex", route->nexthop.ifindex),
+ JSON_BUILD_PAIR_BYTE_ARRAY_NON_EMPTY("Metrics", route->metric.metrics, route->metric.n_metrics),
+ JSON_BUILD_PAIR_STRING_NON_EMPTY("TCPCongestionControlAlgorithm", route->metric.tcp_congestion_control_algo));
+ if (r < 0)
+ return r;
+ } else {
+ _cleanup_free_ char *scope = NULL, *protocol = NULL, *table = NULL, *flags = NULL, *state = NULL;
+
+ 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(route->manager, route->table, /* append_num = */ false, &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 = sd_json_variant_merge_objectbo(
+ &v,
+ SD_JSON_BUILD_PAIR_STRING("ScopeString", scope),
+ SD_JSON_BUILD_PAIR_STRING("ProtocolString", protocol),
+ SD_JSON_BUILD_PAIR_STRING("TypeString", route_type_to_string(route->type)),
+ SD_JSON_BUILD_PAIR_STRING("TableString", table),
+ JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("MTU", route_metric_get(&route->metric, RTAX_MTU)),
+ SD_JSON_BUILD_PAIR_UNSIGNED("Preference", route->pref),
+ SD_JSON_BUILD_PAIR_STRING("FlagsString", strempty(flags)),
+ JSON_BUILD_PAIR_FINITE_USEC("LifetimeUSec", route->lifetime_usec),
+ SD_JSON_BUILD_PAIR_STRING("ConfigState", state));
+ if (r < 0)
+ return r;
+ }
+
+ return sd_json_variant_append_array(array, v);
}
-static int routes_append_json(Manager *manager, int ifindex, sd_json_variant **v) {
+int routes_append_json(Manager *manager, int ifindex, sd_json_variant **v) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
Route *route;
int r;
@@ -266,10 +310,21 @@ static int routes_append_json(Manager *manager, int ifindex, sd_json_variant **v
assert(v);
SET_FOREACH(route, manager->routes) {
- if (route->nexthop.ifindex != ifindex)
- continue;
+ if (ifindex >= 0) {
+ if (route->nexthop.ifindex != ifindex)
+ continue;
+ } else {
+ /* negative ifindex means we are serializing now. */
+
+ if (route->source == NETWORK_CONFIG_SOURCE_FOREIGN)
+ continue;
+ if (!route_exists(route))
+ continue;
+
+ log_route_debug(route, "Serializing", manager);
+ }
- r = route_append_json(route, &array);
+ r = route_append_json(route, /* serializing = */ ifindex < 0, &array);
if (r < 0)
return r;
}
@@ -1413,7 +1468,7 @@ int link_build_json(Link *link, sd_json_variant **ret) {
if (r < 0)
return r;
- r = addresses_append_json(link->addresses, &v);
+ r = addresses_append_json(link, /* serializing = */ false, &v);
if (r < 0)
return r;