mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
network: DHCP server Add support to transmit SIP server
1. DHCP server trasmit 2. Client parses and saves in leases Implements http://www.rfc-editor.org/rfc/rfc3361.txt ``` Frame 134: 348 bytes on wire (2784 bits), 348 bytes captured (2784 bits) on interface 0 Ethernet II, Src: 42:65:85:d6:4e:32 (42:65:85:d6:4e:32), Dst: 1e:04:f8:b8:2f:d4 (1e:04:f8:b8:2f:d4) Internet Protocol Version 4, Src: 192.168.5.1, Dst: 192.168.5.11 User Datagram Protocol, Src Port: 67, Dst Port: 68 Dynamic Host Configuration Protocol (ACK) Message type: Boot Reply (2) Hardware type: Ethernet (0x01) Hardware address length: 6 Hops: 0 Transaction ID: 0x7cc87cb4 Seconds elapsed: 0 Bootp flags: 0x0000 (Unicast) Client IP address: 0.0.0.0 Your (client) IP address: 192.168.5.11 Next server IP address: 0.0.0.0 Relay agent IP address: 0.0.0.0 Client MAC address: 1e:04:f8:b8:2f:d4 (1e:04:f8:b8:2f:d4) Client hardware address padding: 00000000000000000000 Server host name not given Boot file name not given Magic cookie: DHCP Option: (53) DHCP Message Type (ACK) Length: 1 DHCP: ACK (5) Option: (51) IP Address Lease Time Length: 4 IP Address Lease Time: (3600s) 1 hour Option: (1) Subnet Mask (255.255.255.0) Length: 4 Subnet Mask: 255.255.255.0 Option: (3) Router Length: 4 Router: 192.168.5.1 Option: (6) Domain Name Server Length: 4 Domain Name Server: 192.168.5.1 Option: (42) Network Time Protocol Servers Length: 4 Network Time Protocol Server: 192.168.1.1 Option: (120) SIP Servers <=====here Length: 9 SIP Server Encoding: IPv4 Address (1) SIP Server Address: 192.168.1.1 SIP Server Address: 192.168.5.2 Option: (101) TCode Length: 13 TZ TCode: Europe/Berlin Option: (54) DHCP Server Identifier (192.168.5.1) Length: 4 DHCP Server Identifier: 192.168.5.1 Option: (255) End Option End: 255 ``` ``` cat /run/systemd/netif/state ✔ ⚡ 3148 16:40:51 OPER_STATE=routable CARRIER_STATE=carrier ADDRESS_STATE=routable DNS=192.168.94.2 192.168.5.1 NTP=192.168.5.1 SIP=192.168.1.1 192.168.5.2 ``` aa
This commit is contained in:
parent
5bc945bec4
commit
299d578f7f
@ -1348,6 +1348,14 @@
|
||||
and take precedence over any statically configured ones.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>UseSIP=</varname></term>
|
||||
<listitem>
|
||||
<para>When true (the default), the SIP servers received
|
||||
from the DHCP server will be saved at the state files and can be
|
||||
read via <function>sd_network_link_get_sip_servers()</function> function.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>UseMTU=</varname></term>
|
||||
<listitem>
|
||||
@ -1776,6 +1784,19 @@
|
||||
<varname>DNS=</varname>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>EmitSIP=</varname></term>
|
||||
<term><varname>SIP=</varname></term>
|
||||
|
||||
<listitem><para>Similar to the <varname>EmitDNS=</varname> and
|
||||
<varname>DNS=</varname> settings described above, these
|
||||
settings configure whether and what SIP server information
|
||||
shall be emitted as part of the DHCP lease. The same syntax,
|
||||
propagation semantics and defaults apply as for
|
||||
<varname>EmitDNS=</varname> and
|
||||
<varname>DNS=</varname>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>EmitRouter=</varname></term>
|
||||
|
||||
|
@ -58,6 +58,9 @@ struct sd_dhcp_lease {
|
||||
struct in_addr *ntp;
|
||||
size_t ntp_size;
|
||||
|
||||
struct in_addr *sip;
|
||||
size_t sip_size;
|
||||
|
||||
struct sd_dhcp_route *static_route;
|
||||
size_t static_route_size, static_route_allocated;
|
||||
|
||||
|
@ -65,6 +65,18 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||
|
||||
break;
|
||||
}
|
||||
case SD_DHCP_OPTION_SIP_SERVER:
|
||||
if (*offset + 3 + optlen > size)
|
||||
return -ENOBUFS;
|
||||
|
||||
options[*offset] = code;
|
||||
options[*offset + 1] = optlen + 1;
|
||||
options[*offset + 2] = 1;
|
||||
|
||||
memcpy_safe(&options[*offset + 3], optval, optlen);
|
||||
*offset += 3 + optlen;
|
||||
|
||||
break;
|
||||
default:
|
||||
if (*offset + 2 + optlen > size)
|
||||
return -ENOBUFS;
|
||||
|
@ -45,8 +45,8 @@ struct sd_dhcp_server {
|
||||
|
||||
char *timezone;
|
||||
|
||||
struct in_addr *ntp, *dns;
|
||||
unsigned n_ntp, n_dns;
|
||||
struct in_addr *ntp, *dns, *sip;
|
||||
unsigned n_ntp, n_dns, n_sip;
|
||||
|
||||
bool emit_router;
|
||||
|
||||
|
@ -120,6 +120,17 @@ int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
return (int) lease->ntp_size;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(domainname, -EINVAL);
|
||||
@ -269,6 +280,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
|
||||
free(lease->domainname);
|
||||
free(lease->dns);
|
||||
free(lease->ntp);
|
||||
free(lease->sip);
|
||||
free(lease->static_route);
|
||||
free(lease->client_id);
|
||||
free(lease->vendor_specific);
|
||||
@ -402,6 +414,36 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
|
||||
assert(option);
|
||||
assert(ret);
|
||||
assert(n_ret);
|
||||
|
||||
if (len <= 0) {
|
||||
*ret = mfree(*ret);
|
||||
*n_ret = 0;
|
||||
} else {
|
||||
size_t n_addresses;
|
||||
struct in_addr *addresses;
|
||||
int l = len - 1;
|
||||
|
||||
if (l % 4 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
n_addresses = l / 4;
|
||||
|
||||
addresses = newdup(struct in_addr, option + 1, n_addresses);
|
||||
if (!addresses)
|
||||
return -ENOMEM;
|
||||
|
||||
free(*ret);
|
||||
*ret = addresses;
|
||||
*n_ret = n_addresses;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lease_parse_routes(
|
||||
const uint8_t *option, size_t len,
|
||||
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
|
||||
@ -555,6 +597,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
||||
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_SIP_SERVER:
|
||||
r = lease_parse_sip_server(option, len, &lease->sip, &lease->sip_size);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_STATIC_ROUTE:
|
||||
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
|
||||
if (r < 0)
|
||||
@ -893,6 +941,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_sip(lease, &addresses);
|
||||
if (r > 0) {
|
||||
fputs("SIP=", f);
|
||||
serialize_in_addrs(f, addresses, r, false, NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_domainname(lease, &string);
|
||||
if (r >= 0)
|
||||
fprintf(f, "DOMAINNAME=%s\n", string);
|
||||
@ -983,6 +1038,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
*broadcast = NULL,
|
||||
*dns = NULL,
|
||||
*ntp = NULL,
|
||||
*sip = NULL,
|
||||
*mtu = NULL,
|
||||
*routes = NULL,
|
||||
*domains = NULL,
|
||||
@ -1011,6 +1067,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
"BROADCAST", &broadcast,
|
||||
"DNS", &dns,
|
||||
"NTP", &ntp,
|
||||
"SIP", &sip,
|
||||
"MTU", &mtu,
|
||||
"DOMAINNAME", &lease->domainname,
|
||||
"HOSTNAME", &lease->hostname,
|
||||
@ -1115,6 +1172,14 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
||||
lease->ntp_size = r;
|
||||
}
|
||||
|
||||
if (sip) {
|
||||
r = deserialize_in_addrs(&lease->sip, sip);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", ntp);
|
||||
else
|
||||
lease->ntp_size = r;
|
||||
}
|
||||
|
||||
if (mtu) {
|
||||
r = safe_atou16(mtu, &lease->mtu);
|
||||
if (r < 0)
|
||||
|
@ -139,6 +139,7 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
|
||||
free(server->timezone);
|
||||
free(server->dns);
|
||||
free(server->ntp);
|
||||
free(server->sip);
|
||||
|
||||
hashmap_free(server->leases_by_client_id);
|
||||
|
||||
@ -498,6 +499,15 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
|
||||
return r;
|
||||
}
|
||||
|
||||
if (server->n_sip > 0) {
|
||||
r = dhcp_option_append(
|
||||
&packet->dhcp, req->max_optlen, &offset, 0,
|
||||
SD_DHCP_OPTION_SIP_SERVER,
|
||||
sizeof(struct in_addr) * server->n_sip, server->sip);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (server->timezone) {
|
||||
r = dhcp_option_append(
|
||||
&packet->dhcp, req->max_optlen, &offset, 0,
|
||||
@ -1124,6 +1134,32 @@ int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], u
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
|
||||
assert_return(server, -EINVAL);
|
||||
|
||||
|
@ -249,6 +249,10 @@ _public_ int sd_network_link_get_route_domains(int ifindex, char ***ret) {
|
||||
return network_link_get_strv(ifindex, "ROUTE_DOMAINS", ret);
|
||||
}
|
||||
|
||||
_public_ int sd_network_link_get_sip_servers(int ifindex, char ***ret) {
|
||||
return network_link_get_strv(ifindex, "SIP", ret);
|
||||
}
|
||||
|
||||
_public_ int sd_network_link_get_dns_default_route(int ifindex) {
|
||||
char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
|
||||
_cleanup_free_ char *s = NULL;
|
||||
|
@ -91,6 +91,38 @@ int config_parse_dhcp_use_dns(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_dhcp_use_sip(
|
||||
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 *network = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = parse_boolean(rvalue);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse UseSIP=%s, ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
network->dhcp_use_sip = r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_dhcp_use_ntp(
|
||||
const char* unit,
|
||||
const char *filename,
|
||||
|
@ -31,5 +31,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_ntp);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_sip);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
|
||||
|
@ -137,6 +137,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_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_debug("Copying SIP server information from %s", link->ifname);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int dhcp4_server_configure(Link *link) {
|
||||
Address *address;
|
||||
Link *uplink = NULL;
|
||||
@ -209,6 +258,24 @@ int dhcp4_server_configure(Link *link) {
|
||||
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");
|
||||
}
|
||||
|
||||
r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to set router emission for DHCP server: %m");
|
||||
@ -345,3 +412,55 @@ int config_parse_dhcp_server_ntp(
|
||||
n->dhcp_server_ntp = m;
|
||||
}
|
||||
}
|
||||
|
||||
int config_parse_dhcp_server_sip(
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
@ -9,3 +9,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);
|
||||
|
@ -1159,6 +1159,12 @@ int dhcp4_configure(Link *link) {
|
||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP server: %m");
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_sip) {
|
||||
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_SIP_SERVER);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for SIP server: %m");
|
||||
}
|
||||
|
||||
if (link->network->dhcp_use_timezone) {
|
||||
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
|
||||
if (r < 0)
|
||||
|
@ -3597,6 +3597,22 @@ int link_save(Link *link) {
|
||||
space = true;
|
||||
}
|
||||
|
||||
fputc('\n', f);
|
||||
|
||||
fputs("SIP=", f);
|
||||
space = false;
|
||||
fputstrv(f, link->network->sip, NULL, &space);
|
||||
|
||||
if (link->network->dhcp_use_sip &&
|
||||
link->dhcp_lease) {
|
||||
const struct in_addr *addresses;
|
||||
|
||||
r = sd_dhcp_lease_get_sip(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;
|
||||
|
@ -1333,16 +1333,16 @@ 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, *search_domains = NULL, *route_domains = NULL;
|
||||
Link *link;
|
||||
Iterator i;
|
||||
_cleanup_free_ char *temp_path = NULL;
|
||||
_cleanup_strv_free_ char **p = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = 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;
|
||||
LinkAddressState address_state = LINK_ADDRESS_STATE_OFF;
|
||||
const char *operstate_str, *carrier_state_str, *address_state_str;
|
||||
_cleanup_free_ char *temp_path = NULL;
|
||||
_cleanup_strv_free_ char **p = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
Link *link;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -1357,6 +1357,10 @@ static int manager_save(Manager *m) {
|
||||
if (!ntp)
|
||||
return -ENOMEM;
|
||||
|
||||
sip = ordered_set_new(&string_hash_ops);
|
||||
if (!sip)
|
||||
return -ENOMEM;
|
||||
|
||||
search_domains = ordered_set_new(&dns_name_hash_ops);
|
||||
if (!search_domains)
|
||||
return -ENOMEM;
|
||||
@ -1426,6 +1430,18 @@ static int manager_save(Manager *m) {
|
||||
return r;
|
||||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
@ -1476,6 +1492,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, "DOMAINS=", search_domains);
|
||||
ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
|
||||
|
||||
|
@ -145,6 +145,7 @@ DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier,
|
||||
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
|
||||
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
|
||||
DHCPv4.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp)
|
||||
DHCPv4.UseSIP, config_parse_bool, 0, offsetof(Network, dhcp_use_sip)
|
||||
DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_use_mtu)
|
||||
DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_use_hostname)
|
||||
DHCPv4.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
|
||||
@ -182,6 +183,8 @@ DHCPServer.EmitDNS, config_parse_bool,
|
||||
DHCPServer.DNS, config_parse_dhcp_server_dns, 0, 0
|
||||
DHCPServer.EmitNTP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_ntp)
|
||||
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.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)
|
||||
|
@ -363,6 +363,7 @@ int network_load_one(Manager *manager, const char *filename) {
|
||||
.dhcp = ADDRESS_FAMILY_NO,
|
||||
.dhcp_critical = -1,
|
||||
.dhcp_use_ntp = true,
|
||||
.dhcp_use_sip = true,
|
||||
.dhcp_use_dns = true,
|
||||
.dhcp_use_hostname = true,
|
||||
.dhcp_use_routes = true,
|
||||
@ -386,6 +387,7 @@ int network_load_one(Manager *manager, const char *filename) {
|
||||
|
||||
.dhcp_server_emit_dns = true,
|
||||
.dhcp_server_emit_ntp = true,
|
||||
.dhcp_server_emit_sip = true,
|
||||
.dhcp_server_emit_router = true,
|
||||
.dhcp_server_emit_timezone = true,
|
||||
|
||||
@ -546,6 +548,8 @@ static Network *network_free(Network *network) {
|
||||
|
||||
strv_free(network->ntp);
|
||||
free(network->dns);
|
||||
strv_free(network->sip);
|
||||
free(network->sip);
|
||||
ordered_set_free_free(network->search_domains);
|
||||
ordered_set_free_free(network->route_domains);
|
||||
strv_free(network->bind_carrier);
|
||||
@ -608,6 +612,7 @@ static Network *network_free(Network *network) {
|
||||
free(network->dhcp_server_timezone);
|
||||
free(network->dhcp_server_dns);
|
||||
free(network->dhcp_server_ntp);
|
||||
free(network->dhcp_server_sip);
|
||||
|
||||
set_free_free(network->dnssec_negative_trust_anchors);
|
||||
|
||||
|
@ -93,6 +93,7 @@ struct Network {
|
||||
bool dhcp_use_dns;
|
||||
bool dhcp_routes_to_dns;
|
||||
bool dhcp_use_ntp;
|
||||
bool dhcp_use_sip;
|
||||
bool dhcp_use_mtu;
|
||||
bool dhcp_use_routes;
|
||||
bool dhcp_use_timezone;
|
||||
@ -110,12 +111,19 @@ struct Network {
|
||||
|
||||
/* DHCP Server Support */
|
||||
bool dhcp_server;
|
||||
|
||||
bool dhcp_server_emit_dns;
|
||||
struct in_addr *dhcp_server_dns;
|
||||
unsigned n_dhcp_server_dns;
|
||||
|
||||
bool dhcp_server_emit_ntp;
|
||||
struct in_addr *dhcp_server_ntp;
|
||||
unsigned n_dhcp_server_ntp;
|
||||
|
||||
bool dhcp_server_emit_sip;
|
||||
struct in_addr *dhcp_server_sip;
|
||||
unsigned n_dhcp_server_sip;
|
||||
|
||||
bool dhcp_server_emit_router;
|
||||
bool dhcp_server_emit_timezone;
|
||||
char *dhcp_server_timezone;
|
||||
@ -257,6 +265,7 @@ struct Network {
|
||||
Set *dnssec_negative_trust_anchors;
|
||||
|
||||
char **ntp;
|
||||
char **sip;
|
||||
char **bind_carrier;
|
||||
};
|
||||
|
||||
|
@ -87,6 +87,7 @@ enum {
|
||||
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
||||
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
|
||||
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
|
||||
SD_DHCP_OPTION_SIP_SERVER = 120,
|
||||
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
|
||||
SD_DHCP_OPTION_PRIVATE_BASE = 224,
|
||||
/* Windows 10 option to send when Anonymize=true */
|
||||
|
@ -44,6 +44,7 @@ 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_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);
|
||||
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_search_domains(sd_dhcp_lease *lease, char ***domains);
|
||||
|
@ -46,8 +46,9 @@ 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_dns(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
|
||||
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
|
||||
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_emit_router(sd_dhcp_server *server, int enabled);
|
||||
|
||||
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
|
||||
|
@ -160,6 +160,9 @@ int sd_network_link_get_search_domains(int ifindex, char ***domains);
|
||||
/* Get the route DNS domain names for a given link. */
|
||||
int sd_network_link_get_route_domains(int ifindex, char ***domains);
|
||||
|
||||
/* Get the sip servers for a given link. */
|
||||
int sd_network_link_get_sip_servers(int ifindex, char ***sip);
|
||||
|
||||
/* Get whether this link shall be used as 'default route' for DNS queries */
|
||||
int sd_network_link_get_dns_default_route(int ifindex);
|
||||
|
||||
|
@ -72,6 +72,7 @@ UseRoutes=
|
||||
IAID=
|
||||
UserClass=
|
||||
UseNTP=
|
||||
UseSIP=
|
||||
UseMTU=
|
||||
UseDomainName=
|
||||
RouteMetric=
|
||||
@ -245,6 +246,8 @@ PoolOffset=
|
||||
Timezone=
|
||||
EmitDNS=
|
||||
NTP=
|
||||
EmitSIP=
|
||||
SIP=
|
||||
EmitRouter=
|
||||
MaxLeaseTimeSec=
|
||||
DefaultLeaseTimeSec=
|
||||
|
Loading…
Reference in New Issue
Block a user