From: Stefan Hanreich <s.hanreich@proxmox.com>
To: Gabriel Goller <g.goller@proxmox.com>, pve-devel@lists.proxmox.com
Subject: Re: [PATCH pve-network v3 2/9] test: add test for frr.conf.local merging
Date: Fri, 6 Mar 2026 10:27:45 +0100 [thread overview]
Message-ID: <f0b69b9a-c2b2-4dc1-a76c-7b8f34c8841b@proxmox.com> (raw)
In-Reply-To: <20260305100331.80741-12-g.goller@proxmox.com>
as we discussed off-list:
We should have a section in this test-case for every supported line by
the old conf.local parser. One that extends an existing section (if we
generate one in the SDN stack) and one that adds a new section of the
respective type. E.g. VRFs and ipv6 prefix-lists are completely missing.
On 3/5/26 11:04 AM, Gabriel Goller wrote:
> Add a test that tests the frr.conf.local merging. This should ensure we
> do not run into further regressions.
>
> Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
> ---
> src/test/run_test_zones.pl | 16 +-
> .../expected_controller_config | 148 ++++++++++++++++++
> .../frr_local_merge/expected_sdn_interfaces | 53 +++++++
> .../zones/evpn/frr_local_merge/frr.conf.local | 75 +++++++++
> .../zones/evpn/frr_local_merge/interfaces | 7 +
> .../zones/evpn/frr_local_merge/sdn_config | 81 ++++++++++
> 6 files changed, 377 insertions(+), 3 deletions(-)
> create mode 100644 src/test/zones/evpn/frr_local_merge/expected_controller_config
> create mode 100644 src/test/zones/evpn/frr_local_merge/expected_sdn_interfaces
> create mode 100644 src/test/zones/evpn/frr_local_merge/frr.conf.local
> create mode 100644 src/test/zones/evpn/frr_local_merge/interfaces
> create mode 100644 src/test/zones/evpn/frr_local_merge/sdn_config
>
> diff --git a/src/test/run_test_zones.pl b/src/test/run_test_zones.pl
> index 905b2f42e1dc..806225735e6b 100755
> --- a/src/test/run_test_zones.pl
> +++ b/src/test/run_test_zones.pl
> @@ -126,12 +126,22 @@ foreach my $test (@tests) {
> reload_controller => sub {
> return;
> },
> - read_local_frr_config => sub {
> - return;
> - },
> );
> }
>
> + # Mock read_local_frr_config in PVE::Network::SDN::Frr to support testing frr.conf.local merging
> + my $frr_local_config;
> + my $frr_local_path = "./$test/frr.conf.local";
> + if (-e $frr_local_path) {
> + $frr_local_config = read_file($frr_local_path);
> + }
> + my $mocked_frr = Test::MockModule->new('PVE::Network::SDN::Frr');
> + $mocked_frr->mock(
> + read_local_frr_config => sub {
> + return $frr_local_config;
> + },
> + );
> +
> my $name = $test;
> my $expected = read_file("./$test/expected_sdn_interfaces");
>
> diff --git a/src/test/zones/evpn/frr_local_merge/expected_controller_config b/src/test/zones/evpn/frr_local_merge/expected_controller_config
> new file mode 100644
> index 000000000000..82f36c9e37ec
> --- /dev/null
> +++ b/src/test/zones/evpn/frr_local_merge/expected_controller_config
> @@ -0,0 +1,148 @@
> +frr version 10.4.1
> +frr defaults datacenter
> +hostname localhost
> +log syslog informational
> +service integrated-vtysh-config
> +!
> +!
> +vrf vrf_myzone
> + vni 1000
> +exit-vrf
> +!
> +interface ens19
> + no ip ospf passive
> +!
> +interface eth0
> + ip router isis isis1
> +!
> +interface eth1
> + ip router isis isis1
> + isis circuit-type level-2-only
> +!
> +interface iface2
> + ip ospf area 0
> +!
> +router bgp 65000
> + bgp router-id 192.168.0.1
> + no bgp default ipv4-unicast
> + coalesce-time 1000
> + bgp disable-ebgp-connected-route-check
> + neighbor BGP peer-group
> + neighbor BGP remote-as external
> + neighbor BGP bfd
> + neighbor 172.16.0.254 peer-group BGP
> + neighbor 172.17.0.254 peer-group BGP
> + neighbor VTEP peer-group
> + neighbor VTEP remote-as 65000
> + neighbor VTEP bfd
> + neighbor VTEP update-source dummy1
> + neighbor 192.168.0.2 peer-group VTEP
> + neighbor 192.168.0.3 peer-group VTEP
> + neighbor 192.168.1.1 remote-as 65001
> + neighbor 192.168.1.1 description "External Peer"
> + neighbor VTEP prefix-list MY_PREFIX_LIST out
> + neighbor VTEP allowas-in 1
> + neighbor VTEP remote-as 64600
> + no neighbor VTEP peer-group
> + !
> + address-family ipv4 unicast
> + network 192.168.0.1/32
> + neighbor BGP activate
> + neighbor BGP soft-reconfiguration inbound
> + neighbor VTEP activate
> + exit-address-family
> + !
> + address-family l2vpn evpn
> + neighbor VTEP activate
> + neighbor VTEP route-map MAP_VTEP_IN in
> + neighbor VTEP route-map MAP_VTEP_OUT out
> + advertise-all-vni
> + advertise-svi-ip
> + no neighbor VTEP route-map MAP_VTEP_IN in
> + neighbor VTEP route-map MAP_VTEP_IN_CUSTOM in
> + exit-address-family
> +exit
> +!
> +router bgp 65000 vrf vrf_myzone
> + bgp router-id 192.168.0.1
> + no bgp hard-administrative-reset
> + no bgp graceful-restart notification
> +exit
> +!
> +router eigrp 1
> + network 10.0.0.0/8
> +exit
> +!
> +router isis isis1
> + net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00
> + redistribute ipv4 connected level-1
> + redistribute ipv6 connected level-1
> + log-adjacency-changes
> +exit
> +!
> +router ospf
> + passive-interface default
> +exit
> +!
> +ip prefix-list PL_ALLOW seq 10 permit 10.0.0.0/8 le 24
> +ip prefix-list loopbacks_ips seq 10 permit 0.0.0.0/0 le 32
> +!
> +bgp community-list standard CL_LOCAL permit 65000:200
> +!
> +route-map CUSTOM_MAP permit 1
> + match ip address prefix-list PL_ALLOW
> +exit
> +!
> +route-map MAP_VTEP_IN permit 1
> +exit
> +!
> +route-map MAP_VTEP_IN permit 2
> + set community 65000:200
> +exit
> +!
> +route-map MAP_VTEP_OUT permit 1
> +exit
> +!
> +route-map MAP_VTEP_OUT permit 2
> + set community 65000:100
> +exit
> +!
> +route-map MAP_VTEP_OUT permit 3
> + match ip next-hop LOCAL
> +exit
> +!
> +route-map correct_src permit 1
> + match ip address prefix-list loopbacks_ips
> + set src 192.168.0.1
> +exit
> +!
> +route-map correct_src deny 2
> + match ip next-hop NOT_LOCAL
> +exit
> +!
> +ip protocol bgp route-map correct_src
> +router ospf
> + ospf router-id 172.20.30.1
> +exit
> +!
> +interface dummy_test
> + ip ospf area 0
> + ip ospf passive
> +exit
> +!
> +interface ens19
> + ip ospf area 0
> +exit
> +!
> +access-list pve_ospf_test_ips permit 172.20.30.0/24
> +!
> +route-map pve_ospf permit 100
> + match ip address pve_ospf_test_ips
> + set src 172.20.30.1
> +exit
> +!
> +ip protocol ospf route-map pve_ospf
> +!
> +!
> +line vty
> +!
> diff --git a/src/test/zones/evpn/frr_local_merge/expected_sdn_interfaces b/src/test/zones/evpn/frr_local_merge/expected_sdn_interfaces
> new file mode 100644
> index 000000000000..c7ddf44ef6d3
> --- /dev/null
> +++ b/src/test/zones/evpn/frr_local_merge/expected_sdn_interfaces
> @@ -0,0 +1,53 @@
> +#version:1
> +
> +auto myvnet
> +iface myvnet
> + address 10.0.0.1/24
> + hwaddress A2:1D:CB:1A:C0:8B
> + bridge_ports vxlan_myvnet
> + bridge_stp off
> + bridge_fd 0
> + mtu 1450
> + ip-forward on
> + arp-accept on
> + vrf vrf_myzone
> +
> +auto vrf_myzone
> +iface vrf_myzone
> + vrf-table auto
> + post-up ip route add vrf vrf_myzone unreachable default metric 4278198272
> +
> +auto vrfbr_myzone
> +iface vrfbr_myzone
> + bridge-ports vrfvx_myzone
> + bridge_stp off
> + bridge_fd 0
> + mtu 1450
> + vrf vrf_myzone
> +
> +auto vrfvx_myzone
> +iface vrfvx_myzone
> + vxlan-id 1000
> + vxlan-local-tunnelip 192.168.0.1
> + bridge-learning off
> + bridge-arp-nd-suppress on
> + mtu 1450
> +
> +auto vxlan_myvnet
> +iface vxlan_myvnet
> + vxlan-id 100
> + vxlan-local-tunnelip 192.168.0.1
> + bridge-learning off
> + bridge-arp-nd-suppress on
> + mtu 1450
> +
> +auto dummy_test
> +iface dummy_test inet static
> + address 172.20.30.1/32
> + link-type dummy
> + ip-forward 1
> +
> +auto ens19
> +iface ens19 inet static
> + address 172.16.3.10/31
> + ip-forward 1
> diff --git a/src/test/zones/evpn/frr_local_merge/frr.conf.local b/src/test/zones/evpn/frr_local_merge/frr.conf.local
> new file mode 100644
> index 000000000000..9003dd47c83b
> --- /dev/null
> +++ b/src/test/zones/evpn/frr_local_merge/frr.conf.local
> @@ -0,0 +1,75 @@
> +!
> +! Custom FRR configuration to be merged
> +!
> +ip nht resolve-via-default
> +!
> +ip route 192.0.2.0/24 198.51.100.1
> +!
> +ip protocol bgp route-map correct_src
> +!
> +router bgp 65000
> + neighbor 192.168.1.1 remote-as 65001
> + neighbor 192.168.1.1 description "External Peer"
> + address-family l2vpn evpn
> + advertise-svi-ip
> + exit-address-family
> + address-family ipv4 unicast
> + neighbor VTEP activate
> + exit-address-family
> +exit
> +!
> +route-map MAP_VTEP_OUT permit 1
> + set community 65000:100
> +exit
> +!
> +route-map MAP_VTEP_OUT permit 2
> + match ip next-hop LOCAL
> +exit
> +!
> +route-map correct_src deny 1
> + match ip next-hop NOT_LOCAL
> +exit
> +!
> +route-map MAP_VTEP_IN permit 2
> + set community 65000:200
> +exit
> +!
> +ip prefix-list PL_ALLOW seq 10 permit 10.0.0.0/8 le 24
> +!
> +route-map CUSTOM_MAP permit 10
> + match ip address prefix-list PL_ALLOW
> +exit
> +!
> +bgp community-list standard CL_LOCAL permit 65000:200
> +!
> +interface eth1
> + isis circuit-type level-2-only
> +exit
> +!
> +interface iface2
> + ip ospf area 0
> +exit
> +!
> +interface ens19
> + no ip ospf passive
> +exit
> +!
> +router ospf
> + passive-interface default
> +exit
> +!
> +router bgp 65000
> + neighbor VTEP prefix-list MY_PREFIX_LIST out
> + neighbor VTEP allowas-in 1
> + neighbor VTEP remote-as 64600
> + no neighbor VTEP peer-group
> + address-family l2vpn evpn
> + no neighbor VTEP route-map MAP_VTEP_IN in
> + neighbor VTEP route-map MAP_VTEP_IN_CUSTOM in
> + exit-address-family
> +exit
> +!
> +router eigrp 1
> + network 10.0.0.0/8
> +exit
> +!
> diff --git a/src/test/zones/evpn/frr_local_merge/interfaces b/src/test/zones/evpn/frr_local_merge/interfaces
> new file mode 100644
> index 000000000000..66bb826a44b3
> --- /dev/null
> +++ b/src/test/zones/evpn/frr_local_merge/interfaces
> @@ -0,0 +1,7 @@
> +auto vmbr0
> +iface vmbr0 inet static
> + address 192.168.0.1/24
> + gateway 192.168.0.254
> + bridge-ports eth0
> + bridge-stp off
> + bridge-fd 0
> diff --git a/src/test/zones/evpn/frr_local_merge/sdn_config b/src/test/zones/evpn/frr_local_merge/sdn_config
> new file mode 100644
> index 000000000000..4f90ab416495
> --- /dev/null
> +++ b/src/test/zones/evpn/frr_local_merge/sdn_config
> @@ -0,0 +1,81 @@
> +{
> + version => 1,
> + vnets => {
> + ids => {
> + myvnet => { tag => "100", type => "vnet", zone => "myzone" },
> + },
> + },
> +
> + zones => {
> + ids => { myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000, 'mac' => 'A2:1D:CB:1A:C0:8B' } },
> + },
> + controllers => {
> + ids => {
> + evpnctl => {
> + type => "evpn",
> + 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3',
> + asn => "65000"
> + },
> + bgplocalhost => {
> + type => "bgp",
> + 'peers' => '172.16.0.254,172.17.0.254',
> + ebgp => "1",
> + asn => "65000",
> + loopback => 'dummy1',
> + node => "localhost"
> + },
> + localhost => {
> + type => "isis",
> + 'isis-domain' => 'isis1',
> + 'isis-ifaces' => 'eth1,eth0',
> + 'isis-net' => "47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00",
> + loopback => 'dummy1',
> + node => "localhost",
> + },
> + },
> + },
> +
> + subnets => {
> + ids => {
> + 'myzone-10.0.0.0-24' => {
> + 'type' => 'subnet',
> + 'vnet' => 'myvnet',
> + 'gateway' => '10.0.0.1',
> + }
> + }
> + },
> + fabrics => {
> + ids => {
> + test_pathfinder => {
> + id => 'test_pathfinder',
> + interfaces => [
> + 'name=ens19,ip=172.16.3.20/31'
> + ],
> + ip => '172.20.30.2',
> + type => 'ospf_node'
> + },
> + test => {
> + ip_prefix => '172.20.30.0/24',
> + area => '0',
> + type => 'ospf_fabric',
> + id => 'test',
> + },
> + test_localhost => {
> + id => 'test_localhost',
> + interfaces => [
> + 'name=ens19,ip=172.16.3.10/31'
> + ],
> + ip => '172.20.30.1',
> + type => 'ospf_node'
> + },
> + test_raider => {
> + type => 'ospf_node',
> + ip => '172.20.30.3',
> + id => 'test_raider',
> + interfaces => [
> + 'name=ens19,ip=172.16.3.30/31'
> + ]
> + }
> + }
> + }
> +}
next prev parent reply other threads:[~2026-03-06 9:26 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-05 10:03 [PATCH manager/network/proxmox{-ve-rs,-perl-rs} v3 00/19] Generate frr config using jinja templates and rust types Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 1/8] ve-config: firewall: cargo fmt Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 2/8] frr: add proxmox-frr-templates package that contains templates Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 3/8] ve-config: remove FrrConfigBuilder struct Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 4/8] sdn-types: support variable-length NET identifier Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 5/8] frr: add template serializer and serialize fabrics using templates Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 6/8] frr: add isis configuration and templates Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 7/8] frr: support custom frr configuration lines Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-ve-rs v3 8/8] frr: add bgp support with templates and serialization Gabriel Goller
2026-03-05 10:03 ` [PATCH proxmox-perl-rs v3 1/1] sdn: add function to generate the frr config for all daemons Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 1/9] tests: use Test::Differences to make test assertions Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 2/9] test: add test for frr.conf.local merging Gabriel Goller
2026-03-06 9:27 ` Stefan Hanreich [this message]
2026-03-06 10:51 ` Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 3/9] test: bgp: add some various integration tests Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 4/9] sdn: write structured frr config that can be rendered using templates Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 5/9] sdn: remove duplicate comment line '!' in frr config Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 6/9] tests: rearrange some statements in the " Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 7/9] sdn: adjust frr.conf.local merging to rust template types Gabriel Goller
2026-03-06 10:35 ` Stefan Hanreich
2026-03-06 10:54 ` Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 8/9] test: adjust frr_local_merge test for new template generation Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-network v3 9/9] api: add dry-run endpoint for sdn apply to preview changes Gabriel Goller
2026-03-06 9:24 ` Stefan Hanreich
2026-03-06 12:08 ` Gabriel Goller
2026-03-05 10:03 ` [PATCH pve-manager v3 1/1] sdn: add dry-run diff view for sdn apply Gabriel Goller
2026-03-06 9:24 ` Stefan Hanreich
2026-03-06 12:37 ` Gabriel Goller
2026-03-06 12:58 ` [PATCH manager/network/proxmox{-ve-rs,-perl-rs} v3 00/19] Generate frr config using jinja templates and rust types Gabriel Goller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f0b69b9a-c2b2-4dc1-a76c-7b8f34c8841b@proxmox.com \
--to=s.hanreich@proxmox.com \
--cc=g.goller@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox