bgpkit_parser/models/bgp/
mod.rs1pub mod attributes;
4pub mod capabilities;
5pub mod community;
6pub mod elem;
7pub mod error;
8pub mod flowspec;
9pub mod linkstate;
10pub mod role;
11pub mod tunnel_encap;
12
13pub use attributes::*;
14pub use community::*;
15pub use elem::*;
16pub use error::*;
17pub use flowspec::*;
18pub use linkstate::*;
19pub use role::*;
20pub use tunnel_encap::*;
21
22use crate::models::network::*;
23use capabilities::{
24 AddPathCapability, BgpCapabilityType, BgpExtendedMessageCapability, BgpRoleCapability,
25 ExtendedNextHopCapability, FourOctetAsCapability, GracefulRestartCapability,
26 MultiprotocolExtensionsCapability, RouteRefreshCapability,
27};
28use num_enum::{IntoPrimitive, TryFromPrimitive};
29use std::net::Ipv4Addr;
30
31pub type BgpIdentifier = Ipv4Addr;
32
33#[derive(Debug, TryFromPrimitive, IntoPrimitive, Copy, Clone, PartialEq, Hash)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35#[repr(u8)]
36pub enum BgpMessageType {
37 OPEN = 1,
38 UPDATE = 2,
39 NOTIFICATION = 3,
40 KEEPALIVE = 4,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq)]
45#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
46pub enum BgpMessage {
47 Open(BgpOpenMessage),
48 Update(BgpUpdateMessage),
49 Notification(BgpNotificationMessage),
50 KeepAlive,
51}
52
53impl BgpMessage {
54 pub const fn msg_type(&self) -> BgpMessageType {
55 match self {
56 BgpMessage::Open(_) => BgpMessageType::OPEN,
57 BgpMessage::Update(_) => BgpMessageType::UPDATE,
58 BgpMessage::Notification(_) => BgpMessageType::NOTIFICATION,
59 BgpMessage::KeepAlive => BgpMessageType::KEEPALIVE,
60 }
61 }
62}
63
64#[derive(Debug, Clone, PartialEq, Eq)]
86#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
87pub struct BgpOpenMessage {
88 pub version: u8,
89 pub asn: Asn,
90 pub hold_time: u16,
91 pub sender_ip: Ipv4Addr,
92 pub extended_length: bool,
93 pub opt_params: Vec<OptParam>,
94}
95
96#[derive(Debug, Clone, PartialEq, Eq)]
97#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
98pub struct OptParam {
99 pub param_type: u8,
100 pub param_len: u16,
101 pub param_value: ParamValue,
102}
103
104#[derive(Debug, Clone, PartialEq, Eq)]
105#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
106pub enum ParamValue {
107 Raw(Vec<u8>),
108 Capacities(Vec<Capability>),
109}
110
111#[derive(Debug, Clone, PartialEq, Eq)]
116#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
117pub struct Capability {
118 pub ty: BgpCapabilityType,
119 pub value: CapabilityValue,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
124#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
125pub enum CapabilityValue {
126 Raw(Vec<u8>),
128 MultiprotocolExtensions(MultiprotocolExtensionsCapability),
130 RouteRefresh(RouteRefreshCapability),
132 ExtendedNextHop(ExtendedNextHopCapability),
134 GracefulRestart(GracefulRestartCapability),
136 FourOctetAs(FourOctetAsCapability),
138 AddPath(AddPathCapability),
140 BgpRole(BgpRoleCapability),
142 BgpExtendedMessage(BgpExtendedMessageCapability),
144}
145
146#[derive(Debug, Clone, PartialEq, Default, Eq)]
147#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
148pub struct BgpUpdateMessage {
152 pub withdrawn_prefixes: Vec<NetworkPrefix>,
166
167 pub attributes: Attributes,
169
170 pub announced_prefixes: Vec<NetworkPrefix>,
185}
186
187#[derive(Debug, Clone, PartialEq, Eq)]
188#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
189pub struct BgpNotificationMessage {
190 pub error: BgpError,
191 pub data: Vec<u8>,
192}
193
194#[cfg(test)]
195mod tests {
196 use super::*;
197
198 #[test]
199 fn test_message_type() {
200 let open = BgpMessage::Open(BgpOpenMessage {
201 version: 4,
202 asn: Asn::new_32bit(1),
203 hold_time: 180,
204 sender_ip: Ipv4Addr::new(192, 0, 2, 1),
205 extended_length: false,
206 opt_params: vec![],
207 });
208 assert_eq!(open.msg_type(), BgpMessageType::OPEN);
209
210 let update = BgpMessage::Update(BgpUpdateMessage::default());
211 assert_eq!(update.msg_type(), BgpMessageType::UPDATE);
212
213 let notification = BgpMessage::Notification(BgpNotificationMessage {
214 error: BgpError::Unknown(0, 0),
215 data: vec![],
216 });
217 assert_eq!(notification.msg_type(), BgpMessageType::NOTIFICATION);
218
219 let keepalive = BgpMessage::KeepAlive;
220 assert_eq!(keepalive.msg_type(), BgpMessageType::KEEPALIVE);
221 }
222
223 #[test]
224 #[cfg(feature = "serde")]
225 fn test_serde() {
226 let open = BgpMessage::Open(BgpOpenMessage {
227 version: 4,
228 asn: Asn::new_32bit(1),
229 hold_time: 180,
230 sender_ip: Ipv4Addr::new(192, 0, 2, 1),
231 extended_length: false,
232 opt_params: vec![],
233 });
234 let serialized = serde_json::to_string(&open).unwrap();
235 let deserialized: BgpMessage = serde_json::from_str(&serialized).unwrap();
236 assert_eq!(open, deserialized);
237
238 let update = BgpMessage::Update(BgpUpdateMessage::default());
239 let serialized = serde_json::to_string(&update).unwrap();
240 let deserialized: BgpMessage = serde_json::from_str(&serialized).unwrap();
241 assert_eq!(update, deserialized);
242
243 let notification = BgpMessage::Notification(BgpNotificationMessage {
244 error: BgpError::Unknown(0, 0),
245 data: vec![],
246 });
247 let serialized = serde_json::to_string(¬ification).unwrap();
248 let deserialized: BgpMessage = serde_json::from_str(&serialized).unwrap();
249 assert_eq!(notification, deserialized);
250
251 let keepalive = BgpMessage::KeepAlive;
252 let serialized = serde_json::to_string(&keepalive).unwrap();
253 let deserialized: BgpMessage = serde_json::from_str(&serialized).unwrap();
254 assert_eq!(keepalive, deserialized);
255 }
256}