networkd: unfoobar serialization of links

We'd start writing an entry line, then another one, then another one,
and then output the rest of the first one, and then some other random
stuff, and the rest of some other lines... Results were ...eh... random.

Let's define a helper to avoid some of the copy&paste madness, and separate
blocks that output a single line with /**********************************/.

This rework doesn't change what data is written, it only tries to fix the
format of the output. The fact that some entries only write data from
link->network, and some from either link->network or link, some stuff only
for dhpc4 leases while some for both dhpc4 and dhcp6, etc, looks rather
suspicious too, but I didn't touch this.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-05-24 22:02:47 +02:00
parent 00813316b0
commit d5e172d2fb
2 changed files with 149 additions and 144 deletions

2
TODO
View File

@ -1227,6 +1227,8 @@ Features:
- duplicate address check for static IPs (like ARPCHECK in network-scripts) - duplicate address check for static IPs (like ARPCHECK in network-scripts)
- whenever uplink info changes, make DHCP server send out FORCERENEW - whenever uplink info changes, make DHCP server send out FORCERENEW
* Figure out how to do unittests of networkd's state serialization
* dhcp: * dhcp:
- figure out how much we can increase Maximum Message Size - figure out how much we can increase Maximum Message Size

View File

@ -3999,6 +3999,61 @@ static void link_save_dns(FILE *f, struct in_addr_data *dns, unsigned n_dns, boo
} }
} }
static void serialize_addresses(
FILE *f,
const char *lvalue,
bool *space,
char **addresses,
sd_dhcp_lease *lease,
bool conditional,
sd_dhcp_lease_info what,
sd_dhcp6_lease *lease6,
bool conditional6,
int (*lease6_get_addr)(sd_dhcp6_lease*, const struct in6_addr**),
int (*lease6_get_fqdn)(sd_dhcp6_lease*, char ***)) {
int r;
bool _space = false;
if (!space)
space = &_space;
if (lvalue)
fprintf(f, "%s=", lvalue);
fputstrv(f, addresses, NULL, space);
if (lease && conditional) {
const struct in_addr *lease_addresses;
r = sd_dhcp_lease_get_servers(lease, what, &lease_addresses);
if (r > 0)
if (serialize_in_addrs(f, lease_addresses, r, space, in4_addr_is_non_local) > 0)
*space = true;
}
if (lease6 && conditional6 && lease6_get_addr) {
const struct in6_addr *in6_addrs;
r = lease6_get_addr(lease6, &in6_addrs);
if (r > 0) {
if (*space)
fputc(' ', f);
serialize_in6_addrs(f, in6_addrs, r);
*space = true;
}
}
if (lease6 && conditional6 && lease6_get_fqdn) {
char **in6_hosts;
r = lease6_get_fqdn(lease6, &in6_hosts);
if (r > 0)
fputstrv(f, in6_hosts, NULL, space);
}
if (lvalue)
fputc('\n', f);
}
int link_save(Link *link) { int link_save(Link *link) {
const char *admin_state, *oper_state, *carrier_state, *address_state; const char *admin_state, *oper_state, *carrier_state, *address_state;
_cleanup_free_ char *temp_path = NULL; _cleanup_free_ char *temp_path = NULL;
@ -4055,14 +4110,11 @@ int link_save(Link *link) {
fprintf(f, "REQUIRED_FOR_ONLINE=%s\n", fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
yes_no(link->network->required_for_online)); yes_no(link->network->required_for_online));
fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s", LinkOperationalStateRange st = link->network->required_operstate_for_online;
strempty(link_operstate_to_string(link->network->required_operstate_for_online.min))); fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s%s%s\n",
strempty(link_operstate_to_string(st.min)),
if (link->network->required_operstate_for_online.max != LINK_OPERSTATE_RANGE_DEFAULT.max) st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? ":" : "",
fprintf(f, ":%s", st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? strempty(link_operstate_to_string(st.max)) : "");
strempty(link_operstate_to_string(link->network->required_operstate_for_online.max)));
fprintf(f, "\n");
if (link->dhcp6_client) { if (link->dhcp6_client) {
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease); r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
@ -4072,35 +4124,24 @@ int link_save(Link *link) {
fprintf(f, "NETWORK_FILE=%s\n", link->network->filename); fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
/************************************************************/
fputs("DNS=", f); fputs("DNS=", f);
space = false; space = false;
if (link->n_dns != (unsigned) -1) if (link->n_dns != (unsigned) -1)
link_save_dns(f, link->dns, link->n_dns, &space); link_save_dns(f, link->dns, link->n_dns, &space);
else else
link_save_dns(f, link->network->dns, link->network->n_dns, &space); link_save_dns(f, link->network->dns, link->network->n_dns, &space);
if (link->network->dhcp_use_dns && serialize_addresses(f, NULL, &space,
link->dhcp_lease) { NULL,
const struct in_addr *addresses; link->dhcp_lease,
link->network->dhcp_use_dns,
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses); SD_DHCP_LEASE_DNS_SERVERS,
if (r > 0) dhcp6_lease,
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0) link->network->dhcp6_use_dns,
space = true; sd_dhcp6_lease_get_dns,
} NULL);
if (link->network->dhcp6_use_dns && dhcp6_lease) {
const struct in6_addr *in6_addrs;
r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
if (r > 0) {
if (space)
fputc(' ', f);
serialize_in6_addrs(f, in6_addrs, r);
space = true;
}
}
/* Make sure to flush out old entries before we use the NDISC data */ /* Make sure to flush out old entries before we use the NDISC data */
ndisc_vacuum(link); ndisc_vacuum(link);
@ -4119,100 +4160,47 @@ int link_save(Link *link) {
fputc('\n', f); fputc('\n', f);
fputs("NTP=", f); /************************************************************/
space = false;
fputstrv(f, link->ntp ?: link->network->ntp, NULL, &space);
if (link->network->dhcp_use_ntp && serialize_addresses(f, "NTP", NULL,
link->dhcp_lease) { link->ntp ?: link->network->ntp,
const struct in_addr *addresses; link->dhcp_lease,
link->network->dhcp_use_ntp,
SD_DHCP_LEASE_NTP_SERVERS,
dhcp6_lease,
link->network->dhcp6_use_ntp,
sd_dhcp6_lease_get_ntp_addrs,
sd_dhcp6_lease_get_ntp_fqdn);
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses); serialize_addresses(f, "SIP", NULL,
if (r > 0) link->network->sip,
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0) link->dhcp_lease,
space = true; link->network->dhcp_use_sip,
} SD_DHCP_LEASE_SIP_SERVERS,
false, NULL, NULL, NULL);
fputc('\n', f); serialize_addresses(f, "POP3_SERVERS", NULL,
link->network->pop3,
link->dhcp_lease,
true,
SD_DHCP_LEASE_POP3_SERVERS,
false, NULL, NULL, NULL);
fputs("SIP=", f); serialize_addresses(f, "SMTP_SERVERS", NULL,
space = false; link->network->smtp,
fputstrv(f, link->network->sip, NULL, &space); link->dhcp_lease,
true,
SD_DHCP_LEASE_SMTP_SERVERS,
false, NULL, NULL, NULL);
if (link->network->dhcp_use_sip && serialize_addresses(f, "LPR_SERVERS", NULL,
link->dhcp_lease) { link->network->lpr,
const struct in_addr *addresses; link->dhcp_lease,
true,
SD_DHCP_LEASE_LPR_SERVERS,
false, NULL, NULL, NULL);
r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses); /************************************************************/
if (r > 0)
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
space = true;
}
fputc('\n', f);
fputs("POP3_SERVERS=", f);
space = false;
fputstrv(f, link->network->pop3, NULL, &space);
fputc('\n', f);
fputs("SMTP_SERVERS=", f);
space = false;
fputstrv(f, link->network->smtp, NULL, &space);
fputc('\n', f);
fputs("LPR_SERVERS=", f);
space = false;
fputstrv(f, link->network->lpr, NULL, &space);
if (link->dhcp_lease) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses);
if (r > 0)
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
space = true;
}
if (link->dhcp_lease) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses);
if (r > 0)
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
space = true;
}
if (link->dhcp_lease) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_lpr_servers(link->dhcp_lease, &addresses);
if (r > 0)
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
space = true;
}
if (link->network->dhcp6_use_ntp && dhcp6_lease) {
const struct in6_addr *in6_addrs;
char **hosts;
r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
&in6_addrs);
if (r > 0) {
if (space)
fputc(' ', f);
serialize_in6_addrs(f, in6_addrs, r);
space = true;
}
r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
if (r > 0)
fputstrv(f, hosts, NULL, &space);
}
fputc('\n', f);
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) { if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
if (link->dhcp_lease) { if (link->dhcp_lease) {
@ -4246,6 +4234,8 @@ int link_save(Link *link) {
fputc('\n', f); fputc('\n', f);
/************************************************************/
fputs("ROUTE_DOMAINS=", f); fputs("ROUTE_DOMAINS=", f);
space = false; space = false;
ORDERED_SET_FOREACH(p, link->route_domains ?: link->network->route_domains, i) ORDERED_SET_FOREACH(p, link->route_domains ?: link->network->route_domains, i)
@ -4269,47 +4259,58 @@ int link_save(Link *link) {
fputc('\n', f); fputc('\n', f);
/************************************************************/
fprintf(f, "LLMNR=%s\n", fprintf(f, "LLMNR=%s\n",
resolve_support_to_string(link->llmnr >= 0 ? link->llmnr : link->network->llmnr)); resolve_support_to_string(link->llmnr >= 0 ? link->llmnr : link->network->llmnr));
/************************************************************/
fprintf(f, "MDNS=%s\n", fprintf(f, "MDNS=%s\n",
resolve_support_to_string(link->mdns >= 0 ? link->mdns : link->network->mdns)); resolve_support_to_string(link->mdns >= 0 ? link->mdns : link->network->mdns));
if (link->dns_default_route >= 0)
fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(link->dns_default_route));
else if (link->network->dns_default_route >= 0)
fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(link->network->dns_default_route));
if (link->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID) /************************************************************/
fprintf(f, "DNS_OVER_TLS=%s\n",
dns_over_tls_mode_to_string(link->dns_over_tls_mode));
else if (link->network->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
fprintf(f, "DNS_OVER_TLS=%s\n",
dns_over_tls_mode_to_string(link->network->dns_over_tls_mode));
if (link->dnssec_mode != _DNSSEC_MODE_INVALID) int dns_default_route =
fprintf(f, "DNSSEC=%s\n", link->dns_default_route >= 0 ? link->dns_default_route :
dnssec_mode_to_string(link->dnssec_mode)); link->network->dns_default_route;
else if (link->network->dnssec_mode != _DNSSEC_MODE_INVALID) if (dns_default_route >= 0)
fprintf(f, "DNSSEC=%s\n", fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(dns_default_route));
dnssec_mode_to_string(link->network->dnssec_mode));
if (!set_isempty(link->dnssec_negative_trust_anchors)) { /************************************************************/
DnsOverTlsMode dns_over_tls_mode =
link->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID ? link->dns_over_tls_mode :
link->network->dns_over_tls_mode;
if (dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
fprintf(f, "DNS_OVER_TLS=%s\n", dns_over_tls_mode_to_string(dns_over_tls_mode));
/************************************************************/
DnssecMode dnssec_mode =
link->dnssec_mode != _DNSSEC_MODE_INVALID ? link->dnssec_mode :
link->network->dnssec_mode;
if (dnssec_mode != _DNSSEC_MODE_INVALID)
fprintf(f, "DNSSEC=%s\n", dnssec_mode_to_string(dnssec_mode));
/************************************************************/
Set *nta_anchors = link->dnssec_negative_trust_anchors;
if (set_isempty(nta_anchors))
nta_anchors = link->network->dnssec_negative_trust_anchors;
if (!set_isempty(nta_anchors)) {
const char *n; const char *n;
fputs("DNSSEC_NTA=", f); fputs("DNSSEC_NTA=", f);
space = false; space = false;
SET_FOREACH(n, link->dnssec_negative_trust_anchors, i) SET_FOREACH(n, nta_anchors, i)
fputs_with_space(f, n, NULL, &space);
fputc('\n', f);
} else if (!set_isempty(link->network->dnssec_negative_trust_anchors)) {
const char *n;
fputs("DNSSEC_NTA=", f);
space = false;
SET_FOREACH(n, link->network->dnssec_negative_trust_anchors, i)
fputs_with_space(f, n, NULL, &space); fputs_with_space(f, n, NULL, &space);
fputc('\n', f); fputc('\n', f);
} }
/************************************************************/
fputs("ADDRESSES=", f); fputs("ADDRESSES=", f);
space = false; space = false;
SET_FOREACH(a, link->addresses, i) { SET_FOREACH(a, link->addresses, i) {
@ -4324,6 +4325,8 @@ int link_save(Link *link) {
} }
fputc('\n', f); fputc('\n', f);
/************************************************************/
fputs("ROUTES=", f); fputs("ROUTES=", f);
space = false; space = false;
SET_FOREACH(route, link->routes, i) { SET_FOREACH(route, link->routes, i) {