From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 561851FF0AA for ; Fri, 21 Aug 2026 16:04:15 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 92FFC2161E; Fri, 21 Aug 2026 16:04:14 +0200 (CEST) From: Gabriel Goller To: pve-devel@lists.proxmox.com Subject: [PATCH proxmox-ve-rs 01/15] frr: add VRF-aware OSPF rendering Date: Fri, 21 Aug 2026 16:03:45 +0200 Message-ID: <20260821140404.322081-2-g.goller@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260821140404.322081-1-g.goller@proxmox.com> References: <20260821140404.322081-1-g.goller@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1787321022565 X-SPAM-LEVEL: Spam detection results: 0 AWL 1.102 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust 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: OM6MA5NIPTRTV3WBBJM4IAQF7ZMQVHBJ X-Message-ID-Hash: OM6MA5NIPTRTV3WBBJM4IAQF7ZMQVHBJ X-MailFrom: g.goller@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: Add an optional VRF name and render it in the FRR interface declaration. Keep OSPF router configuration for custom VRFs separately from the router in the default routing table (like we do with BGP). Signed-off-by: Gabriel Goller --- proxmox-frr-templates/templates/fabricd.jinja | 2 +- proxmox-frr-templates/templates/interface.jinja | 6 +++++- proxmox-frr-templates/templates/isisd.jinja | 2 +- proxmox-frr-templates/templates/ospfd.jinja | 12 +++++++++++- proxmox-frr/debian/control | 8 ++++---- proxmox-frr/src/ser/mod.rs | 6 ++++++ 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/proxmox-frr-templates/templates/fabricd.jinja b/proxmox-frr-templates/templates/fabricd.jinja index 068959a97e0e..04283180679e 100644 --- a/proxmox-frr-templates/templates/fabricd.jinja +++ b/proxmox-frr-templates/templates/fabricd.jinja @@ -6,7 +6,7 @@ router openfabric {{ router_name }} exit {% endfor %} {% for interface_name, interface_config in openfabric.interfaces|items %} -{% call interface(interface_name, interface_config.addresses_v4, interface_config.addresses_v6) %} +{% call interface(interface_name, interface_config.addresses_v4, interface_config.addresses_v6, interface_config.vrf) %} {% if interface_config.fabric_id and interface_config.is_ipv4 %} ip router openfabric {{ interface_config.fabric_id }} {% endif %} diff --git a/proxmox-frr-templates/templates/interface.jinja b/proxmox-frr-templates/templates/interface.jinja index 4c5014844fc8..e52b05681bb8 100644 --- a/proxmox-frr-templates/templates/interface.jinja +++ b/proxmox-frr-templates/templates/interface.jinja @@ -1,6 +1,10 @@ -{% macro interface(name, addresses_v4, addresses_v6) %} +{% macro interface(name, addresses_v4, addresses_v6, vrf) %} ! +{% if vrf %} +interface {{ name }} vrf {{ vrf }} +{% else %} interface {{ name }} +{% endif %} {% for address in addresses_v6 %} ipv6 address {{address}} {% endfor %} diff --git a/proxmox-frr-templates/templates/isisd.jinja b/proxmox-frr-templates/templates/isisd.jinja index e3c9292d575c..2d369d75eee6 100644 --- a/proxmox-frr-templates/templates/isisd.jinja +++ b/proxmox-frr-templates/templates/isisd.jinja @@ -20,7 +20,7 @@ router isis {{ router_name }} exit {% endfor %} {% for interface_name, interface_config in isis.interfaces|items %} -{% call interface(interface_name, interface_config.addresses_v4, interface_config.addresses_v6) %} +{% call interface(interface_name, interface_config.addresses_v4, interface_config.addresses_v6, interface_config.vrf) %} {% if interface_config.domain and interface_config.is_ipv4 %} ip router isis {{ interface_config.domain }} {% endif %} diff --git a/proxmox-frr-templates/templates/ospfd.jinja b/proxmox-frr-templates/templates/ospfd.jinja index 427ed7f9ddb4..5d440f2ff663 100644 --- a/proxmox-frr-templates/templates/ospfd.jinja +++ b/proxmox-frr-templates/templates/ospfd.jinja @@ -9,8 +9,18 @@ router ospf {% endfor %} exit {% endif %} +{% for vrf_name, router in ospf.vrf_router|items %} +! +router ospf vrf {{ vrf_name }} + ospf router-id {{ router.router_id }} +{% for redistribution in router.redistribute %} + redistribute {{ redistribution.source }}{% if redistribution.metric is defined %} metric {{ redistribution.metric }}{% endif %}{% if redistribution.route_map is defined %} route-map {{ redistribution.route_map }}{% endif %} + +{% endfor %} +exit +{% endfor %} {% for interface_name, interface_config in ospf.interfaces|items %} -{% call interface(interface_name, interface_config.addresses_v4, interface_config.addresses_v6) %} +{% call interface(interface_name, interface_config.addresses_v4, interface_config.addresses_v6, interface_config.vrf) %} ip ospf area {{ interface_config.area }} {% if interface_config.passive %} ip ospf passive diff --git a/proxmox-frr/debian/control b/proxmox-frr/debian/control index b118becedeea..183472b32d5e 100644 --- a/proxmox-frr/debian/control +++ b/proxmox-frr/debian/control @@ -10,8 +10,8 @@ Build-Depends-Arch: cargo:native , librust-minijinja-2+default-dev (>= 2.5-~~) , librust-minijinja-2+loader-dev (>= 2.5-~~) , librust-minijinja-2+multi-template-dev (>= 2.5-~~) , - librust-proxmox-network-types-1+api-types-dev (>= 1.0.1-~~) , - librust-proxmox-network-types-1+default-dev (>= 1.0.1-~~) , + librust-proxmox-network-types-1+api-types-dev (>= 1.1.2-~~) , + librust-proxmox-network-types-1+default-dev (>= 1.1.2-~~) , librust-proxmox-sdn-types-0.2+default-dev , librust-proxmox-serde-1+default-dev , librust-proxmox-sortable-macro-1+default-dev , @@ -36,8 +36,8 @@ Depends: librust-minijinja-2+default-dev (>= 2.5-~~), librust-minijinja-2+loader-dev (>= 2.5-~~), librust-minijinja-2+multi-template-dev (>= 2.5-~~), - librust-proxmox-network-types-1+api-types-dev (>= 1.0.1-~~), - librust-proxmox-network-types-1+default-dev (>= 1.0.1-~~), + librust-proxmox-network-types-1+api-types-dev (>= 1.1.2-~~), + librust-proxmox-network-types-1+default-dev (>= 1.1.2-~~), librust-proxmox-sdn-types-0.2+default-dev, librust-proxmox-serde-1+default-dev, librust-proxmox-sortable-macro-1+default-dev, diff --git a/proxmox-frr/src/ser/mod.rs b/proxmox-frr/src/ser/mod.rs index b651121b4a82..22c503950ba3 100644 --- a/proxmox-frr/src/ser/mod.rs +++ b/proxmox-frr/src/ser/mod.rs @@ -146,6 +146,8 @@ pub struct Interface { pub addresses_v4: Vec, #[serde(default)] pub addresses_v6: Vec, + #[serde(default)] + pub vrf: Option, #[serde(flatten)] pub properties: T, @@ -155,6 +157,7 @@ impl From for Interface for Interface { Interface { addresses_v4: Vec::new(), addresses_v6: Vec::new(), + vrf: None, properties: value, } } @@ -259,6 +263,8 @@ pub struct OspfFrrConfig { #[serde(default)] pub router: Option, #[serde(default)] + pub vrf_router: BTreeMap, + #[serde(default)] pub interfaces: BTreeMap>, } -- 2.47.3