Re: [RFC] A CAN Bus (SocketCAN-like) networking stack for FreeBSD
Jérémie JOURDIN <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.hackers |
|---|---|
| Message-ID | <PATP264MB5109B7BE21048ED459221BF8FD6BA@PATP264MB5109.FRAP264.PROD.OUTLOOK.COM> |
Hello,
Yes, I think it’s time for upstream submission.
This is my first kernel development project.
While the code is running on some systems, I'm under no illusion that it fully meets FreeBSD's kernel conventions and quality standards.
I expect there are areas where locking patterns, KPI usage, or naming conventions could be improved.
The code is entirely additive, integration should be easy.
The 8 commits could be :
1.
can: add CAN protocol headers and frame definitions
2.
can: add core PF_CAN domain, netisr handler, and interface layer
3.
can: add CAN_RAW socket protocol
4.
can: add virtual CAN interface (vcan)
5.
can: add canconfig(8) configuration utility
6.
can: add candump(8), cansend(8), and slcand(8) utilities
7.
can: add AHC0512 hardware driver
8.
can: add NMEA 2000 / SAE J1939 protocol
Few questions to ease integration :
1.
Which AF_ number should CAN use ?
2.
Should AF_CAN go in sys/sys/socket.h directly or stay as a local #define in my dev/can/can.h for now?
3.
Is slot 11 acceptable for NETISR_CAN ?
4.
Should CAN be gated behind a MK_CAN build knob, or always built ?
5.
Is the dev/can/ location acceptable, or should it be net/can/ ?
*
The CAN stack is a protocol family, not a device driver.
*
But it also contains device drivers.
*
FreeBSD convention would suggest splitting : protocol layer in net/can/, hardware drivers stay in dev/can/
About the current implementation :
This is a PF_CAN / AF_CAN domain implementation, bringing Linux SocketCAN API compatibility to the FreeBSD network stack.
The implementation is ~7,200 lines of kernel code and ~3,700 lines of userland utilities.
The kernel API mirrors Linux SocketCAN so existing documentation and protocol knowledge transfers, but the implementation is native FreeBSD: kqueue, netisr, epoch, ifnet, style(9).
Architecture :
The stack is split into loadable kernel modules:
*
can.ko : Core domain registration (DOMAIN_SET), netisr handler (NETISR_CAN), generic CAN interface layer (can_if.c), ioctl handler, and bit-timing calculator
*
can_raw.ko : CAN_RAW socket protocol with filter support (join/invert modes), loopback control, and recv_own_msgs semantics
*
can_nmea2000.ko : NMEA 2000 / SAE J1939 protocol with Fast Packet reassembly, Address Claim (PGN 60928), and Product Information (PGN 126996)
*
vcan.ko : Virtual CAN interface (cloned, like lo(4) for CAN)
*
ahc0512.ko : Hardware driver for the AHC0512 CAN controller
Frame format support :
* Classical CAN 2.0B (16-byte MTU)
* CAN FD with BRS/ESI (72-byte MTU)
*
CAN XL (up to 2060-byte MTU) - including VCID options via CAN_RAW_XL_VCID_OPTS
Key design decisions (e.g. what I’ve done to fix problem/bug/freeze/crash... ) :
*
Netisr integration. Frames enter the stack via netisr_queue() (protocol NETISR_CAN, policy NETISR_POLICY_SOURCE). The handler takes a brief epoch read-section to snapshot the protocol list, then releases it before calling each protocol's input function. This prevents epoch grace period starvation under high frame rates.
*
Epoch-based PCB synchronization. Protocol control blocks are traversed under net_epoch. Teardown uses epoch_call() for deferred free, avoiding the deadlock that occurred when I used epoch_wait() inside the netisr handler.
*
Lock-free vcan transmit. The virtual interface avoids CAN_LOCK entirely on the transmit path - using only atomic operations and netisr_queue() (asynchronous). This solved a priority inversion problem where 7-8 concurrent user threads starved the netisr thread, causing permanent backpressure and system freeze.
*
Per-interface netisr backpressure. Each interface tracks in-flight frames with an atomic counter (netisr_inflight). Transmit is rejected early with ENOBUFS when the per-interface backlog exceeds a tunable threshold (sysctl dev.can.netisr_backlog_max, default 256). This prevents mbuf starvation without relying on global netisr queue limits alone.
*
Hardware abstraction. struct can_softc provides a function-pointer-based HAL (transmit, bittiming, ctrlmode, powermode, bus state, error counters). Hardware drivers fill in these callbacks. The AHC0512 driver demonstrates the pattern with a spin-lock ISR that snapshots volatile state, then defers all processing to a taskqueue task.
Userland tools :
*
canconfig - Interface configuration: bitrate, data-bitrate (FD), control modes, filters
*
candump - Frame capture (ported from linux can-utils)
*
cansend - Frame transmission (ported from linux can-utils)
*
slcand - Serial Line CAN daemon (useful to test the stack with cheap USB dongle, like CANNable devices).
*
n2kdump - NMEA 2000 frame decoder with PGN configuration
What's been « well-tested » :
The stack has been through some hardening :
*
Fixed multiple UAF bugs in mbuf allocation (can_alloc_mbuf / m_align misuse)
*
Fixed deadlocks in watchdog/restart paths under heavy load
*
Fixed ifnet refcount leaks
*
Resolved CAN_LOCK contention issues on vcan (the synchronous netisr_dispatch → asynchronous netisr_queue change)
*
Epoch hold duration reduction to prevent liveness issues
*
slcand crash fix under ENOBUFS pressure
*
DoS hardening: 512-filter limit per socket, socket buffer caps at 2MB
Known gaps :
* CAN_BCM (Broadcast Manager) and CAN_ISOTP (ISO 15765-2 Transport) protocols are declared but not implemented
*
gs_usb driver (USB CAN adapters) was prototyped but removed, will be a clean follow-up patch
*
No netlink integration yet, still using legacy ioctls via canconfig, will be a clean follow-up patch
* The NMEA 2000 module may be too specialized for the base system - could be a separate port
*
aarch64 support is present in my build system but hardware testing has been amd64-only so far
Jérémie
De : [email protected] <[email protected]>
Date : mercredi, 18 février 2026 à 23:00
À : Adrian Chadd <[email protected]>
Cc : Jérémie JOURDIN <[email protected]>, Ed Maste <[email protected]>, [email protected] <[email protected]>
Objet : Re: [RFC] A CAN Bus (SocketCAN-like) networking stack for FreeBSD
[Vous ne recevez pas souvent de courriers de [email protected]. Découvrez pourquoi ceci est important à https://aka.ms/LearnAboutSenderIdentification ]
CAUTION: External Sender. This email originated from outside of ADVENS. Do not click on links or open attachments from senders you do not trust.
Hi,
Some progress in implementation?
Dne 2025-10-29 06:08, Adrian Chadd napsal:
> hi! did anyone get back to you about this?
>
> Yes I think CAN support would benefit the community! Please send over
> some diffs and we can start reviewing!
>
> -adrian
>
> On Thu, 18 Sept 2025 at 09:58, Jérémie JOURDIN
> <[email protected]> wrote:
>
>> Hello,
>>
>> This is an update to my initial proposal regarding a CAN Bus stack
>> for FreeBSD. I'm happy to report that we now have a working
>> proof-of-concept implementation.
>>
>> For context, this project—tentatively named "NetCAN"—provides
>> kernel-level support for the Controller Area Network protocol,
>> modeled after the widely adopted Linux SocketCAN framework. It
>> introduces the PF_CAN protocol family, allowing userland
>> applications to interact with CAN bus hardware through a standard
>> socket API.
>>
>> The stack is designed to be modular, with a clear separation between
>> the protocol implementation, the generic network interface layer
>> (can_if), and hardware-specific device drivers.
>>
>> So far, the project is composed of:
>>
>> Kernel Modules
>>
>> * can.ko: Core module registering the PF_CAN protocol family and
>> the CAN netisr.
>> * can_raw.ko: CAN_RAW protocol implementation for SOCK_RAW sockets.
>> * vcan.ko: Virtual CAN loopback driver (vcanX), which is CAN FD
>> capable.
>>
>> User-space Tools
>>
>> * canconfig: Utility for configuring CAN interfaces (bitrate,
>> mode, etc.).
>> * canutils (candump, cansend): A port of the essential Linux
>> can-utils.
>>
>> -------------------------
>>
>> Stack Architecture Overview
>>
>> The architecture is designed to align with standard FreeBSD
>> networking practices.
>>
>> can.c (Core Domain): Registers the PF_CAN/AF_CAN domain.
>>
>> can_raw.c (Raw Socket): Manages the CAN_RAW protocol, socket
>> lifecycle, send/write operations, setsockopt, and packet delivery
>> from the netisr to sockets via software filters.
>>
>> can_if.c (Generic Interface Layer): Provides the ifnet abstraction
>> (canX) for all hardware drivers. It handles the if_transmit entry
>> point, software loopback, and exposes service routines for drivers
>> to report bus state and errors.
>>
>> struct can_softc (Driver Contract): The contract a hardware driver
>> must fulfill, providing function pointers for hardware-specific
>> operations (transmit, set bitrate, etc.).
>>
>> -------------------------
>>
>> We are already planning to use it in our own FreeBSD-based products,
>> which ensures we have a strong commitment to its long-term
>> maintenance.
>> Our goal would be to contribute this stack to the FreeBSD base
>> system.
>>
>> Before preparing a formal submission, I am seeking feedback from the
>> community, specifically on:
>>
>> * The overall architecture and API design.
>> * Real-world use cases or specific hardware (CAN adapters) that you
>> believe are critical to support.
>> * Any obvious design patterns that feel more aligned with Linux
>> than FreeBSD and could be improved.
>>
>> Any and all feedback is welcome.
>>
>> Thank you,
>>
>> Jérémie
>>
>> From: Jérémie JOURDIN <[email protected]>
>> Date: Monday, 23 June 2025 at 08:57
>> To: Tomek CEDRO <[email protected]>
>> Cc: [email protected] <[email protected]>
>> Subject: Re: FreeBSD-native CAN Stack and AF_CAN Protocol Family
>>
>> Theoretically, yes, the CAN stack is intended to be
>> hardware-independent.
>>
>> I suppose there will also be drivers to create or modify, but that
>> shouldn’t be the most complicated part.
>>
>> De : Tomek CEDRO <[email protected]>
>> Date : vendredi, 20 juin 2025 à 20:29
>> À : Jérémie JOURDIN <[email protected]>
>> Cc : [email protected] <[email protected]>
>> Objet : Re: FreeBSD-native CAN Stack and AF_CAN Protocol Family
>>
>> CAUTION: External Sender. This email originated from outside of
>> ADVENS. Do not click on links or open attachments from senders you
>> do not trust.
>>
>> On Fri, Jun 20, 2025, 14:52 Jérémie JOURDIN
>> <[email protected]> wrote:
>>
>>> Hello all,
>>>
>>> I am working on a system (15-current) that requires interaction
>>> with a CAN network.
>>>
>>> So far, I have developped a driver for my controller, able to send
>>> and receive CAN frames to and from connected devices.
>>>
>>> I’d like to implement a FreeBSD-native CAN network stack that is
>>> API-compatible with Linux’s Netlink CAN (netcan).
>>>
>>> This would allow us to recompile and use existing Linux userland
>>> tools with minimal changes.
>>>
>>> If you believe this development could benefit the community, I
>>> would be happy to submit a set of patches (driver + netcan
>>> support).
>>>
>>> We’re considering defining a new Protocol Family, AF_CAN, for
>>> this purpose.
>>>
>>> Would it be acceptable to use the first available « AF_VENDORXX
>>> » from sys/socket.h ?
>>>
>>> I would appreciate your thoughts, advice, and any recommendations
>>> you may have on this matter.
>>>
>>> -- Jérémie
>>
>> Hello Jeremie, sounds great! :-) Would that work with simple
>> USB-UART-CAN adapters? :-)
>>
>> --
>> CeDeROM, SQ7MHZ, https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.tomek.cedro.info%2F&data=05%7C02%7Cjeremie.jourdin%40advens.fr%7C4c386712a93a4188c11c08de6f38be89%7Cfdb2b8eeeac84d539e82f047b37099f8%7C0%7C0%7C639070488465967529%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C60000%7C%7C%7C&sdata=TG1XxCJxquNQ3j4xP7DADdEVO7MfZ4sVmw4qUYoExPA%3D&reserved=0<http://www.tomek.cedro.info/> [1]
>
>
> Links:
> ------
> [1] https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.tomek.cedro.info%2F&data=05%7C02%7Cjeremie.jourdin%40advens.fr%7C4c386712a93a4188c11c08de6f38be89%7Cfdb2b8eeeac84d539e82f047b37099f8%7C0%7C0%7C639070488465983952%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C60000%7C%7C%7C&sdata=02MHKdUeEHDjndCyRRgonxuz%2FarVhKg%2ByTIZnTQSTkE%3D&reserved=0<http://www.tomek.cedro.info/>