summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/network/networkd-link.c35
-rw-r--r--src/network/networkd-manager.c56
-rw-r--r--src/network/networkd-network.c24
-rw-r--r--src/network/networkd-network.h5
4 files changed, 90 insertions, 30 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 0b634572a9..b7743557ec 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -854,28 +854,26 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda
static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
- char **a;
+ unsigned i;
log_debug("Copying DNS server information from %s", link->ifname);
if (!link->network)
return 0;
- STRV_FOREACH(a, link->network->dns) {
- struct in_addr ia;
+ for (i = 0; i < link->network->n_dns; i++) {
/* Only look for IPv4 addresses */
- if (inet_pton(AF_INET, *a, &ia) <= 0)
+ if (link->network->dns[i].family != AF_INET)
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
- addresses[n_addresses++] = ia;
+ addresses[n_addresses++] = link->network->dns[i].address.in;
}
- if (link->network->dhcp_use_dns &&
- link->dhcp_lease) {
+ if (link->network->dhcp_use_dns && link->dhcp_lease) {
const struct in_addr *da = NULL;
int n;
@@ -919,8 +917,7 @@ static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
addresses[n_addresses++] = ia;
}
- if (link->network->dhcp_use_ntp &&
- link->dhcp_lease) {
+ if (link->network->dhcp_use_ntp && link->dhcp_lease) {
const struct in_addr *da = NULL;
int n;
@@ -3235,7 +3232,7 @@ int link_save(Link *link) {
if (r < 0)
goto fail;
- fchmod(fileno(f), 0644);
+ (void) fchmod(fileno(f), 0644);
fprintf(f,
"# This is private data. Do not parse.\n"
@@ -3248,6 +3245,7 @@ int link_save(Link *link) {
sd_dhcp6_lease *dhcp6_lease = NULL;
const char *dhcp_domainname = NULL;
char **dhcp6_domains = NULL;
+ unsigned j;
if (link->dhcp6_client) {
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
@@ -3259,7 +3257,22 @@ int link_save(Link *link) {
fputs("DNS=", f);
space = false;
- fputstrv(f, link->network->dns, NULL, &space);
+
+ for (j = 0; j < link->network->n_dns; j++) {
+ _cleanup_free_ char *b = NULL;
+
+ r = in_addr_to_string(link->network->dns[j].family,
+ &link->network->dns[j].address, &b);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to format address, ignoring: %m");
+ continue;
+ }
+
+ if (space)
+ fputc(' ', f);
+ fputs(b, f);
+ space = true;
+ }
if (link->network->dhcp_use_dns &&
link->dhcp_lease) {
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index a1252c9b51..c3d3f48a3f 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -774,11 +774,48 @@ static int manager_connect_rtnl(Manager *m) {
return 0;
}
-static int ordered_set_put_in_addr(OrderedSet *s, const struct in_addr *address) {
+static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
char *p;
int r;
assert(s);
+ assert(address);
+
+ r = in_addr_to_string(address->family, &address->address, &p);
+ if (r < 0)
+ return r;
+
+ r = ordered_set_consume(s, p);
+ if (r == -EEXIST)
+ return 0;
+
+ return r;
+}
+
+static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
+ int r, c = 0;
+ unsigned i;
+
+ assert(s);
+ assert(addresses || n == 0);
+
+ for (i = 0; i < n; i++) {
+ r = ordered_set_put_in_addr_data(s, addresses+i);
+ if (r < 0)
+ return r;
+
+ c += r;
+ }
+
+ return c;
+}
+
+static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
+ char *p;
+ int r;
+
+ assert(s);
+ assert(address);
r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
if (r < 0)
@@ -791,14 +828,15 @@ static int ordered_set_put_in_addr(OrderedSet *s, const struct in_addr *address)
return r;
}
-static int ordered_set_put_in_addrv(OrderedSet *s, const struct in_addr *addresses, int n) {
- int r, i, c = 0;
+static int ordered_set_put_in4_addrv(OrderedSet *s, const struct in_addr *addresses, unsigned n) {
+ int r, c = 0;
+ unsigned i;
assert(s);
- assert(n <= 0 || addresses);
+ assert(n == 0 || addresses);
for (i = 0; i < n; i++) {
- r = ordered_set_put_in_addr(s, addresses+i);
+ r = ordered_set_put_in4_addr(s, addresses+i);
if (r < 0)
return r;
@@ -865,7 +903,7 @@ static int manager_save(Manager *m) {
continue;
/* First add the static configured entries */
- r = ordered_set_put_strdupv(dns, link->network->dns);
+ r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
if (r < 0)
return r;
@@ -890,7 +928,7 @@ static int manager_save(Manager *m) {
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
if (r > 0) {
- r = ordered_set_put_in_addrv(dns, addresses, r);
+ r = ordered_set_put_in4_addrv(dns, addresses, r);
if (r < 0)
return r;
} else if (r < 0 && r != -ENODATA)
@@ -902,7 +940,7 @@ static int manager_save(Manager *m) {
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
if (r > 0) {
- r = ordered_set_put_in_addrv(ntp, addresses, r);
+ r = ordered_set_put_in4_addrv(ntp, addresses, r);
if (r < 0)
return r;
} else if (r < 0 && r != -ENODATA)
@@ -934,7 +972,7 @@ static int manager_save(Manager *m) {
if (r < 0)
return r;
- fchmod(fileno(f), 0644);
+ (void) fchmod(fileno(f), 0644);
fprintf(f,
"# This is private data. Do not parse.\n"
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index e3a77c2152..bc4dc95ff9 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -244,7 +244,7 @@ void network_free(Network *network) {
free(network->mac);
strv_free(network->ntp);
- strv_free(network->dns);
+ free(network->dns);
strv_free(network->search_domains);
strv_free(network->route_domains);
strv_free(network->bind_carrier);
@@ -396,7 +396,7 @@ int network_apply(Network *network, Link *link) {
route->protocol = RTPROT_STATIC;
}
- if (!strv_isempty(network->dns) ||
+ if (network->n_dns > 0 ||
!strv_isempty(network->ntp) ||
!strv_isempty(network->search_domains) ||
!strv_isempty(network->route_domains))
@@ -1004,29 +1004,35 @@ int config_parse_dns(
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
+ struct in_addr_data *m;
int family;
- r = extract_first_word(&rvalue, &w, NULL, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE);
- if (r == 0)
- break;
+ r = extract_first_word(&rvalue, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
break;
}
+ if (r == 0)
+ break;
r = in_addr_from_string_auto(w, &family, &a);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse dns server address, ignoring: %s", w);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse dns server address, ignoring: %s", w);
continue;
}
- r = strv_consume(&n->dns, w);
- if (r < 0)
+ m = realloc(n->dns, (n->n_dns + 1) * sizeof(struct in_addr_data));
+ if (!m)
return log_oom();
- w = NULL;
+ m[n->n_dns++] = (struct in_addr_data) {
+ .family = family,
+ .address = a,
+ };
+
+ n->dns = m;
}
return 0;
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 735d7f7a77..17cff956da 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -194,7 +194,10 @@ struct Network {
Hashmap *routes_by_section;
Hashmap *fdb_entries_by_section;
- char **search_domains, **route_domains, **dns, **ntp, **bind_carrier;
+ struct in_addr_data *dns;
+ unsigned n_dns;
+
+ char **search_domains, **route_domains, **ntp, **bind_carrier;
ResolveSupport llmnr;
ResolveSupport mdns;