network: introduce [DHCPv4] RequestAddress= setting

This may be useful when requesting a specific address.

Closes #29437.
This commit is contained in:
Yu Watanabe 2023-10-04 20:46:55 +09:00
parent 5d896defeb
commit b93bf1bf9f
4 changed files with 38 additions and 6 deletions

View file

@ -2098,6 +2098,17 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
<!-- DHCP packet contents -->
<varlistentry>
<term><varname>RequestAddress=</varname></term>
<listitem>
<para>Takes an IPv4 address. When specified, the Requested IP Address option (option code 50) is
added with it to the initial DHCPDISCOVER message sent by the DHCP client. Defaults to unset, and
an already assigned dynamic address to the interface is automatically picked.</para>
<xi:include href="version-info.xml" xpointer="v255"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SendHostname=</varname></term>
<listitem>
@ -2232,6 +2243,7 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
are implied and these settings in the .network file are silently ignored. Also,
<varname>Hostname=</varname>,
<varname>MUDURL=</varname>,
<varname>RequestAddress</varname>,
<varname>RequestOptions=</varname>,
<varname>SendOption=</varname>,
<varname>SendVendorOption=</varname>,

View file

@ -1383,15 +1383,15 @@ static int dhcp4_set_client_identifier(Link *link) {
return 0;
}
static int dhcp4_set_request_address(Link *link) {
static int dhcp4_find_dynamic_address(Link *link, struct in_addr *ret) {
Address *a;
assert(link);
assert(link->network);
assert(link->dhcp_client);
assert(ret);
if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
return 0;
return false;
SET_FOREACH(a, link->addresses) {
if (a->source != NETWORK_CONFIG_SOURCE_FOREIGN)
@ -1403,11 +1403,29 @@ static int dhcp4_set_request_address(Link *link) {
}
if (!a)
return false;
*ret = a->in_addr.in;
return true;
}
static int dhcp4_set_request_address(Link *link) {
struct in_addr a;
assert(link);
assert(link->network);
assert(link->dhcp_client);
a = link->network->dhcp_request_address;
if (in4_addr_is_null(&a))
(void) dhcp4_find_dynamic_address(link, &a);
if (in4_addr_is_null(&a))
return 0;
log_link_debug(link, "DHCPv4 CLIENT: requesting " IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(a->in_addr.in));
return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in);
log_link_debug(link, "DHCPv4 CLIENT: requesting %s.", IN4_ADDR_TO_STRING(&a));
return sd_dhcp_client_set_request_address(link->dhcp_client, &a);
}
static bool link_needs_dhcp_broadcast(Link *link) {

View file

@ -214,6 +214,7 @@ NextHop.Family, config_parse_nexthop_family,
NextHop.OnLink, config_parse_nexthop_onlink, 0, 0
NextHop.Blackhole, config_parse_nexthop_blackhole, 0, 0
NextHop.Group, config_parse_nexthop_group, 0, 0
DHCPv4.RequestAddress, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_request_address)
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCPv4.UseDNS, config_parse_dhcp_use_dns, AF_INET, 0
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)

View file

@ -114,6 +114,7 @@ struct Network {
/* DHCP Client Support */
AddressFamily dhcp;
struct in_addr dhcp_request_address;
DHCPClientIdentifier dhcp_client_identifier;
DUID dhcp_duid;
uint32_t dhcp_iaid;