networkd: DHCP client add support to send RELEASE packet

closes #10820
This commit is contained in:
Susant Sahani 2019-05-13 20:00:28 +05:30 committed by Yu Watanabe
parent bdb397ed10
commit 1501b429a9
7 changed files with 61 additions and 3 deletions

View File

@ -1470,6 +1470,14 @@
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SendRelease=</varname></term>
<listitem>
<para>When true, the DHCPv4 client sends a DHCP release packet when it stops.
Defaults to false.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RapidCommit=</varname></term>
<listitem>

View File

@ -606,7 +606,7 @@ static int client_message_init(
assert(ret);
assert(_optlen);
assert(_optoffset);
assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST));
assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST, DHCP_RELEASE));
optlen = DHCP_MIN_OPTIONS_SIZE;
size = sizeof(DHCPPacket) + optlen;
@ -697,7 +697,7 @@ static int client_message_init(
MAY contain the Parameter Request List option. */
/* NOTE: in case that there would be an option to do not send
* any PRL at all, the size should be checked before sending */
if (client->req_opts_size > 0) {
if (client->req_opts_size > 0 && type != DHCP_RELEASE) {
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
client->req_opts_size, client->req_opts);
@ -729,7 +729,7 @@ static int client_message_init(
*/
/* RFC7844 section 3:
SHOULD NOT contain any other option. */
if (!client->anonymize) {
if (!client->anonymize && type != DHCP_RELEASE) {
max_size = htobe16(size);
r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
@ -861,6 +861,41 @@ static int client_send_discover(sd_dhcp_client *client) {
return 0;
}
static int client_send_release(sd_dhcp_client *client) {
_cleanup_free_ DHCPPacket *release = NULL;
size_t optoffset, optlen;
int r;
assert(client);
assert(!IN_SET(client->state, DHCP_STATE_STOPPED));
r = client_message_init(client, &release, DHCP_RELEASE,
&optlen, &optoffset);
if (r < 0)
return r;
/* Fill up release IP and MAC */
release->dhcp.ciaddr = client->lease->address;
memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
r = dhcp_network_send_udp_socket(client->fd,
client->lease->server_address,
DHCP_PORT_SERVER,
&release->dhcp,
sizeof(DHCPMessage) + optoffset);
if (r < 0)
return r;
log_dhcp_client(client, "RELEASE");
return 0;
}
static int client_send_request(sd_dhcp_client *client) {
_cleanup_free_ DHCPPacket *request = NULL;
size_t optoffset, optlen;
@ -1858,6 +1893,14 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
return r;
}
int sd_dhcp_client_send_release(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
client_send_release(client);
return 0;
}
int sd_dhcp_client_stop(sd_dhcp_client *client) {
DHCP_CLIENT_DONT_DESTROY(client);

View File

@ -564,6 +564,9 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
}
if (link->network->dhcp_send_release)
(void) sd_dhcp_client_send_release(client);
_fallthrough_;
case SD_DHCP_CLIENT_EVENT_EXPIRED:
case SD_DHCP_CLIENT_EVENT_IP_CHANGE:

View File

@ -149,6 +149,7 @@ DHCP.RouteTable, config_parse_section_route_table,
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCP.IAID, config_parse_iaid, 0, 0
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCP.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
DHCP.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)

View File

@ -128,6 +128,7 @@ struct Network {
bool rapid_commit;
bool dhcp_use_hostname;
bool dhcp_route_table_set;
bool dhcp_send_release;
DHCPUseDomains dhcp_use_domains;
Set *dhcp_black_listed_ip;

View File

@ -176,6 +176,7 @@ int sd_dhcp_client_get_lease(
int sd_dhcp_client_stop(sd_dhcp_client *client);
int sd_dhcp_client_start(sd_dhcp_client *client);
int sd_dhcp_client_send_release(sd_dhcp_client *client);
sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);

View File

@ -64,6 +64,7 @@ ListenPort=
UseTimezone=
RouteTable=
BlackList=
SendRelease=
[Route]
Destination=
Protocol=