udhcpc: DHCPDECLINE on lease renewal when ARP replies are echoed back

"Stormont, Brian via busybox" <[email protected]> Wed, 8 Jul 2026 20:17:03 +0000
Newsgroups gmane.linux.busybox
Message-ID <DS0PR03MB718004D170FCBE60D4E4E87ABBFF2@DS0PR03MB7180.namprd03.prod.outlook.com>
--===============6611643992324725997==
Content-Language: en-US
Content-Type: multipart/alternative;
	boundary="_000_DS0PR03MB718004D170FCBE60D4E4E87ABBFF2DS0PR03MB7180namp_"

--_000_DS0PR03MB718004D170FCBE60D4E4E87ABBFF2DS0PR03MB7180namp_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

While using udhcpc, we ran into an issue where udhcpc consistently declines
a lease upon its renewal attempt.  An analysis of the behavior is described
below:

When run with -a (arping), udhcpc performs the RFC 2131 section 3.1
post-DHCPACK ARP check by calling arpping() with safe_mac =3D=3D NULL. With=
 a
NULL safe_mac, arpping() treats any ARP reply for the tested address as a
conflict, including a reply whose sender hardware address is our own MAC.

Some networks echo a station's own broadcast frames back to it. RFC 5227
section 2.1.1 explicitly calls this out ("many wireless access points may
'rebroadcast' any received broadcast packets to all recipients, including
the original sender itself") and includes a precaution to ignore ARP
packets whose sender hardware address is one of the host's own interfaces.

We hit this with an Aruba access point configured to convert broadcast ARP
requests to unicast ("broadcast filtering" in ARP mode): the AP delivers
the client's own ARP frames back to it. Because the address is still
assigned during a renewal, the host answers the echoed request itself, and
arpping() then sees an ARP reply for the just-ACKed address carrying our
own MAC and reports a conflict, so udhcpc sends a DHCPDECLINE.

This ARP check runs for DHCPACKs in the RENEWING, RENEW_REQUESTED and
REBINDING states as well as REQUESTING, so the client repeatedly declines
the address it is actively using at each renewal (T/2) and churns to a new
address. On the server this also exhausts the pool, since declined
addresses are held down (e.g. ISC Kea's default decline-probation-period
is 24h).

It appears a simple fix for this would be to pass client_data.client_mac as
safe_mac, as udhcpd already does in its arpping() call in dhcpd.c, so a
reply from our own hardware address is not treated as a conflict.

Is there a reason the safe_mac parameter isn't already used for DHCP client
requests?

An alternative (or complementary) fix would be to run the post-ACK ARP
check only on initial acquisition (REQUESTING) and not on renewal/rebind,
since RFC 2131 3.1 frames the check as part of first-time configuration
and the address is already in active use on renewal. The one-line
safe_mac change suggested is a more general fix and also covers the case
where the AP proxy-answers on the client's behalf.

Best regards,
Brian


________________________________
- CONFIDENTIAL-

This email and any files transmitted with it are confidential, and may also=
 be legally privileged. If you are not the intended recipient, you may not =
review, use, copy, or distribute this message. If you receive this email in=
 error, please notify the sender immediately by reply email and then delete=
 this email.

--_000_DS0PR03MB718004D170FCBE60D4E4E87ABBFF2DS0PR03MB7180namp_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
1">
<style type=3D"text/css" style=3D"display:none;"> P {margin-top:0;margin-bo=
ttom:0;} </style>
</head>
<body dir=3D"ltr">
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
While using udhcpc, we ran into an issue where udhcpc consistently declines=
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
a lease upon its renewal attempt. &nbsp;An analysis of the behavior is desc=
ribed</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
below:</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
When run with -a (arping), udhcpc performs the RFC 2131 section 3.1</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
post-DHCPACK ARP check by calling arpping() with safe_mac =3D=3D NULL. With=
 a</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
NULL safe_mac, arpping() treats any ARP reply for the tested address as a</=
div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
conflict, including a reply whose sender hardware address is our own MAC.</=
div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
Some networks echo a station's own broadcast frames back to it. RFC 5227</d=
iv>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
section 2.1.1 explicitly calls this out (&quot;many wireless access points =
may</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
'rebroadcast' any received broadcast packets to all recipients, including</=
div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
the original sender itself&quot;) and includes a precaution to ignore ARP</=
div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
packets whose sender hardware address is one of the host's own interfaces.<=
/div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
We hit this with an Aruba access point configured to convert broadcast ARP<=
/div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
requests to unicast (&quot;broadcast filtering&quot; in ARP mode): the AP d=
elivers</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
the client's own ARP frames back to it. Because the address is still</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
assigned during a renewal, the host answers the echoed request itself, and<=
/div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
arpping() then sees an ARP reply for the just-ACKed address carrying our</d=
iv>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
own MAC and reports a conflict, so udhcpc sends a DHCPDECLINE.</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
This ARP check runs for DHCPACKs in the RENEWING, RENEW_REQUESTED and</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
REBINDING states as well as REQUESTING, so the client repeatedly declines</=
div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
the address it is actively using at each renewal (T/2) and churns to a new<=
/div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
address. On the server this also exhausts the pool, since declined</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
addresses are held down (e.g. ISC Kea's default decline-probation-period</d=
iv>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
is 24h).</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
It appears a simple fix for this would be to pass client_data.client_mac as=
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
safe_mac, as udhcpd already does in its arpping() call in dhcpd.c, so a</di=
v>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
reply from our own hardware address is not treated as a conflict.</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
Is there a reason the safe_mac parameter isn't already used for DHCP client=
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
requests? &nbsp;</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
An alternative (or complementary) fix would be to run the post-ACK ARP</div=
>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
check only on initial acquisition (REQUESTING) and not on renewal/rebind,</=
div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
since RFC 2131 3.1 frames the check as part of first-time configuration</di=
v>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
and the address is already in active use on renewal. The one-line</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
safe_mac change suggested is a more general fix and also covers the case</d=
iv>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
where the AP proxy-answers on the client's behalf.</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
Best regards,</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 11pt; c=
olor: rgb(0, 0, 0);">
Brian</div>
<br>
<br>
<hr>
- CONFIDENTIAL- <br>
<br>
This email and any files transmitted with it are confidential, and may also=
 be legally privileged. If you are not the intended recipient, you may not =
review, use, copy, or distribute this message. If you receive this email in=
 error, please notify the sender
 immediately by reply email and then delete this email.
</body>
</html>

--_000_DS0PR03MB718004D170FCBE60D4E4E87ABBFF2DS0PR03MB7180namp_--

--===============6611643992324725997==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox

--===============6611643992324725997==--