DHCP: Add support to emit and retrieve POP3 server

This commit is contained in:
Susant Sahani
2020-03-28 03:34:27 +01:00
parent f678ac7e29
commit 284e8fd0d7
8 changed files with 168 additions and 9 deletions
+117
View File
@@ -140,6 +140,55 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
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_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;
@@ -281,6 +330,22 @@ int dhcp4_server_configure(Link *link) {
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");
r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
if (r < 0)
return log_link_error_errno(link, r, "Failed to set router emission for DHCP server: %m");
@@ -486,3 +551,55 @@ int config_parse_dhcp_server_sip(
n->dhcp_server_sip = m;
}
}
int config_parse_dhcp_server_pop3_servers(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
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;
}
}
+1
View File
@@ -12,3 +12,4 @@ int dhcp4_server_configure(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_pop3_servers);
+15
View File
@@ -4100,6 +4100,21 @@ int link_save(Link *link) {
space = true;
}
fputc('\n', f);
fputs("POP3_SERVERS=", f);
space = false;
fputstrv(f, link->network->pop3, 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->network->dhcp6_use_ntp && dhcp6_lease) {
struct in6_addr *in6_addrs;
char **hosts;
+19 -9
View File
@@ -1488,7 +1488,8 @@ static int ordered_set_put_in4_addrv(OrderedSet *s,
}
static int manager_save(Manager *m) {
_cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
_cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL,
*search_domains = NULL, *route_domains = NULL;
const char *operstate_str, *carrier_state_str, *address_state_str;
LinkOperationalState operstate = LINK_OPERSTATE_OFF;
LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
@@ -1496,6 +1497,7 @@ static int manager_save(Manager *m) {
_cleanup_free_ char *temp_path = NULL;
_cleanup_strv_free_ char **p = NULL;
_cleanup_fclose_ FILE *f = NULL;
const struct in_addr *addresses;
Link *link;
Iterator i;
int r;
@@ -1512,10 +1514,14 @@ static int manager_save(Manager *m) {
if (!ntp)
return -ENOMEM;
sip = ordered_set_new(&string_hash_ops);
if (!sip)
sip = ordered_set_new(&string_hash_ops);
if (!sip)
return -ENOMEM;
pop3 = ordered_set_new(&string_hash_ops);
if (!pop3)
return -ENOMEM;
search_domains = ordered_set_new(&dns_name_hash_ops);
if (!search_domains)
return -ENOMEM;
@@ -1562,8 +1568,6 @@ static int manager_save(Manager *m) {
/* Secondly, add the entries acquired via DHCP */
if (link->network->dhcp_use_dns) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
if (r > 0) {
r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local);
@@ -1574,8 +1578,6 @@ static int manager_save(Manager *m) {
}
if (link->network->dhcp_use_ntp) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
if (r > 0) {
r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local);
@@ -1586,8 +1588,6 @@ static int manager_save(Manager *m) {
}
if (link->network->dhcp_use_sip) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses);
if (r > 0) {
r = ordered_set_put_in4_addrv(sip, addresses, r, in4_addr_is_non_local);
@@ -1597,6 +1597,15 @@ static int manager_save(Manager *m) {
return r;
}
r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses);
if (r > 0) {
r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local);
if (r < 0)
return r;
} else if (r < 0 && r != -ENODATA)
return r;
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
const char *domainname;
char **domains = NULL;
@@ -1648,6 +1657,7 @@ static int manager_save(Manager *m) {
ordered_set_print(f, "DNS=", dns);
ordered_set_print(f, "NTP=", ntp);
ordered_set_print(f, "SIP=", sip);
ordered_set_print(f, "POP3_SERVERS=", pop3);
ordered_set_print(f, "DOMAINS=", search_domains);
ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
+1
View File
@@ -207,6 +207,7 @@ DHCPServer.EmitNTP, config_parse_bool,
DHCPServer.NTP, config_parse_dhcp_server_ntp, 0, 0
DHCPServer.EmitSIP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_sip)
DHCPServer.SIP, config_parse_dhcp_server_sip, 0, 0
DHCPServer.POP3Servers, config_parse_dhcp_server_pop3_servers, 0, 0
DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router)
DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone)
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
+4
View File
@@ -147,6 +147,9 @@ struct Network {
struct in_addr *dhcp_server_sip;
unsigned n_dhcp_server_sip;
struct in_addr *dhcp_server_pop3;
unsigned n_dhcp_server_pop3;
bool dhcp_server_emit_router;
bool dhcp_server_emit_timezone;
char *dhcp_server_timezone;
@@ -296,6 +299,7 @@ struct Network {
char **ntp;
char **sip;
char **pop3;
char **bind_carrier;
};