<feed xmlns='http://www.w3.org/2005/Atom'>
<title>odhcpd, branch master</title>
<subtitle>OpenWrt DHCP Server</subtitle>
<id>https://git-03.infra.openwrt.org/project/odhcpd/atom?h=master</id>
<link rel='self' href='https://git-03.infra.openwrt.org/project/odhcpd/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/'/>
<updated>2026-11-08T08:54:11Z</updated>
<entry>
<title>dhcpv6-ia: skip invalid parent prefixes for PD routes</title>
<updated>2026-11-08T08:54:11Z</updated>
<author>
<name>lightingghost</name>
</author>
<published>2026-09-09T15:48:47Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=f97b5d335c513cedd5b81ef9f39bdc799de8f535'/>
<id>urn:sha1:f97b5d335c513cedd5b81ef9f39bdc799de8f535</id>
<content type='text'>
The IA_PD reply path uses valid_prefix_length() to skip interface prefixes
that cannot contain the delegated prefix, but __apply_lease() does not.

As a result, a /64 PD lease on an interface carrying both a shorter prefix
and an on-link /64 can install a route for the on-link /64 via the downstream
client, even though that prefix was never delegated.

Apply the same prefix-length validation before installing PD routes.

This keeps route installation consistent with the IA_PD reply path and
prevents a delegated /64 from replacing the directly-connected route of a
/64 parent prefix.


Signed-off-by: lightingghost &lt;zhenp3ngzhou@gmail.com&gt;</content>
</entry>
<entry>
<title>netlink: clear have_link_local on link-local removal</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>John Crispin</name>
</author>
<published>2026-10-28T15:14:40Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=26aa64a0bd819ba34bfcaebf02d0a3d8da530723'/>
<id>urn:sha1:26aa64a0bd819ba34bfcaebf02d0a3d8da530723</id>
<content type='text'>
have_link_local is set when a link-local address appears, but never
cleared when it is deleted. odhcpd then keeps sending RAs without a
usable link-local source address, and the source lookup can fall back
to a global address, which hosts must discard (RFC 4861 section
6.1.2).

On deletion of a link-local address, ask the kernel whether the device
still has a usable one. Move that check from config_parse_interface()
into netlink_has_linklocal() so that both places use it.

Fixes: 7c0f603abc14 ("router: skip RA and wait for LINK-LOCAL to be assigned")
Link: https://github.com/openwrt/odhcpd/pull/430
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>netlink: wait for DAD before marking the link-local address</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>John Crispin</name>
</author>
<published>2026-10-28T15:14:40Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=47324087756b7532923b6e992e2614662ae820a9'/>
<id>urn:sha1:47324087756b7532923b6e992e2614662ae820a9</id>
<content type='text'>
The kernel reports a new link-local address while it is still
tentative, and again when DAD completes. handle_rtm_addr() sets
have_link_local on the first message, so odhcpd sends RAs while the
kernel does not yet accept the address as a source. odhcpd_reload()
already skips tentative addresses. Ignore them here as well; the
message at the end of DAD sets the flag.

Fixes: 7c0f603abc14 ("router: skip RA and wait for LINK-LOCAL to be assigned")
Link: https://github.com/openwrt/odhcpd/pull/430
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>netlink: drop the cached link-local address when it changes</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>John Crispin</name>
</author>
<published>2026-10-28T13:37:03Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=d6c15fb09094801c7eb55777d7485127b8dc479a'/>
<id>urn:sha1:d6c15fb09094801c7eb55777d7485127b8dc479a</id>
<content type='text'>
odhcpd caches the link-local address that it uses as the source of RAs
and NAs, and clears the cache only on a reload. If the address changes
between two reloads, for example on a new PPP session or a MAC change,
sendmsg() fails with EINVAL for every RA and NA until the next reload.

Clear the cache when a link-local address of the device is added or
removed, so that the next send looks up the current address.

Fixes: d402cdae4316 ("ndp: fix macOS IPv6 compatibility by using link-local source addresses")
Link: https://github.com/openwrt/odhcpd/pull/430
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>netlink: set have_link_local on all interfaces of a device</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>John Crispin</name>
</author>
<published>2026-10-28T13:36:49Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=1223f99cef8da38888abf0a8b54fe15d4449f5e1'/>
<id>urn:sha1:1223f99cef8da38888abf0a8b54fe15d4449f5e1</id>
<content type='text'>
More than one odhcpd interface can use the same device. On a new
link-local address, handle_rtm_addr() returns after the first of them,
and the others keep have_link_local false and skip their RAs.

Continue the loop instead, and skip the address refresh after it as
before.

Fixes: 7c0f603abc14 ("router: skip RA and wait for LINK-LOCAL to be assigned")
Link: https://github.com/openwrt/odhcpd/pull/430
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>config: keep a link-down interface over a reload</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>John Crispin</name>
</author>
<published>2026-10-28T13:20:50Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=fad2c8b4136c935a4abf15895c18bebaa6fc443f'/>
<id>urn:sha1:fad2c8b4136c935a4abf15895c18bebaa6fc443f</id>
<content type='text'>
odhcpd_reload() frees an interface whose link is not IFF_RUNNING. When
the link comes up, handle_rtm_link() does not find the interface, and
RA, DHCPv6 and DHCPv4 stay off until the next reload.

Commit 4b38e6b moved the IFF_RUNNING test into reload_services() and
meant to call close_interface() only for an interface that is not in
use, but the test in odhcpd_reload() stayed. Remove it.

Fixes: 4b38e6b5bb96 ("config: fix feature for enabling service only when interface RUNNING")
Link: https://github.com/openwrt/odhcpd/pull/430
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>odhcpd: leave the receive loop on recvmsg errors</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>YAMAMOTO Masaya</name>
</author>
<published>2026-06-22T18:30:56Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=1e7cc9f5804f00c7816b7710985a1198faafdc45'/>
<id>urn:sha1:1e7cc9f5804f00c7816b7710985a1198faafdc45</id>
<content type='text'>
recvmsg() errors other than EAGAIN restart the receive loop without a
log entry, so an error that repeats keeps the loop busy without a
trace. Leave the loop on such errors and log them; uloop calls the
handler again while the socket is readable. Retry on EINTR.

Signed-off-by: YAMAMOTO Masaya &lt;pandax381@gmail.com&gt;
[reworded the commit message, dropped an else after continue]
Link: https://github.com/openwrt/odhcpd/pull/403
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>dhcpv6-ia: zero-initialize first_key to silence -Wmaybe-uninitialized</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>Michael Pfeifroth</name>
</author>
<published>2026-07-21T06:42:39Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=998fdad7e3b253b6586b5320565f277acf50077f'/>
<id>urn:sha1:998fdad7e3b253b6586b5320565f277acf50077f</id>
<content type='text'>
first_key[] is only read on the path guarded by first_key_valid, and
first_key_valid is only set to true after first_key has been populated
by memcpy(). The code is therefore correct, but GCC's uninitialized
analysis cannot correlate the boolean guard with the array's
initialization state.

With glibc's _FORTIFY_SOURCE enabled, memcpy() is expanded inline as
__builtin___memcpy_chk(), and on aarch64 the 16-byte copy is further
lowered to a single 128-bit access. GCC 12 then emits:

  error: '*(__int128 unsigned *)(&amp;first_key[0])' may be used
         uninitialized [-Werror=maybe-uninitialized]

which -Werror in CMakeLists.txt turns into a build failure on
aarch64 glibc targets (e.g. NXP LS1046). musl and non-fortified
builds are unaffected because they don't inline the fortified
wrapper the same way.

Zero-initialize the buffer to silence the false positive. Runtime
behavior is unchanged: when first_key_valid is true, the buffer has
already been overwritten by memcpy(first_key, a-&gt;key, ...).

Signed-off-by: Michael Pfeifroth &lt;micpf@westermo.com&gt;
Link: https://github.com/openwrt/odhcpd/pull/409
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>dhcpv6-ia: accept only the sub-option of the IA type</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>Duc Anh Luu</name>
</author>
<published>2026-10-24T09:28:20Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=6828041a914fcc9ef14b536c09898354d854c253'/>
<id>urn:sha1:6828041a914fcc9ef14b536c09898354d854c253</id>
<content type='text'>
build_ia() and dhcpv6_ia_on_link() accept IA_PREFIX and IA_ADDR
sub-options in either IA type, but pick the structure layout from the
parent IA type. An IA_ADDR (28 bytes) inside an IA_PD is read as a
29-byte dhcpv6_ia_prefix, so the 16-byte memcmp() of ia_p-&gt;addr reads
one byte past the option and, if it is the last option, past the
datagram. A 62-byte multicast Rebind is enough; with the IA_PD ending
exactly at the 8192-byte receive buffer the read leaves data_buf in
odhcpd_receive_packets(). The comparison result decides whether the
address is echoed back with zero lifetimes, so the client can observe
whether the out-of-bounds byte is zero.

Only accept the sub-option type that belongs to the IA (IA_PREFIX in
IA_PD, IA_ADDR in IA_NA), as RFC 8415 sections 21.4 and 21.21 require.

Found with libFuzzer + AddressSanitizer, reproduced against the daemon.

Signed-off-by: Duc Anh Luu &lt;luuducanh05051995@gmail.com&gt;
[split from a combined fix, reworded the subject]
Link: https://github.com/openwrt/odhcpd/pull/428
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
<entry>
<title>dhcpv6: drop relay messages without a client message</title>
<updated>2026-10-28T15:20:45Z</updated>
<author>
<name>Duc Anh Luu</name>
</author>
<published>2026-10-24T09:28:20Z</published>
<link rel='alternate' type='text/html' href='https://git-03.infra.openwrt.org/project/odhcpd/commit/?id=079f447ccc0bf21b8f3657f16b4f91601e082d30'/>
<id>urn:sha1:079f447ccc0bf21b8f3657f16b4f91601e082d30</id>
<content type='text'>
A Relay-Forward whose RELAY_MSG option is empty, or a relay chain deeper
than DHCPV6_HOP_COUNT_LIMIT, never yields a client message:
handle_nested_message() returns without updating hdr, so
handle_client_request() goes on treating the Relay-Forward header as a
client message. update_nested_message() then recurses into the
zero-length RELAY_MSG payload and reads its msg_type one byte past the
end of the datagram, and rewrites that byte to RELAY_REPL if it happens
to hold RELAY_FORW. Any client on the link can trigger this with a
single unauthenticated DHCPv6 packet.

Drop the request when no client message was found, and make
update_nested_message() check the length before reading the header.

Found with libFuzzer + AddressSanitizer, reproduced against the daemon.

Signed-off-by: Duc Anh Luu &lt;luuducanh05051995@gmail.com&gt;
[split from a combined fix, reworded the subject]
Link: https://github.com/openwrt/odhcpd/pull/428
Signed-off-by: John Crispin &lt;john@phrozen.org&gt;
</content>
</entry>
</feed>
