From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 60A8D1FF13B for ; Wed, 25 Mar 2026 10:43:23 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A33C4FAE0; Wed, 25 Mar 2026 10:42:24 +0100 (CET) From: Stefan Hanreich To: pve-devel@lists.proxmox.com Subject: [PATCH cluster/network/proxmox{-ve-rs,-perl-rs} 00/27] Add support for route maps / prefix lists to SDN Date: Wed, 25 Mar 2026 10:41:11 +0100 Message-ID: <20260325094142.174364-1-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1774431663228 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.567 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: WX7KPPVDKRQQZLUJ57NPCZFSAZ2W33A3 X-Message-ID-Hash: WX7KPPVDKRQQZLUJ57NPCZFSAZ2W33A3 X-MailFrom: s.hanreich@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: ## Introduction This patch adds support for managing route maps and prefix lists to the SDN stack. With this patch series, route maps can be applied to the BGP and EVPN controller for incoming / outgoing route filtering. There are currently some other features in development that would make use of route maps as well, namely: * VRF route leaking * Route Redistribution for Fabrics Prefix Lists can be used for matching inside route map match statements. They are implemented so they can be used inside route map match statements for now. ## Motivation There are a lot of use-cases for enabling users to create their own route-maps, which was currently only possible by utilizing frr.conf.local - which was clunky and prone to issues. Route maps can be used for filtering in/outgoing routes and modifiy them, so users could e.g. only selectively advertise some routes via BGP or only import certain EVPN routes from outside. It also allows us to programmatically manage route maps via the UI, e.g. for deeper EVPN integration in PDM. This opens up a lot of possibilities for new features. ## Configuration Format This patch series adds two new configuration files, route-maps.cfg and prefix-lists.cfg in /etc/pve/sdn. ### route-maps.cfg An example route map configuration looks as follows: route-map-entry: example_123 action permit match key=vni,value=23487 set key=tag,value=23487 This would create the following FRR route map entry: route-map example permit 123 match evpn vni 23487 set tag 23487 Every entry in route-maps.cfg maps to an entry in a route map. They are identified by their name as well as their ordering number. `example_123` specifies the 123th entry in the route map 'example'. The main reason for choosing this format is, that having a single section for one route-map would be quite unwieldy. It'd require some format like this, which is pretty awkward to handle / validate: route-map-entry: example action permit,seq=123 match key=vni,value=23487,seq=123 set key=tag,value=23487,seq=123 >>From a UI POV editing singular route map entries seems better as well, and with the mapping of section entries to route map entries, a suitable API design follows quite naturally and easily maps to the respective section config entries, without too much data mangling required. ### prefix-lists.cfg An example prefix list configuration looks as follows: prefix-list: example-1 entries action=permit,prefix=192.0.2.0/24 entries action=permit,prefix=192.0.2.0/24,le=32 entries action=permit,prefix=192.0.2.0/24,le=32,ge=24,seq=123 This would create the following FRR prefix list: ip prefix-list example-1 permit 192.0.2.0/24 ip prefix-list example-1 permit 192.0.2.0/24 le 32 ip prefix-list example-1 seq 123 permit 192.0.2.0/24 le 32 ge 24 ## API endpoints This patch series introduces the following API endpoints in the /cluster/sdn subfolder: ### Route Maps GET /route-maps - lists all route map entries GET /route-maps/ - lists all route map entries for the route map GET /route-maps// - gets the order'th entry in route map POST /route-maps - creates a new route map entry PUT /route-maps// - updates the order'th entry in route map DELETE /route-maps// - deletes the order'th entry in route map ### Prefix Lists GET /prefix-lists - lists all prefix lists GET /prefix-lists/ - get prefix list POST /prefix-lists - create a new prefix list PUT /prefix-lists/ - update prefix list DELETE /prefix-lists/ - delete prefix list ## Open questions How should we handle overriding the auto-generated route maps (e.g. in the EVPN controller) and prefix lists? Currently this patch series disallows creating any route map / prefix list that have the same name as PVE auto-generated ones via the API. They can be overridden by creating a new route map and then selecting it in the respective entity (e.g. via route-map-in in the EVPN controller). Pre-defined prefix-lists cannot currently be overridden, since this usually makes little sense, as they are used in the auto-generated route maps, which can be overriden anyway. pve-cluster: Stefan Hanreich (2): cfs: add 'sdn/route-maps.cfg' to observed files cfs: add 'sdn/prefix-lists.cfg' to observed files src/PVE/Cluster.pm | 2 ++ src/pmxcfs/status.c | 2 ++ 2 files changed, 4 insertions(+) proxmox-ve-rs: Stefan Hanreich (9): sdn-types: add common route-map helper types frr: implement routemap match/set statements via adjacent tagging frr: allow rendering prefix-lists/route-maps separately frr-templates: change route maps template to adapt to new types ve-config: add prefix list section config ve-config: frr: implement frr config generation for prefix lists ve-config: add route map section config ve-config: frr: implement frr config generation for route maps ve-config: fabrics: adapt frr config generation to new format .../templates/route_maps.jinja | 12 +- proxmox-frr/Cargo.toml | 2 +- proxmox-frr/src/ser/route_map.rs | 101 ++- proxmox-frr/src/ser/serializer.rs | 35 +- proxmox-sdn-types/src/bgp.rs | 50 ++ proxmox-sdn-types/src/lib.rs | 135 ++++ proxmox-ve-config/debian/control | 2 + proxmox-ve-config/src/sdn/fabric/frr.rs | 25 +- proxmox-ve-config/src/sdn/mod.rs | 2 + proxmox-ve-config/src/sdn/prefix_list.rs | 347 ++++++++ proxmox-ve-config/src/sdn/route_map.rs | 762 ++++++++++++++++++ 11 files changed, 1408 insertions(+), 65 deletions(-) create mode 100644 proxmox-sdn-types/src/bgp.rs create mode 100644 proxmox-ve-config/src/sdn/prefix_list.rs create mode 100644 proxmox-ve-config/src/sdn/route_map.rs proxmox-perl-rs: Stefan Hanreich (3): pve-rs: sdn: add route maps module pve-rs: sdn: add prefix lists module sdn: add prefix list / route maps to frr config generation helper pve-rs/Cargo.toml | 1 + pve-rs/Makefile | 2 + pve-rs/src/bindings/sdn/mod.rs | 30 ++- pve-rs/src/bindings/sdn/prefix_lists.rs | 199 +++++++++++++++++++ pve-rs/src/bindings/sdn/route_maps.rs | 243 ++++++++++++++++++++++++ 5 files changed, 472 insertions(+), 3 deletions(-) create mode 100644 pve-rs/src/bindings/sdn/prefix_lists.rs create mode 100644 pve-rs/src/bindings/sdn/route_maps.rs pve-network: Stefan Hanreich (13): controller: bgp: evpn: adapt to new match / set frr config syntax sdn: add prefix lists module api2: add prefix list module sdn: add route map module api2: add route maps api module api2: add route map module api2: add route map entry module evpn controller: add route_map_{in,out} parameter sdn: generate route map / prefix list configuration on sdn apply tests: add simple route map test case tests: add bgp evpn route map/prefix list testcase tests: add route map with prefix list testcase bgp controller: allow configuring custom route maps src/PVE/API2/Network/SDN.pm | 14 + src/PVE/API2/Network/SDN/Makefile | 13 +- src/PVE/API2/Network/SDN/PrefixLists.pm | 247 ++++++++++++++++++ src/PVE/API2/Network/SDN/RouteMaps.pm | 137 ++++++++++ src/PVE/API2/Network/SDN/RouteMaps/Makefile | 9 + .../API2/Network/SDN/RouteMaps/RouteMap.pm | 92 +++++++ .../Network/SDN/RouteMaps/RouteMapEntry.pm | 136 ++++++++++ src/PVE/Network/SDN.pm | 14 +- src/PVE/Network/SDN/Controllers/BgpPlugin.pm | 22 +- src/PVE/Network/SDN/Controllers/EvpnPlugin.pm | 43 +-- src/PVE/Network/SDN/Controllers/Plugin.pm | 14 + src/PVE/Network/SDN/Makefile | 14 +- src/PVE/Network/SDN/PrefixLists.pm | 134 ++++++++++ src/PVE/Network/SDN/RouteMaps.pm | 173 ++++++++++++ .../expected_controller_config | 76 ++++++ .../expected_sdn_interfaces | 41 +++ .../bgp_evpn_routemap_prefix_list/interfaces | 7 + .../bgp_evpn_routemap_prefix_list/sdn_config | 86 ++++++ .../evpn/routemap/expected_controller_config | 60 +++++ .../evpn/routemap/expected_sdn_interfaces | 41 +++ src/test/zones/evpn/routemap/interfaces | 7 + src/test/zones/evpn/routemap/sdn_config | 70 +++++ .../expected_controller_config | 49 ++++ .../expected_sdn_interfaces | 41 +++ .../evpn/routemap_prefix_list/interfaces | 7 + .../evpn/routemap_prefix_list/sdn_config | 58 ++++ 26 files changed, 1572 insertions(+), 33 deletions(-) create mode 100644 src/PVE/API2/Network/SDN/PrefixLists.pm create mode 100644 src/PVE/API2/Network/SDN/RouteMaps.pm create mode 100644 src/PVE/API2/Network/SDN/RouteMaps/Makefile create mode 100644 src/PVE/API2/Network/SDN/RouteMaps/RouteMap.pm create mode 100644 src/PVE/API2/Network/SDN/RouteMaps/RouteMapEntry.pm create mode 100644 src/PVE/Network/SDN/PrefixLists.pm create mode 100644 src/PVE/Network/SDN/RouteMaps.pm create mode 100644 src/test/zones/evpn/bgp_evpn_routemap_prefix_list/expected_controller_config create mode 100644 src/test/zones/evpn/bgp_evpn_routemap_prefix_list/expected_sdn_interfaces create mode 100644 src/test/zones/evpn/bgp_evpn_routemap_prefix_list/interfaces create mode 100644 src/test/zones/evpn/bgp_evpn_routemap_prefix_list/sdn_config create mode 100644 src/test/zones/evpn/routemap/expected_controller_config create mode 100644 src/test/zones/evpn/routemap/expected_sdn_interfaces create mode 100644 src/test/zones/evpn/routemap/interfaces create mode 100644 src/test/zones/evpn/routemap/sdn_config create mode 100644 src/test/zones/evpn/routemap_prefix_list/expected_controller_config create mode 100644 src/test/zones/evpn/routemap_prefix_list/expected_sdn_interfaces create mode 100644 src/test/zones/evpn/routemap_prefix_list/interfaces create mode 100644 src/test/zones/evpn/routemap_prefix_list/sdn_config Summary over all repositories: 44 files changed, 3456 insertions(+), 101 deletions(-) -- Generated by git-murpp 0.8.0