bgpkit_parser/lib.rs
1/*!
2BGPKIT Parser aims to provide the most ergonomic MRT/BGP/BMP message parsing Rust API.
3
4BGPKIT Parser has the following features:
5- **performant**: comparable to C-based implementations like `bgpdump` or `bgpreader`.
6- **actively maintained**: we consistently introduce feature updates and bug fixes, and support most of the relevant BGP RFCs.
7- **ergonomic API**: a three-line for loop can already get you started.
8- **battery-included**: ready to handle remote or local, bzip2 or gz data files out of the box
9
10# Getting Started
11
12Add `bgpkit-parser` to your `Cargo.toml`:
13
14```toml
15[dependencies]
16bgpkit-parser = "0.12"
17```
18
19Parse a BGP MRT file in three lines:
20
21```no_run
22use bgpkit_parser::BgpkitParser;
23
24for elem in BgpkitParser::new("http://archive.routeviews.org/route-views4/bgpdata/2022.01/UPDATES/updates.20220101.0000.bz2").unwrap() {
25 println!("{}", elem);
26}
27```
28
29# Examples
30
31The examples below are organized by complexity. For complete runnable examples, check out the [examples folder](https://github.com/bgpkit/bgpkit-parser/tree/main/examples).
32
33## Basic Examples
34
35### Parsing a Single MRT File
36
37Let's say we want to print out all the BGP announcements/withdrawal from a single MRT file, either located remotely or locally.
38Here is an example that does so.
39
40```no_run
41use bgpkit_parser::BgpkitParser;
42let parser = BgpkitParser::new("http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2").unwrap();
43for elem in parser {
44 println!("{}", elem)
45}
46```
47
48Yes, it is this simple!
49
50### Counting BGP Messages
51
52You can use iterator methods for quick analysis. For example, counting the number of announcements/withdrawals in a file:
53
54```no_run
55use bgpkit_parser::BgpkitParser;
56let url = "http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2";
57let count = BgpkitParser::new(url).unwrap().into_iter().count();
58println!("total: {}", count);
59```
60
61Output:
62```text
63total: 255849
64```
65
66## Intermediate Examples
67
68### Filtering BGP Messages
69
70BGPKIT Parser has a built-in [Filter] mechanism to efficiently filter messages. Add filters when creating the parser to only process matching [BgpElem]s.
71
72**Available filter types**: See the [Filter] enum documentation for all options.
73
74```no_run
75use bgpkit_parser::BgpkitParser;
76
77/// Filter by IP prefix
78let parser = BgpkitParser::new("http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2").unwrap()
79 .add_filter("prefix", "211.98.251.0/24").unwrap();
80
81for elem in parser {
82 println!("{}", elem);
83}
84```
85
86**Common filters**:
87- `prefix`: Match a specific IP prefix
88- `origin_asn`: Match origin AS number
89- `peer_asn`: Match peer AS number
90- `peer_ip`: Match peer IP address
91- `elem_type`: Filter by announcement (`a`) or withdrawal (`w`)
92- `as_path`: Match AS path with regex
93
94### Parsing Multiple MRT Files with BGPKIT Broker
95
96[BGPKIT Broker][broker-repo] library provides search API for all RouteViews and RIPE RIS MRT data files. Using the
97broker's Rust API ([`bgpkit-broker`][broker-crates-io]), we can easily compile a list of MRT files that we are interested
98in for any time period and any data type (`update` or `rib`). This allows users to gather information without needing to
99know about the locations of specific data files.
100
101[broker-repo]: https://github.com/bgpkit/bgpkit-broker
102[broker-crates-io]: https://crates.io/crates/bgpkit-broker
103
104The example below shows a relatively more interesting example that does the following:
105- find all BGP archive data created on time 1634693400
106- filter to only BGP updates files
107- find all announcements originated from AS13335
108- print out the total count of the announcements
109
110```no_run
111use bgpkit_parser::{BgpkitParser, BgpElem};
112
113let broker = bgpkit_broker::BgpkitBroker::new()
114 .ts_start("1634693400")
115 .ts_end("1634693400")
116 .page(1);
117
118for item in broker.into_iter().take(2) {
119 log::info!("downloading updates file: {}", &item.url);
120 let parser = BgpkitParser::new(item.url.as_str()).unwrap();
121
122 log::info!("parsing updates file");
123 // iterating through the parser. the iterator returns `BgpElem` one at a time.
124 let elems = parser
125 .into_elem_iter()
126 .filter_map(|elem| {
127 if let Some(origins) = &elem.origin_asns {
128 if origins.contains(&13335.into()) {
129 Some(elem)
130 } else {
131 None
132 }
133 } else {
134 None
135 }
136 })
137 .collect::<Vec<BgpElem>>();
138 log::info!("{} elems matches", elems.len());
139}
140```
141
142### Error Handling
143
144BGPKIT Parser returns `Result` types for operations that may fail. Here are common scenarios and how to handle them:
145
146**Handling Parser Creation Errors**
147
148```no_run
149use bgpkit_parser::BgpkitParser;
150
151// The URL might be invalid or unreachable
152match BgpkitParser::new("http://example.com/data.mrt.bz2") {
153 Ok(parser) => {
154 for elem in parser {
155 println!("{}", elem);
156 }
157 }
158 Err(e) => {
159 eprintln!("Failed to create parser: {}", e);
160 // Common causes:
161 // - Invalid URL or file path
162 // - Network connection issues
163 // - Unsupported compression format
164 }
165}
166```
167
168**Handling Filter Errors**
169
170```no_run
171use bgpkit_parser::BgpkitParser;
172
173let mut parser = BgpkitParser::new("http://example.com/data.mrt.bz2").unwrap();
174
175// Filter addition can fail with invalid input
176match parser.add_filter("prefix", "invalid-prefix") {
177 Ok(_) => println!("Filter added successfully"),
178 Err(e) => {
179 eprintln!("Invalid filter: {}", e);
180 // Common causes:
181 // - Invalid IP prefix format
182 // - Invalid AS number
183 // - Unknown filter type
184 }
185}
186```
187
188**Robust Production Code**
189
190```no_run
191use bgpkit_parser::BgpkitParser;
192
193fn process_mrt_file(url: &str) -> Result<usize, Box<dyn std::error::Error>> {
194 let parser = BgpkitParser::new(url)?
195 .add_filter("origin_asn", "13335")?;
196
197 let mut count = 0;
198 for elem in parser {
199 // Process element
200 count += 1;
201 }
202
203 Ok(count)
204}
205
206// Usage
207match process_mrt_file("http://example.com/updates.bz2") {
208 Ok(count) => println!("Processed {} elements", count),
209 Err(e) => eprintln!("Error: {}", e),
210}
211```
212
213## Advanced Examples
214
215### Parsing Real-time Data Streams
216
217BGPKIT Parser provides parsing for real-time data streams, including [RIS-Live][ris-live-url]
218and [BMP][bmp-rfc]/[OpenBMP][openbmp-url] messages.
219
220**Parsing Messages From RIS-Live**
221
222Here is an example of handling RIS-Live message streams. After connecting to the websocket server,
223we need to subscribe to a specific data stream. In this example, we subscribe to the data stream
224from on collector (`rrc21`). We can then loop and read messages from the websocket.
225
226```no_run
227# #[cfg(feature = "rislive")]
228use bgpkit_parser::parse_ris_live_message;
229use serde_json::json;
230use tungstenite::{connect, Message};
231
232const RIS_LIVE_URL: &str = "ws://ris-live.ripe.net/v1/ws/?client=rust-bgpkit-parser";
233
234/// This is an example of subscribing to RIS-Live's streaming data from one host (`rrc21`).
235///
236/// For more RIS-Live details, check out their documentation at https://ris-live.ripe.net/manual/
237fn main() {
238 // connect to RIPE RIS Live websocket server
239 let (mut socket, _response) =
240 connect(RIS_LIVE_URL)
241 .expect("Can't connect to RIS Live websocket server");
242
243 // subscribe to messages from one collector
244 let msg = json!({"type": "ris_subscribe", "data": {"host": "rrc21"}}).to_string();
245 socket.send(Message::Text(msg.into())).unwrap();
246
247 loop {
248 let msg = socket.read().expect("Error reading message").to_string();
249# #[cfg(feature = "rislive")]
250 if let Ok(elems) = parse_ris_live_message(msg.as_str()) {
251 for elem in elems {
252 println!("{}", elem);
253 }
254 }
255 }
256}
257```
258
259**Parsing OpenBMP Messages From RouteViews Kafka Stream**
260
261[RouteViews](http://www.routeviews.org/routeviews/) provides a real-time Kafka stream of the OpenBMP
262data received from their collectors. Below is a partial example of how we handle the raw bytes
263received from the Kafka stream. For full examples, check out the [examples folder on GitHub](https://github.com/bgpkit/bgpkit-parser/tree/main/examples).
264
265```rust,no_run
266# use log::{info, error};
267# use bytes::Bytes;
268# struct KafkaMessage { value: Vec<u8> }
269# let m = KafkaMessage { value: vec![] };
270use bgpkit_parser::parser::bmp::messages::*;
271use bgpkit_parser::parser::utils::*;
272use bgpkit_parser::{Elementor, parse_openbmp_header, parse_bmp_msg};
273
274let bytes = &m.value;
275let mut data = Bytes::from(bytes.clone());
276let header = parse_openbmp_header(&mut data).unwrap();
277let bmp_msg = parse_bmp_msg(&mut data);
278match bmp_msg {
279 Ok(msg) => {
280 let timestamp = header.timestamp;
281 let per_peer_header = msg.per_peer_header.unwrap();
282 match msg.message_body {
283 BmpMessageBody::RouteMonitoring(m) => {
284 for elem in Elementor::bgp_to_elems(
285 m.bgp_message,
286 timestamp,
287 &per_peer_header.peer_ip,
288 &per_peer_header.peer_asn
289 )
290 {
291 info!("{}", elem);
292 }
293 }
294 _ => {}
295 }
296 }
297 Err(_e) => {
298 let hex = hex::encode(bytes);
299 error!("{}", hex);
300 }
301}
302```
303
304[ris-live-url]: https://ris-live.ripe.net
305[bmp-rfc]: https://datatracker.ietf.org/doc/html/rfc7854
306[openbmp-url]: https://www.openbmp.org/
307
308### Encoding: Archiving Filtered MRT Records
309
310The example will download one MRT file from RouteViews, filter out all the BGP messages that
311are not originated from AS3356, and write the filtered MRT records to disk. Then it re-parses the
312filtered MRT file and prints out the number of BGP messages.
313
314```no_run
315use bgpkit_parser::Elementor;
316use itertools::Itertools;
317use std::io::Write;
318
319let mut updates_encoder = bgpkit_parser::encoder::MrtUpdatesEncoder::new();
320
321bgpkit_parser::BgpkitParser::new(
322 "http://archive.routeviews.org/bgpdata/2023.10/UPDATES/updates.20231029.2015.bz2",
323).unwrap()
324 .add_filter("origin_asn", "3356").unwrap()
325 .into_iter()
326 .for_each(|elem| {
327 updates_encoder.process_elem(&elem);
328 });
329
330let mut mrt_writer = oneio::get_writer("as3356_mrt.gz").unwrap();
331mrt_writer.write_all(updates_encoder.export_bytes().as_ref()).unwrap();
332drop(mrt_writer);
333```
334
335# FAQ & Troubleshooting
336
337## Common Issues
338
339### Parser creation fails with "unsupported compression"
340**Problem**: The file uses an unsupported compression format.
341
342**Solution**: BGPKIT Parser natively supports `.bz2` and `.gz` compression. For other formats, decompress the file first or use the [`oneio`](https://crates.io/crates/oneio) crate which supports additional formats.
343
344### Out of memory when parsing large files
345**Problem**: Collecting all elements into a vector exhausts available memory.
346
347**Solution**: Use streaming iteration instead of collecting:
348```rust,ignore
349// ❌ Don't do this for large files
350let all_elems: Vec<_> = parser.into_iter().collect();
351
352// ✅ Process iteratively
353for elem in parser {
354 // Process one element at a time
355 process(elem);
356}
357```
358
359### Slow performance on network files
360**Problem**: Remote file parsing is slower than expected.
361
362**Solution**:
363- Use the `--cache-dir` option in CLI to cache downloaded files
364- In library code, download the file first with appropriate buffering
365- Consider processing files in parallel if dealing with multiple files
366
367### Missing or incomplete BGP attributes
368**Problem**: Some [BgpElem] fields are `None` when you expect values.
369
370**Solution**: Not all BGP messages contain all attributes. Check the MRT format and BGP message type:
371- Withdrawals typically don't have AS paths or communities
372- Some collectors may not export certain attributes
373- Use pattern matching to handle `Option` types properly
374
375## Performance Tips
376
377### Use filters early
378Apply filters during parser creation to avoid processing unwanted data:
379```rust,ignore
380// ✅ Efficient - filters during parsing
381let parser = BgpkitParser::new(url)?
382 .add_filter("prefix", "1.1.1.0/24")?;
383
384// ❌ Less efficient - processes everything first
385let filtered: Vec<_> = BgpkitParser::new(url)?
386 .into_iter()
387 .filter(|e| e.prefix.to_string() == "1.1.1.0/24")
388 .collect();
389```
390
391### Process multiple files in parallel
392For bulk processing, use parallel iterators:
393```rust,ignore
394use rayon::prelude::*;
395
396let files = vec!["file1.mrt.bz2", "file2.mrt.bz2", "file3.mrt.bz2"];
397files.par_iter().for_each(|file| {
398 let parser = BgpkitParser::new(file).unwrap();
399 // Process each file in parallel
400});
401```
402
403### Choose the right data structure
404- Use [MrtRecord] iteration for minimal memory overhead
405- Use [BgpElem] for easier per-prefix analysis
406- See [Data Representation](#data-representation) for detailed comparison
407
408# Command Line Tool
409
410`bgpkit-parser` is bundled with a utility commandline tool `bgpkit-parser-cli`.
411
412## Installation
413
414### Install compiled binaries
415
416You can install the compiled `bgpkit-parser` CLI binaries with the following methods:
417- **Homebrew** (macOS): `brew install bgpkit/tap/bgpkit-parser`
418- [**Cargo binstall**](https://github.com/cargo-bins/cargo-binstall): `cargo binstall bgpkit-parser`
419
420### From source
421
422You can install the tool by running
423```bash
424cargo install bgpkit-parser --features cli
425```
426or checkout this repository and run
427```bash
428cargo install --path . --features cli
429```
430
431## Usage
432
433Run `bgpkit-parser --help` to see the full list of options.
434
435```text
436MRT/BGP/BMP data processing library
437
438Usage: bgpkit-parser [OPTIONS] <FILE>
439
440Arguments:
441 <FILE> File path to a MRT file, local or remote
442
443Options:
444 -c, --cache-dir <CACHE_DIR> Set the cache directory for caching remote files. Default behavior does not enable caching
445 --json Output as JSON objects
446 --psv Output as full PSV entries with header
447 --pretty Pretty-print JSON output
448 -e, --elems-count Count BGP elems
449 -r, --records-count Count MRT records
450 -o, --origin-asn <ORIGIN_ASN> Filter by origin AS Number
451 -p, --prefix <PREFIX> Filter by network prefix
452 -4, --ipv4-only Filter by IPv4 only
453 -6, --ipv6-only Filter by IPv6 only
454 -s, --include-super Include super-prefix when filtering
455 -S, --include-sub Include sub-prefix when filtering
456 -j, --peer-ip <PEER_IP> Filter by peer IP address
457 -J, --peer-asn <PEER_ASN> Filter by peer ASN
458 -m, --elem-type <ELEM_TYPE> Filter by elem type: announce (a) or withdraw (w)
459 -t, --start-ts <START_TS> Filter by start unix timestamp inclusive
460 -T, --end-ts <END_TS> Filter by end unix timestamp inclusive
461 -a, --as-path <AS_PATH> Filter by AS path regex string
462 -h, --help Print help
463 -V, --version Print version
464
465```
466
467## Common CLI Examples
468
469### Basic usage - Print all BGP messages
470```bash
471bgpkit-parser http://archive.routeviews.org/bgpdata/2021.10/UPDATES/updates.20211001.0000.bz2
472```
473
474### Filter by origin AS
475```bash
476bgpkit-parser -o 13335 updates.20211001.0000.bz2
477```
478
479### Filter by prefix
480```bash
481bgpkit-parser -p 1.1.1.0/24 updates.20211001.0000.bz2
482```
483
484### Output as JSON
485```bash
486bgpkit-parser --json updates.20211001.0000.bz2 > output.json
487```
488
489### Count elements efficiently
490```bash
491bgpkit-parser -e updates.20211001.0000.bz2
492```
493
494### Cache remote files for faster repeated access
495```bash
496bgpkit-parser -c ~/.bgpkit-cache http://example.com/updates.mrt.bz2
497```
498
499### Combine filters
500```bash
501# IPv4 announcements from AS13335
502bgpkit-parser -o 13335 -m a -4 updates.bz2
503```
504
505# Data Representation
506
507BGPKIT Parser provides two ways to access parsed BGP data: [MrtRecord] and [BgpElem]. Choose based on your needs:
508
509```text
510┌──────────────────────────────────────────────┐
511│ MRT File │
512│ (Binary format: bgp4mp, tabledumpv2, etc.) │
513└──────────────────────┬───────────────────────┘
514 │
515 ├──> Parser
516 │
517 ┌─────────────┴────────────────┐
518 │ │
519 ▼ ▼
520 [MrtRecord] [BgpElem]
521 (Low-level) (High-level)
522 │ │
523 └──────────────┬───────────────┘
524 │
525 ▼
526 Your Analysis Code
527```
528
529## [MrtRecord]: Low-level MRT Representation
530
531[MrtRecord] preserves the complete, unmodified information from the MRT file. Use this when you need:
532- **Raw MRT data access**: Direct access to all MRT fields
533- **Format-specific details**: Peer index tables, geo-location data, etc.
534- **Memory efficiency**: Minimal overhead, compact representation
535- **Re-encoding**: Converting back to MRT format
536
537See the [MrtRecord] documentation for the complete structure definition.
538
539**Key components**:
540- `common_header`: Contains timestamp, record type, and metadata
541- `message`: The actual MRT message (TableDump, TableDumpV2, or Bgp4Mp)
542
543**Iteration**: Use [`BgpkitParser::into_record_iter()`] to iterate over [MrtRecord]s.
544
545## [BgpElem]: High-level Per-Prefix Representation
546
547[BgpElem] provides a simplified, per-prefix view of BGP data. Each [BgpElem] represents a single prefix announcement or withdrawal. Use this when you want:
548- **Simple analysis**: Focus on prefixes without worrying about MRT format details
549- **Format-agnostic processing**: Same structure regardless of MRT format
550- **BGP attributes**: Easy access to AS path, communities, etc.
551
552**Example transformation**:
553```text
554MRT Record with 3 prefixes → 3 BgpElem objects
555┌────────────────────────┐ ┌──────────────────┐
556│ BGP UPDATE Message │ │ BgpElem │
557│ AS Path: 64512 64513 │ ────────> │ prefix: P1 │
558│ Prefixes: │ │ as_path: 64512.. │
559│ - P1: 10.0.0.0/24 │ └──────────────────┘
560│ - P2: 10.0.1.0/24 │ ┌──────────────────┐
561│ - P3: 10.0.2.0/24 │ ────────> │ BgpElem │
562└────────────────────────┘ │ prefix: P2 │
563 │ as_path: 64512.. │
564 └──────────────────┘
565 ┌──────────────────┐
566 │ BgpElem │
567 ────────> │ prefix: P3 │
568 │ as_path: 64512.. │
569 └──────────────────┘
570```
571
572See the [BgpElem] documentation for the complete structure definition.
573
574**Key fields**:
575- `timestamp`: Unix timestamp of the BGP message
576- `elem_type`: Announcement or withdrawal
577- `peer_ip` / `peer_asn`: The BGP peer information
578- `prefix`: The IP prefix being announced or withdrawn
579- `as_path`: The AS path attribute (if present)
580- `origin_asns`: Origin AS numbers extracted from AS path
581- `communities`: BGP communities (standard, extended, and large)
582- `next_hop`, `local_pref`, `med`: Other BGP attributes
583
584**Iteration**: Use [`BgpkitParser::into_elem_iter()`] or default iteration to iterate over [BgpElem]s.
585
586## Which One Should I Use?
587
588- **Use [BgpElem]** (default): For most BGP analysis tasks, prefix tracking, AS path analysis
589- **Use [MrtRecord]**: When you need MRT format details, re-encoding, or minimal memory overhead
590
591**Memory trade-off**: [BgpElem] duplicates shared attributes (AS path, communities) for each prefix, consuming more memory but providing simpler analysis.
592
593# RFCs Support
594
595BGPKIT Parser implements comprehensive BGP, MRT, BMP, and related protocol standards. All listed RFCs are fully supported.
596
597**Request a feature**: If you need support for a specific RFC not listed here, please [submit an issue on GitHub](https://github.com/bgpkit/bgpkit-parser/issues).
598
599## Core BGP Protocol
600
601**Most commonly used**:
602- [RFC 4271](https://datatracker.ietf.org/doc/html/rfc4271): A Border Gateway Protocol 4 (BGP-4) - Core protocol
603- [RFC 2858](https://datatracker.ietf.org/doc/html/rfc2858): Multiprotocol Extensions for BGP-4 (IPv6 support)
604- [RFC 6793](https://datatracker.ietf.org/doc/html/rfc6793): Four-Octet AS Number Space
605- [RFC 7911](https://datatracker.ietf.org/doc/html/rfc7911): Advertisement of Multiple Paths (ADD-PATH)
606
607**Additional BGP RFCs**:
608- [RFC 2042](https://datatracker.ietf.org/doc/html/rfc2042): Registering New BGP Attribute Types
609- [RFC 2918](https://datatracker.ietf.org/doc/html/rfc2918): Route Refresh Capability for BGP-4
610- [RFC 3392](https://datatracker.ietf.org/doc/html/rfc3392): Capabilities Advertisement with BGP-4
611- [RFC 4724](https://datatracker.ietf.org/doc/html/rfc4724): Graceful Restart Mechanism for BGP
612- [RFC 4456](https://datatracker.ietf.org/doc/html/rfc4456): BGP Route Reflection
613- [RFC 5065](https://datatracker.ietf.org/doc/html/rfc5065): Autonomous System Confederations for BGP
614- [RFC 5492](https://datatracker.ietf.org/doc/html/rfc5492): Capabilities Advertisement with BGP-4
615- [RFC 7606](https://datatracker.ietf.org/doc/html/rfc7606): Revised Error Handling for BGP UPDATE Messages
616- [RFC 8654](https://datatracker.ietf.org/doc/html/rfc8654): Extended Message Support for BGP
617- [RFC 8950](https://datatracker.ietf.org/doc/html/rfc8950): Advertising IPv4 NLRI with an IPv6 Next Hop
618- [RFC 9072](https://datatracker.ietf.org/doc/html/rfc9072): Extended Optional Parameters Length for BGP OPEN Message
619- [RFC 9234](https://datatracker.ietf.org/doc/html/rfc9234): Route Leak Prevention Using Roles in UPDATE and OPEN Messages
620
621## MRT (Multi-Threaded Routing Toolkit)
622
623- [RFC 6396](https://datatracker.ietf.org/doc/html/rfc6396): MRT Routing Information Export Format
624- [RFC 6397](https://datatracker.ietf.org/doc/html/rfc6397): MRT BGP Routing Information Export Format with Geo-Location Extensions
625- [RFC 8050](https://datatracker.ietf.org/doc/html/rfc8050): MRT Routing Information Export Format with BGP Additional Path Extensions
626
627## BMP (BGP Monitoring Protocol)
628
629- [RFC 7854](https://datatracker.ietf.org/doc/html/rfc7854): BGP Monitoring Protocol (BMP)
630- [RFC 8671](https://datatracker.ietf.org/doc/html/rfc8671): Support for Adj-RIB-Out in BMP
631- [RFC 9069](https://datatracker.ietf.org/doc/html/rfc9069): Support for Local RIB in BMP
632
633## BGP Communities
634
635Full support for standard, extended, and large communities:
636- [RFC 1997](https://datatracker.ietf.org/doc/html/rfc1997): BGP Communities Attribute
637- [RFC 4360](https://datatracker.ietf.org/doc/html/rfc4360): BGP Extended Communities Attribute
638- [RFC 5668](https://datatracker.ietf.org/doc/html/rfc5668): 4-Octet AS Specific BGP Extended Community
639- [RFC 5701](https://datatracker.ietf.org/doc/html/rfc5701): IPv6 Address Specific BGP Extended Community Attribute
640- [RFC 7153](https://datatracker.ietf.org/doc/html/rfc7153): IANA Registries for BGP Extended Communities
641- [RFC 8097](https://datatracker.ietf.org/doc/html/rfc8097): BGP Prefix Origin Validation State Extended Community
642- [RFC 8092](https://datatracker.ietf.org/doc/html/rfc8092): BGP Large Communities
643
644## Advanced Features
645
646**FlowSpec**:
647- [RFC 8955](https://datatracker.ietf.org/doc/html/rfc8955): Dissemination of Flow Specification Rules
648- [RFC 8956](https://datatracker.ietf.org/doc/html/rfc8956): Dissemination of Flow Specification Rules for IPv6
649- [RFC 9117](https://datatracker.ietf.org/doc/html/rfc9117): Revised Validation Procedure for BGP Flow Specifications
650
651**Tunnel Encapsulation**:
652- [RFC 5640](https://datatracker.ietf.org/doc/html/rfc5640): Load-Balancing for Mesh Softwires
653- [RFC 8365](https://datatracker.ietf.org/doc/html/rfc8365): Ethernet VPN (EVPN)
654- [RFC 9012](https://datatracker.ietf.org/doc/html/rfc9012): BGP Tunnel Encapsulation Attribute
655
656**Link-State (BGP-LS)**:
657- [RFC 7752](https://datatracker.ietf.org/doc/html/rfc7752): North-Bound Distribution of Link-State and TE Information
658- [RFC 8571](https://datatracker.ietf.org/doc/html/rfc8571): BGP-LS Advertisement of IGP TE Performance Metric Extensions
659- [RFC 9085](https://datatracker.ietf.org/doc/html/rfc9085): BGP-LS Extensions for Segment Routing
660- [RFC 9294](https://datatracker.ietf.org/doc/html/rfc9294): BGP-LS Advertisement of Application-Specific Link Attributes
661
662# See Also
663
664## Related BGPKIT Projects
665
666- **[BGPKIT Broker](https://github.com/bgpkit/bgpkit-broker)**: Search and discover MRT data files from RouteViews and RIPE RIS
667- **[BGPKIT API](https://data.bgpkit.com)**: RESTful API for MRT data file discovery
668- **[Monocle](https://github.com/bgpkit/monocle)**: Real-time BGP monitoring and alerting
669- **[BGPKIT Commons](https://github.com/bgpkit/bgpkit-commons)**: Common data structures and utilities
670
671## Resources
672
673- **[GitHub Repository](https://github.com/bgpkit/bgpkit-parser)**: Source code, examples, and issue tracking
674- **[Documentation](https://docs.rs/bgpkit-parser)**: Full API documentation
675- **[Changelog](https://github.com/bgpkit/bgpkit-parser/blob/main/CHANGELOG.md)**: Version history and release notes
676
677## Community
678
679- **Questions?** Open a [GitHub Discussion](https://github.com/bgpkit/bgpkit-parser/discussions)
680- **Found a bug?** Submit a [GitHub Issue](https://github.com/bgpkit/bgpkit-parser/issues)
681
682*/
683
684#![doc(
685 html_logo_url = "https://raw.githubusercontent.com/bgpkit/assets/main/logos/icon-transparent.png",
686 html_favicon_url = "https://raw.githubusercontent.com/bgpkit/assets/main/logos/favicon.ico"
687)]
688
689#[cfg(feature = "parser")]
690pub mod encoder;
691pub mod error;
692pub mod models;
693#[cfg(feature = "parser")]
694pub mod parser;
695
696pub use models::BgpElem;
697pub use models::MrtRecord;
698#[cfg(feature = "parser")]
699pub use parser::*;