network: Implement DHCP Option 119 (Domain Search List) (#5932)
This adds a modified version of dhcp6_option_parse_domainname() that is able to parse compressed domain names, borrowing the idea from dns_packet_read_name(). It also adds pieces in networkd-link and networkd-manager to properly save/load the added option field. Resolves #2710.
This commit is contained in:
parent
6e4177315f
commit
b85bc551c3
|
@ -3690,6 +3690,14 @@ test_dhcp_option_LDADD = \
|
||||||
libsystemd-network.la \
|
libsystemd-network.la \
|
||||||
libsystemd-shared.la
|
libsystemd-shared.la
|
||||||
|
|
||||||
|
test_sd_dhcp_lease_SOURCES = \
|
||||||
|
src/libsystemd-network/dhcp-lease-internal.h \
|
||||||
|
src/libsystemd-network/test-sd-dhcp-lease.c
|
||||||
|
|
||||||
|
test_sd_dhcp_lease_LDADD = \
|
||||||
|
libsystemd-network.la \
|
||||||
|
libsystemd-shared.la
|
||||||
|
|
||||||
test_dhcp_client_SOURCES = \
|
test_dhcp_client_SOURCES = \
|
||||||
src/systemd/sd-dhcp-client.h \
|
src/systemd/sd-dhcp-client.h \
|
||||||
src/libsystemd-network/dhcp-protocol.h \
|
src/libsystemd-network/dhcp-protocol.h \
|
||||||
|
@ -3768,6 +3776,7 @@ tests += \
|
||||||
test-dhcp-option \
|
test-dhcp-option \
|
||||||
test-dhcp-client \
|
test-dhcp-client \
|
||||||
test-dhcp-server \
|
test-dhcp-server \
|
||||||
|
test-sd-dhcp-lease \
|
||||||
test-ipv4ll \
|
test-ipv4ll \
|
||||||
test-ndisc-rs \
|
test-ndisc-rs \
|
||||||
test-dhcp6-client \
|
test-dhcp6-client \
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct sd_dhcp_lease {
|
||||||
uint16_t mtu; /* 0 if unset */
|
uint16_t mtu; /* 0 if unset */
|
||||||
|
|
||||||
char *domainname;
|
char *domainname;
|
||||||
|
char **search_domains;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
char *root_path;
|
char *root_path;
|
||||||
|
|
||||||
|
@ -92,6 +93,7 @@ struct sd_dhcp_lease {
|
||||||
int dhcp_lease_new(sd_dhcp_lease **ret);
|
int dhcp_lease_new(sd_dhcp_lease **ret);
|
||||||
|
|
||||||
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
|
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
|
||||||
|
int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains);
|
||||||
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
|
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
|
||||||
|
|
||||||
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
|
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
|
||||||
|
|
|
@ -231,6 +231,21 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
|
||||||
return (int) lease->static_route_size;
|
return (int) lease->static_route_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
|
||||||
|
unsigned r;
|
||||||
|
|
||||||
|
assert_return(lease, -EINVAL);
|
||||||
|
assert_return(domains, -EINVAL);
|
||||||
|
|
||||||
|
r = strv_length(lease->search_domains);
|
||||||
|
if (r > 0) {
|
||||||
|
*domains = lease->search_domains;
|
||||||
|
return (int) r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENODATA;
|
||||||
|
}
|
||||||
|
|
||||||
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
|
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
|
||||||
assert_return(lease, -EINVAL);
|
assert_return(lease, -EINVAL);
|
||||||
assert_return(data, -EINVAL);
|
assert_return(data, -EINVAL);
|
||||||
|
@ -282,6 +297,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
|
||||||
free(lease->static_route);
|
free(lease->static_route);
|
||||||
free(lease->client_id);
|
free(lease->client_id);
|
||||||
free(lease->vendor_specific);
|
free(lease->vendor_specific);
|
||||||
|
strv_free(lease->search_domains);
|
||||||
return mfree(lease);
|
return mfree(lease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,6 +621,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SD_DHCP_OPTION_DOMAIN_SEARCH_LIST:
|
||||||
|
r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m");
|
||||||
|
break;
|
||||||
|
|
||||||
case SD_DHCP_OPTION_HOST_NAME:
|
case SD_DHCP_OPTION_HOST_NAME:
|
||||||
r = lease_parse_domain(option, len, &lease->hostname);
|
r = lease_parse_domain(option, len, &lease->hostname);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -696,6 +718,96 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parses compressed domain names. */
|
||||||
|
int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains) {
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
|
size_t pos = 0, cnt = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(domains);
|
||||||
|
assert_return(option && len > 0, -ENODATA);
|
||||||
|
|
||||||
|
while (pos < len) {
|
||||||
|
_cleanup_free_ char *name = NULL;
|
||||||
|
size_t n = 0, allocated = 0;
|
||||||
|
size_t jump_barrier = pos, next_chunk = 0;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
uint8_t c;
|
||||||
|
c = option[pos++];
|
||||||
|
|
||||||
|
if (c == 0) {
|
||||||
|
/* End of name */
|
||||||
|
break;
|
||||||
|
} else if (c <= 63) {
|
||||||
|
const char *label;
|
||||||
|
|
||||||
|
/* Literal label */
|
||||||
|
label = (const char*) (option + pos);
|
||||||
|
pos += c;
|
||||||
|
if (pos >= len)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(name, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
name[n++] = '.';
|
||||||
|
|
||||||
|
r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
n += r;
|
||||||
|
} else if ((c & 0xc0) == 0xc0) {
|
||||||
|
/* Pointer */
|
||||||
|
|
||||||
|
uint8_t d;
|
||||||
|
uint16_t ptr;
|
||||||
|
|
||||||
|
if (pos >= len)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
d = option[pos++];
|
||||||
|
ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
|
||||||
|
|
||||||
|
/* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
|
||||||
|
if (ptr >= jump_barrier)
|
||||||
|
return -EBADMSG;
|
||||||
|
jump_barrier = ptr;
|
||||||
|
|
||||||
|
/* Save current location so we don't end up re-parsing what's parsed so far. */
|
||||||
|
if (next_chunk == 0)
|
||||||
|
next_chunk = pos;
|
||||||
|
|
||||||
|
pos = ptr;
|
||||||
|
} else
|
||||||
|
return -EBADMSG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(name, allocated, n + 1))
|
||||||
|
return -ENOMEM;
|
||||||
|
name[n] = 0;
|
||||||
|
|
||||||
|
r = strv_extend(&names, name);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
cnt++;
|
||||||
|
|
||||||
|
if (next_chunk != 0)
|
||||||
|
pos = next_chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
*domains = names;
|
||||||
|
names = NULL;
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) {
|
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) {
|
||||||
struct sd_dhcp_raw_option *cur, *option;
|
struct sd_dhcp_raw_option *cur, *option;
|
||||||
|
|
||||||
|
@ -751,6 +863,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||||
const char *string;
|
const char *string;
|
||||||
uint16_t mtu;
|
uint16_t mtu;
|
||||||
_cleanup_free_ sd_dhcp_route **routes = NULL;
|
_cleanup_free_ sd_dhcp_route **routes = NULL;
|
||||||
|
char **search_domains = NULL;
|
||||||
uint32_t t1, t2, lifetime;
|
uint32_t t1, t2, lifetime;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -824,6 +937,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
fprintf(f, "DOMAINNAME=%s\n", string);
|
fprintf(f, "DOMAINNAME=%s\n", string);
|
||||||
|
|
||||||
|
r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
|
||||||
|
if (r > 0) {
|
||||||
|
fputs("DOMAIN_SEARCH_LIST=", f);
|
||||||
|
fputstrv(f, search_domains, NULL, NULL);
|
||||||
|
fputs("\n", f);
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_dhcp_lease_get_hostname(lease, &string);
|
r = sd_dhcp_lease_get_hostname(lease, &string);
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
fprintf(f, "HOSTNAME=%s\n", string);
|
fprintf(f, "HOSTNAME=%s\n", string);
|
||||||
|
@ -905,6 +1025,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||||
*ntp = NULL,
|
*ntp = NULL,
|
||||||
*mtu = NULL,
|
*mtu = NULL,
|
||||||
*routes = NULL,
|
*routes = NULL,
|
||||||
|
*domains = NULL,
|
||||||
*client_id_hex = NULL,
|
*client_id_hex = NULL,
|
||||||
*vendor_specific_hex = NULL,
|
*vendor_specific_hex = NULL,
|
||||||
*lifetime = NULL,
|
*lifetime = NULL,
|
||||||
|
@ -933,6 +1054,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||||
"MTU", &mtu,
|
"MTU", &mtu,
|
||||||
"DOMAINNAME", &lease->domainname,
|
"DOMAINNAME", &lease->domainname,
|
||||||
"HOSTNAME", &lease->hostname,
|
"HOSTNAME", &lease->hostname,
|
||||||
|
"DOMAIN_SEARCH_LIST", &domains,
|
||||||
"ROOT_PATH", &lease->root_path,
|
"ROOT_PATH", &lease->root_path,
|
||||||
"ROUTES", &routes,
|
"ROUTES", &routes,
|
||||||
"CLIENTID", &client_id_hex,
|
"CLIENTID", &client_id_hex,
|
||||||
|
@ -1038,6 +1160,18 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||||
log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu);
|
log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (domains) {
|
||||||
|
_cleanup_strv_free_ char **a = NULL;
|
||||||
|
a = strv_split(domains, " ");
|
||||||
|
if (!a)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (!strv_isempty(a)) {
|
||||||
|
lease->search_domains = a;
|
||||||
|
a = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (routes) {
|
if (routes) {
|
||||||
r = deserialize_dhcp_routes(
|
r = deserialize_dhcp_routes(
|
||||||
&lease->static_route,
|
&lease->static_route,
|
||||||
|
|
90
src/libsystemd-network/test-sd-dhcp-lease.c
Normal file
90
src/libsystemd-network/test-sd-dhcp-lease.c
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "dhcp-lease-internal.h"
|
||||||
|
#include "macro.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
|
|
||||||
|
/* According to RFC1035 section 4.1.4, a domain name in a message can be either:
|
||||||
|
* - a sequence of labels ending in a zero octet
|
||||||
|
* - a pointer
|
||||||
|
* - a sequence of labels ending with a pointer
|
||||||
|
*/
|
||||||
|
static void test_dhcp_lease_parse_search_domains_basic(void) {
|
||||||
|
int r;
|
||||||
|
_cleanup_strv_free_ char **domains = NULL;
|
||||||
|
static const uint8_t optionbuf[] = {
|
||||||
|
0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
|
||||||
|
0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
|
||||||
|
assert_se(r == 2);
|
||||||
|
assert_se(streq(domains[0], "FOO.BAR"));
|
||||||
|
assert_se(streq(domains[1], "ABCD.EFG"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dhcp_lease_parse_search_domains_ptr(void) {
|
||||||
|
int r;
|
||||||
|
_cleanup_strv_free_ char **domains = NULL;
|
||||||
|
static const uint8_t optionbuf[] = {
|
||||||
|
0x03, 'F', 'O', 'O', 0x00, 0xC0, 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
|
||||||
|
assert_se(r == 2);
|
||||||
|
assert_se(streq(domains[0], "FOO"));
|
||||||
|
assert_se(streq(domains[1], "FOO"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dhcp_lease_parse_search_domains_labels_and_ptr(void) {
|
||||||
|
int r;
|
||||||
|
_cleanup_strv_free_ char **domains = NULL;
|
||||||
|
static const uint8_t optionbuf[] = {
|
||||||
|
0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
|
||||||
|
0x03, 'A', 'B', 'C', 0xC0, 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
|
||||||
|
assert_se(r == 2);
|
||||||
|
assert_se(streq(domains[0], "FOO.BAR"));
|
||||||
|
assert_se(streq(domains[1], "ABC.BAR"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tests for exceptions. */
|
||||||
|
|
||||||
|
static void test_dhcp_lease_parse_search_domains_no_data(void) {
|
||||||
|
_cleanup_strv_free_ char **domains = NULL;
|
||||||
|
static const uint8_t optionbuf[3] = {0, 0, 0};
|
||||||
|
|
||||||
|
assert_se(dhcp_lease_parse_search_domains(NULL, 0, &domains) == -ENODATA);
|
||||||
|
assert_se(dhcp_lease_parse_search_domains(optionbuf, 0, &domains) == -ENODATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dhcp_lease_parse_search_domains_loops(void) {
|
||||||
|
_cleanup_strv_free_ char **domains = NULL;
|
||||||
|
static const uint8_t optionbuf[] = {
|
||||||
|
0x03, 'F', 'O', 'O', 0x00, 0x03, 'B', 'A', 'R', 0xC0, 0x06,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains) == -EBADMSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dhcp_lease_parse_search_domains_wrong_len(void) {
|
||||||
|
_cleanup_strv_free_ char **domains = NULL;
|
||||||
|
static const uint8_t optionbuf[] = {
|
||||||
|
0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
|
||||||
|
0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf) - 5, &domains) == -EBADMSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
test_dhcp_lease_parse_search_domains_basic();
|
||||||
|
test_dhcp_lease_parse_search_domains_ptr();
|
||||||
|
test_dhcp_lease_parse_search_domains_labels_and_ptr();
|
||||||
|
test_dhcp_lease_parse_search_domains_no_data();
|
||||||
|
test_dhcp_lease_parse_search_domains_loops();
|
||||||
|
test_dhcp_lease_parse_search_domains_wrong_len();
|
||||||
|
}
|
|
@ -3266,6 +3266,7 @@ int link_save(Link *link) {
|
||||||
sd_dhcp6_lease *dhcp6_lease = NULL;
|
sd_dhcp6_lease *dhcp6_lease = NULL;
|
||||||
const char *dhcp_domainname = NULL;
|
const char *dhcp_domainname = NULL;
|
||||||
char **dhcp6_domains = NULL;
|
char **dhcp6_domains = NULL;
|
||||||
|
char **dhcp_domains = NULL;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
|
||||||
if (link->dhcp6_client) {
|
if (link->dhcp6_client) {
|
||||||
|
@ -3375,13 +3376,16 @@ int link_save(Link *link) {
|
||||||
fputc('\n', f);
|
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) {
|
||||||
(void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
|
(void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
|
||||||
|
(void) sd_dhcp_lease_get_search_domains(link->dhcp_lease, &dhcp_domains);
|
||||||
|
}
|
||||||
if (dhcp6_lease)
|
if (dhcp6_lease)
|
||||||
(void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
|
(void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs("DOMAINS=", f);
|
fputs("DOMAINS=", f);
|
||||||
|
space = false;
|
||||||
fputstrv(f, link->network->search_domains, NULL, &space);
|
fputstrv(f, link->network->search_domains, NULL, &space);
|
||||||
|
|
||||||
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
|
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
|
||||||
|
@ -3389,6 +3393,8 @@ int link_save(Link *link) {
|
||||||
|
|
||||||
if (dhcp_domainname)
|
if (dhcp_domainname)
|
||||||
fputs_with_space(f, dhcp_domainname, NULL, &space);
|
fputs_with_space(f, dhcp_domainname, NULL, &space);
|
||||||
|
if (dhcp_domains)
|
||||||
|
fputstrv(f, dhcp_domains, NULL, &space);
|
||||||
if (dhcp6_domains)
|
if (dhcp6_domains)
|
||||||
fputstrv(f, dhcp6_domains, NULL, &space);
|
fputstrv(f, dhcp6_domains, NULL, &space);
|
||||||
|
|
||||||
|
@ -3399,13 +3405,16 @@ int link_save(Link *link) {
|
||||||
fputc('\n', f);
|
fputc('\n', f);
|
||||||
|
|
||||||
fputs("ROUTE_DOMAINS=", f);
|
fputs("ROUTE_DOMAINS=", f);
|
||||||
fputstrv(f, link->network->route_domains, NULL, NULL);
|
space = false;
|
||||||
|
fputstrv(f, link->network->route_domains, NULL, &space);
|
||||||
|
|
||||||
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
|
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
|
||||||
NDiscDNSSL *dd;
|
NDiscDNSSL *dd;
|
||||||
|
|
||||||
if (dhcp_domainname)
|
if (dhcp_domainname)
|
||||||
fputs_with_space(f, dhcp_domainname, NULL, &space);
|
fputs_with_space(f, dhcp_domainname, NULL, &space);
|
||||||
|
if (dhcp_domains)
|
||||||
|
fputstrv(f, dhcp_domains, NULL, &space);
|
||||||
if (dhcp6_domains)
|
if (dhcp6_domains)
|
||||||
fputstrv(f, dhcp6_domains, NULL, &space);
|
fputstrv(f, dhcp6_domains, NULL, &space);
|
||||||
|
|
||||||
|
|
|
@ -961,15 +961,20 @@ static int manager_save(Manager *m) {
|
||||||
|
|
||||||
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
|
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
|
||||||
const char *domainname;
|
const char *domainname;
|
||||||
|
char **domains = NULL;
|
||||||
|
|
||||||
|
OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
|
||||||
r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
|
r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
|
r = ordered_set_put_strdup(target_domains, domainname);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else if (r != -ENODATA)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES)
|
r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
|
||||||
r = ordered_set_put_strdup(search_domains, domainname);
|
if (r >= 0) {
|
||||||
else
|
r = ordered_set_put_strdupv(target_domains, domains);
|
||||||
r = ordered_set_put_strdup(route_domains, domainname);
|
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
} else if (r != -ENODATA)
|
} else if (r != -ENODATA)
|
||||||
|
|
|
@ -76,6 +76,7 @@ enum {
|
||||||
SD_DHCP_OPTION_FQDN = 81,
|
SD_DHCP_OPTION_FQDN = 81,
|
||||||
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
||||||
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
|
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
|
||||||
|
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
|
||||||
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
|
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
|
||||||
SD_DHCP_OPTION_PRIVATE_BASE = 224,
|
SD_DHCP_OPTION_PRIVATE_BASE = 224,
|
||||||
SD_DHCP_OPTION_PRIVATE_LAST = 254,
|
SD_DHCP_OPTION_PRIVATE_LAST = 254,
|
||||||
|
|
|
@ -49,6 +49,7 @@ 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_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||||
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
|
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
|
||||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
|
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
|
||||||
|
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
|
||||||
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
|
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
|
||||||
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
|
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
|
||||||
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
|
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
|
||||||
|
|
|
@ -800,6 +800,12 @@ tests += [
|
||||||
libsystemd_network],
|
libsystemd_network],
|
||||||
[]],
|
[]],
|
||||||
|
|
||||||
|
[['src/libsystemd-network/test-sd-dhcp-lease.c',
|
||||||
|
'src/libsystemd-network/dhcp-lease-internal.h'],
|
||||||
|
[libshared,
|
||||||
|
libsystemd_network],
|
||||||
|
[]],
|
||||||
|
|
||||||
[['src/libsystemd-network/test-dhcp-client.c',
|
[['src/libsystemd-network/test-dhcp-client.c',
|
||||||
'src/libsystemd-network/dhcp-protocol.h',
|
'src/libsystemd-network/dhcp-protocol.h',
|
||||||
'src/libsystemd-network/dhcp-internal.h',
|
'src/libsystemd-network/dhcp-internal.h',
|
||||||
|
|
Loading…
Reference in a new issue