5 个版本
0.17.6 | 2024 年 6 月 11 日 |
---|---|
0.17.5 | 2024 年 5 月 30 日 |
0.17.4 | 2024 年 5 月 30 日 |
0.17.3 | 2024 年 3 月 24 日 |
0.17.2 | 2024 年 3 月 24 日 |
#18 在 模拟 中
43 次月下载
1.5MB
29K SLoC
网络控制平面模拟器
这是一个用于 BGP 和 OSPF 路由协议的模拟器。它不模拟 OSI 层 1 到 4。因此,路由器和接口没有 IP 地址,而是使用标识符(RouterId
)。此外,模拟器通过全局事件队列交换控制平面消息,而不直接模拟时间。消息不一定反映控制平面消息的序列化和反序列化方式。BGP 和 OSPF 的实现 不 直接对应于 IETF 的规范。相反,协议被简化(例如,路由器不交换 OSPF Hello 和 BGP Keepalive 包)。
功能
- 支持的协议
- BGP
- 任意路由映射
- 路由反射
- 联邦
- 附加路径
- 域间拓扑
- OSPF
- 多个区域
- ECMP
- 虚拟链路
- 静态路由
- MPLS / 源路由
- BGP
- 可交换事件队列
- 我们提供默认的 FIFO 队列和基本计时模型。
- 您可以通过实现
EventQueue
特性来实现您自己的队列。
- 前缀类型选择
- 您可以在
Ipv4Prefix
模式下运行 BGP(具有层次化前缀)。但您也可以选择不使用层次结构,并假设前缀没有重叠,或者 BGP 中只有一个前缀。 - 此选择编码在类型系统中。
- 编译器可以根据前缀类型应用优化(使用
prefix-trie
用于层次化前缀,一个HashMap
用于非重叠前缀,以及一个简单的Option
用于单个前缀)。
- 您可以在
- 通过传递直接消息或使用全局预言机来模拟 OSPF。
- 提取转发状态并根据它检查属性。
- 包含来自 TopologyZoo 的拓扑。
- 将网络配置导出为 Cisco 和 FRR 配置。
示例
以下示例生成了一个包含两个边界路由器(B0
和 B1
)、两个路由反射器(R0
和 R1
)以及两个外部路由器(E0
和 E1
)的网络。这两个路由器都通告前缀 Prefix::from(0)
,并且所有链路具有相同的权重 1.0
。
use bgpsim::prelude::*;
// Define the type of the network.
type Prefix = SimplePrefix; // Use non-overlapping prefixes.
type Queue = BasicEventQueue<Prefix>; // Use a basic FIFO event queue
type Ospf = GlobalOspf; // Use global OSPF without message passing
type Net = Network<Prefix, Queue, Ospf>;
fn main() -> Result<(), NetworkError> {
let mut t = Net::default();
let prefix = Prefix::from(0);
let e0 = t.add_external_router("E0", 1);
let b0 = t.add_router("B0");
let r0 = t.add_router("R0");
let r1 = t.add_router("R1");
let b1 = t.add_router("B1");
let e1 = t.add_external_router("E1", 2);
t.add_link(e0, b0);
t.add_link(b0, r0);
t.add_link(r0, r1);
t.add_link(r1, b1);
t.add_link(b1, e1);
t.set_link_weight(b0, r0, 1.0)?;
t.set_link_weight(r0, b0, 1.0)?;
t.set_link_weight(r0, r1, 1.0)?;
t.set_link_weight(r1, r0, 1.0)?;
t.set_link_weight(r1, b1, 1.0)?;
t.set_link_weight(b1, r1, 1.0)?;
t.set_bgp_session(e0, b0, Some(BgpSessionType::EBgp))?;
t.set_bgp_session(r0, b0, Some(BgpSessionType::IBgpClient))?;
t.set_bgp_session(r0, r1, Some(BgpSessionType::IBgpPeer))?;
t.set_bgp_session(r1, b1, Some(BgpSessionType::IBgpClient))?;
t.set_bgp_session(e1, b1, Some(BgpSessionType::EBgp))?;
// advertise the same prefix on both routers
t.advertise_external_route(e0, prefix, &[1, 2, 3], None, None)?;
t.advertise_external_route(e1, prefix, &[2, 3], None, None)?;
// get the forwarding state
let mut fw_state = t.get_forwarding_state();
// check that all routes are correct
assert_eq!(fw_state.get_paths(b0, prefix)?, vec![vec![b0, r0, r1, b1, e1]]);
assert_eq!(fw_state.get_paths(r0, prefix)?, vec![vec![r0, r1, b1, e1]]);
assert_eq!(fw_state.get_paths(r1, prefix)?, vec![vec![r1, b1, e1]]);
assert_eq!(fw_state.get_paths(b1, prefix)?, vec![vec![b1, e1]]);
Ok(())
}
您可以使用 net!
宏创建相同的网络。
use bgpsim::prelude::*;
fn main() -> Result<(), NetworkError> {
let (t, (e0, b0, r0, r1, b1, e1)) = net! {
Prefix = Ipv4Prefix;
Ospf = GlobalOspf;
links = {
b0 -> r0: 1;
b1 -> r1: 1;
r0 -> r1: 1;
};
sessions = {
e0!(1) -> b0;
e1!(2) -> b1;
r0 -> r1;
r0 -> b0: client;
r1 -> b1: client;
};
routes = {
e0 -> "100.0.0.0/8" as {path: [1, 2, 3]};
e1 -> "100.0.0.0/8" as {path: [2, 3]};
};
return (e0, b0, r0, r1, b1, e1)
};
// get the forwarding state
let mut fw_state = t.get_forwarding_state();
// check that all routes are correct
assert_eq!(fw_state.get_paths(b0, prefix!("100.0.0.0/8" as))?, vec![vec![b0, r0, r1, b1, e1]]);
assert_eq!(fw_state.get_paths(r0, prefix!("100.20.1.3/32" as))?, vec![vec![r0, r1, b1, e1]]);
assert_eq!(fw_state.get_paths(r1, prefix!("100.2.0.0/16" as))?, vec![vec![r1, b1, e1]]);
assert_eq!(fw_state.get_paths(b1, prefix!("100.0.0.0/24" as))?, vec![vec![b1, e1]]);
Ok(())
}
此库包含来自 TopologyZoo 的网络以及方便的构建函数,以便快速生成随机配置。注意,这需要 topology_zoo
和 rand
功能。
use bgpsim::prelude::*;
use bgpsim::builder::*;
type Prefix = SimplePrefix; // Use non-overlapping prefixes.
type Queue = BasicEventQueue<Prefix>; // Use a basic FIFO event queue
type Ospf = GlobalOspf; // Use global OSPF without message passing
type Net = Network<Prefix, Queue, Ospf>;
fn main() -> Result<(), NetworkError> {
// create the Abilene network
let mut net: Net = TopologyZoo::Abilene.build(Queue::new());
// Create 5 random external routers
net.build_external_routers(extend_to_k_external_routers, 5)?;
// Assign random link weights between 10 and 100.
net.build_link_weights(random_link_weight, (10.0, 100.0))?;
// Generate an iBGP full-mesh topology.
net.build_ibgp_full_mesh()?;
// Generate all eBGP sessions
net.build_ebgp_sessions()?;
// Generate route-maps to implement Gao-Rexford routing policies, with probability 20% that
// an external network will be treated as a customer, 30% that it will be treated as peer,
// and 50% that it will be a provider.
let _peer_types = net.build_gao_rexford_policies(GaoRexfordPeerType::random, (0.2, 0.3))?;
Ok(())
}
免责声明
此库是一个研究项目。它最初是为 SGICOMM'21 论文“Snowcap: Synthesizing Network-Wide Configuration Updates”编写的。如果您正在使用此项目,请引用我们。
@INPROCEEDINGS{schneider2021snowcap,
isbn = {978-1-4503-8383-7},
copyright = {In Copyright - Non-Commercial Use Permitted},
doi = {10.3929/ethz-b-000491508},
year = {2021-08},
booktitle = {Proceedings of the 2021 ACM SIGCOMM Conference},
type = {Conference Paper},
institution = {EC},
author = {Schneider, Tibor and Birkner, Rüdiger and Vanbever, Laurent},
keywords = {Network analysis; Configuration; Migration},
language = {en},
address = {New York, NY},
publisher = {Association for Computing Machinery},
title = {Snowcap: Synthesizing Network-Wide Configuration Updates},
PAGES = {33 - 49},
Note = {ACM SIGCOMM 2021 Conference; Conference Location: Online; Conference Date: August 23-27, 2021}
}
依赖项
~4.5–7MB
~106K SLoC