1#![deny(unsafe_code)]
27#![deny(clippy::all)]
28#![warn(clippy::pedantic)]
29
30pub mod attribute;
32pub mod capability;
34pub mod constants;
36pub mod error;
38pub mod evpn;
40pub mod flowspec;
42pub mod header;
44pub mod keepalive;
46pub mod message;
48pub mod nlri;
50pub mod notification;
52pub mod notification_msg;
54pub mod open;
56pub mod route_refresh;
58pub mod update;
60pub mod validate;
62
63pub use capability::{
65 AddPathFamily, AddPathMode, Afi, Capability, ExtendedNextHopFamily, GracefulRestartFamily,
66 LlgrFamily, Safi,
67};
68pub use constants::{EXTENDED_MAX_MESSAGE_LEN, MAX_MESSAGE_LEN};
69pub use error::{DecodeError, EncodeError};
70pub use header::{BgpHeader, MessageType, peek_message_length};
71pub use message::{Message, decode_message, encode_message, encode_message_with_limit};
72pub use notification::NotificationCode;
73pub use notification_msg::NotificationMessage;
74pub use open::OpenMessage;
75pub use route_refresh::{RouteRefreshMessage, RouteRefreshSubtype};
76pub use update::{Ipv4UnicastMode, UpdateMessage};
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
88pub enum RpkiValidation {
89 Valid,
91 Invalid,
93 #[default]
95 NotFound,
96}
97
98impl std::fmt::Display for RpkiValidation {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 match self {
101 Self::Valid => write!(f, "valid"),
102 Self::Invalid => write!(f, "invalid"),
103 Self::NotFound => write!(f, "not_found"),
104 }
105 }
106}
107
108impl std::str::FromStr for RpkiValidation {
109 type Err = String;
110
111 fn from_str(s: &str) -> Result<Self, Self::Err> {
112 match s {
113 "valid" => Ok(Self::Valid),
114 "invalid" => Ok(Self::Invalid),
115 "not_found" => Ok(Self::NotFound),
116 other => Err(format!(
117 "unknown RPKI validation state {other:?}, expected \"valid\", \"invalid\", or \"not_found\""
118 )),
119 }
120 }
121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
125pub enum AspaValidation {
126 Valid,
128 Invalid,
130 #[default]
132 Unknown,
133}
134
135impl std::fmt::Display for AspaValidation {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 match self {
138 Self::Valid => write!(f, "valid"),
139 Self::Invalid => write!(f, "invalid"),
140 Self::Unknown => write!(f, "unknown"),
141 }
142 }
143}
144
145impl std::str::FromStr for AspaValidation {
146 type Err = String;
147
148 fn from_str(s: &str) -> Result<Self, Self::Err> {
149 match s {
150 "valid" => Ok(Self::Valid),
151 "invalid" => Ok(Self::Invalid),
152 "unknown" => Ok(Self::Unknown),
153 other => Err(format!(
154 "unknown ASPA validation state {other:?}, expected \"valid\", \"invalid\", or \"unknown\""
155 )),
156 }
157 }
158}
159
160pub use attribute::{
162 AsPath, AsPathSegment, ExtendedCommunity, LargeCommunity, MpReachNlri, MpUnreachNlri, Origin,
163 PathAttribute, RawAttribute, is_private_asn,
164};
165pub use nlri::{Ipv4NlriEntry, Ipv4Prefix, Ipv6Prefix, NlriEntry, Prefix};
166pub use update::ParsedUpdate;
167pub use validate::{UpdateError, is_valid_ipv6_nexthop};
168
169pub use flowspec::{
171 BitmaskMatch, FlowSpecAction, FlowSpecComponent, FlowSpecPrefix, FlowSpecRule,
172 Ipv6PrefixOffset, NumericMatch,
173};
174
175pub use evpn::{
177 EthernetSegmentIdentifier, EthernetTagId, EvpnEadPerEs, EvpnEadPerEvi, EvpnEs, EvpnImet,
178 EvpnIpPrefixRoute, EvpnIpPrefixValue, EvpnMacIp, EvpnRoute, EvpnRouteKey, MacAddress,
179 MplsLabel, RouteDistinguisher, decode_evpn_nlri, encode_evpn_nlri,
180};
181
182pub const COMMUNITY_LLGR_STALE: u32 = 0xFFFF_0006;
185pub const COMMUNITY_NO_LLGR: u32 = 0xFFFF_0007;
187
188