Merge pull request #15314 from keszybz/network-server-access-functions

Define network server access functions
This commit is contained in:
Lennart Poettering 2020-04-21 09:24:48 +02:00 committed by GitHub
commit 543d1e7854
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 322 additions and 601 deletions

View file

@ -96,59 +96,70 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
return 0;
}
int sd_dhcp_lease_get_servers(
sd_dhcp_lease *lease,
sd_dhcp_lease_info what,
const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
switch (what) {
case SD_DHCP_LEASE_DNS_SERVERS:
if (lease->dns_size <= 0)
return -ENODATA;
*addr = lease->dns;
return (int) lease->dns_size;
case SD_DHCP_LEASE_NTP_SERVERS:
if (lease->ntp_size <= 0)
return -ENODATA;
*addr = lease->ntp;
return (int) lease->ntp_size;
case SD_DHCP_LEASE_SIP_SERVERS:
if (lease->sip_size <= 0)
return -ENODATA;
*addr = lease->sip;
return (int) lease->sip_size;
case SD_DHCP_LEASE_POP3_SERVERS:
if (lease->pop3_server_size <= 0)
return -ENODATA;
*addr = lease->pop3_server;
return (int) lease->pop3_server_size;
case SD_DHCP_LEASE_SMTP_SERVERS:
if (lease->smtp_server_size <= 0)
return -ENODATA;
*addr = lease->smtp_server;
return (int) lease->smtp_server_size;
default:
log_debug("Uknown DHCP lease info item %d.", what);
return -ENXIO;
}
}
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
if (lease->dns_size <= 0)
return -ENODATA;
*addr = lease->dns;
return (int) lease->dns_size;
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_DNS_SERVERS, addr);
}
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
if (lease->ntp_size <= 0)
return -ENODATA;
*addr = lease->ntp;
return (int) lease->ntp_size;
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_NTP_SERVERS, addr);
}
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
if (lease->sip_size <= 0)
return -ENODATA;
*addr = lease->sip;
return (int) lease->sip_size;
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SIP_SERVERS, addr);
}
int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
if (lease->pop3_server_size <= 0)
return -ENODATA;
*addr = lease->pop3_server;
return (int) lease->pop3_server_size;
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_POP3_SERVERS, addr);
}
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
if (lease->smtp_server_size <= 0)
return -ENODATA;
*addr = lease->smtp_server;
return (int) lease->smtp_server_size;
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SMTP_SERVERS, addr);
}
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {

View file

@ -1123,132 +1123,81 @@ int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) {
return 1;
}
int sd_dhcp_server_set_servers(
sd_dhcp_server *server,
sd_dhcp_lease_info what,
const struct in_addr addresses[],
unsigned n_addresses) {
assert_return(server, -EINVAL);
assert_return(addresses || n_addresses == 0, -EINVAL);
struct in_addr **a;
unsigned *n_a;
switch (what) {
case SD_DHCP_LEASE_DNS_SERVERS:
a = &server->dns;
n_a = &server->n_dns;
break;
case SD_DHCP_LEASE_NTP_SERVERS:
a = &server->ntp;
n_a = &server->n_ntp;
break;
case SD_DHCP_LEASE_SIP_SERVERS:
a = &server->sip;
n_a = &server->n_sip;
break;
case SD_DHCP_LEASE_POP3_SERVERS:
a = &server->pop3_server;
n_a = &server->n_pop3_server;
break;
case SD_DHCP_LEASE_SMTP_SERVERS:
a = &server->smtp_server;
n_a = &server->n_smtp_server;
break;
default:
log_debug("Uknown DHCP lease info item %d.", what);
return -ENXIO;
}
if (*n_a == n_addresses &&
memcmp(*a, addresses, sizeof(struct in_addr) * n_addresses) == 0)
return 0;
struct in_addr *c = NULL;
if (n_addresses > 0) {
c = newdup(struct in_addr, addresses, n_addresses);
if (!c)
return -ENOMEM;
}
free(*a);
*a = c;
*n_a = n_addresses;
return 1;
}
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(dns || n <= 0, -EINVAL);
if (server->n_dns == n &&
memcmp(server->dns, dns, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->dns = mfree(server->dns);
server->n_dns = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, dns, n);
if (!c)
return -ENOMEM;
free(server->dns);
server->dns = c;
server->n_dns = n;
}
return 1;
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_DNS_SERVERS, dns, n);
}
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(ntp || n <= 0, -EINVAL);
if (server->n_ntp == n &&
memcmp(server->ntp, ntp, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->ntp = mfree(server->ntp);
server->n_ntp = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, ntp, n);
if (!c)
return -ENOMEM;
free(server->ntp);
server->ntp = c;
server->n_ntp = n;
}
return 1;
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_NTP_SERVERS, ntp, n);
}
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(sip || n <= 0, -EINVAL);
if (server->n_sip == n &&
memcmp(server->sip, sip, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->sip = mfree(server->sip);
server->n_sip = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, sip, n);
if (!c)
return -ENOMEM;
free(server->sip);
server->sip = c;
server->n_sip = n;
}
return 1;
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SIP_SERVERS, sip, n);
}
int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(pop3_server || n <= 0, -EINVAL);
if (server->n_pop3_server == n &&
memcmp(server->pop3_server, pop3_server, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->pop3_server = mfree(server->pop3_server);
server->n_pop3_server = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, pop3_server, n);
if (!c)
return -ENOMEM;
free_and_replace(server->pop3_server, c);
server->n_pop3_server = n;
}
return 1;
int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3[], unsigned n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_POP3_SERVERS, pop3, n);
}
int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(smtp_server || n <= 0, -EINVAL);
if (server->n_smtp_server == n &&
memcmp(server->smtp_server, smtp_server, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->smtp_server = mfree(server->smtp_server);
server->n_smtp_server = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, smtp_server, n);
if (!c)
return -ENOMEM;
free_and_replace(server->smtp_server, c);
server->n_smtp_server = n;
}
return 1;
int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp[], unsigned n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SMTP_SERVERS, smtp, n);
}
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {

View file

@ -45,11 +45,6 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
size_t n_addresses = 0, n_allocated = 0;
unsigned i;
log_link_debug(link, "Copying DNS server information from link");
if (!link->network)
return 0;
for (i = 0; i < link->network->n_dns; i++) {
struct in_addr ia;
@ -91,17 +86,53 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
return sd_dhcp_server_set_dns(s, addresses, n_addresses);
}
static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
static int link_push_uplink_to_dhcp_server(
Link *link,
sd_dhcp_lease_info what,
sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
char **a;
bool lease_condition;
char **servers;
if (!link->network)
return 0;
log_link_debug(link, "Copying NTP server information from link");
log_link_debug(link, "Copying %s from link", dhcp_lease_info_to_string(what));
STRV_FOREACH(a, link->network->ntp) {
switch (what) {
case SD_DHCP_LEASE_DNS_SERVERS:
/* DNS servers are stored as parsed data, so special handling is required.
* TODO: check if DNS servers should be stored unparsed too. */
return link_push_uplink_dns_to_dhcp_server(link, s);
case SD_DHCP_LEASE_NTP_SERVERS:
servers = link->network->ntp;
lease_condition = link->network->dhcp_use_ntp;
break;
case SD_DHCP_LEASE_POP3_SERVERS:
servers = link->network->pop3;
lease_condition = true;
break;
case SD_DHCP_LEASE_SMTP_SERVERS:
servers = link->network->smtp;
lease_condition = true;
break;
case SD_DHCP_LEASE_SIP_SERVERS:
servers = link->network->sip;
lease_condition = link->network->dhcp_use_sip;
break;
default:
assert_not_reached("Uknown DHCP lease info item");
}
char **a;
STRV_FOREACH(a, servers) {
union in_addr_union ia;
/* Only look for IPv4 addresses */
@ -118,173 +149,24 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
addresses[n_addresses++] = ia.in;
}
if (link->network->dhcp_use_ntp && link->dhcp_lease) {
const struct in_addr *da = NULL;
int j, n;
if (lease_condition && link->dhcp_lease) {
const struct in_addr *da;
n = sd_dhcp_lease_get_ntp(link->dhcp_lease, &da);
size_t n = sd_dhcp_lease_get_servers(link->dhcp_lease, what, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
for (j = 0; j < n; j++)
if (in4_addr_is_non_local(&da[j]))
addresses[n_addresses++] = da[j];
for (unsigned i = 0; i < n; i++)
if (in4_addr_is_non_local(&da[i]))
addresses[n_addresses++] = da[i];
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_ntp(s, addresses, n_addresses);
}
static int link_push_uplink_pop3_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;
if (!link->network)
return 0;
log_link_debug(link, "Copying POP3 server information from link");
STRV_FOREACH(a, link->network->pop3) {
union in_addr_union ia;
/* Only look for IPv4 addresses */
if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
continue;
/* Never propagate obviously borked data */
if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia.in;
}
if (link->dhcp_lease) {
const struct in_addr *da = NULL;
int j, n;
n = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
for (j = 0; j < n; j++)
if (in4_addr_is_non_local(&da[j]))
addresses[n_addresses++] = da[j];
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_pop3_server(s, addresses, n_addresses);
}
static int link_push_uplink_smtp_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;
if (!link->network)
return 0;
log_link_debug(link, "Copying SMTP server information from link");
STRV_FOREACH(a, link->network->smtp) {
union in_addr_union ia;
/* Only look for IPv4 addresses */
if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
continue;
/* Never propagate obviously borked data */
if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia.in;
}
if (link->dhcp_lease) {
const struct in_addr *da = NULL;
int j, n;
n = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
for (j = 0; j < n; j++)
if (in4_addr_is_non_local(&da[j]))
addresses[n_addresses++] = da[j];
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_smtp_server(s, addresses, n_addresses);
}
static int link_push_uplink_sip_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;
if (!link->network)
return 0;
log_link_debug(link, "Copying SIP server information from link");
STRV_FOREACH(a, link->network->sip) {
union in_addr_union ia;
/* Only look for IPv4 addresses */
if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
continue;
/* Never propagate obviously borked data */
if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia.in;
}
if (link->network->dhcp_use_sip && link->dhcp_lease) {
const struct in_addr *da = NULL;
int j, n;
n = sd_dhcp_lease_get_sip(link->dhcp_lease, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
for (j = 0; j < n; j++)
if (in4_addr_is_non_local(&da[j]))
addresses[n_addresses++] = da[j];
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_sip(s, addresses, n_addresses);
return sd_dhcp_server_set_servers(s, what, addresses, n_addresses);
}
int dhcp4_server_configure(Link *link) {
@ -326,89 +208,63 @@ int dhcp4_server_configure(Link *link) {
return log_link_error_errno(link, r, "Failed to set default lease time for DHCPv4 server instance: %m");
}
if (link->network->dhcp_server_emit_dns) {
if (link->network->n_dhcp_server_dns > 0)
r = sd_dhcp_server_set_dns(link->dhcp_server, link->network->dhcp_server_dns, link->network->n_dhcp_server_dns);
else {
uplink = manager_find_uplink(link->manager, link);
acquired_uplink = true;
const struct {
bool condition;
const struct in_addr *servers;
unsigned n_servers;
} configs[] = {
[SD_DHCP_LEASE_DNS_SERVERS] = {
link->network->dhcp_server_emit_dns,
link->network->dhcp_server_dns,
link->network->n_dhcp_server_dns,
},
[SD_DHCP_LEASE_NTP_SERVERS] = {
link->network->dhcp_server_emit_ntp,
link->network->dhcp_server_ntp,
link->network->n_dhcp_server_ntp,
},
[SD_DHCP_LEASE_SIP_SERVERS] = {
link->network->dhcp_server_emit_sip,
link->network->dhcp_server_sip,
link->network->n_dhcp_server_sip,
},
[SD_DHCP_LEASE_POP3_SERVERS] = {
true,
link->network->dhcp_server_pop3,
link->network->n_dhcp_server_pop3,
},
[SD_DHCP_LEASE_SMTP_SERVERS] = {
true,
link->network->dhcp_server_smtp,
link->network->n_dhcp_server_smtp,
},
};
assert_cc(ELEMENTSOF(configs) == _SD_DHCP_LEASE_INFO_MAX);
if (!uplink) {
log_link_debug(link, "Not emitting DNS server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_uplink_dns_to_dhcp_server(uplink, link->dhcp_server);
for (unsigned n = 0; n < ELEMENTSOF(configs); n++)
if (configs[n].condition) {
if (configs[n].n_servers > 0)
r = sd_dhcp_server_set_servers(link->dhcp_server, n,
configs[n].servers, configs[n].n_servers);
else {
if (!acquired_uplink) {
uplink = manager_find_uplink(link->manager, link);
acquired_uplink = true;
}
if (!uplink) {
log_link_debug(link,
"Not emitting %s on link, couldn't find suitable uplink.",
dhcp_lease_info_to_string(n));
r = 0;
} else
r = link_push_uplink_to_dhcp_server(uplink, n, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r,
"Failed to set %s for DHCP server, ignoring: %m",
dhcp_lease_info_to_string(n));
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m");
}
if (link->network->dhcp_server_emit_ntp) {
if (link->network->n_dhcp_server_ntp > 0)
r = sd_dhcp_server_set_ntp(link->dhcp_server, link->network->dhcp_server_ntp, link->network->n_dhcp_server_ntp);
else {
if (!acquired_uplink)
uplink = manager_find_uplink(link->manager, link);
if (!uplink) {
log_link_debug(link, "Not emitting NTP server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_uplink_ntp_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
}
if (link->network->dhcp_server_emit_sip) {
if (link->network->n_dhcp_server_sip > 0)
r = sd_dhcp_server_set_sip(link->dhcp_server, link->network->dhcp_server_sip, link->network->n_dhcp_server_sip);
else {
if (!acquired_uplink)
uplink = manager_find_uplink(link->manager, link);
if (!uplink) {
log_link_debug(link, "Not emitting sip server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_uplink_sip_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set SIP server for DHCP server, ignoring: %m");
}
if (link->network->n_dhcp_server_pop3 > 0)
r = sd_dhcp_server_set_pop3_server(link->dhcp_server, link->network->dhcp_server_pop3, link->network->n_dhcp_server_pop3);
else {
if (!acquired_uplink)
uplink = manager_find_uplink(link->manager, link);
if (!uplink) {
log_link_debug(link, "Not emitting POP3 server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_uplink_pop3_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to set POP3 server for DHCP server, ignoring: %m");
if (link->network->n_dhcp_server_smtp > 0)
r = sd_dhcp_server_set_smtp_server(link->dhcp_server, link->network->dhcp_server_smtp, link->network->n_dhcp_server_smtp);
else {
if (!acquired_uplink)
uplink = manager_find_uplink(link->manager, link);
if (!uplink) {
log_link_debug(link, "Not emitting SMTP server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_uplink_smtp_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to SMTP server for DHCP server, ignoring: %m");
r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
if (r < 0)
@ -458,6 +314,51 @@ int dhcp4_server_configure(Link *link) {
return 0;
}
static int config_parse_dhcp_lease_server_list(
const char *unit,
const char *filename,
unsigned line,
const char *lvalue,
const char *rvalue,
struct in_addr **addresses,
unsigned *n_addresses) {
assert(filename);
assert(lvalue);
assert(rvalue);
for (const char *p = rvalue;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
int r;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse %s= address '%s', ignoring: %m", lvalue, w);
continue;
}
struct in_addr *m = reallocarray(*addresses, *n_addresses + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[(*n_addresses)++] = a.in;
*addresses = m;
}
}
int config_parse_dhcp_server_dns(
const char *unit,
const char *filename,
@ -471,45 +372,10 @@ int config_parse_dhcp_server_dns(
void *userdata) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
break;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse DNS server address '%s', ignoring assignment: %m", w);
continue;
}
m = reallocarray(n->dhcp_server_dns, n->n_dhcp_server_dns + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_dns++] = a.in;
n->dhcp_server_dns = m;
}
return 0;
return config_parse_dhcp_lease_server_list(unit, filename, line,
lvalue, rvalue,
&n->dhcp_server_dns, &n->n_dhcp_server_dns);
}
int config_parse_dhcp_server_ntp(
@ -525,43 +391,10 @@ int config_parse_dhcp_server_ntp(
void *userdata) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse NTP server address '%s', ignoring: %m", w);
continue;
}
m = reallocarray(n->dhcp_server_ntp, n->n_dhcp_server_ntp + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_ntp++] = a.in;
n->dhcp_server_ntp = m;
}
return config_parse_dhcp_lease_server_list(unit, filename, line,
lvalue, rvalue,
&n->dhcp_server_ntp, &n->n_dhcp_server_ntp);
}
int config_parse_dhcp_server_sip(
@ -577,45 +410,10 @@ int config_parse_dhcp_server_sip(
void *userdata) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse SIP server address '%s', ignoring: %m", w);
continue;
}
m = reallocarray(n->dhcp_server_sip, n->n_dhcp_server_sip + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_sip++] = a.in;
n->dhcp_server_sip = m;
}
return 0;
return config_parse_dhcp_lease_server_list(unit, filename, line,
lvalue, rvalue,
&n->dhcp_server_sip, &n->n_dhcp_server_sip);
}
int config_parse_dhcp_server_pop3_servers(
@ -631,45 +429,10 @@ int config_parse_dhcp_server_pop3_servers(
void *userdata) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse POP3 server address '%s', ignoring: %m", w);
continue;
}
m = reallocarray(n->dhcp_server_pop3, n->n_dhcp_server_pop3 + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_pop3++] = a.in;
n->dhcp_server_pop3 = m;
}
return 0;
return config_parse_dhcp_lease_server_list(unit, filename, line,
lvalue, rvalue,
&n->dhcp_server_pop3, &n->n_dhcp_server_pop3);
}
int config_parse_dhcp_server_smtp_servers(
@ -685,43 +448,9 @@ int config_parse_dhcp_server_smtp_servers(
void *userdata) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
return config_parse_dhcp_lease_server_list(unit, filename, line,
lvalue, rvalue,
&n->dhcp_server_smtp, &n->n_dhcp_server_smtp);
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse SMTP server address '%s', ignoring: %m", w);
continue;
}
m = reallocarray(n->dhcp_server_smtp, n->n_dhcp_server_smtp + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_smtp++] = a.in;
n->dhcp_server_smtp = m;
}
return 0;
}

View file

@ -8,14 +8,14 @@
#include "string-util.h"
#include "util.h"
static const char * const address_family_table[_ADDRESS_FAMILY_MAX] = {
static const char* const address_family_table[_ADDRESS_FAMILY_MAX] = {
[ADDRESS_FAMILY_NO] = "no",
[ADDRESS_FAMILY_YES] = "yes",
[ADDRESS_FAMILY_IPV4] = "ipv4",
[ADDRESS_FAMILY_IPV6] = "ipv6",
};
static const char * const link_local_address_family_table[_ADDRESS_FAMILY_MAX] = {
static const char* const link_local_address_family_table[_ADDRESS_FAMILY_MAX] = {
[ADDRESS_FAMILY_NO] = "no",
[ADDRESS_FAMILY_YES] = "yes",
[ADDRESS_FAMILY_IPV4] = "ipv4",
@ -24,25 +24,34 @@ static const char * const link_local_address_family_table[_ADDRESS_FAMILY_MAX] =
[ADDRESS_FAMILY_FALLBACK_IPV4] = "ipv4-fallback",
};
static const char * const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
static const char* const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
[ADDRESS_FAMILY_YES] = "both",
[ADDRESS_FAMILY_IPV4] = "ipv4",
[ADDRESS_FAMILY_IPV6] = "ipv6",
};
static const char * const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
static const char* const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
[ADDRESS_FAMILY_NO] = "none",
[ADDRESS_FAMILY_YES] = "both",
[ADDRESS_FAMILY_IPV4] = "ipv4",
[ADDRESS_FAMILY_IPV6] = "ipv6",
};
static const char* const dhcp_lease_info_table[_SD_DHCP_LEASE_INFO_MAX] = {
[SD_DHCP_LEASE_DNS_SERVERS] = "DNS servers",
[SD_DHCP_LEASE_NTP_SERVERS] = "NTP servers",
[SD_DHCP_LEASE_SIP_SERVERS] = "SIP servers",
[SD_DHCP_LEASE_POP3_SERVERS] = "POP3 servers",
[SD_DHCP_LEASE_SMTP_SERVERS] = "SMTP servers",
};
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily);
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
AddressFamily, "Failed to parse option");
DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_info, sd_dhcp_lease_info);
int config_parse_address_family_with_kernel(
const char* unit,

View file

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-dhcp-lease.h"
#include "conf-parser.h"
#include "hash-funcs.h"
#include "macro.h"
@ -38,6 +40,9 @@ AddressFamily routing_policy_rule_address_family_from_string(const char *s) _pur
const char *duplicate_address_detection_address_family_to_string(AddressFamily b) _const_;
AddressFamily duplicate_address_detection_address_family_from_string(const char *s) _pure_;
const char *dhcp_lease_info_to_string(sd_dhcp_lease_info info) _const_;
sd_dhcp_lease_info dhcp_lease_info_from_string(const char *s) _pure_;
int kernel_route_expiration_supported(void);
int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s);

View file

@ -33,6 +33,15 @@ typedef struct sd_dhcp_route sd_dhcp_route;
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
typedef enum sd_dhcp_lease_info {
SD_DHCP_LEASE_DNS_SERVERS = 0,
SD_DHCP_LEASE_NTP_SERVERS,
SD_DHCP_LEASE_SIP_SERVERS,
SD_DHCP_LEASE_POP3_SERVERS,
SD_DHCP_LEASE_SMTP_SERVERS,
_SD_DHCP_LEASE_INFO_MAX,
} sd_dhcp_lease_info;
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1);
@ -42,6 +51,7 @@ int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_servers(sd_dhcp_lease *lease, sd_dhcp_lease_info what, const struct in_addr **addr);
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);

View file

@ -21,6 +21,7 @@
#include <inttypes.h>
#include <netinet/in.h>
#include "sd-dhcp-lease.h"
#include "sd-dhcp-option.h"
#include "sd-event.h"
@ -47,12 +48,19 @@ int sd_dhcp_server_stop(sd_dhcp_server *server);
int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen, uint32_t offset, uint32_t size);
int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_set_servers(
sd_dhcp_server *server,
sd_dhcp_lease_info what,
const struct in_addr addresses[],
unsigned n_addresses);
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n);
int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n);
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v);
int sd_dhcp_server_add_vendor_option(sd_dhcp_server *server, sd_dhcp_option *v);