| Age | Commit message (Collapse) | Author |
|
vpp: T9484: keep net.core.rmem_max at VPP's netlink buffer size
|
|
syslog: T9336: Resolve remote FQDN targets within their configured VRF
|
|
VPP requests a 256 MiB netlink receive buffer (nl-rx-buffer-size), but
the kernel caps it at net.core.rmem_max, which VyOS sets to 2 MiB, so
VPP gets 4 MiB. A large routing table over VPP interfaces can overflow
it, and linux-cp then falls back to a full resync.
Setting the sysctl from the CLI does not help at boot: system sysctl
runs after vpp, so VPP has already opened its socket.
- vpp.py raises net.core.rmem_max to the requested size before VPP is
(re)started; a higher value is kept.
- VPP re-opens its netlink socket on every resync and sizes it again, so
system sysctl no longer applies a lower value while VPP is configured;
it uses the required size and prints a warning.
- When VPP is removed, vpp.py sets net.core.rmem_max back to the value
from system sysctl, or to the default from sysctl.d, read with the new
vyos.utils.system.sysctl_read_default().
- startup.conf.j2 takes nl-rx-buffer-size from the same value
(default_resource_map) instead of its own constant.
|
|
firewall: T9474: multiple issues in rule processing (time based rules, fragment matching and failing commits)
|
|
bgp: T9450: stop re-sending unchanged BGP lines to FRR on every commit
|
|
wlb: T9472: silent daemon failures, ignored options and connections broken by commits
|
|
nat: T9475: commit failures and weight issue in load-balancing, translation issues for port-ranges
|
|
Rsyslog resolves remote targets via the process's default routing
context regardless of a per-remote 'vrf' setting, so a remote given
as an FQDN fails to resolve when the only reachable DNS server lives
in a non-default VRF.
Changes:
- `system_syslog.py` pre-resolves FQDN using VRF remotes at commit time
and renders the resolved address instead of the raw FQDN.
- `vyos-domain-resolver` collects VRF-bound FQDN targets from syslog
and handles a resolved-address change for a syslog remote.
|
|
The CLI's XML default for "bgp conditional-advertisement timer" (60)
is always present in the config dict, so the line was rendered on
every commit. FRR's own default is the same value
(DEFAULT_CONDITIONAL_ROUTES_POLL_TIME, bgpd/bgp_conditional_adv.h) and
bgp_config_write() never prints it back when the value equals the
default, so frr-reload saw the line missing on every reload and sent
it again, both in the default instance and in every VRF instance.
Templates cannot query the XML definition while rendering, so frrender
takes the value from the config defaults of "parameters
conditional-advertisement" (conf.get_config_defaults) and adds it to
the BGP dict as the key xml_default_conditional_advertisement_timer,
for the global instance and for every VRF instance, the same pattern
used for "bgp default local-preference" (T9404). bgpd.frr.j2 renders
the line only when the configured value differs from
xml_default_conditional_advertisement_timer, comparing both as
integers so a timer entered as "060" is still treated as 60.
|
|
"ipv6 address autoconf" lives below "ipv6", so an interface which only
gets its address by SLAAC has no "address" node at all. connect_options()
only worked out the IP type when that node existed and fell back to
ipv4 otherwise, which dialled an IPv4-only bearer and left the interface
without any IPv6.
Read the address list with a default instead. All other combinations of
dhcp, dhcpv6 and autoconf give the same IP type as before.
|
|
With load-balance backends, the translation port and any translation
options were placed between "to" and the hash expression, e.g.
"dnat to:80 numgen random ...". nft rejects that and the commit failed.
The port is now part of every backend in the map and the options follow
the map, so load-balanced port forwarding works.
|
|
The hash for load-balanced NAT rules was always taken modulo 100, while
backend weights may add up to any value. With a sum below 100 some hash
values had no backend in the map; commit only warned about it.
The modulus is now the sum of all weights, so every hash value maps to a
backend and weights act as relative shares. Rules whose weights add up to
100 render exactly as before, and the warning is dropped.
|
|
A translation prefix combined with a port range lost the port range when
the rule had no matching source or destination address - the rule only
said "snat prefix to <prefix>" and gave no warning.
nft has no syntax for a prefix plus port range, so such rules now use the
same map form as rules with an address, keyed on 0.0.0.0/0. This keeps the
1:1 prefix mapping and adds the port range.
|
|
nft converts hour matches to UTC when the ruleset is loaded, using the
offset of that moment. After a daylight saving change, or a change of the
system time-zone, every hour window was off until the next firewall commit.
- A new helper loads only the rules with an hour match again, in place, so
sets such as dynamic, domain and GeoIP groups and all counters are kept.
It is scheduled as a systemd timer for the next UTC offset change and
re-arms itself; firewall and policy route commits arm or remove it.
- Changing the time-zone re-runs firewall and policy route.
The smoketest moves the clock to just before a change in Europe/Berlin and
checks that the window is refreshed and a dynamic group entry survives. It
only runs in the smoketest harness, as it changes the system clock.
|
|
Fragments were detected by overwriting the whole packet mark with a fixed
value before reassembly. Any later mark - a raw "set mark" or a policy route
"set table" - replaced it, so "fragment match-frag" no longer matched, and
marks already present on fragments were lost.
Fragments now only get bit 31 of the mark, which no configurable firewall or
routing policy mark uses:
- fragment matching tests the bit, mark matching ignores it
- firewall and policy route mark writers keep it
- policy route and local-route ip rules mask it while fragments are routed
- it is cleared after the forward and input filters, so later consumers such
as QoS or IPVS see the original mark
WAN load-balancing still overwrites the mark and keeps the previous
behaviour for fragments.
|
|
Rules with a start and stop time were rendered as two separate hour
comparisons. nft converts both to UTC when loading the ruleset, so a window
crossing midnight in UTC never matched - e.g. 22:00-06:00 anywhere, or
01:00-02:00 on a system running in CEST. A start or stop time on its own
had the same problem.
Hours are now rendered as a single range, which nft turns into its
complement when it wraps around midnight. A missing start or stop defaults
to the beginning or end of the day.
|
|
The routing table and mark of a WAN interface followed its position in the
sorted interface list. Adding an interface which sorts before the others
renumbered all of them. Existing connections still carried their old mark
in conntrack and were routed into the wrong table - they broke.
Every interface now keeps its table as long as it stays configured, new
interfaces get the lowest free table. The assignment is dropped once WAN
load-balancing is removed.
|
|
The ttl test considered the interface healthy whenever ping failed. A dead
uplink, where nothing answers, therefore stayed ACTIVE, while a target
answering the ping marked the interface FAILED.
The test now passes if the hop where the TTL runs out reports it, or if the
target is closer and answers itself. If nothing answers within resp-time,
the test fails.
|
|
"limit threshold above" was ignored. The rule always matched the traffic
below the rate, the same as the default "below".
With "above" the rule now matches the traffic exceeding the rate.
|
|
The renderer checked a key no CLI node produces, so "per-packet-balancing"
had no effect and every rule balanced per flow only.
With the option set, the rule no longer matches new connections only and
every packet is balanced on its own.
|
|
"inbound-interface any", offered by completion, was rendered as an
interface literally named "any" and matched no packet, so the rule never
balanced anything.
It now matches traffic entering on any interface except the WAN interfaces
themselves. Matching those as well would also restore the routing mark on
replies arriving from an ISP and send them straight back to that ISP.
|
|
policy: T9346: Allow dot in `prefix-list` and `prefix-list6` names
|
|
VyOS 1.3 allowed a dot in `policy prefix-list` and `policy prefix-list6`
names (pattern `^[-_a-zA-Z0-9.]+$`). The XML rewrite dropped the dot from
the allowed characters, so a 1.3 configuration using such names
can no longer be loaded or committed after an
upgrade. FRR itself accepts the dot in prefix-list names.
|
|
The Mikrotik configuration referenced by T9267 uses
matching-type=substring, documented to match the value anywhere within
the option string. This PR's "substring" match instead compared a
fixed-length slice at a fixed byte offset (default 0) for exact
equality - effectively an anchored prefix match, not a substring
search - which does not reliably reproduce the ticket's own use case
of picking a device model string (e.g. "T42S") out of a longer,
variably-formatted hostname.
Rebuild "hostname substring"/"vendor-class-id substring" on Kea's
match()+lcase() instead of substring()==, so a configured value now
matches anywhere in the option content and case-insensitively (options
like vendor-class-id are not guaranteed to arrive in a fixed case).
Drop the "offset" leaf together with it, since it has no remaining
purpose once matching is no longer anchored to a fixed position, and
there is no released behavior to preserve.
Raw hex input and values containing a literal single quote are
rejected for substring matching in verify(), since neither can be
safely embedded into the generated Kea regular expression; exact
"value" matching is unaffected and still accepts both.
Reported by alexk37 in review of PR #5436.
|
|
The byte length compared by a hostname/vendor-class-id "substring"
match is always derived from "value" for a meaningful equality test:
a shorter length never matches (comparing fewer option bytes against
the full value literal), and a longer one is silently clamped by Kea
to the available bytes, turning what looks like a prefix match into
an exact match of the whole remainder. There is no legitimate use for
setting it independently of "value", so drop the leaf rather than add
another verify() constraint around it.
Reported by alexk37 in review of PR #5436.
|
|
The auto-computed substring length floored instead of rounding up,
so a value like 0x1 produced substring(..., 0, 0) - an always-empty
comparison that can never match, even though Kea itself pads 0x1 to
the single byte 0x01. Round up to match Kea's own padding behavior.
Found by CodeRabbit review on PR #5436.
|
|
Client classes could previously only match on relay agent information
(Option 82). Add matching on the client-sent hostname (Option 12) and
vendor class identifier (Option 60), each with an exact-value or
substring form, so clients sharing a subnet can be told apart by e.g.
device model without splitting the subnet into per-model pools.
Also let a client-class deliver its own options (reusing the existing
subnet/range option syntax), so a match can directly hand out a
model-specific value such as a provisioning URL, independent of which
pool the client's lease is drawn from.
|
|
http-api: T9453: wait for the API server to be ready after a reload
|
|
T7886: add a general method for verifying interface reverse dependencies
|
|
container: T9456: use kernel overlayfs unless storage sits on overlayfs
|
|
vpp: T9161: Fix smoketests failing on NICs capped at 1500 MTU
|
|
pseudo-ethernet: T9253: fix anycast-gateway with shared MAC on bridge VLANs
|
|
firewall: T9332: fix GeoIP source/destination nftables set name colliā¦
|
|
ospf: T9448: do not render metric-type when it is the default
|
|
Since T5003 every system was configured to mount container storage via
fuse-overlayfs. This is only needed on live boot, where the storage sits
on the root overlayfs and podman refuses native overlay. Installed
systems keep it on the persistence partition and paid for a userspace
FUSE process per container plus a round trip on every file operation.
The mount program is now only configured when the storage is backed by
overlayfs, otherwise the kernel overlay driver is used.
Existing storage keeps using fuse-overlayfs: podman records that a mount
program was used, as its layers store whiteouts in a format the kernel
driver does not understand. Moving such a system to kernel overlayfs
requires resetting the container storage and re-pulling all images.
|
|
A commit that changes an already running HTTP API only signals the server
and returns at once. The server then restarts uvicorn asynchronously, and
until it listens again requests through nginx fail. A fixed one-second
sleep was meant to cover this but is too short on slow systems, making
the https smoketest fail intermittently and API clients see errors right
after a commit.
The server now creates a readiness marker once it accepts requests. The
commit clears the marker before reloading and waits for it to reappear,
warning if that takes longer than 30 seconds.
|
|
With metric-type 2 (the CLI default), every FRR reload deletes and
re-adds "default-information originate" and every "redistribute" line
under "router ospf". ospfd flushes the Type-5 LSAs on the delete and
re-originates them right after, so neighbours can briefly lose the
external routes on commits that do not touch OSPF.
ospfd and ospf6d (for redistribute) write "metric-type 1" back to the
running config and print nothing for type 2, their default. The
templates render "metric-type 2", so frr-reload sees a different line
on every reload.
frrender now adds the XML default of metric-type to the OSPF and OSPFv3
dicts as xml_default_metric_type, for the default and every VRF
instance. The templates render metric-type only when it differs from
that default, so the generated config matches what FRR prints back.
OSPFv3 default-information keeps rendering metric-type, as ospf6d
prints it for both types.
Add smoketests that read the generated config and vtysh for types 2,
1 and back to 2. Rename the "ptotocol" loop variable in
test_protocols_ospf.py to "protocol", which the typos check flags on
any change to this file.
|
|
config-management: T6304: Rewrite commit-archive location into a structured CLI
|
|
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.
|
|
interfaces: T9152: Refactor source-validation to use vmaps
|
|
Several anycast-gateway pseudo-ethernets with the same MAC on different
VLANs of one bridge (the usual EVPN layout) failed to commit with
"bridge fdb add ... File exists". The local FDB entry was always installed
without a VLAN, so every interface competed for the same entry. A failing
commit at boot left only one interface configured and dropped the rest of
the config.
The local FDB entry is now bound to the VLAN of the bridge sub-interface
when the bridge is VLAN aware, and it is installed with replace so a
re-commit over an existing entry no longer fails. Two anycast-gateways
with the same MAC on the same source-interface are rejected.
|
|
|
|
Suggested-by: l0crian1 <ryan.claridge13@gmail.com>
|
|
|
|
|
|
On a VPP-bound interface the MTU limit is the NIC's, which only VPP knows
(the kernel side is an LCP tap reporting a meaningless larger max). Reject at
commit an MTU larger than that limit, read from VPP's 'show hardware-interfaces'
(max mtu + driver frame overhead), so the kernel and dataplane cannot silently
end up with different MTUs.
Also apply a VLAN sub-interface's MTU to its VPP dataplane sub-interface and its
linux-cp tap (created with MTU 0), not just the parent; a sub-interface without
its own MTU inherits the parent's. Covers ethernet (vif/vif-s) and VPP
bond/loopback (vif).
|
|
configd: T9368: reconcile FRR after a DHCP lease without the commit socket
|
|
openvpn: T9370: add chacha20poly1305 data cipher
|
|
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.
|
|
bgp: T9404: do not render "bgp default local-preference" when the value is 100
|