public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Stefan Hanreich <s.hanreich@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: Re: [PATCH manager/network/proxmox{-ve-rs,-perl-rs} v6 00/20] Generate frr config using jinja templates and rust types
Date: Thu, 12 Mar 2026 16:42:59 +0100	[thread overview]
Message-ID: <0a35b62d-96f8-4511-9edd-d8dfc9dc6a88@proxmox.com> (raw)
In-Reply-To: <20260312142732.370403-1-g.goller@proxmox.com>

re-ran the SDN e2e test-suite against this series again:

Summary:
        0 skipped
        0 timed out
        0 failed
        10 passed

On 3/12/26 3:27 PM, Gabriel Goller wrote:
> Previously we generated the frr config using one big perl hash, where every
> controller-plugin and zone-plugin would push their stuff. This is not pretty
> and also tricky to unite with our new rust-based fabrics. Furthermore the only
> way to edit or override the frr config is currently the frr.conf.local file,
> which is merged with the perl-hash in a very janky manner, which has sprouted
> numerous forum threads. The main problem with the frr.conf.local is the limited
> control which the user has as to where the override or additional config gets
> placed. There are also a few config overrides or additions to frr.conf.local
> that are currently impossible or generate invalid frr config.
> 
> To improve this we now ship templates, which we use to generate the frr config.
> This is the way it is done in e.g. sonic and vyos. These jinja2 templates are
> then populated using rust-structs. We changed the perl code to generate
> bgp/evpn and isis config that can be deserialized by the rust types and then
> rendered into a frr configuration using the templates.
> 
> # Versioning
> 
> The templates are in the proxmox-frr-templates debian package which, when
> installed, copies the template into `/usr/share/proxmox-frr/templates`, where
> they are read from using `include_str!`. This means the proxmox-frr-templates
> package is only used for development and to version the templates. The user
> only gets them in the binary of proxmox-frr (which, by extension, is in the
> perl-rs shared library).
> 
> # frr.conf.local
> 
> The frr.conf.local merging code has been adjusted so that the frr.conf.local
> still works as before.
> 
> 
> Changelog:
> 
> v6 (thanks @Hannes and @Stefan):
>   * pve-manager: change order of .then and .catch in SdnDiffView
>   * pve-manager: escape output of frr and ifupdown2 config with htmlEncode
>   * pve-network: use int() to convert asn to an integer
>   * ve-rs: fix error when rendering vrfs in the bgp template (ip routes where
>     only rendered when a vni is set)
>   * ve-rs: fix RouteMapMatch to contain a Vni struct so that matches on the vni
>     are rendered correctly
>   * ve-rs: forward to_string impl to deserialize on FrrWord (this way we
>     validate it also when deserializing)
>   * ve-rs: remove obsolete access_list.jinja
>   * ve-rs: correclty match next-hop in route-map template
>   * ve-rs: split interface addresses vec into different ipv4 and ipv6 vec, so
>     that we can tell which one is which in the templates
>   * ve-rs: enable strict mode in minijinja to get errors on undefined variables
> 
> v5 (thanks @Hannes):
>   * Use Sys.Audit instead of Sys.Modify on dry-run api call
>   * Fix dry-run config reading (the running-config was read twice)
> 
> v4 (thanks @Stefan):
>   * Fix completely new bgp router (global 'custom_frr_config') not having a 'exit' statement
>   * Add more testcases for frr.conf.local merging (vrf, ip-access list, ip prefix-list, etc.)
>   * Add more broken testcases (frr_local_merge_router_without_exit)
>   * Chang dry-run api method to GET
>   * Improv dry-run modal (wrap in panel)
>   * Improv commit messages
> 
> v3 (thanks @Stefan):
>   * Fix frr.conf.local merging (add routers of other protocols, fix routemap
>     sequence numbers, error on empty custom_frr_config, various perl style
>     changes)
>   * Add some more stuff to the frr_local_merge test.
>   * Reorder commits so that we have a commit that adds the tests at the
>     beginning and then a separate commit that changes the tests
> 
> v2 (thanks @Hannes and @Stefan):
>   * Removed user overrides (/etc/proxmox-frr/templates/*) and the pvesdn cli
>     tool
>   * Render frr.conf.local configuration at the correct position in the frr.conf
>     (In the middle after the bgp controller)
>   * Fix the default setting for `no bgp default ipv4-unicast` in the bgp
>     controller
>   * Add the ifupdown2 config diff to the dry-run
>   * Improve the dry-run diff view in the ui
>   * Expose `bgp hard-administrative-reset` and `bgp graceful-restart
>     notification`, don't hardcode it in the templates
>   * Add more extensive tests in pve-network (cover more evpn/bgp options, add
>     bgp-only test)
>   * Remove the `bon` dependency and the `Builder` derives (it's not needed right
>     now -- maybe we'll add it again later)
>   * In pve-network, add a undef check for the routemaps in the
>     `fix_routemap_seqs` function
>   * Updated implementation of `InterfaceName` -- use less complicated trait
>     bounds, improve api
>   * Remove obsolete code comments
>   * Squash the `phf` commit into the previous one
> 
> 
> Also thanks to Stefan Hanreich as always :)
> 
> 
> proxmox-ve-rs:
> 
> Gabriel Goller (9):
>   ve-config: firewall: cargo fmt
>   frr: add proxmox-frr-templates package that contains templates
>   ve-config: remove FrrConfigBuilder struct
>   sdn-types: support variable-length NET identifier
>   frr: add template serializer and serialize fabrics using templates
>   frr: add isis configuration and templates
>   frr: support custom frr configuration lines
>   frr: add bgp support with templates and serialization
>   frr: enable minijinja strict undefined behavior mode
> 
>  Makefile                                      |   8 +
>  proxmox-frr-templates/.gitignore              |   1 +
>  proxmox-frr-templates/Makefile                |  50 +++
>  proxmox-frr-templates/debian/changelog        |   5 +
>  proxmox-frr-templates/debian/control          |  17 +
>  proxmox-frr-templates/debian/copyright        |  18 +
>  .../debian/proxmox-frr-templates.install      |   1 +
>  proxmox-frr-templates/debian/rules            |   5 +
>  .../templates/access_lists.jinja              |   6 +
>  .../templates/bgp_router.jinja                | 128 ++++++++
>  proxmox-frr-templates/templates/bgpd.jinja    |  35 ++
>  proxmox-frr-templates/templates/fabricd.jinja |  29 ++
>  .../templates/frr.conf.jinja                  |  12 +
>  .../templates/interface.jinja                 |  12 +
>  .../templates/ip_routes.jinja                 |   8 +
>  proxmox-frr-templates/templates/isisd.jinja   |  32 ++
>  proxmox-frr-templates/templates/ospfd.jinja   |  18 +
>  .../templates/prefix_lists.jinja              |   6 +
>  .../templates/protocol_routemaps.jinja        |  10 +
>  .../templates/route_maps.jinja                |  22 ++
>  proxmox-frr/Cargo.toml                        |   3 +
>  proxmox-frr/debian/control                    |  12 +
>  proxmox-frr/src/ser/bgp.rs                    | 176 ++++++++++
>  proxmox-frr/src/ser/isis.rs                   |  47 +++
>  proxmox-frr/src/ser/mod.rs                    | 307 +++++++++---------
>  proxmox-frr/src/ser/openfabric.rs             |  33 +-
>  proxmox-frr/src/ser/ospf.rs                   |  74 +----
>  proxmox-frr/src/ser/route_map.rs              | 218 +++++--------
>  proxmox-frr/src/ser/serializer.rs             | 232 +++----------
>  proxmox-sdn-types/src/net.rs                  | 140 +++++++-
>  proxmox-ve-config/src/common/valid.rs         |   4 +-
>  proxmox-ve-config/src/firewall/cluster.rs     |   3 +-
>  proxmox-ve-config/src/firewall/types/ipset.rs |   2 +-
>  proxmox-ve-config/src/sdn/fabric/frr.rs       | 284 +++++++++-------
>  proxmox-ve-config/src/sdn/frr.rs              |  42 ---
>  proxmox-ve-config/src/sdn/mod.rs              |   2 -
>  proxmox-ve-config/tests/fabric/main.rs        | 101 +++---
>  .../fabric__openfabric_default_pve.snap       |   2 +-
>  .../fabric__openfabric_default_pve1.snap      |   2 +-
>  .../fabric__openfabric_dualstack_pve.snap     |  13 +-
>  .../fabric__openfabric_ipv6_only_pve.snap     |   4 +-
>  .../fabric__openfabric_multi_fabric_pve1.snap |   2 +-
>  .../snapshots/fabric__ospf_default_pve.snap   |   2 +-
>  .../snapshots/fabric__ospf_default_pve1.snap  |   2 +-
>  .../fabric__ospf_multi_fabric_pve1.snap       |   2 +-
>  45 files changed, 1328 insertions(+), 804 deletions(-)
>  create mode 100644 proxmox-frr-templates/.gitignore
>  create mode 100644 proxmox-frr-templates/Makefile
>  create mode 100644 proxmox-frr-templates/debian/changelog
>  create mode 100644 proxmox-frr-templates/debian/control
>  create mode 100644 proxmox-frr-templates/debian/copyright
>  create mode 100644 proxmox-frr-templates/debian/proxmox-frr-templates.install
>  create mode 100755 proxmox-frr-templates/debian/rules
>  create mode 100644 proxmox-frr-templates/templates/access_lists.jinja
>  create mode 100644 proxmox-frr-templates/templates/bgp_router.jinja
>  create mode 100644 proxmox-frr-templates/templates/bgpd.jinja
>  create mode 100644 proxmox-frr-templates/templates/fabricd.jinja
>  create mode 100644 proxmox-frr-templates/templates/frr.conf.jinja
>  create mode 100644 proxmox-frr-templates/templates/interface.jinja
>  create mode 100644 proxmox-frr-templates/templates/ip_routes.jinja
>  create mode 100644 proxmox-frr-templates/templates/isisd.jinja
>  create mode 100644 proxmox-frr-templates/templates/ospfd.jinja
>  create mode 100644 proxmox-frr-templates/templates/prefix_lists.jinja
>  create mode 100644 proxmox-frr-templates/templates/protocol_routemaps.jinja
>  create mode 100644 proxmox-frr-templates/templates/route_maps.jinja
>  create mode 100644 proxmox-frr/src/ser/bgp.rs
>  create mode 100644 proxmox-frr/src/ser/isis.rs
>  delete mode 100644 proxmox-ve-config/src/sdn/frr.rs
> 
> 
> proxmox-perl-rs:
> 
> Gabriel Goller (1):
>   sdn: add function to generate the frr config for all daemons
> 
>  pve-rs/Makefile                    |  1 +
>  pve-rs/src/bindings/sdn/fabrics.rs | 25 +++----------------------
>  pve-rs/src/bindings/sdn/mod.rs     | 28 ++++++++++++++++++++++++++++
>  3 files changed, 32 insertions(+), 22 deletions(-)
> 
> 
> pve-network:
> 
> Gabriel Goller (9):
>   tests: use Test::Differences to make test assertions
>   test: add tests for frr.conf.local merging
>   test: bgp: add some various integration tests
>   sdn: write structured frr config that can be rendered using templates
>   sdn: remove duplicate comment line '!' in frr config
>   tests: rearrange some statements in the frr config
>   sdn: adjust frr.conf.local merging to rust template types
>   test: adjust frr_local_merge test for new template generation
>   api: add dry-run endpoint for sdn apply to preview changes
> 
>  debian/control                                |   1 +
>  src/PVE/API2/Network/SDN.pm                   |  86 ++++
>  src/PVE/Network/SDN.pm                        |  46 +-
>  src/PVE/Network/SDN/Controllers/BgpPlugin.pm  | 104 +++--
>  src/PVE/Network/SDN/Controllers/EvpnPlugin.pm | 378 ++++++++--------
>  src/PVE/Network/SDN/Controllers/IsisPlugin.pm |  28 +-
>  src/PVE/Network/SDN/Fabrics.pm                |  24 +-
>  src/PVE/Network/SDN/Frr.pm                    | 404 +++++++++---------
>  src/PVE/Network/SDN/Zones.pm                  |   3 +-
>  src/test/debug/generateconfig.pl              |   3 +-
>  src/test/run_test_dns.pl                      |  15 +-
>  src/test/run_test_ipams.pl                    |  13 +-
>  src/test/run_test_subnets.pl                  |  31 +-
>  src/test/run_test_vnets_blackbox.pl           |  23 +-
>  src/test/run_test_zones.pl                    |  23 +-
>  .../expected_controller_config                |   1 -
>  .../evpn/bgp_ebgp/expected_controller_config  |  54 +++
>  .../evpn/bgp_ebgp/expected_sdn_interfaces     |  41 ++
>  src/test/zones/evpn/bgp_ebgp/interfaces       |   7 +
>  src/test/zones/evpn/bgp_ebgp/sdn_config       |  49 +++
>  .../expected_controller_config                |  67 +++
>  .../bgp_ebgp_multihop/expected_sdn_interfaces |  41 ++
>  .../zones/evpn/bgp_ebgp_multihop/interfaces   |  10 +
>  .../zones/evpn/bgp_ebgp_multihop/sdn_config   |  51 +++
>  .../expected_controller_config                |  52 +++
>  .../expected_sdn_interfaces                   |  41 ++
>  .../evpn/bgp_ebgp_reverse_order/interfaces    |   7 +
>  .../evpn/bgp_ebgp_reverse_order/sdn_config    |  49 +++
>  .../bgp_loopback/expected_controller_config   |  65 +++
>  .../evpn/bgp_loopback/expected_sdn_interfaces |  41 ++
>  src/test/zones/evpn/bgp_loopback/interfaces   |  10 +
>  src/test/zones/evpn/bgp_loopback/sdn_config   |  49 +++
>  .../expected_controller_config                |  55 +++
>  .../expected_sdn_interfaces                   |  41 ++
>  .../zones/evpn/bgp_multipath_relax/interfaces |   7 +
>  .../zones/evpn/bgp_multipath_relax/sdn_config |  49 +++
>  .../expected_controller_config                |  76 ++++
>  .../combined_bgp_isis/expected_sdn_interfaces |  41 ++
>  .../zones/evpn/combined_bgp_isis/interfaces   |  10 +
>  .../zones/evpn/combined_bgp_isis/sdn_config   |  57 +++
>  .../expected_controller_config                |   1 -
>  .../evpn/ebgp/expected_controller_config      |   1 -
>  .../ebgp_loopback/expected_controller_config  |   3 +-
>  .../evpn/ebgp_only/expected_controller_config |  25 ++
>  .../evpn/ebgp_only/expected_sdn_interfaces    |   1 +
>  src/test/zones/evpn/ebgp_only/interfaces      |   7 +
>  src/test/zones/evpn/ebgp_only/sdn_config      |  19 +
>  .../evpn/exitnode/expected_controller_config  |   1 -
>  .../expected_controller_config                |   1 -
>  .../expected_controller_config                |   1 -
>  .../exitnode_snat/expected_controller_config  |   1 -
>  .../expected_controller_config                |   1 -
>  .../expected_controller_config                | 184 ++++++++
>  .../frr_local_merge/expected_sdn_interfaces   |  53 +++
>  .../zones/evpn/frr_local_merge/frr.conf.local | 120 ++++++
>  .../zones/evpn/frr_local_merge/interfaces     |   7 +
>  .../zones/evpn/frr_local_merge/sdn_config     |  81 ++++
>  .../expected_controller_config                | 123 ++++++
>  .../expected_sdn_interfaces                   |  38 ++
>  .../frr.conf.local                            |  90 ++++
>  .../interfaces                                |   0
>  .../sdn_config                                |  53 +++
>  .../evpn/ipv4/expected_controller_config      |   1 -
>  .../evpn/ipv4ipv6/expected_controller_config  |   1 -
>  .../expected_controller_config                |   1 -
>  .../evpn/ipv6/expected_controller_config      |   1 -
>  .../ipv6underlay/expected_controller_config   |   1 -
>  .../evpn/isis/expected_controller_config      |  15 +-
>  .../isis_loopback/expected_controller_config  |  15 +-
>  .../expected_controller_config                |  13 +-
>  .../expected_controller_config                |   3 +-
>  .../multiplezones/expected_controller_config  |   1 -
>  .../expected_controller_config                |  13 +-
>  .../ospf_fabric/expected_controller_config    |  13 +-
>  .../evpn/rt_import/expected_controller_config |   1 -
>  .../evpn/vxlanport/expected_controller_config |   1 -
>  76 files changed, 2471 insertions(+), 573 deletions(-)
>  create mode 100644 src/test/zones/evpn/bgp_ebgp/expected_controller_config
>  create mode 100644 src/test/zones/evpn/bgp_ebgp/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/bgp_ebgp/interfaces
>  create mode 100644 src/test/zones/evpn/bgp_ebgp/sdn_config
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_multihop/expected_controller_config
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_multihop/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_multihop/interfaces
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_multihop/sdn_config
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_reverse_order/expected_controller_config
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_reverse_order/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_reverse_order/interfaces
>  create mode 100644 src/test/zones/evpn/bgp_ebgp_reverse_order/sdn_config
>  create mode 100644 src/test/zones/evpn/bgp_loopback/expected_controller_config
>  create mode 100644 src/test/zones/evpn/bgp_loopback/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/bgp_loopback/interfaces
>  create mode 100644 src/test/zones/evpn/bgp_loopback/sdn_config
>  create mode 100644 src/test/zones/evpn/bgp_multipath_relax/expected_controller_config
>  create mode 100644 src/test/zones/evpn/bgp_multipath_relax/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/bgp_multipath_relax/interfaces
>  create mode 100644 src/test/zones/evpn/bgp_multipath_relax/sdn_config
>  create mode 100644 src/test/zones/evpn/combined_bgp_isis/expected_controller_config
>  create mode 100644 src/test/zones/evpn/combined_bgp_isis/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/combined_bgp_isis/interfaces
>  create mode 100644 src/test/zones/evpn/combined_bgp_isis/sdn_config
>  create mode 100644 src/test/zones/evpn/ebgp_only/expected_controller_config
>  create mode 100644 src/test/zones/evpn/ebgp_only/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/ebgp_only/interfaces
>  create mode 100644 src/test/zones/evpn/ebgp_only/sdn_config
>  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
>  create mode 100644 src/test/zones/evpn/frr_local_merge_router_without_exit/expected_controller_config
>  create mode 100644 src/test/zones/evpn/frr_local_merge_router_without_exit/expected_sdn_interfaces
>  create mode 100644 src/test/zones/evpn/frr_local_merge_router_without_exit/frr.conf.local
>  create mode 100644 src/test/zones/evpn/frr_local_merge_router_without_exit/interfaces
>  create mode 100644 src/test/zones/evpn/frr_local_merge_router_without_exit/sdn_config
> 
> 
> pve-manager:
> 
> Gabriel Goller (1):
>   sdn: add dry-run diff view for sdn apply
> 
>  www/manager6/Makefile           |   1 +
>  www/manager6/sdn/SdnDiffView.js | 152 ++++++++++++++++++++++++++++++++
>  www/manager6/sdn/StatusView.js  |   8 ++
>  3 files changed, 161 insertions(+)
>  create mode 100644 www/manager6/sdn/SdnDiffView.js
> 
> 
> Summary over all repositories:
>   127 files changed, 3992 insertions(+), 1399 deletions(-)
> 





      parent reply	other threads:[~2026-03-12 15:43 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-12 14:26 Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 01/20] ve-config: firewall: cargo fmt Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 02/20] frr: add proxmox-frr-templates package that contains templates Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 03/20] ve-config: remove FrrConfigBuilder struct Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 04/20] sdn-types: support variable-length NET identifier Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 05/20] frr: add template serializer and serialize fabrics using templates Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 06/20] frr: add isis configuration and templates Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 07/20] frr: support custom frr configuration lines Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 08/20] frr: add bgp support with templates and serialization Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-ve-rs v6 09/20] frr: enable minijinja strict undefined behavior mode Gabriel Goller
2026-03-12 14:26 ` [PATCH proxmox-perl-rs v6 10/20] sdn: add function to generate the frr config for all daemons Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 11/20] tests: use Test::Differences to make test assertions Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 12/20] test: add tests for frr.conf.local merging Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 13/20] test: bgp: add some various integration tests Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 14/20] sdn: write structured frr config that can be rendered using templates Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 15/20] sdn: remove duplicate comment line '!' in frr config Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 16/20] tests: rearrange some statements in the " Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 17/20] sdn: adjust frr.conf.local merging to rust template types Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 18/20] test: adjust frr_local_merge test for new template generation Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-network v6 19/20] api: add dry-run endpoint for sdn apply to preview changes Gabriel Goller
2026-03-12 14:26 ` [PATCH pve-manager v6 20/20] sdn: add dry-run diff view for sdn apply Gabriel Goller
2026-03-12 15:42 ` Stefan Hanreich [this message]

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=0a35b62d-96f8-4511-9edd-d8dfc9dc6a88@proxmox.com \
    --to=s.hanreich@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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal