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 535E91FF13F for ; Thu, 26 Mar 2026 14:49:56 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id BA83A13F12; Thu, 26 Mar 2026 14:50:18 +0100 (CET) Message-ID: <5f7928c1-8b78-4901-9e08-3860b98f7bcb@proxmox.com> Date: Thu, 26 Mar 2026 14:50:14 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH proxmox-ve-rs 8/9] ve-config: frr: implement frr config generation for route maps To: pve-devel@lists.proxmox.com References: <20260325094142.174364-1-s.hanreich@proxmox.com> <20260325094142.174364-11-s.hanreich@proxmox.com> Content-Language: en-US From: Stefan Hanreich In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.714 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 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: IZTGIQF44CXBYQMFKTY47UT245MPK7NB X-Message-ID-Hash: IZTGIQF44CXBYQMFKTY47UT245MPK7NB 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: On 3/25/26 4:02 PM, Gabriel Goller wrote: > On 25.03.2026 10:41, Stefan Hanreich wrote: >> Implements conversion traits for all the section config types, so they >> can be converted into their respective FRR template counterpart. >> >> This module contains a helper for adding all route map entries to an >> existing FRR configuration. It will overwrite existing route map >> entries that have the same name AND order number. But if entries with >> the same name, but different ordering, exist they will only be added >> to the existing FRR configuration without dropping the other route map >> entries. >> This currently not relevant either way, because the initial API >> implementation will reject creating route maps with names of route >> maps that the stack auto-generates. In the future this behavior can >> be used for selectively overriding / appending existing Proxmox VE >> route maps. >> >> The helper also automatically orders route map entries according to >> their ordering number. This allows for deterministic FRR configuration >> output, which is important for tests and convenient for human >> readability. >> >> Signed-off-by: Stefan Hanreich >> --- >> proxmox-ve-config/src/sdn/route_map.rs | 271 +++++++++++++++++++++++++ >> 1 file changed, 271 insertions(+) >> >> diff --git a/proxmox-ve-config/src/sdn/route_map.rs b/proxmox-ve-config/src/sdn/route_map.rs >> index 3f4da56..8d8c4dc 100644 >> --- a/proxmox-ve-config/src/sdn/route_map.rs >> +++ b/proxmox-ve-config/src/sdn/route_map.rs > [snip] >> + impl Into for MatchAction { >> + fn into(self) -> RouteMapMatch { >> + match self { >> + Self::RouteType(evpn_route_type) => RouteMapMatch::RouteType(evpn_route_type), >> + Self::Vni(vni) => RouteMapMatch::Vni(vni), >> + Self::IpAddressPrefixList(prefix_list_name) => { >> + RouteMapMatch::IpAddressPrefixList(prefix_list_name.into()) >> + } >> + Self::Ip6AddressPrefixList(prefix_list_name) => { >> + RouteMapMatch::Ip6AddressPrefixList(prefix_list_name.into()) >> + } >> + Self::IpNextHopPrefixList(prefix_list_name) => { >> + RouteMapMatch::IpNextHopPrefixList(prefix_list_name.into()) >> + } >> + Self::Ip6NextHopPrefixList(prefix_list_name) => { >> + RouteMapMatch::Ip6NextHopPrefixList(prefix_list_name.into()) >> + } >> + Self::IpNextHopAddress(ipv4_addr) => RouteMapMatch::IpNextHopAddress(*ipv4_addr), >> + Self::Ip6NextHopAddress(ipv6_addr) => RouteMapMatch::Ip6NextHopAddress(*ipv6_addr), >> + Self::Metric(metric) => RouteMapMatch::Metric(metric), >> + Self::LocalPreference(local_preference) => { >> + RouteMapMatch::LocalPreference(local_preference) >> + } >> + Self::Peer(ip_addr) => RouteMapMatch::Peer(ip_addr), >> + Self::Tag(tag) => RouteMapMatch::Tag(tag), >> + } >> + } >> + } >> + >> + impl Into for SetAction { >> + fn into(self) -> RouteMapSet { >> + match self { >> + Self::IpNextHopPeerAddress => RouteMapSet::IpNextHopPeerAddress, >> + Self::IpNextHopUnchanged => RouteMapSet::IpNextHopUnchanged, >> + Self::IpNextHop(ipv4_addr) => RouteMapSet::IpNextHop(*ipv4_addr), >> + Self::Ip6NextHopPeerAddress => RouteMapSet::Ip6NextHopPeerAddress, >> + Self::Ip6NextHopPreferGlobal => RouteMapSet::Ip6NextHopPreferGlobal, >> + Self::Ip6NextHop(ipv6_addr) => RouteMapSet::Ip6NextHop(*ipv6_addr), >> + Self::LocalPreference(local_preference) => { >> + RouteMapSet::LocalPreference(local_preference) >> + } >> + Self::Tag(tag) => RouteMapSet::Tag(tag), >> + Self::Weight(weight) => RouteMapSet::Weight(weight), >> + Self::Metric(metric) => RouteMapSet::Metric(metric), >> + Self::Src(src) => RouteMapSet::Src(src), >> + } >> + } >> + } >> + >> + impl Into for RouteMapEntry { >> + fn into(self) -> FrrRouteMap { >> + FrrRouteMap { >> + seq: self.id.order, >> + action: match self.action { >> + RouteMapAction::Permit => proxmox_frr::ser::route_map::AccessAction::Permit, >> + RouteMapAction::Deny => proxmox_frr::ser::route_map::AccessAction::Deny, >> + }, >> + matches: self >> + .match_actions >> + .into_iter() >> + .map(|match_action| match_action.into_inner().into()) >> + .collect(), >> + sets: self >> + .set_actions >> + .into_iter() >> + .map(|set_action| set_action.into_inner().into()) >> + .collect(), >> + custom_frr_config: Default::default(), >> + } >> + } >> + } > > These impls above could be From<>, even though we never need the other direction > :) clippy otherwise complains. fixed this - thanks!