Merge ~alfonsosanchezbeato/snappy-hwe-snaps/+git/network-manager:fix-dhcp-busy-loop into ~snappy-hwe-team/snappy-hwe-snaps/+git/network-manager:network-manager/xenial/1.2.2

Proposed by Alfonso Sanchez-Beato
Status: Merged
Approved by: Konrad Zapałowicz
Approved revision: f3a9eb6524d947a79e0fd619f3965415332e9bed
Merged at revision: 04d207d59c0764f5cffb7163e4dd3af5dd9a074b
Proposed branch: ~alfonsosanchezbeato/snappy-hwe-snaps/+git/network-manager:fix-dhcp-busy-loop
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/network-manager:network-manager/xenial/1.2.2
Diff against target: 102 lines (+26/-10)
3 files modified
src/systemd/src/libsystemd-network/sd-dhcp-client.c (+1/-1)
src/systemd/src/libsystemd-network/sd-dhcp6-client.c (+1/-1)
src/systemd/src/libsystemd-network/sd-ipv4acd.c (+24/-8)
Reviewer Review Type Date Requested Status
System Enablement Bot continuous-integration Approve
Alfonso Sanchez-Beato continuous-integration Approve
Konrad Zapałowicz (community) Approve
Review via email: mp+354462@code.launchpad.net

Description of the change

Use recv() instead of read() when reading DHCP packets

This applies systemd commit cf447cb62 to fix a busy loop when an empty
DHCP UDP package has been (LP: #1790974).

To post a comment you must log in.
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

Ack

review: Approve
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) :
review: Approve (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index 758dba4..5ca3b4d 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -1591,7 +1591,7 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
1591 if (!message)1591 if (!message)
1592 return -ENOMEM;1592 return -ENOMEM;
15931593
1594 len = read(fd, message, buflen);1594 len = recv(fd, message, buflen, 0);
1595 if (len < 0) {1595 if (len < 0) {
1596 if (errno == EAGAIN || errno == EINTR)1596 if (errno == EAGAIN || errno == EINTR)
1597 return 0;1597 return 0;
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index 8fa1822..d9ef249 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -899,7 +899,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
899 if (!message)899 if (!message)
900 return -ENOMEM;900 return -ENOMEM;
901901
902 len = read(fd, message, buflen);902 len = recv(fd, message, buflen, 0);
903 if (len < 0) {903 if (len < 0) {
904 if (errno == EAGAIN || errno == EINTR)904 if (errno == EAGAIN || errno == EINTR)
905 return 0;905 return 0;
diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
index 9b5ce72..867987c 100644
--- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c
+++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c
@@ -157,8 +157,10 @@ static void ipv4acd_set_state(sd_ipv4acd *ll, IPv4ACDState st, bool reset_counte
157static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) {157static void ipv4acd_client_notify(sd_ipv4acd *ll, int event) {
158 assert(ll);158 assert(ll);
159159
160 if (ll->cb)160 if (!ll->cb)
161 ll->cb(ll, event, ll->userdata);161 return;
162
163 ll->cb(ll, event, ll->userdata);
162}164}
163165
164static void ipv4acd_stop(sd_ipv4acd *ll) {166static void ipv4acd_stop(sd_ipv4acd *ll) {
@@ -348,22 +350,36 @@ static void ipv4acd_on_conflict(sd_ipv4acd *ll) {
348 ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT);350 ipv4acd_client_notify(ll, SD_IPV4ACD_EVENT_CONFLICT);
349}351}
350352
351static int ipv4acd_on_packet(sd_event_source *s, int fd,353static int ipv4acd_on_packet(
352 uint32_t revents, void *userdata) {354 sd_event_source *s,
355 int fd,
356 uint32_t revents,
357 void *userdata) {
358
353 sd_ipv4acd *ll = userdata;359 sd_ipv4acd *ll = userdata;
354 struct ether_arp packet;360 struct ether_arp packet;
361 ssize_t n;
355 int r;362 int r;
356363
364 assert(s);
357 assert(ll);365 assert(ll);
358 assert(fd >= 0);366 assert(fd >= 0);
359367
360 r = read(fd, &packet, sizeof(struct ether_arp));368 n = recv(fd, &packet, sizeof(struct ether_arp), 0);
361 if (r < (int) sizeof(struct ether_arp))369 if (n < 0) {
370 r = log_ipv4acd_debug_errno(ll, errno, "Failed to read ARP packet: %m");
362 goto out;371 goto out;
372 }
373 if ((size_t) n != sizeof(struct ether_arp)) {
374 log_ipv4acd_debug(ll, "Ignoring too short ARP packet.");
375 return 0;
376 }
363377
364 switch (ll->state) {378 switch (ll->state) {
379
365 case IPV4ACD_STATE_ANNOUNCING:380 case IPV4ACD_STATE_ANNOUNCING:
366 case IPV4ACD_STATE_RUNNING:381 case IPV4ACD_STATE_RUNNING:
382
367 if (ipv4acd_arp_conflict(ll, &packet)) {383 if (ipv4acd_arp_conflict(ll, &packet)) {
368 usec_t ts;384 usec_t ts;
369385
@@ -382,15 +398,15 @@ static int ipv4acd_on_packet(sd_event_source *s, int fd,
382 } else398 } else
383 ipv4acd_on_conflict(ll);399 ipv4acd_on_conflict(ll);
384 }400 }
385
386 break;401 break;
402
387 case IPV4ACD_STATE_WAITING_PROBE:403 case IPV4ACD_STATE_WAITING_PROBE:
388 case IPV4ACD_STATE_PROBING:404 case IPV4ACD_STATE_PROBING:
389 case IPV4ACD_STATE_WAITING_ANNOUNCE:405 case IPV4ACD_STATE_WAITING_ANNOUNCE:
390 /* BPF ensures this packet indicates a conflict */406 /* BPF ensures this packet indicates a conflict */
391 ipv4acd_on_conflict(ll);407 ipv4acd_on_conflict(ll);
392
393 break;408 break;
409
394 default:410 default:
395 assert_not_reached("Invalid state.");411 assert_not_reached("Invalid state.");
396 }412 }

Subscribers

People subscribed via source and target branches