From: Stefan Hanreich <s.hanreich@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH proxmox-ve-rs 6/6] frr: add deserialization types for EVPN
Date: Thu, 30 Oct 2025 16:48:15 +0100	[thread overview]
Message-ID: <20251030154851.540408-9-s.hanreich@proxmox.com> (raw)
In-Reply-To: <20251030154851.540408-1-s.hanreich@proxmox.com>
From: Gabriel Goller <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>
Signed-off-by: Stefan Hanreich <s.hanreich@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 8ada547..1b241a0 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 bce0c70..3a73732 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 0000000..97faca4
--- /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: Option<bool>,
+    /// Reason for selection (longer explanatory string)
+    #[serde(rename = "selectionReason")]
+    pub selection_reason: Option<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 dd9f058..121451b 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.3
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply	other threads:[~2025-10-30 15:50 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-30 15:48 [pve-devel] [PATCH common/manager/network/proxmox{-ve-rs, -perl-rs} 00/35] Improve status reporting for SDN / networking Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-common 1/2] iproute2: add helper for detecting bridge members Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-common 2/2] iproute2: add helper for querying vlan information Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-ve-rs 1/6] frr: make room for deserialization structs Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-ve-rs 2/6] frr: add deserialization types for openfabric and ospf Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-ve-rs 3/6] ve-config: add helper function to iterate over all nodes in all fabrics Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-ve-rs 4/6] ve-config: add optional tag property to vnet Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-ve-rs 5/6] frr: fix some route deserialization types Stefan Hanreich
2025-10-30 15:48 ` Stefan Hanreich [this message]
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 01/10] pve-rs: firewall: cargo: fmt Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 02/10] pve-rs: firewall: add missing documentation comments Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 03/10] pve-rs: cargo: bump proxmox-apt and proxmox-ve-config versions Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 04/10] pve-rs: fabrics: update proxmox-frr import path Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 05/10] pve-rs: fabrics: fix clippy lint warnings Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 06/10] pve-rs: fabrics: add function to get status of fabric Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 07/10] pve-rs: fabrics: add function to get l2vpn and l3vpn routes for evpn Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 08/10] pve-rs: fabrics: add function to get routes learned by a fabric Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 09/10] pve-rs: fabrics: add function to get the interfaces used for " Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH proxmox-perl-rs 10/10] pve-rs: fabrics: add function to get the neighbors " Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 1/9] refactor: rework api module structure for the /nodes/{node}/sdn subdir Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 2/9] fabrics: add fabrics status to SDN::status function Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 3/9] sdn: status: add zone type to sdn resource Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 4/9] api: nodes: fabrics: add endpoint for querying route status Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 5/9] api: nodes: fabrics: add endpoint for querying neighbor information Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 6/9] api: nodes: fabrics: add endpoint for querying interface status Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 7/9] api: nodes: zones: add bridge status Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 8/9] api: nodes: zones: add ip vrf endpoint for evpn zones Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-network 9/9] api: nodes: vnets: add mac-vrf endpoint for evpn vnets Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 1/8] api: nodes: use new status module for sdn subdirectory Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 2/8] refactor: ui: sdn browser: parametrize zone content panel Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 3/8] pvestatd: add network resource to status reporting Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 4/8] pvestatd: sdn: adapt to changes in " Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 5/8] ui: resource tree: add network resource Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 6/8] ui: sdn browser: Add ip-vrf panel for evpn zones Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 7/8] ui: sdn browser: add mac vrf panel Stefan Hanreich
2025-10-30 15:48 ` [pve-devel] [PATCH pve-manager 8/8] ui: sdn browser: add zone bridge view Stefan Hanreich
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=20251030154851.540408-9-s.hanreich@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