mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-14 03:10:30 +01:00
dhcp: merge branch 'bg/dhcpv6-hostname-rh1858344'
Fix setting hostname from DHCPv6
https://bugzilla.redhat.com/show_bug.cgi?id=1858344
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/589
(cherry picked from commit 7bf7223ece)
This commit is contained in:
commit
0af19c832b
10 changed files with 151 additions and 52 deletions
|
|
@ -183,6 +183,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = {
|
|||
REQ (NM_DHCP_OPTION_DHCP6_DNS_SERVERS, "dhcp6_name_servers", TRUE ),
|
||||
REQ (NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, "dhcp6_domain_search", TRUE ),
|
||||
REQ (NM_DHCP_OPTION_DHCP6_SNTP_SERVERS, "dhcp6_sntp_servers", TRUE ),
|
||||
REQ (NM_DHCP_OPTION_DHCP6_FQDN, "fqdn_fqdn", FALSE ),
|
||||
REQ (NM_DHCP_OPTION_DHCP6_MUD_URL, "dhcp6_mud_url", FALSE ),
|
||||
|
||||
/* Internal values */
|
||||
|
|
|
|||
|
|
@ -160,7 +160,9 @@ typedef enum {
|
|||
NM_DHCP_OPTION_DHCP6_DNS_SERVERS = 23,
|
||||
NM_DHCP_OPTION_DHCP6_DOMAIN_LIST = 24,
|
||||
NM_DHCP_OPTION_DHCP6_SNTP_SERVERS = 31,
|
||||
NM_DHCP_OPTION_DHCP6_FQDN = 39,
|
||||
NM_DHCP_OPTION_DHCP6_MUD_URL = 112,
|
||||
|
||||
/* Internal values */
|
||||
NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS = 1026,
|
||||
NM_DHCP_OPTION_DHCP6_NM_PREFIXLEN = 1027,
|
||||
|
|
|
|||
|
|
@ -740,6 +740,7 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
|
|||
uint32_t lft_pref, lft_valid;
|
||||
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
|
||||
char **domains;
|
||||
const char *s;
|
||||
nm_auto_free_gstring GString *str = NULL;
|
||||
int num, i;
|
||||
|
||||
|
|
@ -808,6 +809,13 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
|
|||
str->str);
|
||||
}
|
||||
|
||||
if (sd_dhcp6_lease_get_fqdn (lease, &s) >= 0) {
|
||||
nm_dhcp_option_add_option (options,
|
||||
_nm_dhcp_option_dhcp6_options,
|
||||
NM_DHCP_OPTION_DHCP6_FQDN,
|
||||
s);
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_options, g_steal_pointer (&options));
|
||||
return g_steal_pointer (&ip6_config);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -764,7 +764,7 @@ update_system_hostname (NMPolicy *self, const char *msg)
|
|||
/* Grab a hostname out of the device's DHCP6 config */
|
||||
dhcp_config = nm_device_get_dhcp_config (get_default_device (self, AF_INET6), AF_INET6);
|
||||
if (dhcp_config) {
|
||||
dhcp_hostname = nm_dhcp_config_get_option (dhcp_config, "host_name");
|
||||
dhcp_hostname = nm_dhcp_config_get_option (dhcp_config, "fqdn_fqdn");
|
||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||
p = nm_str_skip_leading_spaces (dhcp_hostname);
|
||||
if (p[0]) {
|
||||
|
|
|
|||
|
|
@ -109,8 +109,9 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
|
|||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||
struct in6_addr **addrs, size_t count,
|
||||
size_t *allocated);
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr);
|
||||
int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen,
|
||||
char ***str_arr);
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str);
|
||||
|
||||
int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
|
||||
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ struct sd_dhcp6_lease {
|
|||
size_t ntp_allocated;
|
||||
char **ntp_fqdn;
|
||||
size_t ntp_fqdn_count;
|
||||
char *fqdn;
|
||||
};
|
||||
|
||||
int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
|
||||
|
|
@ -57,5 +58,6 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
|
|||
int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen);
|
||||
int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval,
|
||||
size_t optlen) ;
|
||||
int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||
|
||||
int dhcp6_lease_new(sd_dhcp6_lease **ret);
|
||||
|
|
|
|||
|
|
@ -644,60 +644,104 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
|||
return count;
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
|
||||
size_t pos = 0, idx = 0;
|
||||
static int parse_domain(const uint8_t **data, uint16_t *len, char **out_domain) {
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
const uint8_t *optval = *data;
|
||||
uint16_t optlen = *len;
|
||||
bool first = true;
|
||||
int r;
|
||||
|
||||
if (optlen <= 1)
|
||||
return -ENODATA;
|
||||
|
||||
for (;;) {
|
||||
const char *label;
|
||||
uint8_t c;
|
||||
|
||||
if (optlen == 0)
|
||||
break;
|
||||
|
||||
c = *optval;
|
||||
optval++;
|
||||
optlen--;
|
||||
|
||||
if (c == 0)
|
||||
/* End label */
|
||||
break;
|
||||
if (c > 63)
|
||||
return -EBADMSG;
|
||||
if (c > optlen)
|
||||
return -EMSGSIZE;
|
||||
|
||||
/* Literal label */
|
||||
label = (const char *)optval;
|
||||
optval += c;
|
||||
optlen -= c;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
return -ENOMEM;
|
||||
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
ret[n++] = '.';
|
||||
|
||||
r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n += r;
|
||||
}
|
||||
|
||||
if (n) {
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + 1))
|
||||
return -ENOMEM;
|
||||
ret[n] = 0;
|
||||
}
|
||||
|
||||
*out_domain = TAKE_PTR(ret);
|
||||
*data = optval;
|
||||
*len = optlen;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str) {
|
||||
_cleanup_free_ char *domain = NULL;
|
||||
int r;
|
||||
|
||||
r = parse_domain(&optval, &optlen, &domain);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -ENODATA;
|
||||
if (optlen != 0)
|
||||
return -EINVAL;
|
||||
|
||||
*str = TAKE_PTR(domain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
|
||||
size_t idx = 0;
|
||||
_cleanup_strv_free_ char **names = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(optlen > 1, -ENODATA);
|
||||
assert_return(optval[optlen - 1] == '\0', -EINVAL);
|
||||
if (optlen <= 1)
|
||||
return -ENODATA;
|
||||
if (optval[optlen - 1] != '\0')
|
||||
return -EINVAL;
|
||||
|
||||
while (pos < optlen) {
|
||||
while (optlen > 0) {
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
bool first = true;
|
||||
|
||||
for (;;) {
|
||||
const char *label;
|
||||
uint8_t c;
|
||||
|
||||
c = optval[pos++];
|
||||
|
||||
if (c == 0)
|
||||
/* End of name */
|
||||
break;
|
||||
if (c > 63)
|
||||
return -EBADMSG;
|
||||
|
||||
/* Literal label */
|
||||
label = (const char *)&optval[pos];
|
||||
pos += c;
|
||||
if (pos >= optlen)
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
return -ENOMEM;
|
||||
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
ret[n++] = '.';
|
||||
|
||||
r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n += r;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
r = parse_domain(&optval, &optlen, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, allocated, n + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
ret[n] = 0;
|
||||
|
||||
r = strv_extend(&names, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
|
|
|||
|
|
@ -1288,6 +1288,13 @@ static int client_parse_message(
|
|||
|
||||
break;
|
||||
|
||||
case SD_DHCP6_OPTION_FQDN:
|
||||
r = dhcp6_lease_set_fqdn(lease, optval, optlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
|
||||
if (optlen != 4)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
|
|||
if (!optlen)
|
||||
return 0;
|
||||
|
||||
r = dhcp6_option_parse_domainname(optval, optlen, &domains);
|
||||
r = dhcp6_option_parse_domainname_list(optval, optlen, &domains);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -296,8 +296,8 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
|
|||
break;
|
||||
|
||||
case DHCP6_NTP_SUBOPTION_SRV_FQDN:
|
||||
r = dhcp6_option_parse_domainname(subval, sublen,
|
||||
&servers);
|
||||
r = dhcp6_option_parse_domainname_list(subval, sublen,
|
||||
&servers);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -367,6 +367,38 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) {
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval,
|
||||
size_t optlen) {
|
||||
int r;
|
||||
char *fqdn;
|
||||
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(optval, -EINVAL);
|
||||
|
||||
if (optlen < 2)
|
||||
return -ENODATA;
|
||||
|
||||
/* Ignore the flags field, it doesn't carry any useful
|
||||
information for clients. */
|
||||
r = dhcp6_option_parse_domainname(optval + 1, optlen - 1, &fqdn);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return free_and_replace(lease->fqdn, fqdn);
|
||||
}
|
||||
|
||||
int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **fqdn) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(fqdn, -EINVAL);
|
||||
|
||||
if (lease->fqdn) {
|
||||
*fqdn = lease->fqdn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
|
||||
assert(lease);
|
||||
|
||||
|
|
@ -375,6 +407,7 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
|
|||
dhcp6_lease_free_ia(&lease->pd);
|
||||
|
||||
free(lease->dns);
|
||||
free(lease->fqdn);
|
||||
|
||||
lease->domains = strv_free(lease->domains);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **addrs)
|
|||
int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains);
|
||||
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **addrs);
|
||||
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn);
|
||||
int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **fqdn);
|
||||
|
||||
sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease);
|
||||
sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue