Add listen-only mode support via ip link (issue #25) - #27
Open
knakazawa-ics wants to merge 1 commit into
Open
Conversation
Advertise CAN_CTRLMODE_LISTENONLY when a v3.2+ usermode daemon is connected, and report the control mode to the daemon alongside the bitrate. Because can_changelink() stores ctrlmode without calling into the driver (and requires the interface to be down), the accumulated configuration is reported from ndo_open. The report is skipped when the bitrate is still zero or when nothing changed since the last report, so repeated ifup/ifdown cycles do not re-apply unchanged settings to the hardware. Baudrates seeded by the daemon via SIOCSBAUDRATE count as already reported for the same reason. The listen-only flag is carried in a spare high bit of the existing intrepid_pending_tx_info.count field; bitrate_const caps arbitration bitrates at 1 Mbit/s so the flag cannot collide with a bitrate value. The record layout and the read() protocol are unchanged, and nothing new is sent to daemons that do not announce v3.2+. This encoding is a proposal and pairs with the corresponding icsscand change, which masks the flag before using the bitrate. The bitrate_changed test-then-clear in check_bitrate_change() is now an xchg(), closing the pre-existing window in which a set landing between the test and the clear could be lost, with WRITE_ONCE/READ_ONCE at the setters and the poll() reader. Signed-off-by: Koki Nakazawa <knakazawa@intrepidcs.com>
This was referenced Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds CAN listen-only mode support, addressing the listen-only portion of #25.
It pairs with intrepidcs/icsscand#20; the two are meant to land
together. One design point needs your call: the settings-record encoding (see "Open
question" below).
What this does
ip -details link show can0reports theLISTEN-ONLYctrlmode flag, and the devicestops acknowledging and transmitting while still receiving (verified on hardware, below).
Implementation notes
CAN_CTRLMODE_LISTENONLYis advertised only when a v3.2+ usermode daemon isconnected, so nothing changes for released daemons (3.1.x and older).
can_changelink()stores ctrlmode without calling into the driver and requires theinterface down, so the accumulated configuration is reported from
ndo_open. Thereport is skipped while the bitrate is still zero and when nothing changed since the
last report, so repeated ifup/ifdown cycles do not re-apply unchanged settings.
Baudrates seeded by the daemon via SIOCSBAUDRATE count as already reported.
bitrate_changedgains a second writer (ndo_open); the test-then-clear incheck_bitrate_change()is now anxchg(), closing the pre-existing window inwhich a set landing between the test and the clear could be lost, with
WRITE_ONCE/READ_ONCE at the setters and the poll() reader.
happen at release time, and can add them if you prefer.
Open question: settings-record encoding
The listen-only flag is carried in bit 30 of the existing
intrepid_pending_tx_info.countfield (bitrate_const caps arbitration bitrates at1 Mbit/s, so the flag cannot collide with a real bitrate value; the record layout and
the read() protocol are unchanged). The settings-change record is upstream's design,
so treat this encoding as a proposal: if there are in-flight daemon changes that parse
countas a raw bitrate, or you would rather use a different record type, I canchange both sides. The paired icsscand PR masks the flag before using the bitrate.
Compatibility matrix (verified)
is correctly rejected by netlink (not advertised).
One release-timing assumption to be aware of: icsscand master already reports 3.2.0,
so the daemon-minor gate assumes this pair lands before a 3.2.0 daemon release. If a
stock 3.2.0 daemon without the companion change were to ship first, it would receive
the flag bit and misread it as a bitrate. In that case the daemon should be bumped to
3.3.0 and the gates here changed to minor > 2; happy to adjust to whatever release
plan you prefer.
Known limitations
existing bitrate path): if the daemon cannot apply the mode,
ip -detailswill stillshow LISTEN-ONLY. The daemon logs an error in that case.
forwarded to the device, which suppresses them (no transmit receipts are generated).
reflected back into the netlink ctrlmode at interface creation; the kernel state is
authoritative once configured through ip link.
Testing
Ubuntu 22.04.5, runtime-tested on kernels 5.15.0-187 (built together with the gnu89
fix from #26) and 6.8.0-136; also cross-compiles clean for aarch64. Run with a
neoVI FIRE 3 and a ValueCAN 4-2, each exercised as the SocketCAN device under test
with the other as the remote node. The daemon was started with
LIBICSNEO_USE_SERVD=0(stock discovery is currently affected by intrepidcs/icsscand#21).CAN_SETTINGS.Mode = LISTEN_ONLY; candumpstill receives, the remote transmitter gets no ACK (continuous retransmissions, as
expected with no ACK present), local TX is suppressed by the device.
fd on+dbitratecombined with listen-only behaves the same (BRS FDframes received while listen-only with no ACK generated; clean 5/5 in both
directions after listen-only off).