bgpkit_parser/models/bgp/
role.rs

1use num_enum::{IntoPrimitive, TryFromPrimitive};
2
3/// BGP Role
4///
5/// Defined in [RFC9234](https://www.iana.org/go/rfc9234).
6#[derive(Debug, TryFromPrimitive, IntoPrimitive, PartialEq, Eq, Hash, Copy, Clone)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[repr(u8)]
9pub enum BgpRole {
10    Provider = 0,
11    RouteServer = 1,
12    RouteServerClient = 2,
13    Customer = 3,
14    Peer = 4,
15}
16
17/// Validate the local-remote BGP Role pairs.
18///
19/// This function checks the role correctness by following the description in [Section 4.2 of RFC9234](https://www.rfc-editor.org/rfc/rfc9234.html#section-4.2).
20///
21/// The acceptable local-remote BGP pairs are:
22///
23/// Local AS Role | Remote AS Role
24/// --- | ---
25/// Provider | Customer
26/// Customer | Provider
27/// RouteServer | RouterServer-Client
28/// RouterServer-Client | RouteServer
29/// Peer | Peer
30///
31pub fn validate_role_pairs(local_role: &BgpRole, remote_role: &BgpRole) -> bool {
32    match local_role {
33        BgpRole::Provider => {
34            if let BgpRole::Customer = remote_role {
35                return true;
36            }
37            false
38        }
39        BgpRole::RouteServer => {
40            if let BgpRole::RouteServerClient = remote_role {
41                return true;
42            }
43            false
44        }
45        BgpRole::RouteServerClient => {
46            if let BgpRole::RouteServer = remote_role {
47                return true;
48            }
49            false
50        }
51        BgpRole::Customer => {
52            if let BgpRole::Provider = remote_role {
53                return true;
54            }
55            false
56        }
57        BgpRole::Peer => {
58            if let BgpRole::Peer = remote_role {
59                return true;
60            }
61            false
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use crate::models::BgpRole::*;
70
71    #[test]
72    fn test_bgp_role_validation() {
73        let mut local: BgpRole;
74        let mut remote: BgpRole;
75
76        local = Provider;
77        remote = Customer;
78        assert!(validate_role_pairs(&local, &remote));
79        for remote in [Provider, Peer, RouteServer, RouteServerClient] {
80            assert!(!validate_role_pairs(&local, &remote));
81        }
82
83        local = Customer;
84        remote = Provider;
85        assert!(validate_role_pairs(&local, &remote));
86        for remote in [Customer, Peer, RouteServer, RouteServerClient] {
87            assert!(!validate_role_pairs(&local, &remote));
88        }
89
90        local = RouteServer;
91        remote = RouteServerClient;
92        assert!(validate_role_pairs(&local, &remote));
93        for remote in [Provider, Customer, Peer, RouteServer] {
94            assert!(!validate_role_pairs(&local, &remote));
95        }
96
97        local = RouteServerClient;
98        remote = RouteServer;
99        assert!(validate_role_pairs(&local, &remote));
100        for remote in [Provider, Customer, Peer, RouteServerClient] {
101            assert!(!validate_role_pairs(&local, &remote));
102        }
103
104        local = Peer;
105        remote = Peer;
106        assert!(validate_role_pairs(&local, &remote));
107        for remote in [Provider, Customer, RouteServer, RouteServerClient] {
108            assert!(!validate_role_pairs(&local, &remote));
109        }
110    }
111}