summaryrefslogtreecommitdiff
path: root/src/tests
AgeCommit message (Collapse)Author
12 daysopenvpn: T9370: add chacha20poly1305 data cipherAntonio Quartulli
Offer chacha20poly1305 in "encryption data-ciphers" and "encryption data-ciphers-fallback", rendered as CHACHA20-POLY1305 and allowed with DCO.
14 daysopenvpn: T9364: default the MTU to 1420 when DCO is enabledAntonio Quartulli
The ovpn Kernel module does no MSS clamping, so with a 1500 bytes MTU full sized packets get fragmented on the underlay. Add an "mtu" node, rendered as "tun-mtu". With "offload dco" it defaults to 1420, unless a raw tun-mtu/link-mtu/udp-mtu option is present. Reject "mtu" together with such an option, below 100, and below 1280 when IPv6 runs inside the tunnel.
14 daysopenvpn: T9363: multiply the site-to-site keepalive timeoutAntonio Quartulli
"failure-count" counts missed intervals, so the timeout it describes is interval * failure-count. Server mode renders and verifies it that way; site-to-site passed the bare count to "ping-restart", where it lands as seconds - 60s instead of 600s with the defaults. Render the product. That puts a timeout past the 86400 "ping-restart" accepts within reach, so verify() rejects it and the 5-to-6 migration clamps configurations already beyond it. This changes behaviour on upgrade: site-to-site tunnels now tolerate a longer silence, 600 seconds instead of 60 with the defaults.
2026-09-28Merge pull request #5266 from MPStudyly/T8977_fix_haproxy_rebindDaniil Baturin
T8977: Fix regression with is_addr_assigned and is_listen_port_bind_service
2026-09-26configverify: T8859: remove dead code for verify_diffie_hellman_length()Christian Breunig
Commit a9e9c4acfa ("pki: openvpn: T3642: Migrate OpenVPN to PKI and refactor") was the last caller of verify_diffie_hellman_length() despite the build time testcases. Unused code is dead code, drop it.
2026-09-26python: T8859: fail loudly on an invalid Diffie-Hellman keysize argumentfix/T8859-dh-keysize-validationYuriy Andamasov
The Diffie-Hellman length check stringified the requested minimum keysize into a variable it never used, then converted the original argument again for the comparison. A non-numeric value therefore escaped as an uncaught ValueError from the comparison rather than being reported where it was passed in. The argument is now typed and validated up front: a non-integer raises TypeError, booleans included, and a non-positive integer raises ValueError. Both indicate a logic error in the calling script and should fail loudly instead of silently reporting an undersized key. The only callers today are the unit tests, so the contract is free to change. A file that exists but holds no readable parameters is user input rather than a logic error, and now fails the check instead of propagating the error from openssl. The bit-count pattern becomes a raw string, and the tests pass integer keysizes and cover the new paths.
2026-09-26vyos.utils: T8977: fix regressions in address and port validationChristian Breunig
Whether an interface belongs to a VRF was only established when a VRF was named explicitly. A lookup for the default VRF - what most callers ask for - thus reported an address living in an arbitrary VRF, or on a VRF device itself, as locally assigned, and accepted a configuration the daemon cannot bind later on. Naming the VRF device remains the way to ask for the addresses it carries. Probing the next address family after a failed bind was unreachable, as the argument is validated as a literal beforehand and then resolves to exactly one family. The early return is restored. An interface address carries host bits and must stay valid, but the range variants classify untrusted input handed over to nftables, which only accepts a prefix in canonical form. Those reject host bits again. All of it is covered by tests.
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-22Merge pull request #5466 from rnavarro/fix/configtree-serialize-libvyosconfigChristian Breunig
configtree: T9307: serialize libvyosconfig calls across threads
2026-09-15Merge pull request #5429 from rockfish-vyos/T9254-ike-esnDaniil Baturin
ipsec: T9254: do not emit ESN transforms in IKE proposals
2026-09-14ipsec: T9254: split get_esp_ike_cipher() into get_esp_cipher() / ↵rockfish-vyos
get_ike_cipher() get_esp_ike_cipher() took an esn flag defaulting to True (ESP/CHILD_SA semantics), and every IKE_SA call site had to remember to pass esn=False. Nothing enforced that, so a future call site could reintroduce the ESN-in-IKE bug this task fixed. Following review feedback from hedrok, split it into two public filters: get_esp_cipher(group_config, ike_group=None) ESP/CHILD_SA, esn=True get_ike_cipher(group_config) IKE_SA, esn=False always The shared implementation moves to _get_esp_ike_cipher() (no register_filter), so a template can no longer call it directly and skip picking one of the two entry points. Updated call sites: peer.j2, profile.j2, remote_access.j2, l2tp.j2 (proposals -> get_ike_cipher, esp_proposals -> get_esp_cipher), and test_template.py.
2026-09-13openvpn: T8264: reject the raw options DCO cannot serveAntonio Quartulli
Raw options are appended after --config and therefore override what the CLI rendered, so they have to face the same checks. A single cipher the Kernel module does not implement makes OpenVPN fall back to the userspace data path; "ncp-ciphers" is the 2.4 name for the negotiation list, and outside server and pull mode "cipher" becomes the fallback cipher. "dev-type" other than tun, an AF_UNIX "dev-node" and, in server mode, a "topology" other than subnet drop the offload just the same. "DEFAULT" stands for the built-in list, which OpenVPN expands to AEAD ciphers alone before it weighs the offload, and the migration drops the offload from whatever stays rejected.
2026-09-13openvpn: T8264: keep the keepalive within what OpenVPN acceptsAntonio Quartulli
The CLI renders "keepalive <interval> <interval * failure-count>" while its two ranges are independent, so it can produce parameters the daemon refuses to start on: a timeout below twice the interval, or one beyond the 12 hours OpenVPN is about to cap ping and keepalive at. A zero interval renders "keepalive 0 0", on which OpenVPN skips these checks and simply runs without keepalive, so leave that combination alone. Migrate what stays rejected, or an upgrade would leave a configuration the router can no longer commit at boot.
2026-09-13openvpn: T8264: migrate away DCO the Kernel module cannot serveAntonio Quartulli
"offload dco" was accepted next to tap, static keys, compression, CBC ciphers and raw options OpenVPN refuses to offload, because 2.6 ignored the module altogether. Those combinations now fail verify(), which would break config load on upgrade, so drop the request instead. The migration has to mirror verify_dco() exactly: anything it keeps that verify() turns away leaves a router unable to commit its own configuration.
2026-09-12configtree: T9307: serialize libvyosconfig calls across threadsRobert Navarro
libvyosconfig is not safe for concurrent entry. ctypes releases the GIL for each foreign call, so threads in one process can be inside the library at the same time; two concurrent from_string calls, or from_string racing destroy, corrupt the shared parser state and crash the process with SIGSEGV. vyos-http-api reaches this when a configure operation runs in the threadpool while a retrieve is served on the event loop. Serialize every entry point on one process-wide RLock in the _Lib wrapper. For the entry points that report through the library's global error buffer, read the buffer while the lock is held and keep it per thread, so get_error() returns the caller's own error; destroy, which can run from __del__ between a failed call and get_error(), leaves it untouched.
2026-09-10Merge pull request #5454 from c-po/bond-fix-add-memberChristian Breunig
bond: T9269: keep the bond MAC when appending a member interface
2026-09-10configdict: T9269: no phantom removal when a multi node gains a valueChristian Breunig
A multi node with a single value is a plain string in the JSON rendering of the config tree, and only becomes a list once it holds several values. leaf_node_changed() tested for a string before diffing the lists, so appending a value reported the already configured one as gone. Adding a second bond member thus produced an "interface_remove" entry for the first, and BondIf.update() released it right after enslaving the new one, leaving the bond with the new member only. Normalize to a list and reuse list_diff(). Only the string to list append changes, from [old] to []. interface.py was immune as it re-applies list_diff() to address_old, protocols_static_arp.py was not.
2026-09-09vyos.utils: T9269: no zero-component key path for an empty dictChristian Breunig
dict_to_key_paths() yields the path leading to an empty dict, which is a valueless leaf node. An empty dict at the top level means "no configuration" and yielded a single zero-component path, making dict_to_paths_values() report an option named ''. A bare "interfaces ethernet eth1" - as found in a container, where no hw-id is deployed - could therefore not be added to a bond: Cannot add interface "eth1" to bond, it has a "" assigned! interfaces_ethernet.py recorded the same phantom path in bond_blocked_changes. configdiff.py was immune, owner([]) is falsy.
2026-09-09interfaces: T9269: do not run the hw-id naming pass in a containerChristian Breunig
Container interfaces are veth pairs created by the runtime. They have no backing bus device in sysfs, so discover_physical_interfaces() never considers them, and their MAC is assigned by the host and regenerated on every start. A pending node could thus never be resolved. The pass only spent both bounded hardware waits and then asked for an hw-id that would not survive a restart: interface 'eth0' still has no hw-id configured after this boot's naming pass - bind it manually, e.g. ... Returning before write_status() leaves no status file behind, so warn_missing_interface_hardware() in vyos-router stays quiet by itself. setUpModule() pins the detection off for the test module - the build container would otherwise short-circuit every existing main() test.
2026-08-15T3871: never guess a pending node's hardware when ambiguousChristian Breunig
Reported against the previous PCIe/MAC-sorted replacement fill: on a real, already-provisioned box (hw-id from historical probe-order rescan, unrelated to any PCIe/MAC sort), a configured node's address ended up silently applied to a different physical NIC. Deleting one interface's hw-id (keeping its settings) while a different, unrelated interface's config was fully removed in the same boot was enough - the two freed candidates' MAC order didn't match their old name order, so the deterministic sort swapped them. Once written back by the rescan helper, the wrong binding became permanent and self-reinforcing on every later boot. There's no way to verify, from MAC and PCIe position alone, which of several unconfigured candidates is genuinely a given node's own hardware once its hw-id is gone. Restore strict matching: a node only recovers its hw-id automatically when it's the sole pending node of its type this boot and exactly one candidate exists - any other count leaves it pending and reported rather than guessed. A candidate that isn't matched this way is not otherwise held back - it still gets an ordinary, settings-free bootstrap name instead of being lost, just never inherits another node's configuration. This necessarily changes what a combined "delete one interface fully, clear a different one's hw-id" reboot can auto-resolve; the accompanying test-harness change acknowledges that trade-off explicitly.
2026-08-14Merge pull request #5350 from c-po/boot-ifname-raceDaniil Baturin
boot: T3871: rework interface renaming and ordering
2026-08-14utils: T9185: revert the proposed fix ask_yes_no() busy-looping forever on ↵Viacheslav Hletenko
non-tty stdin
2026-08-13Merge pull request #5383 from ruben-herold/T9177-are-same-ip-family-fixDaniil Baturin
utils: T9177: fix _are_same_ip() using wrong address family
2026-08-13utils: T9185: ask_yes_no() fails fast on non-tty instead of silent defaultRuben Herold
jestabro (and dmbaturin previously, on #5362) pointed out that silently returning `default` on a non-TTY stdin still violates ask_yes_no()'s interactive-only contract, even though it stops the CPU-spin. Per T9185, sageframe's original incident confirms why: a caller that forgets an explicit non-interactive guard gets no error and no visible hang, just a process quietly pegging a core for days. Raise EOFError immediately instead, so a missing guard fails loudly and fast rather than either spinning or silently succeeding. Existing callers that are meant to run non-interactively already check no_prompt/-y before calling this (config_mgmt.py, backend.py) and are unaffected.
2026-08-09utils: T9185: fix ask_yes_no() busy-looping forever on non-tty stdinRuben Herold
commit-confirm (and ~40 other call sites) hang and burn a full CPU core indefinitely when invoked with stdin that isn't a TTY, e.g. a non-interactive vbash session (vbash -c "... commit-confirm 10; exit"). input() raises EOFError immediately and repeatedly in that case, and the except handler in ask_yes_no() looped straight back to input() with no backoff or exit condition. Check stdin.isatty() up front and return the default immediately when it's not a TTY, matching what a user pressing Enter (accepting the default) would already do interactively.
2026-08-08T3871: make boot-time interface naming deterministic and hw-id awareChristian Breunig
Multi-vendor PCIe NIC systems could lose or rename Ethernet/wireless interfaces on boot, because naming was decided from a single per-device udev event before all hardware had a chance to enumerate. Replace that with one authoritative pass, run once configuration is available during router startup: wait for configured hardware, apply every hw-id binding, and name whatever has none yet by PCIe distance from the root complex and MAC address - the same result every boot. A node with its hw-id deleted (NIC replacement) or its whole configuration removed is treated as an ordinary open slot, filled the same way - recovering its original hardware whenever the interfaces that vacated slots this boot also show up as candidates. Boot now reports any interface still unresolved, and the pass is covered by a new test suite in vyos-build named: make testifname Assisted-by: Claude:claude-sonnet-5
2026-08-07utils: T9177: fix ruff findings in touched filesRuben Herold
Same class of pre-existing whole-file ruff findings as vyos-1x#5374's 477dd4d6b: bare except:, one unused except-clause variable, one multi-statement if, and one unused loop variable in python/vyos/utils/network.py. Also renames a duplicate test_is_ipv6_link_local() in test_utils_network.py to test_is_loopback_addr() (its actual subject) - the duplicate name silently shadowed the first test method, so is_ipv6_link_local() was never actually exercised. No behavior changes to application code.
2026-08-07utils: T9177: fix _are_same_ip() using wrong address familyRuben Herold
_are_same_ip() computed the address family of both arguments but only ever passed the first one's family to inet_pton() for both, via a computed-but-unused "s_two" local. Comparing addresses of different families (e.g. one IPv4, one IPv6) raised instead of returning False. Found via ruff flagging s_two as an unused local; the function currently has no callers.
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-07Merge pull request #5275 from BradKollmyer/remote-T8829-head-fallbackJohn Estabrook
remote: T8829: fall back to GET when HEAD is not supported
2026-06-29Merge pull request #5285 from c-po/cmdlDaniil Baturin
utils: T9003: add list-argument variant of cmd() for safer subprocess execution
2026-06-24T9015: add nosetestJohn Estabrook
2026-06-23ipsec: T8975: add unit tests for vti_updown_db lock wiringRobert Navarro
The module previously had no tests. Cover the DB logic (add/remove, multiple connections per interface, removeAllOtherInterfaces, setPersistentInterfaces, seed-from-file) and assert each open_* helper acquires the serialising lock, exercised with vyos.utils.locking.Lock patched out.
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-20utils: T9003: add list-argument variant of cmd() for safer subprocess executionChristian Breunig
A list-argument variant of cmd() for safer subprocess execution named cmdl(). Command must be a list of strings; no shell interpolation is performed, which eliminates a class of command-injection risks present when building commands with f-strings or other string formatting.
2026-05-28T8916: add simple nosetest for subtree_from_partial utilityJohn Estabrook
2026-04-24Merge pull request #5130 from natali-rs1985/T8460Viacheslav Hletenko
vpp: T8460: Use isolated cpus for VPP cpu-cores
2026-04-21vpp: T8460: Use isolated cpus for VPP cpu-coresNataliia Solomko
VPP CPU core assignment now uses kernel-isolated CPUs (from /sys/devices/system/cpu/isolated) with explicit corelist-workers instead of computing offsets from available cores with skip-cores/workers. Added validation that enough CPUs are actually isolated before VPP starts, and that isolate-cpus config only references existing CPU IDs. Moved smoketest for kernel option 'isolate-cpus' to test_vpp.py
2026-04-21T8534: refactor sysctl_(read|write) to accept key partsChristian Breunig
Interface names can contain dots (e.g. VLAN subinterfaces like eth0.10), which conflicts with sysctl's dot-separated key syntax. Change sysctl_read() and sysctl_write() to take key components as a list and normalize each component by replacing . with / before invoking sysctl. This fixes sysctl lookups/updates for VLAN subinterfaces. Extend the SR-TE smoketest to cover a VLAN subinterface. Previous error raising this issue: vyos-configd: sysctl: cannot stat /proc/sys/net/ipv6/conf/eth0/10/seg6_enabled: No such file or directory vyos-configd: sysctl: cannot stat /proc/sys/net/ipv6/conf/eth0/201/seg6_enabled: No such file or directory
2025-12-17login: T8086: replace getpwall() user enumeration to avoid NSS/TACACS timeoutsChristian Breunig
The previous implementation of "system login" relied on Python's pwd.getpwall() to enumerate user accounts. This forces a full walk through the NSS stack, which is acceptable in general but problematic for our use-case. VyOS only needs information about locally created accounts and not remote accounts provided via AAA backends such as TACACS or RADIUS. When TACACS servers are unreachable, NSS lookups become extremely slow due to repeated timeouts. As a result, any operation triggering pwd.getpwall() (including configuration commits) can stall for several minutes. This change introduces a dedicated helper, get_local_passwd_entries(), which reads /etc/passwd directly and avoids NSS entirely. Since only local UIDs are relevant, this provides all required data with no external dependencies. Performance improvement on VyOS 1.4.3 with two unreachable TACACS servers: # set system login tacacs server 192.168.1.50 key test123 # set system login tacacs server 192.168.1.51 key test123 # time commit Before: real 3m29.825s user 0m0.329s sys 0m0.246s After: real 0m1.464s user 0m0.337s sys 0m0.195s This significantly improves commit performance and removes sensitivity to AAA server outages.
2025-09-26image: T5455: Add migration of SSH `known_hosts` files during image upgradeOleksandr Kuchmystyi
During upgrade, the script now checks if any `known_hosts` files exist. If so, it prompts the user to save these SSH fingerprints, and upon confirmation, copies the files to the new image persistence directory.
2025-09-23T7850: add nosetest for util list_stripJohn Estabrook
2025-09-14vyos.utils: T7740: update dict_search to return optional default value (#4700)l0crian1
2025-07-08T7499: add unittest for config tree merge functionJohn Estabrook
2025-06-28T7591: remove copyright years from source filesChristian Breunig
The legal team says years are not necessary so we can go ahead with it, since it will simplify backporting. Automatically removed using: git ls-files | grep -v libvyosconfig | xargs sed -i -E \ 's/^# Copyright (19|20)[0-9]{2}(-[0-9]{4})? VyOS maintainers.*/# Copyright VyOS maintainers and contributors <maintainers@vyos.io>/g' In addition we will error-out during "make" if someone re-adds a legacy copyright notice
2025-06-17firewall: T6951: Add a configuration command for ethertypes that bridge ↵Nataliia Solomko
firewalls should always accept
2025-05-29ssh: T6013: rename trusted-user-ca-key -> truster-user-caChristian Breunig
The current implementation for SSH CA based authentication uses "set service ssh trusted-user-ca-key ca-certificate <foo>" to define an X.509 certificate from "set pki ca <foo> ..." - fun fact, native OpenSSH does not support X.509 certificates and only runs with OpenSSH ssh-keygen generated RSA or EC keys. This commit changes the bahavior to support antive certificates generated using ssh-keygen and loaded to our PKI tree. As the previous implementation did not work at all, no migrations cript is used.
2025-05-04vyos.template: T7122: add Jinja2 clever function helper to read vyos.defaultsChristian Breunig
Add a new category if Jinja2 operands. We already have filters and tests, but sometimes we would like to call a Python function without and data "|" piped to it - that's what they call a clever-function. {{ get_default_port(NAME) }} can be used to retrieve the value from vyos.defaults.internal_ports[NAME] within Jinja2. We no longer need to extend the dictionary with arbitrary data retrieved from vyos.defaults, we can now simply register another clever-function to the Jinja2 backend.
2025-04-28vyos.utils: T7122: fix IPv6 support in check_port_availability()Christian Breunig
Commit 4523e9c897b3 ("wireguard: T3763: Added check for listening port availability") added a function to check if a port is free to use or already occupied by a different running service. This has been done by trying to bind a socket to said given port. Unfortunately there is no support for IPv6 address-fdamily in both socketserver.TCPServer or socketserver.UDPServer. This must be done manually by deriving TCPServer and setting self.address_family for IPv6. The new implementation gets rid of both TCPServer and UDPServer and replaces it with a simple socket binding to a given IPv4/IPv6 address or any interface/ address if unspecified. In addition build time tests are added for the function to check for proper behavior during build time of vyos-1x.
2025-03-20T7246: update libvyosconfig hash and add nosetestJohn Estabrook