mirror of
https://github.com/systemd/systemd
synced 2025-10-05 11:44:45 +02:00
Compare commits
8 Commits
8acee7c35e
...
0ccc31d964
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0ccc31d964 | ||
![]() |
e89f865157 | ||
![]() |
28575ac014 | ||
![]() |
3eb5402b5c | ||
![]() |
3a83ea5bf2 | ||
![]() |
238c427aa9 | ||
![]() |
d2191515ba | ||
![]() |
551bfe7738 |
@ -3233,6 +3233,7 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
|
|||||||
<term><varname>UseDNS=</varname></term>
|
<term><varname>UseDNS=</varname></term>
|
||||||
<term><varname>UseDNR=</varname></term>
|
<term><varname>UseDNR=</varname></term>
|
||||||
<term><varname>UseNTP=</varname></term>
|
<term><varname>UseNTP=</varname></term>
|
||||||
|
<term><varname>UseSIP=</varname></term>
|
||||||
<term><varname>UseHostname=</varname></term>
|
<term><varname>UseHostname=</varname></term>
|
||||||
<term><varname>UseDomains=</varname></term>
|
<term><varname>UseDomains=</varname></term>
|
||||||
<term><varname>NetLabel=</varname></term>
|
<term><varname>NetLabel=</varname></term>
|
||||||
|
18
meson.build
18
meson.build
@ -1775,11 +1775,21 @@ if conf.get('BPF_FRAMEWORK') == 1
|
|||||||
target_triplet_cmd = run_command('gcc', '-print-multiarch', check: false)
|
target_triplet_cmd = run_command('gcc', '-print-multiarch', check: false)
|
||||||
endif
|
endif
|
||||||
if target_triplet_cmd.returncode() == 0
|
if target_triplet_cmd.returncode() == 0
|
||||||
|
sysroot = meson.get_external_property('sys_root', '/')
|
||||||
target_triplet = target_triplet_cmd.stdout().strip()
|
target_triplet = target_triplet_cmd.stdout().strip()
|
||||||
bpf_o_unstripped_cmd += [
|
target_include_dir = sysroot / 'usr' / 'include'
|
||||||
'-isystem',
|
target_triple_include_dir = target_include_dir / target_triplet
|
||||||
'/usr/include/@0@'.format(target_triplet)
|
isystem_dir = ''
|
||||||
]
|
if fs.is_dir(target_triple_include_dir)
|
||||||
|
isystem_dir = target_triple_include_dir
|
||||||
|
elif fs.is_dir(target_include_dir)
|
||||||
|
isystem_dir = target_include_dir
|
||||||
|
endif
|
||||||
|
if isystem_dir != ''
|
||||||
|
bpf_o_unstripped_cmd += [
|
||||||
|
'-isystem', isystem_dir
|
||||||
|
]
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bpf_o_unstripped_cmd += [
|
bpf_o_unstripped_cmd += [
|
||||||
|
@ -43,6 +43,9 @@ struct sd_dhcp6_lease {
|
|||||||
char **ntp_fqdn;
|
char **ntp_fqdn;
|
||||||
struct in6_addr *sntp;
|
struct in6_addr *sntp;
|
||||||
size_t sntp_count;
|
size_t sntp_count;
|
||||||
|
struct in6_addr *sip;
|
||||||
|
size_t sip_count;
|
||||||
|
char **sip_domains;
|
||||||
char *fqdn;
|
char *fqdn;
|
||||||
char *captive_portal;
|
char *captive_portal;
|
||||||
struct sd_dhcp6_option **sorted_vendor_options;
|
struct sd_dhcp6_option **sorted_vendor_options;
|
||||||
@ -62,6 +65,8 @@ int dhcp6_lease_add_dns(sd_dhcp6_lease *lease, const uint8_t *optval, size_t opt
|
|||||||
int dhcp6_lease_add_domains(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
int dhcp6_lease_add_domains(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||||
int dhcp6_lease_add_ntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
int dhcp6_lease_add_ntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||||
int dhcp6_lease_add_sntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
int dhcp6_lease_add_sntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||||
|
int dhcp6_lease_add_sip_addrs(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||||
|
int dhcp6_lease_add_sip_domains(sd_dhcp6_lease *lease, const 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_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||||
int dhcp6_lease_set_captive_portal(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
int dhcp6_lease_set_captive_portal(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
|
||||||
|
|
||||||
|
@ -629,6 +629,56 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret) {
|
|||||||
return strv_length(lease->ntp_fqdn);
|
return strv_length(lease->ntp_fqdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dhcp6_lease_add_sip_addrs(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
|
||||||
|
assert(lease);
|
||||||
|
assert(optval || optlen == 0);
|
||||||
|
|
||||||
|
if (optlen == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return dhcp6_option_parse_addresses(optval, optlen, &lease->sip, &lease->sip_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_dhcp6_lease_get_sip_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
|
||||||
|
assert_return(lease, -EINVAL);
|
||||||
|
|
||||||
|
if (lease->sip) {
|
||||||
|
if (ret)
|
||||||
|
*ret = lease->sip;
|
||||||
|
return lease->sip_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENODATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dhcp6_lease_add_sip_domains(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
|
||||||
|
_cleanup_strv_free_ char **domains = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(lease);
|
||||||
|
assert(optval || optlen == 0);
|
||||||
|
|
||||||
|
if (optlen == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = dhcp6_option_parse_domainname_list(optval, optlen, &domains);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return strv_extend_strv_consume(&lease->sip_domains, TAKE_PTR(domains), /* filter_duplicates = */ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_dhcp6_lease_get_sip_domains(sd_dhcp6_lease *lease, char ***ret) {
|
||||||
|
assert_return(lease, -EINVAL);
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
|
if (!lease->sip_domains)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
*ret = lease->sip_domains;
|
||||||
|
return strv_length(lease->sip_domains);
|
||||||
|
}
|
||||||
|
|
||||||
int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
|
int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) {
|
||||||
char *fqdn;
|
char *fqdn;
|
||||||
int r;
|
int r;
|
||||||
@ -930,6 +980,19 @@ static int dhcp6_lease_parse_message(
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SD_DHCP6_OPTION_SIP_SERVER_ADDRESS:
|
||||||
|
r = dhcp6_lease_add_sip_addrs(lease, optval, optlen);
|
||||||
|
if (r < 0)
|
||||||
|
log_dhcp6_client_errno(client, r, "Failed to parse SIP server address option, ignoring: %m");
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME:
|
||||||
|
r = dhcp6_lease_add_sip_domains(lease, optval, optlen);
|
||||||
|
if (r < 0)
|
||||||
|
log_dhcp6_client_errno(client, r, "Failed to parse SIP server domain name option, ignoring: %m");
|
||||||
|
break;
|
||||||
|
|
||||||
case SD_DHCP6_OPTION_CAPTIVE_PORTAL:
|
case SD_DHCP6_OPTION_CAPTIVE_PORTAL:
|
||||||
r = dhcp6_lease_set_captive_portal(lease, optval, optlen);
|
r = dhcp6_lease_set_captive_portal(lease, optval, optlen);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -1020,6 +1083,8 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
|
|||||||
free(lease->ntp);
|
free(lease->ntp);
|
||||||
strv_free(lease->ntp_fqdn);
|
strv_free(lease->ntp_fqdn);
|
||||||
free(lease->sntp);
|
free(lease->sntp);
|
||||||
|
free(lease->sip);
|
||||||
|
strv_free(lease->sip_domains);
|
||||||
|
|
||||||
return mfree(lease);
|
return mfree(lease);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,10 @@
|
|||||||
0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05
|
0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05
|
||||||
#define NTP2_BYTES \
|
#define NTP2_BYTES \
|
||||||
0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06
|
0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06
|
||||||
|
#define SIP1_BYTES \
|
||||||
|
0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
|
||||||
|
#define SIP2_BYTES \
|
||||||
|
0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
|
||||||
#define CLIENT_ID_BYTES \
|
#define CLIENT_ID_BYTES \
|
||||||
0x00, 0x02, 0x00, 0x00, 0xab, 0x11, 0x61, 0x77, 0x40, 0xde, 0x13, 0x42, 0xc3, 0xa2
|
0x00, 0x02, 0x00, 0x00, 0xab, 0x11, 0x61, 0x77, 0x40, 0xde, 0x13, 0x42, 0xc3, 0xa2
|
||||||
#define SERVER_ID_BYTES \
|
#define SERVER_ID_BYTES \
|
||||||
@ -67,6 +71,8 @@ static const struct in6_addr sntp1 = { { { SNTP1_BYTES } } };
|
|||||||
static const struct in6_addr sntp2 = { { { SNTP2_BYTES } } };
|
static const struct in6_addr sntp2 = { { { SNTP2_BYTES } } };
|
||||||
static const struct in6_addr ntp1 = { { { NTP1_BYTES } } };
|
static const struct in6_addr ntp1 = { { { NTP1_BYTES } } };
|
||||||
static const struct in6_addr ntp2 = { { { NTP2_BYTES } } };
|
static const struct in6_addr ntp2 = { { { NTP2_BYTES } } };
|
||||||
|
static const struct in6_addr sip1 = { { { SIP1_BYTES } } };
|
||||||
|
static const struct in6_addr sip2 = { { { SIP2_BYTES } } };
|
||||||
static const uint8_t client_id[] = { CLIENT_ID_BYTES };
|
static const uint8_t client_id[] = { CLIENT_ID_BYTES };
|
||||||
static const uint8_t server_id[] = { SERVER_ID_BYTES };
|
static const uint8_t server_id[] = { SERVER_ID_BYTES };
|
||||||
static uint8_t vendor_suboption_data[] = { VENDOR_SUBOPTION_BYTES };
|
static uint8_t vendor_suboption_data[] = { VENDOR_SUBOPTION_BYTES };
|
||||||
@ -107,6 +113,8 @@ TEST(client_basic) {
|
|||||||
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVER) >= 0);
|
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVER) >= 0);
|
||||||
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) >= 0);
|
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) >= 0);
|
||||||
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVER) >= 0);
|
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVER) >= 0);
|
||||||
|
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS) >= 0);
|
||||||
|
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME) >= 0);
|
||||||
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_VENDOR_OPTS) >= 0);
|
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_VENDOR_OPTS) >= 0);
|
||||||
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN) >= 0);
|
assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN) >= 0);
|
||||||
assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
|
assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
|
||||||
@ -737,6 +745,13 @@ static const uint8_t msg_reply[] = {
|
|||||||
/* NTP server (fqdn suboption) */
|
/* NTP server (fqdn suboption) */
|
||||||
0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
|
0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
|
||||||
0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
||||||
|
/* SIP server addresses */
|
||||||
|
0x00, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS, 0x00, 0x20,
|
||||||
|
SIP1_BYTES,
|
||||||
|
SIP2_BYTES,
|
||||||
|
/* SIP server domains */
|
||||||
|
0x00, SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME, 0x00, 0x0b,
|
||||||
|
0x03, 's', 'i', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
||||||
/* Domain list */
|
/* Domain list */
|
||||||
0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
|
0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
|
||||||
0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
||||||
@ -819,6 +834,13 @@ static const uint8_t msg_advertise[] = {
|
|||||||
/* NTP server (fqdn suboption) */
|
/* NTP server (fqdn suboption) */
|
||||||
0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
|
0x00, DHCP6_NTP_SUBOPTION_SRV_FQDN, 0x00, 0x0b,
|
||||||
0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
0x03, 'n', 't', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
||||||
|
/* SIP server addresses */
|
||||||
|
0x00, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS, 0x00, 0x20,
|
||||||
|
SIP1_BYTES,
|
||||||
|
SIP2_BYTES,
|
||||||
|
/* SIP server domains */
|
||||||
|
0x00, SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME, 0x00, 0x0b,
|
||||||
|
0x03, 's', 'i', 'p', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
||||||
/* Domain list */
|
/* Domain list */
|
||||||
0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
|
0x00, SD_DHCP6_OPTION_DOMAIN, 0x00, 0x0b,
|
||||||
0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
0x03, 'l', 'a', 'b', 0x05, 'i', 'n', 't', 'r', 'a', 0x00,
|
||||||
@ -899,6 +921,14 @@ static void test_lease_common(sd_dhcp6_client *client) {
|
|||||||
assert_se(streq(strv[0], "ntp.intra"));
|
assert_se(streq(strv[0], "ntp.intra"));
|
||||||
assert_se(!strv[1]);
|
assert_se(!strv[1]);
|
||||||
|
|
||||||
|
assert_se(sd_dhcp6_lease_get_sip_addrs(lease, &addrs) == 2);
|
||||||
|
assert_se(in6_addr_equal(&addrs[0], &sip1));
|
||||||
|
assert_se(in6_addr_equal(&addrs[1], &sip2));
|
||||||
|
|
||||||
|
assert_se(sd_dhcp6_lease_get_sip_domains(lease, &strv) == 1);
|
||||||
|
assert_se(streq(strv[0], "sip.intra"));
|
||||||
|
assert_se(!strv[1]);
|
||||||
|
|
||||||
assert_se(lease->sntp_count == 2);
|
assert_se(lease->sntp_count == 2);
|
||||||
assert_se(in6_addr_equal(&lease->sntp[0], &sntp1));
|
assert_se(in6_addr_equal(&lease->sntp[0], &sntp1));
|
||||||
assert_se(in6_addr_equal(&lease->sntp[1], &sntp2));
|
assert_se(in6_addr_equal(&lease->sntp[1], &sntp2));
|
||||||
|
@ -687,6 +687,16 @@ static int dhcp6_configure(Link *link) {
|
|||||||
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request SNTP servers: %m");
|
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request SNTP servers: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link->network->dhcp6_use_sip > 0) {
|
||||||
|
r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SIP_SERVER_ADDRESS);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request SIP servers: %m");
|
||||||
|
|
||||||
|
r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to request SIP server domain names: %m");
|
||||||
|
}
|
||||||
|
|
||||||
SET_FOREACH(request_options, link->network->dhcp6_request_options) {
|
SET_FOREACH(request_options, link->network->dhcp6_request_options) {
|
||||||
uint32_t option = PTR_TO_UINT32(request_options);
|
uint32_t option = PTR_TO_UINT32(request_options);
|
||||||
|
|
||||||
|
@ -819,39 +819,6 @@ static int ntp_append_json(Link *link, sd_json_variant **v) {
|
|||||||
return json_variant_set_field_non_null(v, "NTP", array);
|
return json_variant_set_field_non_null(v, "NTP", array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sip_append_json(Link *link, sd_json_variant **v) {
|
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
|
|
||||||
const struct in_addr *sip;
|
|
||||||
union in_addr_union s;
|
|
||||||
int n_sip, r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(v);
|
|
||||||
|
|
||||||
if (!link->network || !link->network->dhcp_use_sip || !link->dhcp_lease)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
n_sip = sd_dhcp_lease_get_sip(link->dhcp_lease, &sip);
|
|
||||||
if (n_sip <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
for (int i = 0; i < n_sip; i++) {
|
|
||||||
r = server_append_json_one_addr(AF_INET,
|
|
||||||
&(union in_addr_union) { .in = sip[i], },
|
|
||||||
NETWORK_CONFIG_SOURCE_DHCP4,
|
|
||||||
&s,
|
|
||||||
&array);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return json_variant_set_field_non_null(v, "SIP", array);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int domain_append_json(int family, const char *domain, NetworkConfigSource s, const union in_addr_union *p, sd_json_variant **array) {
|
static int domain_append_json(int family, const char *domain, NetworkConfigSource s, const union in_addr_union *p, sd_json_variant **array) {
|
||||||
assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6));
|
assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6));
|
||||||
assert(domain);
|
assert(domain);
|
||||||
@ -864,6 +831,78 @@ static int domain_append_json(int family, const char *domain, NetworkConfigSourc
|
|||||||
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family));
|
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sip_append_json(Link *link, sd_json_variant **v) {
|
||||||
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(v);
|
||||||
|
|
||||||
|
if (!link->network)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (link->dhcp_lease && link->network->dhcp_use_sip) {
|
||||||
|
const struct in_addr *sip;
|
||||||
|
union in_addr_union s;
|
||||||
|
int n_sip;
|
||||||
|
|
||||||
|
n_sip = sd_dhcp_lease_get_sip(link->dhcp_lease, &sip);
|
||||||
|
if (n_sip <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
for (int i = 0; i < n_sip; i++) {
|
||||||
|
r = server_append_json_one_addr(AF_INET,
|
||||||
|
&(union in_addr_union) { .in = sip[i], },
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP4,
|
||||||
|
&s,
|
||||||
|
&array);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->dhcp6_lease && link->network->dhcp6_use_sip) {
|
||||||
|
const struct in6_addr *sip_addr;
|
||||||
|
union in_addr_union s;
|
||||||
|
char **domains;
|
||||||
|
int n_sip;
|
||||||
|
|
||||||
|
r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
n_sip = sd_dhcp6_lease_get_sip_addrs(link->dhcp6_lease, &sip_addr);
|
||||||
|
for (int i = 0; i < n_sip; i++) {
|
||||||
|
r = server_append_json_one_addr(AF_INET6,
|
||||||
|
&(union in_addr_union) { .in6 = sip_addr[i], },
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP6,
|
||||||
|
&s,
|
||||||
|
&array);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sd_dhcp6_lease_get_sip_domains(link->dhcp6_lease, &domains) >= 0)
|
||||||
|
STRV_FOREACH(p, domains) {
|
||||||
|
r = domain_append_json(AF_INET6,
|
||||||
|
*p,
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP6,
|
||||||
|
&s,
|
||||||
|
&array);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_variant_set_field_non_null(v, "SIP", array);
|
||||||
|
}
|
||||||
|
|
||||||
static int domains_append_json(Link *link, bool is_route, sd_json_variant **v) {
|
static int domains_append_json(Link *link, bool is_route, sd_json_variant **v) {
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
|
||||||
OrderedSet *link_domains, *network_domains;
|
OrderedSet *link_domains, *network_domains;
|
||||||
|
@ -310,6 +310,7 @@ DHCPv6.UseDNR, config_parse_tristate,
|
|||||||
DHCPv6.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp6_use_hostname)
|
DHCPv6.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp6_use_hostname)
|
||||||
DHCPv6.UseDomains, config_parse_use_domains, 0, offsetof(Network, dhcp6_use_domains)
|
DHCPv6.UseDomains, config_parse_use_domains, 0, offsetof(Network, dhcp6_use_domains)
|
||||||
DHCPv6.UseNTP, config_parse_tristate, 0, offsetof(Network, dhcp6_use_ntp)
|
DHCPv6.UseNTP, config_parse_tristate, 0, offsetof(Network, dhcp6_use_ntp)
|
||||||
|
DHCPv6.UseSIP, config_parse_bool, 0, offsetof(Network, dhcp6_use_sip)
|
||||||
DHCPv6.UseCaptivePortal, config_parse_bool, 0, offsetof(Network, dhcp6_use_captive_portal)
|
DHCPv6.UseCaptivePortal, config_parse_bool, 0, offsetof(Network, dhcp6_use_captive_portal)
|
||||||
DHCPv6.MUDURL, config_parse_mud_url, 0, offsetof(Network, dhcp6_mudurl)
|
DHCPv6.MUDURL, config_parse_mud_url, 0, offsetof(Network, dhcp6_mudurl)
|
||||||
DHCPv6.SendHostname, config_parse_dhcp_send_hostname, AF_INET6, 0
|
DHCPv6.SendHostname, config_parse_dhcp_send_hostname, AF_INET6, 0
|
||||||
|
@ -413,6 +413,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||||||
.dhcp6_use_domains = _USE_DOMAINS_INVALID,
|
.dhcp6_use_domains = _USE_DOMAINS_INVALID,
|
||||||
.dhcp6_use_hostname = true,
|
.dhcp6_use_hostname = true,
|
||||||
.dhcp6_use_ntp = -1,
|
.dhcp6_use_ntp = -1,
|
||||||
|
.dhcp6_use_sip = true,
|
||||||
.dhcp6_use_captive_portal = true,
|
.dhcp6_use_captive_portal = true,
|
||||||
.dhcp6_use_rapid_commit = true,
|
.dhcp6_use_rapid_commit = true,
|
||||||
.dhcp6_send_hostname = true,
|
.dhcp6_send_hostname = true,
|
||||||
|
@ -181,6 +181,7 @@ typedef struct Network {
|
|||||||
int dhcp6_use_dnr;
|
int dhcp6_use_dnr;
|
||||||
bool dhcp6_use_hostname;
|
bool dhcp6_use_hostname;
|
||||||
int dhcp6_use_ntp;
|
int dhcp6_use_ntp;
|
||||||
|
bool dhcp6_use_sip;
|
||||||
bool dhcp6_use_captive_portal;
|
bool dhcp6_use_captive_portal;
|
||||||
bool dhcp6_use_rapid_commit;
|
bool dhcp6_use_rapid_commit;
|
||||||
UseDomains dhcp6_use_domains;
|
UseDomains dhcp6_use_domains;
|
||||||
|
@ -264,6 +264,25 @@ static int link_put_sip(Link *link, OrderedSet **s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link->dhcp6_lease && link->network->dhcp6_use_sip) {
|
||||||
|
const struct in6_addr *addresses;
|
||||||
|
char **domains;
|
||||||
|
|
||||||
|
r = sd_dhcp6_lease_get_sip_addrs(link->dhcp6_lease, &addresses);
|
||||||
|
if (r >= 0) {
|
||||||
|
r = ordered_set_put_in6_addrv(s, addresses, r);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_dhcp6_lease_get_sip_domains(link->dhcp6_lease, &domains);
|
||||||
|
if (r >= 0) {
|
||||||
|
r = ordered_set_put_strdupv_full(s, &dns_name_hash_ops_free, domains);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -842,7 +861,10 @@ static int link_save(Link *link) {
|
|||||||
link->dhcp_lease,
|
link->dhcp_lease,
|
||||||
link->network->dhcp_use_sip,
|
link->network->dhcp_use_sip,
|
||||||
SD_DHCP_LEASE_SIP,
|
SD_DHCP_LEASE_SIP,
|
||||||
NULL, false, NULL, NULL);
|
link->dhcp6_lease,
|
||||||
|
link->network->dhcp6_use_sip,
|
||||||
|
sd_dhcp6_lease_get_sip_addrs,
|
||||||
|
sd_dhcp6_lease_get_sip_domains);
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
|
@ -77,6 +77,8 @@ int sd_dhcp6_lease_get_dnr(sd_dhcp6_lease *lease, sd_dns_resolver **ret);
|
|||||||
int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret);
|
int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret);
|
||||||
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret);
|
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret);
|
||||||
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret);
|
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret);
|
||||||
|
int sd_dhcp6_lease_get_sip_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret);
|
||||||
|
int sd_dhcp6_lease_get_sip_domains(sd_dhcp6_lease *lease, char ***ret);
|
||||||
int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **ret);
|
int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **ret);
|
||||||
int sd_dhcp6_lease_get_captive_portal(sd_dhcp6_lease *lease, const char **ret);
|
int sd_dhcp6_lease_get_captive_portal(sd_dhcp6_lease *lease, const char **ret);
|
||||||
int sd_dhcp6_lease_get_vendor_options(sd_dhcp6_lease *lease, sd_dhcp6_option ***ret);
|
int sd_dhcp6_lease_get_vendor_options(sd_dhcp6_lease *lease, sd_dhcp6_option ***ret);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
({ \
|
({ \
|
||||||
typeof(ret) _r = (ret); \
|
typeof(ret) _r = (ret); \
|
||||||
user_record_unref(*_r); \
|
user_record_unref(*_r); \
|
||||||
assert_se(user_record_build((ret), SD_JSON_BUILD_OBJECT(SD_JSON_BUILD_PAIR_STRING("disposition", "regular"), __VA_ARGS__)) >= 0); \
|
ASSERT_OK(user_record_build((ret), SD_JSON_BUILD_OBJECT(SD_JSON_BUILD_PAIR_STRING("disposition", "regular"), __VA_ARGS__))); \
|
||||||
0; \
|
0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ TEST(self_changes) {
|
|||||||
USER(&new,
|
USER(&new,
|
||||||
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999));
|
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999));
|
||||||
assert_se(!user_record_self_changes_allowed(curr, new));
|
ASSERT_FALSE(user_record_self_changes_allowed(curr, new));
|
||||||
|
|
||||||
/* manually allowlisted */
|
/* manually allowlisted */
|
||||||
USER(&curr,
|
USER(&curr,
|
||||||
@ -35,7 +35,7 @@ TEST(self_changes) {
|
|||||||
SD_JSON_BUILD_PAIR_ARRAY("selfModifiableFields", SD_JSON_BUILD_STRING("notInHardCodedList")),
|
SD_JSON_BUILD_PAIR_ARRAY("selfModifiableFields", SD_JSON_BUILD_STRING("notInHardCodedList")),
|
||||||
/* change in order shouldn't affect things */
|
/* change in order shouldn't affect things */
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999));
|
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999));
|
||||||
assert_se(user_record_self_changes_allowed(curr, new));
|
ASSERT_TRUE(user_record_self_changes_allowed(curr, new));
|
||||||
|
|
||||||
/* default allowlisted */
|
/* default allowlisted */
|
||||||
USER(&curr,
|
USER(&curr,
|
||||||
@ -44,7 +44,7 @@ TEST(self_changes) {
|
|||||||
USER(&new,
|
USER(&new,
|
||||||
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
||||||
SD_JSON_BUILD_PAIR_STRING("realName", "New Name"));
|
SD_JSON_BUILD_PAIR_STRING("realName", "New Name"));
|
||||||
assert_se(user_record_self_changes_allowed(curr, new));
|
ASSERT_TRUE(user_record_self_changes_allowed(curr, new));
|
||||||
|
|
||||||
/* introduced new default allowlisted */
|
/* introduced new default allowlisted */
|
||||||
USER(&curr,
|
USER(&curr,
|
||||||
@ -52,7 +52,7 @@ TEST(self_changes) {
|
|||||||
USER(&new,
|
USER(&new,
|
||||||
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
||||||
SD_JSON_BUILD_PAIR_STRING("realName", "New Name"));
|
SD_JSON_BUILD_PAIR_STRING("realName", "New Name"));
|
||||||
assert_se(user_record_self_changes_allowed(curr, new));
|
ASSERT_TRUE(user_record_self_changes_allowed(curr, new));
|
||||||
|
|
||||||
/* introduced new not allowlisted */
|
/* introduced new not allowlisted */
|
||||||
USER(&curr,
|
USER(&curr,
|
||||||
@ -60,7 +60,7 @@ TEST(self_changes) {
|
|||||||
USER(&new,
|
USER(&new,
|
||||||
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999));
|
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999));
|
||||||
assert_se(!user_record_self_changes_allowed(curr, new));
|
ASSERT_FALSE(user_record_self_changes_allowed(curr, new));
|
||||||
|
|
||||||
/* privileged section: default allowlisted */
|
/* privileged section: default allowlisted */
|
||||||
USER(&curr,
|
USER(&curr,
|
||||||
@ -71,7 +71,7 @@ TEST(self_changes) {
|
|||||||
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
||||||
SD_JSON_BUILD_PAIR_OBJECT("privileged",
|
SD_JSON_BUILD_PAIR_OBJECT("privileged",
|
||||||
SD_JSON_BUILD_PAIR_STRING("passwordHint", "New Hint")));
|
SD_JSON_BUILD_PAIR_STRING("passwordHint", "New Hint")));
|
||||||
assert_se(user_record_self_changes_allowed(curr, new));
|
ASSERT_TRUE(user_record_self_changes_allowed(curr, new));
|
||||||
|
|
||||||
/* privileged section: not allowlisted */
|
/* privileged section: not allowlisted */
|
||||||
USER(&curr,
|
USER(&curr,
|
||||||
@ -82,7 +82,7 @@ TEST(self_changes) {
|
|||||||
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
|
||||||
SD_JSON_BUILD_PAIR_OBJECT("privileged",
|
SD_JSON_BUILD_PAIR_OBJECT("privileged",
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999)));
|
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999)));
|
||||||
assert_se(!user_record_self_changes_allowed(curr, new));
|
ASSERT_FALSE(user_record_self_changes_allowed(curr, new));
|
||||||
|
|
||||||
/* privileged section: manually allowlisted */
|
/* privileged section: manually allowlisted */
|
||||||
USER(&curr,
|
USER(&curr,
|
||||||
@ -95,7 +95,7 @@ TEST(self_changes) {
|
|||||||
SD_JSON_BUILD_PAIR_ARRAY("selfModifiablePrivileged", SD_JSON_BUILD_STRING("notInHardCodedList")),
|
SD_JSON_BUILD_PAIR_ARRAY("selfModifiablePrivileged", SD_JSON_BUILD_STRING("notInHardCodedList")),
|
||||||
SD_JSON_BUILD_PAIR_OBJECT("privileged",
|
SD_JSON_BUILD_PAIR_OBJECT("privileged",
|
||||||
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999)));
|
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999)));
|
||||||
assert_se(user_record_self_changes_allowed(curr, new));
|
ASSERT_TRUE(user_record_self_changes_allowed(curr, new));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_TEST_MAIN(LOG_INFO);
|
DEFINE_TEST_MAIN(LOG_INFO);
|
||||||
|
@ -12,9 +12,9 @@ TEST(is_valid_documentation_url) {
|
|||||||
ASSERT_TRUE(documentation_url_is_valid("man:systemd.special(7)"));
|
ASSERT_TRUE(documentation_url_is_valid("man:systemd.special(7)"));
|
||||||
ASSERT_TRUE(documentation_url_is_valid("info:bar"));
|
ASSERT_TRUE(documentation_url_is_valid("info:bar"));
|
||||||
|
|
||||||
ASSERT_TRUE(!documentation_url_is_valid("foo:"));
|
ASSERT_FALSE(documentation_url_is_valid("foo:"));
|
||||||
ASSERT_TRUE(!documentation_url_is_valid("info:"));
|
ASSERT_FALSE(documentation_url_is_valid("info:"));
|
||||||
ASSERT_TRUE(!documentation_url_is_valid(""));
|
ASSERT_FALSE(documentation_url_is_valid(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_TEST_MAIN(LOG_INFO);
|
DEFINE_TEST_MAIN(LOG_INFO);
|
||||||
|
@ -8433,6 +8433,52 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
|||||||
check(self, False, True, needs_reconfigure=True)
|
check(self, False, True, needs_reconfigure=True)
|
||||||
check(self, False, False)
|
check(self, False, False)
|
||||||
|
|
||||||
|
def test_dhcp_client_use_sip(self):
|
||||||
|
def check(self, ipv4, ipv6, needs_reconfigure=False):
|
||||||
|
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
|
||||||
|
with open(os.path.join(network_unit_dir, '25-dhcp-client.network.d/override.conf'), mode='w', encoding='utf-8') as f:
|
||||||
|
f.write('[DHCPv4]\nUseSIP=')
|
||||||
|
f.write('yes' if ipv4 else 'no')
|
||||||
|
f.write('\n[DHCPv6]\nUseSIP=')
|
||||||
|
f.write('yes' if ipv6 else 'no')
|
||||||
|
|
||||||
|
networkctl_reload()
|
||||||
|
if needs_reconfigure:
|
||||||
|
networkctl_reconfigure('veth99')
|
||||||
|
self.wait_online('veth99:routable')
|
||||||
|
|
||||||
|
# link becomes 'routable' when at least one protocol provide an valid address. Hence, we need to explicitly wait for both addresses.
|
||||||
|
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
|
||||||
|
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
|
||||||
|
|
||||||
|
output = networkctl_status('veth99')
|
||||||
|
print(output)
|
||||||
|
if ipv4 and ipv6:
|
||||||
|
self.assertRegex(output, 'SIP: 192.168.5.1\n *2600::1\n *foo.example.com')
|
||||||
|
elif ipv4:
|
||||||
|
self.assertIn('SIP: 192.168.5.1', output)
|
||||||
|
elif ipv6:
|
||||||
|
self.assertRegex(output, 'SIP: 2600::1\n *foo.example.com')
|
||||||
|
else:
|
||||||
|
self.assertNotIn('SIP: 192.168.5.1', output)
|
||||||
|
self.assertNotIn('SIP: 2600::1', output)
|
||||||
|
self.assertNotIn('SIP: foo.example.com', output)
|
||||||
|
|
||||||
|
check_json(networkctl_json())
|
||||||
|
|
||||||
|
copy_network_unit('25-veth.netdev', '25-dhcp-server-veth-peer.network', '25-dhcp-client.network', copy_dropins=False)
|
||||||
|
|
||||||
|
start_networkd()
|
||||||
|
self.wait_online('veth-peer:carrier')
|
||||||
|
start_dnsmasq('--dhcp-option=option:sip-server,192.168.5.1',
|
||||||
|
'--dhcp-option=option6:sip-server,[2600::1]',
|
||||||
|
'--dhcp-option=option6:sip-server-domain,foo.example.com')
|
||||||
|
|
||||||
|
check(self, True, True)
|
||||||
|
check(self, True, False)
|
||||||
|
check(self, False, True, needs_reconfigure=True)
|
||||||
|
check(self, False, False)
|
||||||
|
|
||||||
def test_dhcp_client_use_captive_portal(self):
|
def test_dhcp_client_use_captive_portal(self):
|
||||||
def check(self, ipv4, ipv6, needs_reconfigure=False):
|
def check(self, ipv4, ipv6, needs_reconfigure=False):
|
||||||
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
|
os.makedirs(os.path.join(network_unit_dir, '25-dhcp-client.network.d'), exist_ok=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user