bgp_models/bgp/
role.rs

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