dhcp: don't stop receiving packets when the link goes down

When the link goes down, DHCP client_receive_message*() functions return an
error and the related I/O source is removed from the main loop. With the
current implementation of systemd-networkd this doesn't matter because the DHCP
client is always stopped on carrier down and restarted on carrier up. However
it seems wrong to have the DHCP client crippled (because no packet can be
received anymore) once the link goes temporarily down.

Change the receive functions to ignore a ENETDOWN event so that the client will
be able to receive packets again after the link comes back.
This commit is contained in:
Beniamino Galvani 2019-02-17 19:06:34 +01:00 committed by Yu Watanabe
parent 825ace96b1
commit 22a3fd2da9
2 changed files with 19 additions and 3 deletions

View file

@ -1684,6 +1684,12 @@ static int client_receive_message_udp(
assert(client);
buflen = next_datagram_size_fd(fd);
if (buflen == -ENETDOWN) {
/* the link is down. Don't return an error or the I/O event
source will be disconnected and we won't be able to receive
packets again when the link comes back. */
return 0;
}
if (buflen < 0)
return buflen;
@ -1693,7 +1699,8 @@ static int client_receive_message_udp(
len = recv(fd, message, buflen, 0);
if (len < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
/* see comment above for why we shouldn't error out on ENETDOWN. */
if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
return 0;
return log_dhcp_client_errno(client, errno,
@ -1771,6 +1778,8 @@ static int client_receive_message_raw(
assert(client);
buflen = next_datagram_size_fd(fd);
if (buflen == -ENETDOWN)
return 0;
if (buflen < 0)
return buflen;
@ -1782,7 +1791,7 @@ static int client_receive_message_raw(
len = recvmsg(fd, &msg, 0);
if (len < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
return 0;
return log_dhcp_client_errno(client, errno,

View file

@ -1112,6 +1112,12 @@ static int client_receive_message(
assert(client->event);
buflen = next_datagram_size_fd(fd);
if (buflen == -ENETDOWN) {
/* the link is down. Don't return an error or the I/O event
source will be disconnected and we won't be able to receive
packets again when the link comes back. */
return 0;
}
if (buflen < 0)
return buflen;
@ -1121,7 +1127,8 @@ static int client_receive_message(
len = recv(fd, message, buflen, 0);
if (len < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
/* see comment above for why we shouldn't error out on ENETDOWN. */
if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
return 0;
return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m");