summaryrefslogtreecommitdiff
path: root/src/services
AgeCommit message (Collapse)Author
4 daysvpp: T9161: Fix smoketests failing on NICs capped at 1500 MTUNataliia Solomko
VPP now rejects an MTU above the NIC limit, but the CI NICs are capped at 1500, so tests using MTU 2500 on eth1 failed. The rejected commit also left a queued initial VPP dependency in the commit daemon, which the next commit ran with the old config, so every following test failed too. Pending initial dependents are now cleared before each script run in vyos-configd and vyos-commitd, and the tests use MTUs that fit any NIC.
6 daysfrrender: T9368: reconcile FRR after a DHCP lease without the commit socketChristian Breunig
Reconciling the FRR configuration after a DHCP lease event was requested from the configuration daemon over the socket the commit pipeline uses. The daemon serves one client at a time and assumes it is the running commit, so the request either landed in the middle of the handshake which hands over the configuration, or kept the daemon busy past the 10ms a commit waits for it. Either way the commit fell back to running the conf-mode scripts directly. Those never render FRR, only the daemon does, so the commit succeeded while FRR kept the configuration rendered before it, until the next lease event. A lease event now renders FRR in its own process, and a commit which could not use the daemon renders FRR itself instead of skipping the reload. Both take the same lock. A commit post-hook would remove the second case, for a full render on every commit.
2026-09-29Merge pull request #5491 from omnom62/T8989-hotfix-oidc_aud_validationJohn Estabrook
http-api: T8989: Hotfix to enforce audience validation if OIDC is configured
2026-09-29Merge pull request #5499 from c-po/wwan-improvementsChristian Breunig
wwan: T9350: possible dead interface after boot, disconnect does not stick
2026-09-29https: T8989: Hotfix to enforce audience settings with OIDC is configuredomnom62
2026-09-28Merge pull request #5503 from c-po/T9354Christian Breunig
op-mode: T9354: replace "reset connection" with "reconnect interface"
2026-09-26vyos.utils: T8977: let a caller accept a non-local address as assignedMichael Pardatscher
Whether an address may be bound is not the same question as whether it is currently configured somewhere: the kernel permits binding a foreign address once the non-local bind sysctl is set, which is how a failover address is commonly handed over after the commit. Callers can now opt into that, the default is unchanged. A lookup no longer skips the VRF device itself, which carries the addresses of its own L3 domain, and an interface name can be retrieved for an address without the caller asking a yes/no question in the first place. Address and range validation is split into separate checks, so a caller no longer has to accept ranges where only an address is meaningful. The two duplicated version checks are dropped in favour of the existing ones. Co-authored-by: Christian Breunig <christian@breunig.cc>
2026-09-25op-mode: T9354: replace "reset connection" with "reconnect interface"Christian Breunig
"connect interface" and "disconnect interface" cannot be combined to restart a dialer interface when the CLI session runs over that very interface, yet the command which does cover it was filed under an unrelated top-level node and was hard to find. It is now "reconnect interface <ifname>", mirroring the existing connect and disconnect commands. "reset connection" is removed, no alias is kept. The removed command was reachable through the REST API as a "reset" path. A dedicated "/reconnect" endpoint takes its place, so the operation stays available to API consumers.
2026-09-24wwan: T9350: wait for the modem to become dialable, not merely listedChristian Breunig
A modem is on the bus while still probing, so a dial could start too early and leave the interface without a session until something re-dialled it.
2026-09-24wwan: T9350: properly disconnect "disconnect interface wwanN"Christian Breunig
Two things kept an operator disconnect from taking effect. vyos-netlinkd re-dials every configured WWAN interface that has lost its session. It cannot tell a session lost to RF signal loss from one that was taken down on purpose, so the disconnect was undone on the next reconcile pass, at most 30 seconds later: $ disconnect interface wwan0 08:53:33 t+10s state=registered 08:53:43 t+20s state=registered 08:53:53 t+30s state=connected <- re-dialled 08:54:03 t+40s state=connected vyos-netlinkd: WWAN interface wwan0 is not connected, re-dialling... vyos-netlinkd: Re-dialled WWAN interface wwan0 Record the intent instead of inferring it from the session state. op-mode "disconnect" drops a marker in /run/vyos-wwan, which _reconcile_wwan() honours and "connect" removes again. conf_mode removes it too, so a commit keeps re-asserting the configured state - the marker only survives for as long as nobody says otherwise, and never across a reboot.
2026-09-24wwan: T9350: move session re-dial from cron into vyos-netlinkdChristian Breunig
/etc/cron.d/vyos-wwan re-ran the conf_mode script every 5 minutes via op-mode "connect interface wwanN" to re-establish a session lost to RF signal loss. Re-entering conf_mode from cron is unsafe: the cron job knows nothing about the boot commit or about a commit in flight, so when a tick lands before the running config is populated, get_config() returns nothing but {'ifname', 'deleted'} and apply() takes the teardown branch instead of dialling. It then stops the DHCP clients, stops ModemManager and unlinks its own cron file, leaving wwan0 down with no way to recover until the next commit: CRON[1869]: (root) CMD (/usr/libexec/vyos/vyos-check-wwan.py) systemd[1]: Stopping DHCP client on wwan0... systemd[1]: Stopping Modem Manager... This is timing dependent - it only bites when a */5 tick coincides with boot - which is why it presents as an intermittently dead WWAN interface. Move the re-dial into vyos-netlinkd, which already tracks these interfaces for DHCP and already gates all of its work behind boot_configuration_complete() and commit_in_progress2(). A re-dial can therefore no longer land on a half-applied configuration. It also dials ModemManager directly rather than re-entering conf_mode, so the teardown branch is no longer reachable from the recovery path at all.
2026-09-01http-api: T8989: address Copilot review commentsomnom62
- Remove fallback 'oidc-client' identity - tokens without sub/client_id are now rejected - Suppress OIDC validation error details from stdout - Cache discovered JWKS URI back to session to avoid per-request discovery - token_op now accepts X-API-Key header alongside form field - Reset REST/OIDC session attributes on SIGHUP reload to prevent stale config persisting after nodes are removed
2026-09-01http-api: T8989: fix routers.py regressions from initial commitomnom62
- Restore mask_dict/config_dict variable names in _execute_configure_op (shadowing of Config object was causing potential crash on delete ops) - Fix load_section_tree() call to pass correct 3 arguments - Pass data.destructive to merge_config() to preserve destructive behavior
2026-09-01http-api: T8989: set bounded timeout for OIDC discovery requestomnom62
2026-09-01http-api: T8989: address OIDC review commentsomnom62
- Use OpenID Connect discovery (/.well-known/openid-configuration) to resolve JWKS URI when jwks-url is not explicitly configured - Add optional audience validation via new oidc audience config node - Require exp claim in OIDC tokens - Reject jwks-url without issuer at commit time
2026-09-01http-api: T8989: add OAuth2/OIDC authentication for REST APIomnom62
Add support for validating OIDC Bearer tokens issued by external identity providers (Keycloak, Azure AD, Okta, Vault, etc.) against the configured JWKS endpoint. Configuration: set service https api rest authentication oidc issuer <url> set service https api rest authentication oidc jwks-url <url> If jwks-url is not set, it is derived from the issuer URL using the standard OpenID Connect discovery path. Auth priority: mTLS -> VyOS JWT -> OIDC -> API key
2026-08-26http-api: T8989: address review commentsomnom62
- Make ApiModel.key optional to allow Bearer/X-API-Key/mTLS auth without requiring a dummy key field in the request body - Add thread safety to REST token secret initialization - Cast rest_token_exp and rest_secret_len to int on load - Use defensive dict.get() for authentication config access
2026-08-26http-api: T8989: Update src/services/api/rest/libs/token_auth.pyomnom62
Co-authored-by: Viacheslav Hletenko <seversss265@gmail.com>
2026-08-26http-api: T8989: linter fixesomnom62
2026-08-26http-api: T8989: add mTLS client certificate authenticationomnom62
Add support for mutual TLS (mTLS) authentication to the VyOS REST API. When configured, nginx requests a client certificate and verifies it against the configured CA chain. FastAPI reads the X-Client-Verify header set by nginx and bypasses API key/token authentication when the client certificate is valid. Configuration: set service https certificates ca-certificate <name> set service https certificates verify-client <optional|required> Note: requires TLSv1.2 due to nginx 1.22 TLSv1.3 post-handshake authentication limitations. TLSv1.3 support pending nginx upgrade.
2026-08-26http-api: T8989: add REST Bearer token authenticationomnom62
Add JWT Bearer token support to the REST API, as an additional authentication method alongside the existing form-field key and X-API-Key header. - New POST /token endpoint mints a JWT for a valid API key - auth_required() accepts Authorization: Bearer <token> alongside existing key/X-API-Key auth - New config nodes: service https api rest authentication {expiration, secret-length} (defaults: 3600s / 32 bytes) - REST tokens use an independent signing secret from GraphQL's, since GraphQL may not be enabled on all deployments and the two subsystems have different expiry requirements - nginx location regex updated to allow /token - service_https.py default-value merge generalized to also apply to the rest node, not just graphql, so REST authentication defaults populate correctly on commit
2026-08-24Merge pull request #5414 from jvoss/api_traceroute_vrfJohn Estabrook
http-api: T9223: add VRF option to traceroute REST API endpoint
2026-08-24http-api: T9223: add VRF option to traceroute REST API endpointJonathan Voss
2026-08-24Merge pull request #5415 from jvoss/api_pingJohn Estabrook
http-api: T9224: add ping endpoint to REST API
2026-08-18T8482: reject commits referencing an incomplete policy objectChristian Breunig
A verify() failure in one conf_mode script (e.g. "policy prefix-list") did not stop vyos-configd/vyos-commitd from still pushing the shared FRR configuration to vtysh once the last script in the same commit batch happened to succeed on its own, since the render step only checked that last script's own result. Track whether any earlier script in the batch failed and gate the shared FRR render on it in both commit daemons.
2026-08-18http-api: T9224: add ping endpoint to REST APIJonathan Voss
2026-08-11vyos-netlinkd: T9086: drain netlink during commit to avoid stale link-DOWNBrad Kollmyer
Original bug: while a commit held the lock, the daemon called sleep(1) without reading the netlink socket. The pending message stayed queued in the kernel buffer, so once the commit ended, a stale event (e.g. a DOWN from a disable that had already been re-enabled) got processed as if it were fresh - stopping dhclient on an interface that was actually back UP. The applied fix keeps only the two pieces that are actually load-bearing: 1. Drain instead of sleep - while commit_in_progress2() is true, still call ipr.get() to read and discard any pending netlink messages, so nothing stale survives to be processed after the commit ends. 2. Reconcile on commit end - once the commit finishes, walk all matching interfaces, compare live sysfs operstate against the last state the daemon acted on (_iface_prev_operstate), and run the normal DHCP handler for any that disagree. This catches a real transition that happened only inside the drain window and would otherwise be silently lost. Dropped from the original fix: an unconditional live-sysfs override inside _handle_dhcp_events() that ran on every event, not just around commits - redundant with reconcile, and risked discarding genuine fast link flaps unrelated to any commit. Co-authored-by: Christian Breunig <christian@breunig.cc>
2026-07-30vyos-netlinkd: T9143: seed operstate cache at startupAriel E
The state tracker starts empty whenever vyos-netlinkd starts, so the first same-state RTM_NEWLINK UP notification is treated as a transition and unnecessarily restarts DHCP. Seed matching interface states from the kernel link dump after binding the rtnetlink socket. This preserves real DOWN-to-UP handling while suppressing the first redundant UP notification.
2026-07-23Merge pull request #5327 from BradKollmyer/T9076-remote-group-intervalDaniil Baturin
firewall: T9076: add per-remote-group update interval
2026-07-17utils: T9008: migrate remaining cmd() callers to cmdl() and remove cmd()Christian Breunig
Complete the safer-subprocess migration started by the cmdl()/ifconfig refactoring and convert every remaining vyos.utils.process.cmd() call site to the list-based cmdl(). Drop the vyos.utils.process.cmd() implementation as it is no longer in use.
2026-07-10firewall: T9076: add per-remote-group update intervalBrad Kollmyer
Add 'set firewall group remote-group <name> interval <value>' to control how often each remote group list is re-downloaded, independent of the global resolver-interval that also drives domain-group/FQDN resolution. The value accepts plain seconds or time-unit suffixes s/m/h/d/w (e.g. 4h), range 60 seconds to 4 weeks, enforced at commit time after conversion. When unset, the group keeps following 'firewall global-options resolver-interval', so existing configurations are unaffected. vyos-domain-resolver now tracks a last-update timestamp per remote group and sleeps until the next due update instead of a fixed resolver-interval tick, honoring per-group intervals both shorter and longer than the global one. A group is only stamped as updated after a successful download; failed downloads fall back to the cached list and are retried at the resolver cadence rather than after the full group interval. human_to_seconds() now treats a plain number as seconds instead of returning 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08T9068: refactor vyos-configd with config managerJohn Estabrook
2026-07-07Merge pull request #5275 from BradKollmyer/remote-T8829-head-fallbackJohn Estabrook
remote: T8829: fall back to GET when HEAD is not supported
2026-06-29ci: T8490: fix typos in comments, strings, and local identifiersYuriy Andamasov
Reaches a clean typos baseline for the T8490 ruleset pilot. Categories: - Comments/docs: recursivly, taret, passsed, characted, arhive, AtrributeError; "ned" -> "new" (migration comments). - Messages/strings: writeable -> writable (x5); OCaml log "Commandis" -> "Command is". - Local variables (all refs in-function): commited, formating, presistent; inpt_range -> input_range; tz_datas -> tz_data_raw (avoids the tz_data collision). - Self-contained renames (definition + all references in-file): formated_stats, _get_formatted_output_conections -> ..._connections, expension_failure -> expansion_failure (ping + traceroute), snmpd_restart_reqired -> ..._required. False positives are allowlisted centrally (vyos/.github, separate PR), NOT changed here: mke2fs, Maya-calendar "Mak", RFC 4122 "IDentifier" (hostapd), and VPP's "U-Forwrd" bridge-domain column header (op_mode/vpp.py + the VPP smoketest assert the real upstream `vppctl` output). Verified: typos clean, py_compile of every edited .py, zero remaining old-identifier references. 🤖 Generated by [robots](https://vyos.io)
2026-06-22vyos-netlink: T7965: only re-apply QoS configuration to individual interfaceChristian Breunig
The previous vyos-netlinkd implementation for QoS policy re-apply was very heavy. It conducted a full CLI validation and re-apply on every interface. Instead we do not only re-apply the QoS configuration to the interface which has had an address change detected by vyos-netlinkd. This can be tested by checking "tc qdisc show" before disconnecting a PPPoE interface and during/after reconnect. There will be no qdisc until the dynamic interface has received an IP address - then the qdisc will be re-applied.
2026-06-21remote: T8829: fall back to GET when HEAD is not supportedBrad Kollmyer
HttpC.download() always probed remote URLs with HEAD before GET to discover redirects and Content-Length. Some APIs (e.g. AbuseIPDB) reject HEAD with 405 Method Not Allowed, causing firewall remote-group downloads to fail and leave empty cached list files. Treat HEAD 405/501 as unsupported and proceed with GET using the original URL. When HEAD does not provide Content-Length, read it from the GET response headers instead. Validate available storage after determining file size and before opening the destination file. Log sanitized download errors in vyos-domain-resolver when a remote- group list-file fetch fails. Add unit tests with mock servers that return 405 or 501 on HEAD and 200 on GET.
2026-06-20vyos-netlink: T7965: re-apply QoS configuration on dynamic interfacesopswill
Re-apply QoS after dynamic interfaces get addresses after connect/disconnect. When PPPoE interfaces re-connect we need to re-do QoS settings.
2026-06-17firewall: T8991: Fix IndexError with domain resolver mishandling blank linessarthurdev
2026-06-03vyos-netlinkd: T8950: track per-interface operstate to suppress UP-to-UP ↵Robert Navarro
DHCP restarts _handle_dhcp_events() restarts dhclient/dhcp6c on every RTM_NEWLINK that carries operstate=UP, regardless of whether the interface was already UP. Normal kernel events that re-notify UP without a preceding DOWN (e.g. post-migration gratuitous-ARP, promiscuous-mode toggles) trigger unnecessary DHCP restarts. Each restart also creates a feedback loop: dhclient-script runs "ip link set dev <if> up" during PREINIT, which emits another RTM_NEWLINK(UP), which triggers another restart. One seed event becomes 10+ restarts in 15 seconds. Add a module-level dict tracking the last observed operstate per interface. Only proceed with the DHCP restart when the transition is DOWN-to-UP or when no previous state is recorded (first boot / service restart). UP-to-UP re-notifications are suppressed with a LOG_DEBUG message. Validated on a production VyOS 2026.05.26-1327-rolling router: a controlled KVM live migration after the patch produced zero DHCP restarts (all UP-to-UP events suppressed), with no impact on normal DOWN-to-UP DHCP recovery.
2026-05-28T8502: add server support for config-sync excluded pathsJohn Estabrook
2026-05-18vyos-netlinkd: T8781: try IPRoute.bind() RTNL subscription first (#5207)Christian Breunig
Not all pyroute2 versions which ship IPRoute() support subscribing to RTNL multicast groups. If subscribing fails, fallback to all messages.
2026-05-15vyos-netlinkd: T8781: use faster commit_in_progress2 with order O(1)Christian Breunig
Move to the re-implementation of the commit in progress check added in commit 002d45b70efd ("vyos.commit: T8781: move from O(n) to O(1) for commit_in_progress() checks").
2026-05-15vyos-netlinkd: T8781: do not call commit_in_progress() for EVERY netlink ↵Christian Breunig
message (#5199) * vyos-netlinkd: T8781: do not call commit_in_progress() for EVERY netlink message Signed-off-by: Fabrizzio Petrucci <fabrizziopm@compumundohipermegared.one> * vyos-netlinkd: T8781: restrict netlink subscription to link multicast group Bind IPRoute with RTMGRP_LINK only so route/rule/neighbour/address updates (e.g. full-table BGP) are not delivered to this socket. Add a match wildcard so unexpected message types do not raise MatchError and get logged as generic errors. --------- Signed-off-by: Fabrizzio Petrucci <fabrizziopm@compumundohipermegared.one> Co-authored-by: Fabrizzio Petrucci <fabrizziopm@compumundohipermegared.one>
2026-05-14T8831: smoketests: irregular PermissionError caused by systemctl stopChristian Breunig
Failures appear during PPPoEIf.remove() -> flush_addrs() -> set_dhcpv6(False), where disable uses self._cmd(f'systemctl stop ...'), which raises on any non-zero exit code of cmd(). PermissionError: [Errno 1] is misleading: cmd() raises OSError(exit_code, feedback); exit code 1 maps to PermissionError in Python 3, so logs point at "permissions" while the real signal is systemctl stop returned 1 (job failure, timeout, restart contention with Restart=always on dhcp6c@.service. Add a small systemd teardown helper stop_systemd_unit() validating the return codes from the "systemctl stop" calls.
2026-04-12vyos-netlinkd: T8486: fix high-cpu utilisation due to excessive CLI callsChristian Breunig
strace: Process 16362 attached [pid 16362] execve("/bin/cli-shell-api", ["/bin/cli-shell-api", "--show-active-only", "showConfig", "interfaces"], ...) = 0 [pid 16362] +++ exited with 0 +++ --- SIGCHLD ... strace: Process 16363 attached [pid 16363] execve("/bin/cli-shell-api", ["/bin/cli-shell-api", "--show-active-only", "showConfig", "interfaces"], ...) = 0 [pid 16363] +++ exited with 0 +++ --- SIGCHLD ... This would appear to be due to vyos-netlinkd calling op_mode_config_dict() more than is necessary: it can be called only when it may be applicable (this patch). Co-Authored-by: John Estabrook <jestabro@vyos.io>
2026-04-02Merge pull request #4872 from c-po/vyos-netlinkdChristian Breunig
vyos-netlinkd: T8047: replacement of netplugd
2026-03-27T8410: Fix typos and mistakes for comments and messagesViacheslav Hletenko
Fix typos and mistakes No functional changes
2026-03-24T8410: Fix typos and mistakes for operational and configuration commandsViacheslav Hletenko
Fix typos and mistakes in the commands and comments No functional changes
2026-03-19vyos-netlinkd: T8047: replace netplugdChristian Breunig
Implementing a daemon that listens for netlink messages in Python was discussed for many years. This is a proof-of-concept implementation how we can listen for netlink messages and process them in Python. Python 3.10 minimum is required due to the use of case statements which mimics C-style switch/case instructions. Add example: set interfaces ethernet eth1 vif 21 address dhcp set interfaces ethernet eth1 vif 21 address dhcpv6 commit If network cable is unplugged: vyos-netlinkd[12681]: RTM_NEWLINK -> eth3.10, state=DOWN, mac=00:50:56:b3:9d:8e vyos-netlinkd[12681]: Stopping dhclient@eth3.10.service... vyos-netlinkd[12681]: Stopping dhcp6c@eth3.10.service... If cable is plugged back in: vyos-netlinkd[12681]: RTM_NEWLINK -> eth3.10, state=DOWN, mac=00:50:56:b3:9d:8e vyos-netlinkd[12681]: RTM_NEWLINK -> eth3.10, state=UP, mac=00:50:56:b3:9d:8e vyos-netlinkd[12681]: Restarting dhclient@eth3.10.service... vyos-netlinkd[12681]: Restarting dhcp6c@eth3.10.service...
2026-02-09http-api: T8235: Use asyncio lock to prevent deadlock in config-file handlerNavneetBarwal-RA
The HTTPS API config-file handler previously used a blocking threading.Lock in an async FastAPI endpoint, which can block the event loop and make the API unresponsive under concurrent load. This commit replaces the blocking lock with an asyncio.Lock to serialize config operations without blocking async execution, resolving the reported deadlock when concurrent /config-file load operations occur. The behavior of run_in_threadpool and background task scheduling remains consistent with prior logic, so the handler preserves existing commit and commit-confirm semantics.