Four *_attach_event helpers swallow sd_event_default() failures and
return success while leaving obj->event NULL:
sd_dhcp_client_attach_event (sd-dhcp-client.c)
sd_dhcp6_client_attach_event (sd-dhcp6-client.c)
sd_ndisc_attach_event (sd-ndisc.c)
sd_radv_attach_event (sd-radv.c)
Each contains the same copy-pasted typo in the NULL-event branch:
r = sd_event_default(&obj->event);
if (r < 0)
return 0; /* swallows -ENOMEM / -ECHILD */
The caller is told the attach succeeded, but obj->event is still
NULL. A subsequent *_start() then trips assert_return(obj->event,
-EINVAL) and returns a spurious -EINVAL (or aborts on assert-abort
builds), and any consumer of *_get_event() dereferences NULL.
The sibling helper sd_dhcp_server_attach_event already uses the
correct pattern:
r = sd_event_default(&server->event);
if (r < 0)
return r;
Fix by returning r instead of 0 at each of the four sites so the
sd_event_default() errno is propagated to the caller and ownership
stays with the caller.
Assisted-by: kres (claude-opus-4-7)
Signed-off-by: Chris Mason <clm@meta.com>
There exists a small window of time in icmp6_bind() between creating the
ICMPv6 socket and binding it to an ifindex, where the link-scoped socket
can process an ICMPv6 packet received on any interface. The applies to
both sd-radv and sd-ndisc codepaths.
This change adds an explicit check for ifindex on the receive path and
ignores packets received on other interfaces.
Co-developed-by: OpenAI Codex <noreply@openai.com>
When the periodic RA timer fires, any error returned by sendmsg()
currently propagates up through sd_radv_send() into radv_timeout(),
which then calls sd_radv_stop(). The RA engine is never started again
until the next carrier transition.
On an 802.3ad bond there is a window right after carrier-up where the
link is administratively up but no aggregator has been selected yet, so
sendmsg() returns ENOBUFS. If the very first RA after a flap lands in
that window, radv stops permanently and all clients lose their SLAAC
addresses, on-link/PD prefixes, and default router once the previously
advertised lifetimes expire, while IPv4 keeps working, leading to a very
confusing situation with v4 up and v6 down.
Handle this the same way solicited RAs already do (see
radv_process_packet()): log the failure and reschedule the timer instead
of giving up. ra_sent is left untouched on failure so we stay in the
fast initial-advertisement regime until a send actually succeeds.
For libsystemd's headers, the changes made depend on whether the
header is installed or not. For installed headers, the only change
made is that commonly included headers were moved to _sd-common.h.
For these headers, there should be no noticeable change in behavior
when including them. For non-installed headers, includes were replaced
with forward declarations where possible as usual.
Split out of #37344.
I cannot find any RFC that states we should not send multiple route
prefix or pref64 options that have intersection with others.
Moreover, each route prefix option has preference field, thus, user may
want to send e.g. a prefix with the normal preference, and another sub
prefix with the high preference. Previously, such configuration was
prohibited. Let's allow that now.
As the caller may want to update multiple prefixes and friends.
Let's not automatically announce on update in library side.
Currently, only prefix is updated during running. Hence, this does not
change any effective behavior.
This also makes too large retransmit time handled gracefully,
as even if a too large value is specified, usec_to_be32_msec() in
radv_send_router() will handle it gracefully anyway.
Note, networkd still refuses such invalid values. Hence, this does not
change any effective behavior.
There are many possible reasons to stop the service;
tentative reboot of the service or the system, the router may be
revoked, and so on.
And, each situations, the availability of the previously announced
options e.g. prefixes, DNSSL and so on is not clear.
So, let's announce only the clear information, that is, the router
lifetime is zero. which indicates that the router will be invalidated
(regardless tentative or not).
- split out radv_setup_recv_event(),
- slightly update log messages,
- use DIV_ROUND_UP(),
- use structured initializer more.
No functional change, just preparation for later commits.
This is preparation for #28891, which adds a bunch more helpers around
"struct iovec", at which point this really deserves its own .c/.h file.
The idea is that we sooner or later can consider "struct iovec" as an
entirely generic mechanism to reference some binary blob, and is the
go-to type for this purpose whenever we need one.
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.
Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state
Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.
In some places, initialization is dropped if unnecessary.
Since we don't need the error value, and the buffer is allocated with a fixed
size, the whole logic provided by in_addr_to_string() becomes unnecessary, so
it's enough to wrap inet_ntop() directly.
inet_ntop() can only fail with ENOSPC. But we specify a buffer that is supposed
to be large enough, so this should never fail. A bunch of tests of this are added.
This allows all the wrappers like strna(), strnull(), strempty() to be dropped.
The guard of 'if (DEBUG_LOGGING)' can be dropped from around log_debug(),
because log_debug() implements the check outside of the function call. But
log_link_debug() does not, so it we need it to avoid unnecessary evaluation of
the formatting.
Let's raise our supported baseline a bit: CLOCK_BOOTTIME started to work
with timerfd in kernel 3.15 (i.e. back in 2014), let's require support
for it now.
This will raise our baseline only modestly from 3.13 → 3.15.