From: Yu Watanabe Date: Wed, 4 Oct 2023 11:46:55 +0000 (+0900) Subject: network: introduce [DHCPv4] RequestAddress= setting X-Git-Tag: v255-rc1~329^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b93bf1bf9fb8f091c52588c5fc9edef6225f4ed3;p=thirdparty%2Fsystemd.git network: introduce [DHCPv4] RequestAddress= setting This may be useful when requesting a specific address. Closes #29437. --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 8d462615ac6..33c559cddb5 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2098,6 +2098,17 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix + + RequestAddress= + + 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. + + + + + SendHostname= @@ -2232,6 +2243,7 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix are implied and these settings in the .network file are silently ignored. Also, Hostname=, MUDURL=, + RequestAddress, RequestOptions=, SendOption=, SendVendorOption=, diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 2a6237c6d51..3e8038ede6b 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -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 0; + 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; - log_link_debug(link, "DHCPv4 CLIENT: requesting " IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(a->in_addr.in)); + if (in4_addr_is_null(&a)) + (void) dhcp4_find_dynamic_address(link, &a); + + if (in4_addr_is_null(&a)) + return 0; - 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) { diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index ab456efb9e9..42e989e1160 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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) diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 34bc179d75b..cc2cf36f5ce 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -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;