5个版本 (3个重大更改)
新 0.4.1 | 2024年8月8日 |
---|---|
0.4.0 | 2024年8月7日 |
0.3.0 | 2024年1月31日 |
0.2.0 | 2023年10月9日 |
0.1.0 | 2023年3月5日 |
#2 in #bgp
318 每月下载量
用于 3 crates
1MB
23K SLoC
NetGauze BGP Pkt
BGP-4协议表示和线格式序列化/反序列化(serde)
概述
NetGauze BGP Pkt是一个表示BGP-4数据包的库。它旨在实现以下4个目标:
- 广泛支持各种与BGP相关的RFC。请参阅支持的BGP-4协议功能。
- 使用Rust本地表示BGP协议,使其难以构建错误的BGP数据包。我们通过大量依赖Rust提供的丰富类型系统来实现这一点。
- 可选的本地BGP线协议序列化/反序列化(serde)。除了支持知名的serde库之外,这使该库适用于构建更广泛的应用程序。
- 广泛的测试。这包括使用从实际数据包跟踪中提取的单元测试和模糊测试。
示例
运行示例: cargo run --example bgp
use std::io::Cursor;
use std::net::Ipv4Addr;
use netgauze_bgp_pkt::capabilities::*;
use netgauze_bgp_pkt::open::*;
use netgauze_bgp_pkt::*;
use netgauze_iana::address_family::*;
use netgauze_parse_utils::{ReadablePDUWithOneInput, Span, WritablePDU};
pub fn main() {
// Construct a new BGP message
let msg = BgpMessage::Open(BgpOpenMessage::new(
100,
180,
Ipv4Addr::new(5, 5, 5, 5),
vec![
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::MultiProtocolExtensions(
MultiProtocolExtensionsCapability::new(AddressType::Ipv4Unicast),
)]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::MultiProtocolExtensions(
MultiProtocolExtensionsCapability::new(AddressType::Ipv4MplsLabeledVpn),
)]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::CiscoRouteRefresh]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::RouteRefresh]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::FourOctetAs(
FourOctetAsCapability::new(100),
)]),
BgpOpenMessageParameter::Capabilities(vec![BgpCapability::ExtendedNextHopEncoding(
ExtendedNextHopEncodingCapability::new(vec![
ExtendedNextHopEncoding::new(AddressType::Ipv4Unicast, AddressFamily::IPv6),
ExtendedNextHopEncoding::new(AddressType::Ipv4Multicast, AddressFamily::IPv6),
ExtendedNextHopEncoding::new(
AddressType::Ipv4MplsLabeledVpn,
AddressFamily::IPv6,
),
]),
)]),
],
));
println!("JSON representation of BGP packet: {}", serde_json::to_string(&msg).unwrap());
// Serialize the message into it's BGP binary format
let mut buf: Vec<u8> = vec![];
let mut cursor = Cursor::new(&mut buf);
msg.write(&mut cursor).unwrap();
assert_eq!(
buf,
vec![
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 83,
1, 4, 0, 100, 0, 180, 5, 5, 5, 5, 54, 2, 6, 1, 4, 0, 1, 0, 1, 2, 6, 1, 4, 0, 1, 0, 128,
2, 2, 128, 0, 2, 2, 2, 0, 2, 6, 65, 4, 0, 0, 0, 100, 2, 20, 5, 18, 0, 1, 0, 1, 0, 2, 0,
1, 0, 2, 0, 2, 0, 1, 0, 128, 0, 2
]
);
// Deserialize the message from binary format
let (_, msg_back) = BgpMessage::from_wire(Span::new(&buf), true).unwrap();
assert_eq!(msg, msg_back);
}
支持的BGP协议功能
支持的消息类型
消息类型 | RFCs | 备注 |
---|---|---|
开放 | RFC 4271 | 请参阅下文支持的特性 |
更新 | RFC 4271 | 请参阅下文支持的路径属性 |
通知 | RFC 4271 | 请参阅下文支持的通知子代码 |
KeepAlive | RFC 4271 | |
RouteRefresh | RFC 2918 和 RFC 7313 | 请参阅下文支持的路由刷新操作 |
BGP Open消息中支持的特性
特性 | RFCs | 备注 |
---|---|---|
多协议扩展(MP-BGP) | RFC 4760 | 请参阅以下支持的地址族 |
RouteRefresh | RFC 2918 | |
增强路由刷新 | RFC 7313 | |
添加路径 | RFC 7911 | |
扩展消息 | RFC 8654 | |
四个字节的AS号 | RFC 6793 | |
扩展下一跳编码 | RFC 8950 | |
多个标签 | RFC 8277 | |
实验性 | RFC 8810 | 代码为239-254的特性被标记为实验性,我们将其值读取为Vec |
未知 | RFC 5492 | 我们携带能力代码及其值对应的 u8 向量 |
BGP更新消息中支持的路径属性
路径属性 | RFCs | 公认 | 可选 | 可传递 | 备注 |
---|---|---|---|---|---|
起源 | RFC 4271 | 是 | 否 | 是 | |
AS_PATH | RFC 4271 和 RFC 6793 | 是 | 否 | 是 | |
NEXT_HOP | RFC 4271 | 是 | 否 | 是 | |
多出口判定器 (MED) | RFC 4271 | 是 | 是 | 否 | |
本地优先级 (LocalPref) | RFC 4271 | 是 | 是 | ||
原子聚合 | RFC 4271 | 是 | 是 | 是 | |
聚合器 | RFC 4271 | 是 | 是 | 是 | |
团体属性 | RFC 1997 | 否 | 是 | 是 | |
扩展团体属性 | RFC 4360 | 否 | 是 | 是 | |
扩展团体属性 IPv6 | RFC 5701 | 否 | 是 | 是 | |
大型团体属性 | RFC 8092 | 否 | 是 | 是 | |
路由反射 | RFC 4456 | 否 | 是 | 否 | |
四字节 AS_PATH | RFC 6793 | 否 | 是 | 是 | |
MP_REACH_NLRI | RFC 4760 | 否 | 是 | 否 | |
MP_UNREACH_NLRI | RFC 4760 | 否 | 是 | 否 | |
未知属性 | N/A | N/A | N/A | 捕获所有属性,将其值作为 Vec 读取并保留 |
MP-BGP 支持的地址族
RFC | 地址族 (AFI) | 后续地址族 (SAFI) | 备注 |
---|---|---|---|
1 = IPv4 | 1 = 单播 | ||
1 = IPv4 | 2 = 多播 | ||
RFC 8277 | 1 = IPv4 | 4 = MPLS 标记单播 | 带有 MPLS 标签的 NLRI |
RFC 4364 | 1 = IPv4 | 128 = MPLS 标记单播 | |
RFC 4684 | 1 = IPv4 | 132 = 路由目标约束 | |
2 = IPv6 | 1 = 单播 | ||
2 = IPv6 | 2 = 多播 | ||
RFC 8277 | 2 = IPv6 | 4 = MPLS 标记单播 | 带有 MPLS 标签的 NLRI |
RFC 4659 | 2 = IPv4 | 128 = MPLS 标记单播 | |
RFC 7432 和 RFC9136 | 25 = L2 VPN | 70 = BGP EVPNs | 支持 1 至 5 的路由类型 |
支持的通告子代码
特性 | RFCs | 备注 |
---|---|---|
保留 | ||
达到的最大前缀数 | RFC 4486 | |
管理性关闭 | RFC 4486 | |
对等体未配置 | RFC 4486 | |
管理性重置 | RFC 4486 | |
连接被拒绝 | RFC 4486 | |
其他配置更改 | RFC 4486 | |
连接冲突解决 | RFC 4486 | |
资源耗尽 | RFC 4486 | |
硬重置 | RFC 8538 | |
BFD 下降 | RFC 9384 |
开发文档
-
运行数据包 Serde 基准测试*
cargo bench --features bench
-
使用此库来模糊接受
BgpMessage
的其他代码
#![no_main]
use libfuzzer_sys::fuzz_target;
use netgauze_bgp_pkt::BgpMessage;
fuzz_target!(|data: BgpMessage| {
// Some fuzzing target that accepts BgpMessage as input and need to be fuzzed
});
依赖项
~0.9–13MB
~143K SLoC