use bgpsim_macros::prefix;
use crate::{
builder::*,
config::{ConfigExpr, ConfigModifier},
event::BasicEventQueue,
export::{cisco_frr_generators::Target, Addressor, CfgGen, CiscoFrrCfgGen, DefaultAddressor},
network::Network,
ospf::OspfImpl,
route_map::{RouteMapBuilder, RouteMapDirection},
types::{NonOverlappingPrefix, Prefix, SimplePrefix, ASN},
};
mod cisco;
mod frr;
fn iface_names(target: Target) -> Vec<String> {
match target {
Target::CiscoNexus7000 => (1..=48).map(|i| format!("Ethernet8/{i}")).collect(),
Target::Frr => (1..=8).map(|i| format!("eth{i}")).collect(),
}
}
fn addressor<P: Prefix, Q, Ospf: OspfImpl>(
net: &Network<P, Q, Ospf>,
) -> DefaultAddressor<P, Q, Ospf> {
DefaultAddressor::new(net, 8, 24, 30).unwrap()
}
fn generate_internal_config_full_mesh(target: Target) -> String {
let mut net = Network::<SimplePrefix, BasicEventQueue<_>>::new(BasicEventQueue::new());
net.build_topology(ASN(65500), CompleteGraph(4)).unwrap();
net.build_external_routers(ASN(65500), ASN(100), vec![0.into(), 1.into()])
.unwrap();
net.build_link_weights(100.0).unwrap();
net.build_ibgp_full_mesh().unwrap();
net.build_ebgp_sessions().unwrap();
let mut ip = addressor(&net);
let mut cfg_gen = CiscoFrrCfgGen::new(&net, 0.into(), target, iface_names(target)).unwrap();
cfg_gen.generate_config(&net, &mut ip).unwrap()
}
fn generate_internal_config_route_reflector(target: Target) -> String {
let mut net = Network::<SimplePrefix, BasicEventQueue<_>>::new(BasicEventQueue::new());
net.build_topology(ASN(65500), CompleteGraph(4)).unwrap();
net.build_external_routers(ASN(65500), ASN(100), vec![0.into(), 1.into()])
.unwrap();
net.build_link_weights(100.0).unwrap();
net.build_ibgp_route_reflection(vec![0.into()]).unwrap();
net.build_ebgp_sessions().unwrap();
let mut ip = addressor(&net);
let mut cfg_gen = CiscoFrrCfgGen::new(&net, 0.into(), target, iface_names(target)).unwrap();
cfg_gen.generate_config(&net, &mut ip).unwrap()
}
fn net_for_route_maps<P: Prefix>() -> Network<P, BasicEventQueue<P>> {
let mut net = Network::<P, BasicEventQueue<_>>::new(BasicEventQueue::new());
net.build_topology(ASN(65500), CompleteGraph(4)).unwrap();
net.build_external_routers(ASN(65500), ASN(100), vec![0.into(), 1.into()])
.unwrap();
net.build_link_weights(100.0).unwrap();
net.build_ibgp_full_mesh().unwrap();
net.build_ebgp_sessions().unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Incoming,
RouteMapBuilder::new()
.allow()
.order(10)
.match_community((65500, 10))
.match_prefix(0.into())
.set_weight(10)
.continue_at(30)
.build(),
)
.unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Incoming,
RouteMapBuilder::new()
.allow()
.order(20)
.match_community((65500, 20))
.set_weight(20)
.exit()
.build(),
)
.unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Incoming,
RouteMapBuilder::new()
.allow()
.order(30)
.match_community((65500, 30))
.set_weight(30)
.continue_next()
.build(),
)
.unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Incoming,
RouteMapBuilder::new()
.allow()
.order(40)
.match_community((65500, 40))
.set_weight(40)
.continue_next()
.build(),
)
.unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Outgoing,
RouteMapBuilder::new()
.deny()
.order(10)
.match_community((65500, 20))
.build(),
)
.unwrap();
net
}
fn generate_internal_config_route_maps<P: Prefix>(target: Target) -> String {
let net = net_for_route_maps::<P>();
let mut ip = addressor(&net);
let mut cfg_gen = CiscoFrrCfgGen::new(&net, 0.into(), target, iface_names(target)).unwrap();
cfg_gen.generate_config(&net, &mut ip).unwrap()
}
fn net_for_route_maps_pec<P: Prefix>() -> Network<P, BasicEventQueue<P>> {
let mut net = Network::<P, BasicEventQueue<_>>::new(BasicEventQueue::new());
net.build_topology(ASN(65500), CompleteGraph(4)).unwrap();
net.build_external_routers(ASN(65500), ASN(100), vec![0.into(), 1.into()])
.unwrap();
net.build_link_weights(100.0).unwrap();
net.build_ibgp_full_mesh().unwrap();
net.build_ebgp_sessions().unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Incoming,
RouteMapBuilder::new()
.allow()
.order(10)
.match_prefix(0.into())
.set_weight(10)
.exit()
.build(),
)
.unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Incoming,
RouteMapBuilder::new()
.allow()
.order(20)
.match_prefix(1.into())
.set_weight(20)
.exit()
.build(),
)
.unwrap();
net.set_bgp_route_map(
0.into(),
4.into(),
RouteMapDirection::Incoming,
RouteMapBuilder::new()
.allow()
.order(30)
.match_prefix(0.into())
.match_prefix(1.into())
.set_weight(30)
.exit()
.build(),
)
.unwrap();
net
}
fn generate_internal_config_route_maps_with_pec<P: Prefix + NonOverlappingPrefix>(
target: Target,
) -> String {
let net = net_for_route_maps_pec::<P>();
let mut ip = addressor(&net);
ip.register_pec(
0.into(),
vec![
prefix!("200.0.1.0/24"),
prefix!("200.0.2.0/24"),
prefix!("200.0.3.0/24"),
prefix!("200.0.4.0/24"),
prefix!("200.0.5.0/24"),
],
);
let mut cfg_gen = CiscoFrrCfgGen::new(&net, 0.into(), target, iface_names(target)).unwrap();
cfg_gen.generate_config(&net, &mut ip).unwrap()
}
fn generate_external_config<P: Prefix>(target: Target) -> String {
let mut net = Network::<P, BasicEventQueue<_>>::new(BasicEventQueue::new());
net.build_topology(ASN(65500), CompleteGraph(4)).unwrap();
net.build_external_routers(ASN(65500), ASN(100), vec![0.into(), 1.into()])
.unwrap();
net.build_link_weights(100.0).unwrap();
net.build_ibgp_full_mesh().unwrap();
net.build_ebgp_sessions().unwrap();
net.advertise_route(4.into(), P::from(0), None::<ASN>, None, None)
.unwrap();
let mut ip = addressor(&net);
let mut cfg_gen = CiscoFrrCfgGen::new(&net, 4.into(), target, iface_names(target)).unwrap();
cfg_gen.generate_config(&net, &mut ip).unwrap()
}
fn generate_external_config_pec<P: Prefix + NonOverlappingPrefix>(target: Target) -> String {
let mut net = Network::<P, BasicEventQueue<_>>::new(BasicEventQueue::new());
net.build_topology(ASN(65500), CompleteGraph(4)).unwrap();
net.build_external_routers(ASN(65500), ASN(100), vec![0.into(), 1.into()])
.unwrap();
net.build_link_weights(100.0).unwrap();
net.build_ibgp_full_mesh().unwrap();
net.build_ebgp_sessions().unwrap();
net.advertise_route(4.into(), P::from(0), None::<ASN>, None, None)
.unwrap();
let mut ip = addressor(&net);
ip.register_pec(
0.into(),
vec![
prefix!("200.0.1.0/24"),
prefix!("200.0.2.0/24"),
prefix!("200.0.3.0/24"),
prefix!("200.0.4.0/24"),
prefix!("200.0.5.0/24"),
],
);
let mut cfg_gen = CiscoFrrCfgGen::new(&net, 4.into(), target, iface_names(target)).unwrap();
cfg_gen.generate_config(&net, &mut ip).unwrap()
}
fn generate_external_config_withdraw(target: Target) -> (String, String) {
let mut net = Network::<SimplePrefix, BasicEventQueue<_>>::new(BasicEventQueue::new());
net.build_topology(ASN(65500), CompleteGraph(4)).unwrap();
net.build_external_routers(ASN(65500), ASN(100), vec![0.into(), 1.into()])
.unwrap();
net.build_link_weights(100.0).unwrap();
net.build_ibgp_full_mesh().unwrap();
net.build_ebgp_sessions().unwrap();
net.advertise_route(4.into(), SimplePrefix::from(100), None::<ASN>, None, None)
.unwrap();
net.advertise_route(4.into(), SimplePrefix::from(101), None::<ASN>, None, None)
.unwrap();
let mut ip = addressor(&net);
let mut cfg_gen = CiscoFrrCfgGen::new(&net, 4.into(), target, iface_names(target)).unwrap();
let c = cfg_gen.generate_config(&net, &mut ip).unwrap();
println!("{c}");
let withdraw_c = cfg_gen
.generate_command(
&net,
&mut ip,
ConfigModifier::Remove(ConfigExpr::AdvertiseRoute {
router: 4.into(),
prefix: SimplePrefix::from(101),
as_path: Default::default(),
med: Default::default(),
community: Default::default(),
}),
)
.unwrap();
(c, withdraw_c)
}