Re: [RFC] A CAN Bus (SocketCAN-like) networking stack for FreeBSD
Adrian Chadd <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.hackers |
|---|---|
| Message-ID | <CAJ-VmonE5rWFi58h8vBe=Bj0xSpA==vDYq+oF3FDuUNQ4UrY9w@mail.gmail.com> |
hi! would you mind sharing the code in its present form? that way we can take an initial look at it and help you through your questions. thanks! -adrian On Thu, 19 Feb 2026 at 05:20, Jérémie JOURDIN <[email protected]> wrote: > > 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 : > > can: add CAN protocol headers and frame definitions > can: add core PF_CAN domain, netisr handler, and interface layer > can: add CAN_RAW socket protocol > can: add virtual CAN interface (vcan) > can: add canconfig(8) configuration utility > can: add candump(8), cansend(8), and slcand(8) utilities > can: add AHC0512 hardware driver > can: add NMEA 2000 / SAE J1939 protocol > > > Few questions to ease integration : > > Which AF_ number should CAN use ? > Should AF_CAN go in sys/sys/socket.h directly or stay as a local #define in my dev/can/can.h for now? > Is slot 11 acceptable for NETISR_CAN ? > Should CAN be gated behind a MK_CAN build knob, or always built ? > 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 [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