bgp_models/
network.rs

1//! Common network-related structs.
2
3use crate::err::BgpModelsError;
4use ipnet::IpNet;
5use serde::{Deserialize, Serialize, Serializer};
6use std::fmt::{Display, Formatter};
7use std::net::{Ipv4Addr, Ipv6Addr};
8use std::str::FromStr;
9
10/// Meta information for an address/prefix.
11///
12/// [AddrMeta] is a struct that used to save address family and as number length information
13/// when parsing [TableDumpMessage].
14///
15/// The meta information includes:
16/// 1. `afi`: address family ([Afi]): IPv4 or IPv6,
17/// 2. `asn_len`: AS number length ([AsnLength]): 16 or 32 bits.
18#[derive(Debug, Clone, Serialize, Copy)]
19pub struct AddrMeta {
20    pub afi: Afi,
21    pub asn_len: AsnLength,
22}
23
24/// AS number length: 16 or 32 bits.
25#[derive(Debug, Clone, Serialize, Copy, Deserialize, PartialEq, Eq)]
26pub enum AsnLength {
27    Bits16,
28    Bits32,
29}
30
31/// ASN -- Autonomous System Number
32#[derive(Debug, Clone, Copy, Eq)]
33pub struct Asn {
34    pub asn: u32,
35    pub len: AsnLength,
36}
37
38impl PartialEq for Asn {
39    fn eq(&self, other: &Self) -> bool {
40        self.asn == other.asn
41    }
42}
43
44impl PartialEq<i32> for Asn {
45    fn eq(&self, other: &i32) -> bool {
46        self.asn as i32 == *other
47    }
48}
49
50impl PartialEq<u32> for Asn {
51    fn eq(&self, other: &u32) -> bool {
52        self.asn == *other
53    }
54}
55
56impl From<u32> for Asn {
57    fn from(v: u32) -> Self {
58        Asn {
59            asn: v,
60            len: AsnLength::Bits32,
61        }
62    }
63}
64
65impl From<i32> for Asn {
66    fn from(v: i32) -> Self {
67        Asn {
68            asn: v as u32,
69            len: AsnLength::Bits32,
70        }
71    }
72}
73
74impl From<Asn> for i32 {
75    fn from(val: Asn) -> Self {
76        val.asn as i32
77    }
78}
79
80impl From<Asn> for u32 {
81    fn from(value: Asn) -> Self {
82        value.asn
83    }
84}
85
86impl Serialize for Asn {
87    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
88    where
89        S: Serializer,
90    {
91        serializer.serialize_u32(self.asn)
92    }
93}
94
95/// AFI -- Address Family Identifier
96///
97/// https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml
98#[derive(Debug, PartialEq, Primitive, Clone, Copy, Serialize, Eq)]
99pub enum Afi {
100    Ipv4 = 1,
101    Ipv6 = 2,
102}
103
104/// SAFI -- Subsequent Address Family Identifier
105///
106/// SAFI can be: Unicast, Multicast, or both.
107#[derive(Debug, PartialEq, Primitive, Clone, Copy, Serialize, Eq)]
108pub enum Safi {
109    Unicast = 1,
110    Multicast = 2,
111    UnicastMulticast = 3,
112}
113
114/// enum that represents the type of the next hop address.
115///
116/// [NextHopAddress] is used when parsing for next hops in [Nlri].
117#[derive(Debug, PartialEq, Copy, Clone, Serialize, Eq)]
118pub enum NextHopAddress {
119    Ipv4(Ipv4Addr),
120    Ipv6(Ipv6Addr),
121    Ipv6LinkLocal(Ipv6Addr, Ipv6Addr),
122}
123
124/// A representation of a IP prefix with optional path ID.
125#[derive(Debug, PartialEq, Eq, Clone, Copy)]
126pub struct NetworkPrefix {
127    pub prefix: IpNet,
128    pub path_id: u32,
129}
130
131impl Serialize for NetworkPrefix {
132    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
133    where
134        S: Serializer,
135    {
136        serializer.serialize_str(self.to_string().as_str())
137    }
138}
139
140impl FromStr for NetworkPrefix {
141    type Err = BgpModelsError;
142
143    fn from_str(s: &str) -> Result<Self, Self::Err> {
144        let prefix = IpNet::from_str(s)?;
145        Ok(NetworkPrefix { prefix, path_id: 0 })
146    }
147}
148
149impl NetworkPrefix {
150    pub fn new(prefix: IpNet, path_id: u32) -> NetworkPrefix {
151        NetworkPrefix { prefix, path_id }
152    }
153}
154
155impl Display for NetworkPrefix {
156    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
157        write!(f, "{}", self.prefix)
158    }
159}
160
161impl Display for Asn {
162    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
163        write!(f, "{}", self.asn)
164    }
165}