summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-06-09Potential fix for pull request findingDenys Fedoryshchenko
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-05radius: update server secret on config reloadDenys Fedoryshchenko
On EV_CONFIG_RELOAD, __add_server() re-parses each server line into a fresh rad_server_t and, when it matches an existing server by addr/auth_port/acct_port, copied over only the timeout/limit/bind fields before freeing the new struct. The freshly parsed secret was discarded, so editing a shared secret and reloading had no effect until a full restart. The strdup'd secret on the freed struct was also leaked on every matched reload. Adopt the new secret into the existing server (freeing the old one) so secret changes take effect on reload. New requests read req->serv->secret directly, so they pick up the update immediately. This covers both the modern "server=" path and the legacy auth-server/acct-server path, which both funnel through __add_server().
2026-06-04log_file: don't register general target when log-file is unsetDenys Fedoryshchenko
The general log target was registered unconditionally in init(), even when no log-file= option was configured. The backing log_file pointer is only allocated when the option is present, so the first general-routed log message dereferenced NULL in queue_log() (spin_lock(&NULL->lock)), crashing the daemon. This made commenting out log-file= a foot-gun. Guard the registration on log_file being allocated, mirroring how the fail/per-user/per-session targets are already conditional. Also bail out of general_reopen() early when log-file is unset, so a SIGHUP after a config reload that dropped log-file can't call open(NULL, ...).
2026-06-03ippool/ipv6pool: bitmap allocator + online reconfigurationDenys Fedoryshchenko
Replace the pre-generated free-list (one heap node per allocatable address/prefix) with a per-pool bitmap. Each pool holds a list of contiguous ranges, each range owning one bitmap (1 bit per unit); a lease is a small per-session malloc wrapper around the ipdb item, so pool memory is no longer shared or mutated by sessions. Memory now scales with capacity at ~1 bit/unit instead of ~96B (v4) / ~128B (v6) per unit; startup, `show ippool`, and backup-restore are O(1) instead of O(N)/O(N*M). Oversized IPv6 ranges (prefix_len-mask > 24) are rejected at parse time instead of OOMing in the malloc loop. The ipdb_t vtable, the owner-based put dispatch, ipdb.h structs, and struct ap_session are unchanged; RADIUS and chap-secrets backends are untouched (reconcile filters by owner). Preserved behavior: p2p/net30 allocators (via a step/gw_offset/ peer_offset geometry triple), shuffle (randomized scan start), named pools, next-chains, gw-ip-address, RADIUS pool-name attrs, and the USE_BACKUP save/restore path. `gw=` is now accepted-and-ignored (its per-address local gateway was already overridden at allocation time). New: online reconfiguration. An EV_CONFIG_RELOAD handler rebuilds the pool set and reconciles live sessions (sessions are the source of truth, the bitmap is rebuilt from them) under pool_set_rwlock(write) -> ses_lock(read) -> per-pool spinlock. Sessions whose address left the pools are handled per a new `reload-orphan = keep|disconnect` knob (default keep); foreign in-range addresses are reserved to avoid duplicate assignment. Adds extra/bitpool.h (shared bit-array helpers) and a standalone extra/bitpool_test.c (not wired into cmake) covering the bitmap and the v4/v6 address<->bit math, cross-checked against an __int128 reference. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-06-02Merge pull request #314 from nuclearcat/metrics-moduleDenys Fedoryshchenko
Metrics module
2026-05-29Rejecting any PADR lacking a Service-Name tag (RFC 2516 compliance)Denys Fedoryshchenko
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-23pppoe/disc: drop packets with unsupported PPPoE typekhedor
The unsupported-PPPoE-type branch in disc_read() logs a warning but falls through to forward() instead of dropping the packet. Compare with the unsupported-version branch immediately above, which has the same shape but continues: if (hdr->ver != 1) { if (conf_verbose) log_warn(...unsupported version...); continue; } if (hdr->type != 1) { if (conf_verbose) log_warn(...unsupported type...); /* falls through into forward() */ } Add the missing continue so malformed packets are dropped instead of processed. Signed-off-by: khedor <khedor@gmail.com>
2026-05-23pppoe/disc: fix free_net memmove count and overlap handlingkhedor
free_net() compacts the nets[] array by sliding entries left after removing one: memcpy(nets + i, nets + i + 1, net_cnt - i - 1); Two bugs: 1. The count is a raw element count, not a byte count. nets[] holds 'struct disc_net *' pointers, so only (net_cnt - i - 1) bytes are moved instead of (net_cnt - i - 1) * sizeof(nets[0]). On the usual 8-byte-pointer build, 7 of every 8 surviving pointers are lost, leaving uninitialised holes in the array. 2. Source and destination overlap (nets + i and nets + i + 1), so memcpy is undefined behaviour. The correct primitive is memmove. Switch to memmove and multiply the count by sizeof(nets[0]). Signed-off-by: khedor <khedor@gmail.com>
2026-05-23pppoe/disc: fix init_net allocation sizekhedor
In init_net(), the buffer for struct disc_net was sized as n = _malloc(sizeof(*net) + (HASH_BITS + 1) * sizeof(struct tree)); but 'net' is the const struct ap_net * argument, not the disc_net being allocated. sizeof(*net) is therefore sizeof(struct ap_net), which is substantially smaller than sizeof(struct disc_net). Every field of *n written past the ap_net-sized prefix (ctx, hnd, net, refs, etc.) lands in unallocated heap memory. Use sizeof(*n) so the allocation matches the actual destination type. Signed-off-by: khedor <khedor@gmail.com>
2026-05-21fix: dict.c: split() could return 0, making dict_load read ptr[-1]Denys Fedoryshchenko
If a RADIUS dictionary contains a line consisting of exactly one word with no trailing spaces (for example, standard keywords like "END-VENDOR\n" or "END-TLV\n" ), this bug getting triggered. Triggering crash is compiler dependent, it might not happen now, but a bit different compiler, flags, and it might crash on load. Reported-by: Khedor <khedor@gmail.com> Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-21strip: Fix invalid parsingDenys Fedoryshchenko
strip() memmove count was one short, dropping the NULL terminator; dpado_parse error path leaked already-parsed range entries. Also affects ipoe. Since strip is identical in both, we can place fixed common function in utils. Reported-by: Khedor <khedor@gmail.com> Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: resolve protocol stat symbols via dlsymDenys Fedoryshchenko
The previous weak-symbol workaround let the module load on musl (which treats RTLD_LAZY as RTLD_NOW) but introduced a silent failure: weak undefined references are bound to NULL at our own dlopen time and are not updated when a later RTLD_GLOBAL dlopen brings the protocol module in. In any [modules] ordering where metrics comes before pppoe / l2tp / pptp / sstp / ipoe, the function pointers stay NULL and per-protocol session metrics silently disappear from both Prometheus and JSON output, with no log to indicate why. Replace the weak declarations with a small table and resolve each protocol's stat_starting/stat_active pair via dlsym(RTLD_DEFAULT, ...) the first time we render after the module is seen as loaded. dlsym walks the live global scope at call time, so it picks up symbols regardless of dlopen order; the resolved pointers are cached so subsequent scrapes do not re-walk the loader. The five near-identical render blocks in render_prometheus() and render_json() collapse into table-driven loops. libdl is already a transitive dependency of accel-pppd via triton, so no build-system changes are needed. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14tests: Add metrics module coverageDenys Fedoryshchenko
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: queue partial response writesDenys Fedoryshchenko
write_all() previously did a blocking-style loop on a O_NONBLOCK socket and bailed on the first EAGAIN. With a slow scrape client or a small kernel send buffer that meant the response was truncated and the connection dropped mid-flight. Allocate one contiguous xmit_buf per response holding header + body, then drain it in xmit_flush(): * full write → mark the client for disconnect on the next event loop tick; * EAGAIN/EWOULDBLOCK → enable MD_MODE_WRITE so cln_write() resumes the drain when the socket becomes writable; * hard error → mark for disconnect, caller tears down. cln_read() now stops reading once a response is queued (read events during the response phase are uninteresting since we'll close on flush), and cln_write() finishes the drain and disconnects when the last byte is out. The existing per-client read timer doubles as a write deadline, so a peer that opens the connection and never reads still gets cleaned up after read_timeout seconds. Smoke-tested with a python client that uses SO_RCVBUF=256 and sleep(0.05) between recv()s — it now reads the entire ~2.8 KiB body across many short reads. Five concurrent slow readers plus a fast scrape all complete successfully. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: back off accept loop on persistent errorsDenys Fedoryshchenko
Previously the only path out of serv_read()'s accept loop was an EAGAIN/EWOULDBLOCK return; every other failure logged once and fell back into `continue`. With a level-readable listening fd, that means EMFILE/ENFILE/ENOBUFS/ENOMEM pin the worker thread spinning on accept() and saturate the log. Detect that class of error and pause the listener: disable MD_MODE_READ on serv_hnd, arm a one-shot triton timer for one second, and on expiry re-enable the handler. EINTR and ECONNABORTED are kept as transient retries — those are normal and short-lived. Verified by running the daemon under `prlimit --nofile=24` and opening enough slow connections to exhaust the limit. The first accept failure logs metrics: accept failed: Too many open files; backing off 1s then the daemon idles at 0% CPU instead of spinning; once fds free up it resumes accepting. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: per-client read timeout and max-clients capDenys Fedoryshchenko
A scrape client that opens a TCP connection and never sends a full request line+headers used to keep its accel-pppd-side fd registered indefinitely. Combined with the default `allowed_ips` (= allow all), a single peer could exhaust the daemon's file descriptors slowloris-style. Give every accepted connection a triton timer armed for `read_timeout` seconds (default 5). On expiry, disconnect_client() tears down the fd, the timer, and the buffer. The timer is canceled implicitly when the client is disconnected for any other reason because disconnect_client() now deletes the timer before freeing the client. Also cap the number of in-flight clients at `max_clients` (default 64). Excess connections are accepted and immediately closed so the kernel listen backlog still drains. Both knobs accept 0 to disable. The default values are documented in accel-ppp.conf(5) alongside the existing [metrics] options. Smoke-tested: * a connection that sends nothing is dropped from the daemon's fd table when read_timeout elapses; subsequent scrapes still succeed; * with max_clients=3 and five concurrent silent connections, the daemon holds exactly three ESTAB sockets, the others are closed. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: document module in conf, manpage, and CHANGELOGDenys Fedoryshchenko
Add a commented `[metrics]` block to the example accel-ppp.conf and a matching `#metrics` entry in the [modules] list so operators see the feature when reading the sample config. Document the section in accel-ppp.conf(5) next to [connlimit]: the format/address/allowed_ips options, the path/method behaviour, and how the ACL accepts either the bracketed or bare comma-separated form. Add an Unreleased entry to CHANGELOG.md announcing the module. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: render JSON when format=jsonDenys Fedoryshchenko
Replace the previous `{}` stub with a structured JSON document carrying the same fields as the Prometheus exposition: build info, uptime, CPU%, RSS/virtual memory, the triton core counters, session counts by state, and a `protocols` object whose keys are only present for modules that are actually loaded. Strings are emitted through a small helper that escapes the JSON control characters (\b, \f, \n, \r, \t, \", \\) and falls back to \u00XX for other bytes below 0x20, so the version string and any future textual labels survive without producing invalid JSON. The output passes `python3 -m json.tool` against a running daemon. Content-Type is already set to application/json by content_type(), so no transport changes are needed. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: render Prometheus exposition for /metricsDenys Fedoryshchenko
Fill in the body that GET /metrics returns when format=prometheus. The exposed series mirror what `show stat` prints over the CLI today: * accel_ppp_build_info{version="..."} 1 * accel_ppp_uptime_seconds * accel_ppp_cpu_percent * accel_ppp_memory_{rss,virt}_bytes (read from /proc/<pid>/statm) * accel_ppp_core_mempool_{allocated,available}_bytes * accel_ppp_core_threads{,_active} * accel_ppp_core_contexts{,_sleeping,_pending} * accel_ppp_core_md_handlers{,_pending} * accel_ppp_core_timers{,_pending} * accel_ppp_sessions{state="starting|active|finishing"} * accel_ppp_protocol_sessions{protocol=...,state=...} for every protocol module that is currently loaded — pppoe, l2tp, pptp, sstp, ipoe — gated by triton_module_loaded() so we never call a stat helper from a module that wasn't loaded. A small growing strbuf helper coalesces the rendering into a single buffer that is passed to send_response() in one shot. Per-protocol forward declarations rely on the existing RTLD_LAZY|RTLD_GLOBAL load behaviour used by net-snmp, so the metrics .so does not need to link against pppoe.so, l2tp.so, etc. json format remains a stubbed `{}` body — the next commit replaces that with a real renderer. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: gate listener with allowed_ips ACLDenys Fedoryshchenko
Parse the `allowed_ips` option in [metrics] as a comma-separated list of IPv4 CIDR entries. Both the bracketed form allowed_ips = ["1.2.3.4/32", "5.6.7.0/24"] and a bare comma-separated form are accepted; surrounding whitespace, matched quotes, and the optional [ ] are stripped. A bare address without a prefix is treated as /32. When the list is empty (option missing or empty value), all peers are allowed and behavior is unchanged. Otherwise serv_read() rejects any peer that doesn't match a configured CIDR by closing the freshly accepted socket before allocating client state, so scanners get nothing more than a TCP reset. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-14metrics: add HTTP listener with /metrics endpointDenys Fedoryshchenko
Stand up a minimal HTTP/1.1 server on top of triton's md handler, using the same pattern as cli/tcp.c. The listener: * binds the address configured in [metrics]/address (IPv4 only for now); * accepts non-blocking connections, reads up to the first "\r\n\r\n" into a fixed-size buffer (2 KiB), then dispatches one request and closes the connection; * routes GET /metrics to a placeholder 200 response (body is empty until the metrics rendering lands in a later commit); * returns 404 for other paths, 405 for non-GET, 413 if the request headers do not fit, and 400 for an unparseable request line. Content-Type is selected from the configured format (prometheus or json) so the next commits can plug in real bodies without touching the transport. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-13metrics: scaffold module with config parsingDenys Fedoryshchenko
Add a new extra module `metrics` that will eventually expose statistics over HTTP. This first commit only: * creates accel-pppd/extra/metrics.c with an init() that parses the [metrics] section options `format` (prometheus|json) and `address` (host:port); * wires the new shared library into the extras CMakeLists. No listener, no metrics rendering yet — those land in follow-up commits. With this commit alone, loading the `metrics` module just logs the configured listen address and format and is otherwise inert. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-13Merge pull request #308 from nuclearcat/stats-reworkDenys Fedoryshchenko
stats: improve how we handle statistics in the code
2026-05-04triton: encapsulate statistics countersDenys Fedoryshchenko
Group the Triton core statistics in struct triton_stat_t and keep the storage private to triton.c instead of exporting the writable triton_stat object through triton.h. This keeps ownership inside the Triton core while preserving the existing CLI and ACCEL-PPP-MIB counter semantics. Route counter updates through triton_stat_*() helpers. Thread, context, md handler, timer, mempool, CPU, and start-time update paths no longer open-code direct triton_stat mutations; the update policy now lives beside the Triton-owned storage and uses relaxed atomic operations for the simple counters. Make the CLI show-stat path render from a local snapshot and update statCore SNMP readers to use triton_stat_start_time() and triton_stat_cpu(). Out-of-tree modules that accessed the exported triton_stat object directly must switch to the new accessors, because triton_stat is no longer part of the public ABI. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04session: encapsulate statistics countersDenys Fedoryshchenko
Group the core session starting, active, and finishing statistics behind the private ap_session_stat storage in session.c instead of exposing writable counters through ap_session.h. This keeps ownership inside the session core while preserving the existing CLI and ACCEL-PPP-MIB counter semantics. Route session counter updates through ap_session_stat_*() helpers. Session start, activation, termination, finish, and shutdown-idle paths no longer open-code individual counter increments/decrements; the update policy now lives beside the session-owned storage and uses relaxed atomic operations for the simple state counters. Make the CLI show-stat path render from a local snapshot and convert the PPP SNMP starting/active/finishing scalars from watched raw pointers to scalar handlers. PPP controllers now read max-session limits through ap_session_stat_starting() and ap_session_stat_active(), removing external direct access to ap_session_stat. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04sstp: encapsulate statistics countersDenys Fedoryshchenko
Group the SSTP starting and active statistics in struct sstp_stat_t and keep the storage under the SSTP server object instead of exposing writable stat_* globals. This keeps ownership inside the SSTP control code while preserving the existing CLI and ACCEL-PPP-MIB counter semantics. Route counter updates through sstp_stat_*() helpers. Connection accept, transition to PPP setup, and disconnect paths no longer open-code individual counter increments/decrements; the update policy now lives beside the SSTP-owned storage and uses relaxed atomic operations for the simple state counters. Make the CLI show-stat path render from a local snapshot and convert the SSTP SNMP starting/active scalars from watched raw pointers to scalar handlers. SNMP now reads through sstp_stat_starting() and sstp_stat_active(), removing the old sstp_get_stat() pointer escape hatch. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04ipoe: encapsulate statistics countersDenys Fedoryshchenko
Group the IPOE starting, active, and delayed offer statistics in struct ipoe_stat_t and keep the storage private to ipoe.c instead of exposing writable stat_* globals. This keeps ownership inside the IPOE control code while preserving the existing CLI and ACCEL-PPP-MIB counter semantics. Route counter updates through ipoe_stat_*() helpers. Session setup, activation, teardown, and delayed offer queue paths no longer open-code individual counter increments/decrements; the update policy now lives beside the IPOE-owned storage and uses relaxed atomic operations for the simple state counters. Make the CLI show-stat path render from a local snapshot and convert the IPOE SNMP starting/active scalars from watched raw pointers to scalar handlers. SNMP now reads through ipoe_stat_starting() and ipoe_stat_active(), removing the old ipoe_get_stat() pointer escape hatch. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04net-snmp: fix ASN_INTEGER scalar value sizeDenys Fedoryshchenko
Use long storage for ASN_INTEGER scalar values passed to snmp_set_var_typed_value(). PPTP, L2TP, and PPPoE starting/active handlers previously passed unsigned int locals, and statCoreCPU passed triton_stat.cpu directly, which does not match Net-SNMP's C representation for ASN_INTEGER on 64-bit systems. Keep the exposed MIB values and access paths unchanged; only stage the values through correctly sized local variables before encoding them for Net-SNMP. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04pptp: encapsulate statistics countersDenys Fedoryshchenko
Group the PPTP starting and active statistics in struct pptp_stat_t and keep the storage under the PPTP server object instead of exposing writable stat_* globals. This keeps ownership inside the PPTP control code while preserving the existing CLI and ACCEL-PPP-MIB counter semantics. Route counter updates through pptp_stat_*() helpers. Connection setup, transition to PPP, and teardown paths no longer open-code individual counter increments/decrements; the update policy now lives beside the PPTP-owned storage and uses relaxed atomic operations for the simple state counters. Make the CLI show-stat path render from a local snapshot and convert the PPTP SNMP starting/active scalars from watched raw pointers to scalar handlers. SNMP now reads through pptp_stat_starting() and pptp_stat_active(), removing the old pptp_get_stat() pointer escape hatch. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04l2tp: encapsulate statistics countersDenys Fedoryshchenko
Group the L2TP tunnel, control-session, and data-session statistics in struct l2tp_stat_t and keep the storage private to l2tp.c instead of spreading writable stat_* globals through the module. This keeps the ownership boundary in the L2TP control code while preserving the existing CLI and ACCEL-PPP-MIB counter semantics. Route counter updates through l2tp_stat_*() helpers. Tunnel, control-session, and data-session state transitions no longer open-code individual counter increments/decrements; the update policy now lives beside the L2TP-owned storage and uses relaxed atomic operations for the simple state counters. Make the CLI show-stat path render from a local snapshot and convert the L2TP SNMP starting/active scalars from watched raw pointers to scalar handlers. SNMP now reads through l2tp_stat_starting() and l2tp_stat_active(), removing the old l2tp_get_stat() pointer escape hatch. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04radius: encapsulate server statistics countersDenys Fedoryshchenko
Group the per-server RADIUS statistics in struct rad_server_stat_t under rad_server_t.stat instead of keeping auth, accounting, interim, and failure counters as separate fields on rad_server_t. This keeps the statistics state collected behind one ownership boundary and makes the relationship between the total counters and their rolling accumulators explicit. Route counter updates through rad_server_stat_*() helpers. Auth, accounting, interim, and server-failure paths no longer open-code individual counter increments and accumulator updates; the update policy now lives in serv.c with the rest of the RADIUS server accounting logic. Make the CLI show-stat path render from a local snapshot. The displayed totals are loaded with relaxed atomic reads, the rolling one-minute/five-minute values are collected in one place, and the in-flight request/queue counters are copied under the server lock before printing. Future changes to synchronization or accumulator storage can stay inside the snapshot/update helpers instead of leaking into the CLI formatting code. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04pppoe: encapsulate statistics countersDenys Fedoryshchenko
Group the PPPoE statistics in struct pppoe_stat_t and keep the storage private to pppoe.c instead of exporting writable counter globals through pppoe.h. The CLI now reads a snapshot with pppoe_stat_get(), while the packet/control paths update the counters through the PPPoE-owned storage using relaxed atomic operations. Convert the PPPoE SNMP starting/active scalars from watched raw pointers to scalar handlers. This removes the old pppoe_get_stat() pointer escape hatch and makes SNMP read the counters through pppoe_stat_starting() and pppoe_stat_active(), so the synchronization policy is applied consistently outside the PPPoE module. This also fixes the long-standing PPPoE starting counter behavior. PPPoE used to expose starting in the CLI and ACCEL-PPP-MIB, but never updated it, so it always reported zero. Track a per-connection ppp_starting state, increment starting when the controller begins channel setup, move the session from starting to active after establish_ppp() succeeds, and decrement starting on setup failure before PPP becomes active. This matches the state accounting used by the other PPP controllers. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-04Merge pull request #312 from nuclearcat/fix-ci2Denys Fedoryshchenko
ci: Tightening warning condition in dmesg checks
2026-05-04ci: Tightening warning condition in dmesg checksDenys Fedoryshchenko
The boot-time RETBleed: WARNING: Spectre v2 mitigation... line matches the broad WARNING: regex. The intent of that pattern was to catch kernel WARN_ON() splats, which always begin with WARNING: CPU:. We can tighten checks, to avoid false positive. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-02Merge pull request #310 from nuclearcat/fix-ciSergey V. Lobanov
Fix vlan_mod kernel WARNING issue
2026-05-02Merge pull request #309 from nuclearcat/small-bugsSergey V. Lobanov
fix: typo, dont close wrong descriptor
2026-05-02ci: fail workflows on kernel issues found in dmesgDenys Fedoryshchenko
Recently i wasted several hours searching bug in workflows/userspace. Turned out in dmesg we had highly visible WARNING that we dont watch. After each test run, dump dmesg and grep for canonical kernel-issue markers (WARNING, BUG, Oops, kernel panic, GPF, KASAN, kernel UBSAN, soft/hard lockup, hung tasks, bad page state, invalid opcode). Fail the job if any are present, with a GitHub Actions error annotation. Until now, kernel WARNs from out-of-tree drivers (e.g. vlan_mon tripping the new ETH_P_ALL ptype_head WARN_ON in 6.6+) were silently swallowed by the existing 'Display processes and dmesg after tests' steps -- visible only if a human inspected the log. The check runs with if: always() so it triggers both on test failure and on test completion. Applied to all four workflows that load kernel modules: run-tests-asan-ubsan.yml, run-tests.yml (Test-in-Qemu, Test-in-Alpine, Test-in-GH, Test-in-GH-Coverage), run-tests-32bit.yml, and run-tests-bigendian.yml. P.S. Some whitespace churn included. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-05-02vlan_mon: bind ETH_P_ALL packet handler to init_net on kernels >= 6.6Denys Fedoryshchenko
The vlan_mon driver registers a global packet_type with type=ETH_P_ALL to intercept PADI/IP/ARP frames before they reach the protocol stack. Since Linux 6.6 the per-net-namespace ptype_all conversion (commit "net: af_packet: switch ptype_all to per-net-namespace lists") requires every ETH_P_ALL packet_type to have either ->dev or ->af_packet_net set; ptype_head() now does: WARN_ON_ONCE(!pt->af_packet_net && !pt->dev); return pt->dev ? &pt->dev->ptype_all : &pt->af_packet_net->ptype_all; With both fields NULL on our static vlan_pt, dev_add_pack() trips the WARN at module load and the handler is never linked into any usable list, so vlan_pt_recv() is never invoked. Userspace sets up the genetlink subscription correctly and gets a clean ACK from VLAN_MON_CMD_ADD, but no notifications ever arrive because the kernel side never sees the PADI. PPPoE-over-VLAN tests time out waiting for PADO. This was visible on Ubuntu's 6.17 azure kernel as a backtrace from vlan_mon_init -> dev_add_pack at net/core/dev.c:609 in dmesg, and as a silent failure of tests/accel-pppd/pppoe/test_pppoe_vlan_mon. Set vlan_pt.af_packet_net = &init_net before dev_add_pack() on kernels new enough to require it. The driver only operates in init_net anyway (all dev_get_by_index() calls are against &init_net), so this matches existing behaviour. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-04-30fix: typo, dont close wrong descriptorDenys Fedoryshchenko
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-03-16Merge pull request #297 from nuclearcat/fixes-radiusDenys Fedoryshchenko
Various radius fixes
2026-03-01Merge pull request #301 from nuclearcat/bugfix-radius-stopDenys Fedoryshchenko
radius: fix stop accounting timeout flow and request cleanup
2026-02-28radius: fix stop accounting timeout flow and request cleanupDenys Fedoryshchenko
When sending accounting STOP requests, the timer callback was incorrectly set to the START timeout handler. This caused stop retries to follow the wrong termination path. Also clear rpd->acct_req before freeing on stop timeout/shutdown failures to avoid leaving a stale pointer. This bug is very nasty, revealed during stress tests, leading to memory corruption and other bad stuff when there is noticeable loss of radius "Stop" packets. Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
2026-02-23Merge pull request #300 from marekm72/marekm72-patch-1-printf-hDenys Fedoryshchenko
Simplify Alpine Linux / musl libc port
2026-02-22Replace linux/if.h with net/if.h includemarekm72
2026-02-22Replace linux/if.h with net/if.h in ipoe.hmarekm72
2026-02-22Update header includes in ipoe.cmarekm72
Replaced Linux-specific headers with their net counterparts.
2026-02-22Refactor ARP header includes in arp.cmarekm72
Replaced conditional inclusion of if_arp.h and if_packet.h with direct includes.
2026-02-22Refactor session free function pointer in l2tp.cmarekm72
2026-02-22Clean up CMakeLists.txt by removing unused checksmarekm72
Removed checks for __free_fn_t and good ifarp in CMakeLists.txt.
2026-02-22Remove printf.h check from CMakeLists.txtmarekm72
Removed check for printf.h and related definitions.