public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Gabriel Goller <g.goller@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH proxmox-ve-rs 3/3] frr: add deserialization types for EVPN
Date: Fri,  5 Sep 2025 13:44:58 +0200	[thread overview]
Message-ID: <20250905114504.195110-4-g.goller@proxmox.com> (raw)
In-Reply-To: <20250905114504.195110-1-g.goller@proxmox.com>

Add deserialization types for the `show bgp l2vpn evpn route vni <vni>`
command. This command shows all the L2VPN (EVPN) routes that are
distributed over BGP.

Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
---
 proxmox-frr/Cargo.toml     |   1 +
 proxmox-frr/debian/control |   2 +
 proxmox-frr/src/de/evpn.rs | 165 +++++++++++++++++++++++++++++++++++++
 proxmox-frr/src/de/mod.rs  |   1 +
 4 files changed, 169 insertions(+)
 create mode 100644 proxmox-frr/src/de/evpn.rs

diff --git a/proxmox-frr/Cargo.toml b/proxmox-frr/Cargo.toml
index 8ada547301e8..1b241a03e60d 100644
--- a/proxmox-frr/Cargo.toml
+++ b/proxmox-frr/Cargo.toml
@@ -14,6 +14,7 @@ thiserror = { workspace = true }
 anyhow = "1"
 tracing = "0.1"
 serde = { workspace = true, features = [ "derive" ] }
+serde_repr = "0.1"
 
 proxmox-network-types = { workspace = true }
 proxmox-sdn-types = { workspace = true }
diff --git a/proxmox-frr/debian/control b/proxmox-frr/debian/control
index bce0c709b13e..3a73732de962 100644
--- a/proxmox-frr/debian/control
+++ b/proxmox-frr/debian/control
@@ -11,6 +11,7 @@ Build-Depends-Arch: cargo:native <!nocheck>,
  librust-proxmox-sdn-types-0.1+default-dev <!nocheck>,
  librust-serde-1+default-dev <!nocheck>,
  librust-serde-1+derive-dev <!nocheck>,
+ librust-serde-repr-0.1+default-dev <!nocheck>,
  librust-thiserror-2+default-dev <!nocheck>,
  librust-tracing-0.1+default-dev <!nocheck>
 Maintainer: Proxmox Support Team <support@proxmox.com>
@@ -31,6 +32,7 @@ Depends:
  librust-proxmox-sdn-types-0.1+default-dev,
  librust-serde-1+default-dev,
  librust-serde-1+derive-dev,
+ librust-serde-repr-0.1+default-dev,
  librust-thiserror-2+default-dev,
  librust-tracing-0.1+default-dev
 Provides:
diff --git a/proxmox-frr/src/de/evpn.rs b/proxmox-frr/src/de/evpn.rs
new file mode 100644
index 000000000000..bbc44c9a9522
--- /dev/null
+++ b/proxmox-frr/src/de/evpn.rs
@@ -0,0 +1,165 @@
+use std::{collections::HashMap, net::IpAddr};
+
+use proxmox_network_types::mac_address::MacAddress;
+use serde::Deserialize;
+use serde_repr::Deserialize_repr;
+
+/// All EVPN routes
+#[derive(Debug, Default, Deserialize)]
+pub struct Routes(pub HashMap<String, Entry>);
+
+/// The evpn routes a stored in a hashtable, which has a numPrefix and numPath key at
+/// the end which stores the number of paths and prefixes. These two keys have a i32
+/// value, while the other entries have a normal [`Route`] entry.
+#[derive(Debug, Deserialize)]
+#[serde(untagged)]
+pub enum Entry {
+    /// Route
+    Route(Route),
+    // This stores the numPrefix and numPath properties (which are not used) (this is
+    // a workaround)
+    Metadata(i32),
+}
+
+/// An EVPN route
+#[derive(Debug, Deserialize)]
+pub struct Route {
+    /// The full EVPN prefix
+    pub prefix: String,
+    /// Length of the prefix
+    #[serde(rename = "prefixLen")]
+    pub prefix_len: i32,
+    /// Paths to the EVPN route
+    pub paths: Vec<Vec<Path>>,
+}
+
+/// An EVPN Route Path
+#[derive(Debug, Deserialize)]
+pub struct Path {
+    /// Is this path valid
+    pub valid: bool,
+    /// Is this the best path
+    pub bestpath: bool,
+    /// Reason for selection (longer explanatory string)
+    #[serde(rename = "selectionReason")]
+    pub selection_reason: String,
+    /// From where the EVPN Route path comes
+    #[serde(rename = "pathFrom")]
+    pub path_from: PathFrom,
+    /// EVPN route type
+    #[serde(rename = "routeType")]
+    pub route_type: RouteType,
+    /// Ethernet tag
+    #[serde(rename = "ethTag")]
+    pub ethernet_tag: i32,
+    /// Mac Address length
+    #[serde(rename = "macLen")]
+    pub mac_length: Option<i32>,
+    /// Mac Address
+    pub mac: Option<MacAddress>,
+    /// IP Address lenght
+    #[serde(rename = "ipLen")]
+    pub ip_length: Option<i32>,
+    /// IP Address
+    pub ip: Option<IpAddr>,
+    /// Local Preference of the path
+    #[serde(rename = "locPrf")]
+    pub local_preference: Option<i32>,
+    /// Weight of the path
+    pub weight: i32,
+    /// PeerId, can be either IP or unspecified
+    #[serde(rename = "peerId")]
+    pub peer_id: PeerId,
+    /// AS path of the EVPN route
+    #[serde(rename = "path")]
+    pub as_path: String,
+    /// Origin of the route
+    pub origin: Origin,
+    /// Extended BGP Community
+    #[serde(rename = "extendedCommunity")]
+    pub extended_community: ExtendedCommunity,
+    /// Nexthops
+    pub nexthops: Vec<Nexthop>,
+}
+
+/// PeerId of the EVPN route path
+#[derive(Debug, Deserialize)]
+#[serde(untagged)]
+pub enum PeerId {
+    /// IP Address
+    IpAddr(IpAddr),
+    /// Not specified
+    Unspec(String),
+}
+
+/// Nexthop of a EVPN path
+#[derive(Debug, Deserialize)]
+pub struct Nexthop {
+    /// IP of the nexthop
+    pub ip: IpAddr,
+    /// Hostname of the nexthop
+    pub hostname: String,
+    /// Afi of the ip
+    pub afi: Option<Protocol>,
+    /// Used
+    pub used: bool,
+}
+
+/// Protocol AFI for a EVPN nexthop
+#[derive(Debug, Deserialize)]
+pub enum Protocol {
+    /// IPV4
+    #[serde(rename = "ipv4")]
+    IPv4,
+    /// IPV6
+    #[serde(rename = "ipv6")]
+    IPv6,
+}
+
+/// Extended Community for EVPN route
+#[derive(Debug, Deserialize)]
+pub struct ExtendedCommunity {
+    /// String with all the BGP ExtendedCommunities (this also contains the
+    /// RouteTarget)
+    pub string: String,
+}
+
+/// Origin of the EVPN route
+#[derive(Debug, Deserialize)]
+pub enum Origin {
+    /// Interior Gateway Protocol
+    #[serde(rename = "IGP")]
+    Igp,
+    #[serde(rename = "EGP")]
+    /// Exterior Gateway Protocol
+    Egp,
+    #[serde(rename = "incomplete")]
+    /// Incomplete
+    Incomplete,
+}
+
+/// EVPN RouteType
+#[derive(Debug, Deserialize_repr)]
+#[repr(u8)]
+pub enum RouteType {
+    /// EthernetAutoDiscovery
+    EthernetAutoDiscovery = 1,
+    /// MacIpAdvertisement
+    MacIpAdvertisement = 2,
+    /// InclusiveMulticastEthernetTag
+    InclusiveMulticastEthernetTag = 3,
+    /// EthernetSegment
+    EthernetSegment = 4,
+    /// IpPrefix
+    IpPrefix = 5,
+}
+
+/// From where the EVPN route path comes
+#[derive(Debug, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum PathFrom {
+    /// Internal
+    Internal,
+    /// External
+    External,
+}
diff --git a/proxmox-frr/src/de/mod.rs b/proxmox-frr/src/de/mod.rs
index 2771a1c36661..c0f262e410ee 100644
--- a/proxmox-frr/src/de/mod.rs
+++ b/proxmox-frr/src/de/mod.rs
@@ -3,6 +3,7 @@ use std::{collections::HashMap, net::IpAddr};
 use proxmox_network_types::ip_address::Cidr;
 use serde::{Deserialize, Serialize};
 
+pub mod evpn;
 pub mod openfabric;
 pub mod ospf;
 
-- 
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  parent reply	other threads:[~2025-09-05 11:45 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-05 11:44 [pve-devel] [PATCH network/proxmox{-ve-rs, -perl-rs} 0/6] Add status endpoints for EVPN statistics Gabriel Goller
2025-09-05 11:44 ` [pve-devel] [PATCH proxmox-ve-rs 1/3] ve-config: add optional tag property to vnet Gabriel Goller
2025-09-05 11:44 ` [pve-devel] [PATCH proxmox-ve-rs 2/3] frr: fix some route deserialization types Gabriel Goller
2025-09-05 11:44 ` Gabriel Goller [this message]
2025-09-05 11:44 ` [pve-devel] [PATCH proxmox-perl-rs 1/2] pve-rs: sdn: fabrics: update openfabric/ospf route filtering Gabriel Goller
2025-09-05 11:45 ` [pve-devel] [PATCH proxmox-perl-rs 2/2] pve-rs: sdn: add functions to retrieve the Zone/Vnet routes Gabriel Goller
2025-09-05 11:45 ` [pve-devel] [PATCH pve-network 1/1] sdn: add vnet and zone status endpoints 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=20250905114504.195110-4-g.goller@proxmox.com \
    --to=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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal