From 3b60ededae1ae1294336755253fecaf713101e38 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 00:56:34 +0900 Subject: [PATCH 01/11] network: json: add several entries for wait-online --- src/network/networkd-json.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index daf4f0085ab..6e5f30750e6 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -462,7 +462,15 @@ static int network_build_json(Network *network, JsonVariant **ret) { } return json_build(ret, JSON_BUILD_OBJECT( - JSON_BUILD_PAIR_STRING("NetworkFile", network->filename))); + JSON_BUILD_PAIR_STRING("NetworkFile", network->filename), + JSON_BUILD_PAIR_BOOLEAN("RequiredForOnline", network->required_for_online), + JSON_BUILD_PAIR("RequiredOperationalStateForOnline", + JSON_BUILD_ARRAY(JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.min)), + JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.max)))), + JSON_BUILD_PAIR_STRING("RequiredFamilyForOnline", + link_required_address_family_to_string(network->required_family_for_online)), + JSON_BUILD_PAIR_STRING("ActivationPolicy", + activation_policy_to_string(network->activation_policy)))); } static int device_build_json(sd_device *device, JsonVariant **ret) { From ee5b48341e3f1f4f4820533f4cfd577c10fc7b3e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 01:08:53 +0900 Subject: [PATCH 02/11] dhcp: make sd_dhcp_lease_get_servers() accepts NULL --- src/libsystemd-network/sd-dhcp-lease.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 095a4ee6837..dd82163d9f7 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -105,12 +105,13 @@ int sd_dhcp_lease_get_servers( assert_return(lease, -EINVAL); assert_return(what >= 0, -EINVAL); assert_return(what < _SD_DHCP_LEASE_SERVER_TYPE_MAX, -EINVAL); - assert_return(addr, -EINVAL); if (lease->servers[what].size <= 0) return -ENODATA; - *addr = lease->servers[what].addr; + if (addr) + *addr = lease->servers[what].addr; + return (int) lease->servers[what].size; } From 5656ff9dd183574d5335f410d824e01439f07fbc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 01:12:14 +0900 Subject: [PATCH 03/11] dhcp6: make sd_dhcp6_lease_get_dns() and friends accepts NULL --- src/libsystemd-network/sd-dhcp6-lease.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 22fb77c19e1..a47e6a01992 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -239,12 +239,13 @@ int dhcp6_lease_add_dns(sd_dhcp6_lease *lease, const uint8_t *optval, size_t opt int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret) { assert_return(lease, -EINVAL); - assert_return(ret, -EINVAL); if (!lease->dns) return -ENOENT; - *ret = lease->dns; + if (ret) + *ret = lease->dns; + return lease->dns_count; } @@ -337,16 +338,17 @@ int dhcp6_lease_add_sntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t op int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret) { assert_return(lease, -EINVAL); - assert_return(ret, -EINVAL); if (lease->ntp) { - *ret = lease->ntp; + if (ret) + *ret = lease->ntp; return lease->ntp_count; } if (lease->sntp && !lease->ntp_fqdn) { /* Fallback to the deprecated SNTP option. */ - *ret = lease->sntp; + if (ret) + *ret = lease->sntp; return lease->sntp_count; } @@ -355,12 +357,12 @@ int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr ** int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret) { assert_return(lease, -EINVAL); - assert_return(ret, -EINVAL); if (!lease->ntp_fqdn) return -ENOENT; - *ret = lease->ntp_fqdn; + if (ret) + *ret = lease->ntp_fqdn; return strv_length(lease->ntp_fqdn); } From 2e62139a2138d1903cf769b042159f053cc7208b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 01:49:50 +0900 Subject: [PATCH 04/11] network: introduce NETWORK_CONFIG_SOURCE_RUNTIME --- src/network/networkd-util.c | 1 + src/network/networkd-util.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/network/networkd-util.c b/src/network/networkd-util.c index b0020efe899..661f1030169 100644 --- a/src/network/networkd-util.c +++ b/src/network/networkd-util.c @@ -19,6 +19,7 @@ static const char * const network_config_source_table[_NETWORK_CONFIG_SOURCE_MAX [NETWORK_CONFIG_SOURCE_DHCP6] = "DHCPv6", [NETWORK_CONFIG_SOURCE_DHCP6PD] = "DHCPv6-PD", [NETWORK_CONFIG_SOURCE_NDISC] = "NDisc", + [NETWORK_CONFIG_SOURCE_RUNTIME] = "runtime", }; DEFINE_STRING_TABLE_LOOKUP_TO_STRING(network_config_source, NetworkConfigSource); diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h index 6318b91118a..ba03ddcc556 100644 --- a/src/network/networkd-util.h +++ b/src/network/networkd-util.h @@ -27,6 +27,7 @@ typedef enum NetworkConfigSource { NETWORK_CONFIG_SOURCE_DHCP6, NETWORK_CONFIG_SOURCE_DHCP6PD, NETWORK_CONFIG_SOURCE_NDISC, + NETWORK_CONFIG_SOURCE_RUNTIME, /* through D-Bus method */ _NETWORK_CONFIG_SOURCE_MAX, _NETWORK_CONFIG_SOURCE_INVALID = -EINVAL, } NetworkConfigSource; From 2ab60af29d96ffc573b0c5ad415b6006efe081d2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 02:12:08 +0900 Subject: [PATCH 05/11] network: json: append DNS server information --- src/network/networkd-json.c | 170 ++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 6e5f30750e6..042b2b984a6 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -499,6 +499,166 @@ static int device_build_json(sd_device *device, JsonVariant **ret) { JSON_BUILD_PAIR_STRING_NON_EMPTY("Model", model))); } +static int dns_build_json_one(Link *link, const struct in_addr_full *a, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) { + _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; + int r; + + assert(link); + assert(a); + assert(ret); + + if (a->ifindex != 0 && a->ifindex != link->ifindex) { + *ret = NULL; + return 0; + } + + r = json_build(&v, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_INTEGER("Family", a->family), + JSON_BUILD_PAIR_IN_ADDR("Address", &a->address, a->family), + JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("Port", a->port), + JSON_BUILD_PAIR_CONDITION(a->ifindex != 0, "InterfaceIndex", JSON_BUILD_INTEGER(a->ifindex)), + JSON_BUILD_PAIR_STRING_NON_EMPTY("ServerName", a->server_name), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)), + JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, a->family))); + if (r < 0) + return r; + + *ret = TAKE_PTR(v); + return 1; +} + +static int dns_build_json(Link *link, JsonVariant **ret) { + JsonVariant **elements = NULL; + size_t n = 0; + int r; + + assert(link); + assert(ret); + + if (!link->network) { + *ret = NULL; + return 0; + } + + if (link->n_dns != UINT_MAX) { + for (unsigned i = 0; i < link->n_dns; i++) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = dns_build_json_one(link, link->dns[i], NETWORK_CONFIG_SOURCE_RUNTIME, NULL, elements + n); + if (r < 0) + goto finalize; + if (r > 0) + n++; + } + } else { + for (unsigned i = 0; i < link->network->n_dns; i++) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = dns_build_json_one(link, link->network->dns[i], NETWORK_CONFIG_SOURCE_STATIC, NULL, elements + n); + if (r < 0) + goto finalize; + if (r > 0) + n++; + } + + if (link->dhcp_lease && link->network->dhcp_use_dns) { + const struct in_addr *dns; + union in_addr_union s; + int n_dns; + + r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); + if (r < 0) + goto finalize; + + n_dns = sd_dhcp_lease_get_dns(link->dhcp_lease, &dns); + for (int i = 0; i < n_dns; i++) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = dns_build_json_one(link, + &(struct in_addr_full) { .family = AF_INET, .address.in = dns[i], }, + NETWORK_CONFIG_SOURCE_DHCP4, + &s, + elements + n); + if (r < 0) + goto finalize; + if (r > 0) + n++; + } + } + + if (link->dhcp6_lease && link->network->dhcp6_use_dns) { + const struct in6_addr *dns; + union in_addr_union s; + int n_dns; + + r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6); + if (r < 0) + goto finalize; + + n_dns = sd_dhcp6_lease_get_dns(link->dhcp6_lease, &dns); + for (int i = 0; i < n_dns; i++) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = dns_build_json_one(link, + &(struct in_addr_full) { .family = AF_INET6, .address.in6 = dns[i], }, + NETWORK_CONFIG_SOURCE_DHCP6, + &s, + elements + n); + if (r < 0) + goto finalize; + if (r > 0) + n++; + } + } + + if (link->network->ipv6_accept_ra_use_dns) { + NDiscRDNSS *a; + + SET_FOREACH(a, link->ndisc_rdnss) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = dns_build_json_one(link, + &(struct in_addr_full) { .family = AF_INET6, .address.in6 = a->address, }, + NETWORK_CONFIG_SOURCE_NDISC, + &(union in_addr_union) { .in6 = a->router }, + elements + n); + if (r < 0) + goto finalize; + if (r > 0) + n++; + } + } + } + + if (n == 0) { + *ret = NULL; + r = 0; + goto finalize; + } + + r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNS", JSON_BUILD_VARIANT_ARRAY(elements, n)))); + +finalize: + json_variant_unref_many(elements, n); + free(elements); + return r; +} + int link_build_json(Link *link, JsonVariant **ret) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL; _cleanup_free_ char *type = NULL, *flags = NULL; @@ -574,6 +734,16 @@ int link_build_json(Link *link, JsonVariant **ret) { w = json_variant_unref(w); + r = dns_build_json(link, &w); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + + w = json_variant_unref(w); + r = addresses_build_json(link->addresses, &w); if (r < 0) return r; From dfd0a5f127d8a2530b1445d9c9efaf66bee917fc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 16:22:12 +0900 Subject: [PATCH 06/11] network: json: append NTP server information --- src/network/networkd-json.c | 164 ++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 042b2b984a6..14ebf60e895 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -2,6 +2,7 @@ #include +#include "dns-domain.h" #include "ip-protocol-list.h" #include "netif-util.h" #include "networkd-address.h" @@ -659,6 +660,159 @@ finalize: return r; } +static int server_build_json_one_addr(int family, const union in_addr_union *a, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) { + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(a); + assert(ret); + + return json_build(ret, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_INTEGER("Family", family), + JSON_BUILD_PAIR_IN_ADDR("Address", a, family), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)), + JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family))); +} + +static int server_build_json_one_fqdn(int family, const char *fqdn, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) { + assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6)); + assert(fqdn); + assert(ret); + + return json_build(ret, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_STRING("Server", fqdn), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)), + JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family))); +} + +static int server_build_json_one_string(const char *str, NetworkConfigSource s, JsonVariant **ret) { + union in_addr_union a; + int family; + + assert(str); + assert(ret); + + if (in_addr_from_string_auto(str, &family, &a) >= 0) + return server_build_json_one_addr(family, &a, s, NULL, ret); + + return server_build_json_one_fqdn(AF_UNSPEC, str, s, NULL, ret); +} + +static int ntp_build_json(Link *link, JsonVariant **ret) { + JsonVariant **elements; + size_t n = 0; + char **p; + int r; + + assert(link); + assert(ret); + + if (!link->network) { + *ret = NULL; + return 0; + } + + STRV_FOREACH(p, link->ntp ?: link->network->ntp) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = server_build_json_one_string(*p, NETWORK_CONFIG_SOURCE_RUNTIME, elements + n); + if (r < 0) + goto finalize; + + n++; + } + + if (!link->ntp) { + if (link->dhcp_lease && link->network->dhcp_use_ntp) { + const struct in_addr *ntp; + union in_addr_union s; + int n_ntp; + + r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); + if (r < 0) + goto finalize; + + n_ntp = sd_dhcp_lease_get_ntp(link->dhcp_lease, &ntp); + for (int i = 0; i < n_ntp; i++) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = server_build_json_one_addr(AF_INET, + &(union in_addr_union) { .in = ntp[i], }, + NETWORK_CONFIG_SOURCE_DHCP4, + &s, + elements + n); + if (r < 0) + goto finalize; + + n++; + } + } + + if (link->dhcp6_lease && link->network->dhcp6_use_ntp) { + const struct in6_addr *ntp_addr; + union in_addr_union s; + char **ntp_fqdn; + int n_ntp; + + r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6); + if (r < 0) + goto finalize; + + n_ntp = sd_dhcp6_lease_get_ntp_addrs(link->dhcp6_lease, &ntp_addr); + for (int i = 0; i < n_ntp; i++) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = server_build_json_one_addr(AF_INET6, + &(union in_addr_union) { .in6 = ntp_addr[i], }, + NETWORK_CONFIG_SOURCE_DHCP6, + &s, + elements + n); + if (r < 0) + goto finalize; + + n++; + } + + n_ntp = sd_dhcp6_lease_get_ntp_fqdn(link->dhcp6_lease, &ntp_fqdn); + for (int i = 0; i < n_ntp; i++) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = server_build_json_one_fqdn(AF_INET6, + ntp_fqdn[i], + NETWORK_CONFIG_SOURCE_DHCP6, + &s, + elements + n); + if (r < 0) + goto finalize; + + n++; + } + } + } + + if (n == 0) { + *ret = NULL; + return 0; + } + + r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NTP", JSON_BUILD_VARIANT_ARRAY(elements, n)))); + +finalize: + json_variant_unref_many(elements, n); + free(elements); + return r; +} + int link_build_json(Link *link, JsonVariant **ret) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL; _cleanup_free_ char *type = NULL, *flags = NULL; @@ -744,6 +898,16 @@ int link_build_json(Link *link, JsonVariant **ret) { w = json_variant_unref(w); + r = ntp_build_json(link, &w); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + + w = json_variant_unref(w); + r = addresses_build_json(link->addresses, &w); if (r < 0) return r; From 0843ec6c44c7b41b14f6f32d3ee7039e5e615296 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 16:43:38 +0900 Subject: [PATCH 07/11] network: json: append SIP server information --- src/network/networkd-json.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 14ebf60e895..d5a72fe8e4b 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -813,6 +813,55 @@ finalize: return r; } +static int sip_build_json(Link *link, JsonVariant **ret) { + const struct in_addr *sip; + JsonVariant **elements; + union in_addr_union s; + size_t n = 0; + int n_sip, r; + + assert(link); + assert(ret); + + if (!link->network || !link->network->dhcp_use_sip || !link->dhcp_lease) { + *ret = NULL; + return 0; + } + + n_sip = sd_dhcp_lease_get_sip(link->dhcp_lease, &sip); + if (n_sip <= 0) { + *ret = NULL; + return 0; + } + + r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); + if (r < 0) + return r; + + elements = new(JsonVariant*, n_sip); + if (!elements) + return -ENOMEM; + + for (int i = 0; i < n_sip; i++) { + r = server_build_json_one_addr(AF_INET, + &(union in_addr_union) { .in = sip[i], }, + NETWORK_CONFIG_SOURCE_DHCP4, + &s, + elements + n); + if (r < 0) + goto finalize; + if (r > 0) + n++; + } + + r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("SIP", JSON_BUILD_VARIANT_ARRAY(elements, n)))); + +finalize: + json_variant_unref_many(elements, n); + free(elements); + return r; +} + int link_build_json(Link *link, JsonVariant **ret) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL; _cleanup_free_ char *type = NULL, *flags = NULL; @@ -908,6 +957,16 @@ int link_build_json(Link *link, JsonVariant **ret) { w = json_variant_unref(w); + r = sip_build_json(link, &w); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + + w = json_variant_unref(w); + r = addresses_build_json(link->addresses, &w); if (r < 0) return r; From 1f65aa3a58df09143067c1e302618faf2a9915e3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 17:03:11 +0900 Subject: [PATCH 08/11] network: make both search_domains and route_domains allocated on DBus call --- src/network/networkd-link-bus.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index 47e0d40d576..765733b38c4 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -195,9 +195,16 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_ if (r < 0) return r; + search_domains = ordered_set_new(&string_hash_ops_free); + if (!search_domains) + return -ENOMEM; + + route_domains = ordered_set_new(&string_hash_ops_free); + if (!route_domains) + return -ENOMEM; + for (;;) { _cleanup_free_ char *str = NULL; - OrderedSet **domains; const char *name; int route_only; @@ -219,12 +226,7 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_ if (r < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name); - domains = route_only ? &route_domains : &search_domains; - r = ordered_set_ensure_allocated(domains, &string_hash_ops_free); - if (r < 0) - return r; - - r = ordered_set_consume(*domains, TAKE_PTR(str)); + r = ordered_set_consume(route_only ? route_domains : search_domains, TAKE_PTR(str)); if (r == -EEXIST) continue; if (r < 0) From de045939ad2320c148018686e83c59570a551ba3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 17:34:56 +0900 Subject: [PATCH 09/11] network: json: append domains --- src/network/networkd-json.c | 160 ++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index d5a72fe8e4b..1a3afc56654 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -862,6 +862,146 @@ finalize: return r; } +static int domain_build_json(int family, const char *domain, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) { + assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6)); + assert(domain); + assert(ret); + + return json_build(ret, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_STRING("Domain", domain), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)), + JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family))); +} + +static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) { + OrderedSet *link_domains, *network_domains; + JsonVariant **elements = NULL; + DHCPUseDomains use_domains; + union in_addr_union s; + char **p, **domains; + const char *domain; + size_t n = 0; + int r; + + assert(link); + assert(ret); + + if (!link->network) { + *ret = NULL; + return 0; + } + + link_domains = is_route ? link->route_domains : link->search_domains; + network_domains = is_route ? link->network->route_domains : link->network->search_domains; + use_domains = is_route ? DHCP_USE_DOMAINS_ROUTE : DHCP_USE_DOMAINS_YES; + + ORDERED_SET_FOREACH(domain, link_domains ?: network_domains) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = domain_build_json(AF_UNSPEC, domain, + link_domains ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC, + NULL, elements + n); + if (r < 0) + goto finalize; + + n++; + } + + if (!link_domains) { + if (link->dhcp_lease && + link->network->dhcp_use_domains == use_domains) { + r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in); + if (r < 0) + goto finalize; + + if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domain) >= 0) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = domain_build_json(AF_INET, domain, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n); + if (r < 0) + goto finalize; + + n++; + } + + if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0) { + STRV_FOREACH(p, domains) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = domain_build_json(AF_INET, *p, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n); + if (r < 0) + goto finalize; + + n++; + } + } + } + + if (link->dhcp6_lease && + link->network->dhcp6_use_domains == use_domains) { + r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6); + if (r < 0) + goto finalize; + + if (sd_dhcp6_lease_get_domains(link->dhcp6_lease, &domains) >= 0) { + STRV_FOREACH(p, domains) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = domain_build_json(AF_INET6, *p, NETWORK_CONFIG_SOURCE_DHCP6, &s, elements + n); + if (r < 0) + goto finalize; + + n++; + } + } + } + + if (link->network->ipv6_accept_ra_use_domains == use_domains) { + NDiscDNSSL *a; + + SET_FOREACH(a, link->ndisc_dnssl) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = domain_build_json(AF_INET6, NDISC_DNSSL_DOMAIN(a), NETWORK_CONFIG_SOURCE_NDISC, + &(union in_addr_union) { .in6 = a->router }, + elements + n); + if (r < 0) + goto finalize; + + n++; + } + } + } + + if (n == 0) { + *ret = NULL; + return 0; + } + + r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR(is_route ? "RouteDomains" : "SearchDomains", + JSON_BUILD_VARIANT_ARRAY(elements, n)))); + +finalize: + json_variant_unref_many(elements, n); + free(elements); + return r; +} + int link_build_json(Link *link, JsonVariant **ret) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL; _cleanup_free_ char *type = NULL, *flags = NULL; @@ -967,6 +1107,26 @@ int link_build_json(Link *link, JsonVariant **ret) { w = json_variant_unref(w); + r = domains_build_json(link, /* is_route = */ false, &w); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + + w = json_variant_unref(w); + + r = domains_build_json(link, /* is_route = */ true, &w); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + + w = json_variant_unref(w); + r = addresses_build_json(link->addresses, &w); if (r < 0) return r; From 46c31852f19f0ed9fd191d9ee9f6ddcea3426870 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 19:44:22 +0900 Subject: [PATCH 10/11] network: json: append DNSSEC negative trust anchors --- src/network/networkd-json.c | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 1a3afc56654..315d06a091c 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -1002,6 +1002,58 @@ finalize: return r; } +static int nta_build_json(const char *nta, NetworkConfigSource s, JsonVariant **ret) { + assert(nta); + assert(ret); + + return json_build(ret, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_STRING("DNSSECNegativeTrustAnchor", nta), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)))); +} + +static int ntas_build_json(Link *link, JsonVariant **ret) { + JsonVariant **elements = NULL; + const char *nta; + size_t n = 0; + int r; + + assert(link); + assert(ret); + + if (!link->network) { + *ret = NULL; + return 0; + } + + SET_FOREACH(nta, link->dnssec_negative_trust_anchors ?: link->network->dnssec_negative_trust_anchors) { + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = nta_build_json(nta, + link->dnssec_negative_trust_anchors ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC, + elements + n); + if (r < 0) + goto finalize; + + n++; + } + + if (n == 0) { + *ret = NULL; + return 0; + } + + r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSECNegativeTrustAnchors", + JSON_BUILD_VARIANT_ARRAY(elements, n)))); + +finalize: + json_variant_unref_many(elements, n); + free(elements); + return r; +} + int link_build_json(Link *link, JsonVariant **ret) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL; _cleanup_free_ char *type = NULL, *flags = NULL; @@ -1127,6 +1179,16 @@ int link_build_json(Link *link, JsonVariant **ret) { w = json_variant_unref(w); + r = ntas_build_json(link, &w); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + + w = json_variant_unref(w); + r = addresses_build_json(link->addresses, &w); if (r < 0) return r; From b707e43d33b9cd2b00ba30945b05868cda6674d2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 26 Nov 2021 19:57:51 +0900 Subject: [PATCH 11/11] network: json: append DNS misc settings --- src/network/networkd-json.c | 107 ++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 315d06a091c..894badd6f96 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -1054,6 +1054,103 @@ finalize: return r; } +static int dns_misc_build_json(Link *link, JsonVariant **ret) { + JsonVariant **elements = NULL; + ResolveSupport resolve_support; + NetworkConfigSource source; + DnsOverTlsMode mode; + size_t n = 0; + int t, r; + + assert(link); + assert(ret); + + if (!link->network) { + *ret = NULL; + return 0; + } + + resolve_support = link->llmnr >= 0 ? link->llmnr : link->network->llmnr; + if (resolve_support >= 0) { + source = link->llmnr >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; + + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = json_build(elements + n, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_STRING("LLMNR", resolve_support_to_string(resolve_support)), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); + if (r < 0) + goto finalize; + + n++; + } + + resolve_support = link->mdns >= 0 ? link->mdns : link->network->mdns; + if (resolve_support >= 0) { + source = link->mdns >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; + + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = json_build(elements + n, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_STRING("MDNS", resolve_support_to_string(resolve_support)), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); + if (r < 0) + goto finalize; + + n++; + } + + t = link->dns_default_route >= 0 ? link->dns_default_route : link->network->dns_default_route; + if (t >= 0) { + source = link->dns_default_route >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; + + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = json_build(elements + n, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_BOOLEAN("DNSDefaultRoute", t), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); + if (r < 0) + goto finalize; + + n++; + } + + mode = link->dns_over_tls_mode >= 0 ? link->dns_over_tls_mode : link->network->dns_over_tls_mode; + if (mode >= 0) { + source = link->dns_over_tls_mode >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC; + + if (!GREEDY_REALLOC(elements, n + 1)) { + r = -ENOMEM; + goto finalize; + } + + r = json_build(elements + n, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR_STRING("DNSOverTLS", dns_over_tls_mode_to_string(mode)), + JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source)))); + if (r < 0) + goto finalize; + + n++; + } + + r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSettings", + JSON_BUILD_VARIANT_ARRAY(elements, n)))); + +finalize: + json_variant_unref_many(elements, n); + free(elements); + return r; +} + int link_build_json(Link *link, JsonVariant **ret) { _cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL; _cleanup_free_ char *type = NULL, *flags = NULL; @@ -1189,6 +1286,16 @@ int link_build_json(Link *link, JsonVariant **ret) { w = json_variant_unref(w); + r = dns_misc_build_json(link, &w); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + + w = json_variant_unref(w); + r = addresses_build_json(link->addresses, &w); if (r < 0) return r;