From 9104f54962e0a9712797dbdf384bfb008e779419 Mon Sep 17 00:00:00 2001 From: Martin Winter Date: Fri, 21 Aug 2020 01:36:21 +0200 Subject: [PATCH] tests: Add new bgp_features testsuite with test for bgp shutdown Signed-off-by: Martin Winter --- .../bgp_features/r1/bgp_shutdown_summary.json | 20 ++ .../bgp_features/r1/bgp_summary.json | 28 ++ tests/topotests/bgp_features/r1/bgpd.conf | 35 +++ tests/topotests/bgp_features/r1/ospf6d.conf | 22 ++ .../bgp_features/r1/ospf_neighbor.json | 16 + tests/topotests/bgp_features/r1/ospfd.conf | 12 + tests/topotests/bgp_features/r1/zebra.conf | 28 ++ .../bgp_features/r2/bgp_shutdown_summary.json | 20 ++ .../bgp_features/r2/bgp_summary.json | 28 ++ tests/topotests/bgp_features/r2/bgpd.conf | 35 +++ tests/topotests/bgp_features/r2/ospf6d.conf | 22 ++ .../bgp_features/r2/ospf_neighbor.json | 16 + tests/topotests/bgp_features/r2/ospfd.conf | 12 + tests/topotests/bgp_features/r2/zebra.conf | 28 ++ .../bgp_features/r3/bgp_summary.json | 0 tests/topotests/bgp_features/r3/ospf6d.conf | 22 ++ .../bgp_features/r3/ospf_neighbor.json | 16 + tests/topotests/bgp_features/r3/ospfd.conf | 12 + tests/topotests/bgp_features/r3/zebra.conf | 23 ++ .../bgp_features/r4/bgp_shutdown_summary.json | 15 + .../bgp_features/r4/bgp_summary.json | 19 ++ tests/topotests/bgp_features/r4/bgpd.conf | 30 ++ tests/topotests/bgp_features/r4/zebra.conf | 18 ++ .../bgp_features/r5/bgp_summary.json | 20 ++ tests/topotests/bgp_features/r5/bgpd.conf | 30 ++ tests/topotests/bgp_features/r5/zebra.conf | 18 ++ .../bgp_features/test_bgp_features.dot | 83 ++++++ .../bgp_features/test_bgp_features.pdf | Bin 0 -> 20710 bytes .../bgp_features/test_bgp_features.py | 274 ++++++++++++++++++ 29 files changed, 902 insertions(+) create mode 100644 tests/topotests/bgp_features/r1/bgp_shutdown_summary.json create mode 100644 tests/topotests/bgp_features/r1/bgp_summary.json create mode 100644 tests/topotests/bgp_features/r1/bgpd.conf create mode 100644 tests/topotests/bgp_features/r1/ospf6d.conf create mode 100644 tests/topotests/bgp_features/r1/ospf_neighbor.json create mode 100644 tests/topotests/bgp_features/r1/ospfd.conf create mode 100644 tests/topotests/bgp_features/r1/zebra.conf create mode 100644 tests/topotests/bgp_features/r2/bgp_shutdown_summary.json create mode 100644 tests/topotests/bgp_features/r2/bgp_summary.json create mode 100644 tests/topotests/bgp_features/r2/bgpd.conf create mode 100644 tests/topotests/bgp_features/r2/ospf6d.conf create mode 100644 tests/topotests/bgp_features/r2/ospf_neighbor.json create mode 100644 tests/topotests/bgp_features/r2/ospfd.conf create mode 100644 tests/topotests/bgp_features/r2/zebra.conf create mode 100644 tests/topotests/bgp_features/r3/bgp_summary.json create mode 100644 tests/topotests/bgp_features/r3/ospf6d.conf create mode 100644 tests/topotests/bgp_features/r3/ospf_neighbor.json create mode 100644 tests/topotests/bgp_features/r3/ospfd.conf create mode 100644 tests/topotests/bgp_features/r3/zebra.conf create mode 100644 tests/topotests/bgp_features/r4/bgp_shutdown_summary.json create mode 100644 tests/topotests/bgp_features/r4/bgp_summary.json create mode 100644 tests/topotests/bgp_features/r4/bgpd.conf create mode 100644 tests/topotests/bgp_features/r4/zebra.conf create mode 100644 tests/topotests/bgp_features/r5/bgp_summary.json create mode 100644 tests/topotests/bgp_features/r5/bgpd.conf create mode 100644 tests/topotests/bgp_features/r5/zebra.conf create mode 100644 tests/topotests/bgp_features/test_bgp_features.dot create mode 100644 tests/topotests/bgp_features/test_bgp_features.pdf create mode 100755 tests/topotests/bgp_features/test_bgp_features.py diff --git a/tests/topotests/bgp_features/r1/bgp_shutdown_summary.json b/tests/topotests/bgp_features/r1/bgp_shutdown_summary.json new file mode 100644 index 0000000000..70b70de1d1 --- /dev/null +++ b/tests/topotests/bgp_features/r1/bgp_shutdown_summary.json @@ -0,0 +1,20 @@ +{ +"ipv4Unicast":{ + "routerId":"192.168.0.1", + "as":65000, + "vrfId":0, + "vrfName":"default", + "peerCount":2, + "peers":{ + "192.168.0.2":{ + "remoteAs":65000, + "state":"Idle (Admin)" + }, + "192.168.101.2":{ + "remoteAs":65100, + "state":"Idle (Admin)" + } + }, + "totalPeers":2 +} +} diff --git a/tests/topotests/bgp_features/r1/bgp_summary.json b/tests/topotests/bgp_features/r1/bgp_summary.json new file mode 100644 index 0000000000..57aa992fab --- /dev/null +++ b/tests/topotests/bgp_features/r1/bgp_summary.json @@ -0,0 +1,28 @@ +{ +"ipv4Unicast":{ + "routerId":"192.168.0.1", + "as":65000, + "vrfId":0, + "vrfName":"default", + "peerCount":2, + "peers":{ + "192.168.0.2":{ + "hostname":"r2", + "remoteAs":65000, + "outq":0, + "inq":0, + "pfxRcd":7, + "state":"Established" + }, + "192.168.101.2":{ + "hostname":"r4", + "remoteAs":65100, + "outq":0, + "inq":0, + "pfxRcd":3, + "state":"Established" + } + }, + "totalPeers":2 +} +} diff --git a/tests/topotests/bgp_features/r1/bgpd.conf b/tests/topotests/bgp_features/r1/bgpd.conf new file mode 100644 index 0000000000..48b71fc91a --- /dev/null +++ b/tests/topotests/bgp_features/r1/bgpd.conf @@ -0,0 +1,35 @@ +! +hostname r1 +log file bgpd.log +! +router bgp 65000 + bgp router-id 192.168.0.1 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 192.168.0.2 remote-as 65000 + neighbor 192.168.0.2 description Router R2 (iBGP) + neighbor 192.168.0.2 update-source lo + neighbor 192.168.101.2 remote-as 65100 + neighbor 192.168.101.2 description Router R4 (eBGP AS 65100) + ! + address-family ipv4 unicast + network 192.168.0.0/24 + network 192.168.1.0/24 + network 192.168.2.0/24 + network 192.168.3.0/24 + network 192.168.6.0/24 + network 192.168.8.0/24 + neighbor 192.168.101.2 route-map testmap-in in + neighbor 192.168.101.2 route-map testmap-out out + exit-address-family +! +! +! +route-map testmap-in permit 999 +! +route-map testmap-out permit 999 +! +! +line vty +! + diff --git a/tests/topotests/bgp_features/r1/ospf6d.conf b/tests/topotests/bgp_features/r1/ospf6d.conf new file mode 100644 index 0000000000..532da39fb7 --- /dev/null +++ b/tests/topotests/bgp_features/r1/ospf6d.conf @@ -0,0 +1,22 @@ +log file ospf6d.log +! +debug ospf6 neighbor +! +interface r1-lo +! +interface r1-eth0 +! +interface r1-eth1 +! +interface r1-eth2 +! +router ospf6 + ospf6 router-id 192.168.0.1 + log-adjacency-changes + interface r1-lo area 0.0.0.0 + interface r1-eth0 area 0.0.0.0 + interface r1-eth1 area 0.0.0.0 + interface r1-eth2 area 0.0.0.0 +! +line vty +! diff --git a/tests/topotests/bgp_features/r1/ospf_neighbor.json b/tests/topotests/bgp_features/r1/ospf_neighbor.json new file mode 100644 index 0000000000..ecb97d8d74 --- /dev/null +++ b/tests/topotests/bgp_features/r1/ospf_neighbor.json @@ -0,0 +1,16 @@ +{ + "neighbors":{ + "192.168.0.2":[ + { + "priority":1, + "state":"Full\/DR" + } + ], + "192.168.0.3":[ + { + "priority":1, + "state":"Full\/DR" + } + ] + } +} diff --git a/tests/topotests/bgp_features/r1/ospfd.conf b/tests/topotests/bgp_features/r1/ospfd.conf new file mode 100644 index 0000000000..952abdec59 --- /dev/null +++ b/tests/topotests/bgp_features/r1/ospfd.conf @@ -0,0 +1,12 @@ +log file ospfd.log +! +debug ospf event +debug ospf zebra +! +router ospf + ospf router-id 192.168.0.1 + log-adjacency-changes + network 192.168.0.0/20 area 0.0.0.0 +! +line vty +! diff --git a/tests/topotests/bgp_features/r1/zebra.conf b/tests/topotests/bgp_features/r1/zebra.conf new file mode 100644 index 0000000000..61564f1a1a --- /dev/null +++ b/tests/topotests/bgp_features/r1/zebra.conf @@ -0,0 +1,28 @@ +! +hostname r1 +log file zebra.log +! +interface lo + ip address 192.168.0.1/32 + ipv6 address fc00::1/128 +! +interface r1-eth0 + description SW6 Stub Network + ip address 192.168.6.1/24 + ipv6 address fc00:0:0:6::1/64 +! +interface r1-eth1 + description SW0 R1-R2 OSPF & BGP Network + ip address 192.168.1.1/24 + ipv6 address fc00:0:0:1::1/64 +! +interface r1-eth2 + description SW2 R1-R3 OSPF Network + ip address 192.168.3.1/24 + ipv6 address fc00:0:0:3::1/64 +! +interface r1-eth3 + description SW4 R1-R4 eBGP Network + ip address 192.168.101.1/24 + ipv6 address fc00:100:0:1::1/64 +! diff --git a/tests/topotests/bgp_features/r2/bgp_shutdown_summary.json b/tests/topotests/bgp_features/r2/bgp_shutdown_summary.json new file mode 100644 index 0000000000..95de3e3096 --- /dev/null +++ b/tests/topotests/bgp_features/r2/bgp_shutdown_summary.json @@ -0,0 +1,20 @@ +{ +"ipv4Unicast":{ + "routerId":"192.168.0.2", + "as":65000, + "vrfId":0, + "vrfName":"default", + "peerCount":2, + "peers":{ + "192.168.0.1":{ + "remoteAs":65000, + "state":"Active" + }, + "192.168.201.2":{ + "remoteAs":65200, + "state":"Established" + } + }, + "totalPeers":2 +} +} diff --git a/tests/topotests/bgp_features/r2/bgp_summary.json b/tests/topotests/bgp_features/r2/bgp_summary.json new file mode 100644 index 0000000000..f29204116c --- /dev/null +++ b/tests/topotests/bgp_features/r2/bgp_summary.json @@ -0,0 +1,28 @@ +{ +"ipv4Unicast":{ + "routerId":"192.168.0.2", + "as":65000, + "vrfId":0, + "vrfName":"default", + "peerCount":2, + "peers":{ + "192.168.0.1":{ + "hostname":"r1", + "remoteAs":65000, + "outq":0, + "inq":0, + "pfxRcd":8, + "state":"Established" + }, + "192.168.201.2":{ + "hostname":"r5", + "remoteAs":65200, + "outq":0, + "inq":0, + "pfxRcd":2, + "state":"Established" + } + }, + "totalPeers":2 +} +} diff --git a/tests/topotests/bgp_features/r2/bgpd.conf b/tests/topotests/bgp_features/r2/bgpd.conf new file mode 100644 index 0000000000..775733d1d3 --- /dev/null +++ b/tests/topotests/bgp_features/r2/bgpd.conf @@ -0,0 +1,35 @@ +! +hostname r2 +log file bgpd.log +! +router bgp 65000 + bgp router-id 192.168.0.2 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 192.168.0.1 remote-as 65000 + neighbor 192.168.0.1 description Router R1 (iBGP) + neighbor 192.168.0.1 update-source lo + neighbor 192.168.201.2 remote-as 65200 + neighbor 192.168.201.2 description Router R5 (eBGP AS 65200) + ! + address-family ipv4 unicast + network 192.168.0.0/24 + network 192.168.1.0/24 + network 192.168.2.0/24 + network 192.168.3.0/24 + network 192.168.7.0/24 + network 192.168.8.0/24 + neighbor 192.168.201.2 route-map testmap-in in + neighbor 192.168.201.2 route-map testmap-out out + exit-address-family +! +! +! +route-map testmap-in permit 999 +! +route-map testmap-out permit 999 +! +! +line vty +! + diff --git a/tests/topotests/bgp_features/r2/ospf6d.conf b/tests/topotests/bgp_features/r2/ospf6d.conf new file mode 100644 index 0000000000..283d205489 --- /dev/null +++ b/tests/topotests/bgp_features/r2/ospf6d.conf @@ -0,0 +1,22 @@ +log file ospf6d.log +! +debug ospf6 neighbor +! +interface r2-lo +! +interface r2-eth0 +! +interface r2-eth1 +! +interface r2-eth2 +! +router ospf6 + ospf6 router-id 192.168.0.2 + log-adjacency-changes + interface r2-lo area 0.0.0.0 + interface r2-eth0 area 0.0.0.0 + interface r2-eth1 area 0.0.0.0 + interface r2-eth2 area 0.0.0.0 +! +line vty +! diff --git a/tests/topotests/bgp_features/r2/ospf_neighbor.json b/tests/topotests/bgp_features/r2/ospf_neighbor.json new file mode 100644 index 0000000000..5fcbd82ee1 --- /dev/null +++ b/tests/topotests/bgp_features/r2/ospf_neighbor.json @@ -0,0 +1,16 @@ +{ + "neighbors":{ + "192.168.0.1":[ + { + "priority":1, + "state":"Full\/Backup" + } + ], + "192.168.0.3":[ + { + "priority":1, + "state":"Full\/DR" + } + ] + } +} diff --git a/tests/topotests/bgp_features/r2/ospfd.conf b/tests/topotests/bgp_features/r2/ospfd.conf new file mode 100644 index 0000000000..c9ebfe506e --- /dev/null +++ b/tests/topotests/bgp_features/r2/ospfd.conf @@ -0,0 +1,12 @@ +log file ospfd.log +! +debug ospf event +debug ospf zebra +! +router ospf + ospf router-id 192.168.0.2 + log-adjacency-changes + network 192.168.0.0/20 area 0.0.0.0 +! +line vty +! diff --git a/tests/topotests/bgp_features/r2/zebra.conf b/tests/topotests/bgp_features/r2/zebra.conf new file mode 100644 index 0000000000..1d427da6f5 --- /dev/null +++ b/tests/topotests/bgp_features/r2/zebra.conf @@ -0,0 +1,28 @@ +! +hostname r2 +log file zebra.log +! +interface lo + ip address 192.168.0.2/32 + ipv6 address fc00::2/128 +! +interface r2-eth0 + description SW7 Stub Network + ip address 192.168.7.1/24 + ipv6 address fc00:0:0:7::1/64 +! +interface r2-eth1 + description SW0 R1-R2 OSPF & BGP Network + ip address 192.168.1.2/24 + ipv6 address fc00:0:0:1::2/64 +! +interface r2-eth2 + description SW1 R2-R3 OSPF Network + ip address 192.168.2.1/24 + ipv6 address fc00:0:0:2::1/64 +! +interface r2-eth3 + description SW5 R2-R5 eBGP Network + ip address 192.168.201.1/24 + ipv6 address fc00:200:0:1::1/64 +! diff --git a/tests/topotests/bgp_features/r3/bgp_summary.json b/tests/topotests/bgp_features/r3/bgp_summary.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/topotests/bgp_features/r3/ospf6d.conf b/tests/topotests/bgp_features/r3/ospf6d.conf new file mode 100644 index 0000000000..7a6623f979 --- /dev/null +++ b/tests/topotests/bgp_features/r3/ospf6d.conf @@ -0,0 +1,22 @@ +log file ospf6d.log +! +debug ospf6 neighbor +! +interface r3-lo +! +interface r3-eth0 +! +interface r3-eth1 +! +interface r3-eth2 +! +router ospf6 + ospf6 router-id 192.168.0.3 + log-adjacency-changes + interface r3-lo area 0.0.0.0 + interface r3-eth0 area 0.0.0.0 + interface r3-eth1 area 0.0.0.0 + interface r3-eth2 area 0.0.0.0 +! +line vty +! diff --git a/tests/topotests/bgp_features/r3/ospf_neighbor.json b/tests/topotests/bgp_features/r3/ospf_neighbor.json new file mode 100644 index 0000000000..e90a70a8f6 --- /dev/null +++ b/tests/topotests/bgp_features/r3/ospf_neighbor.json @@ -0,0 +1,16 @@ +{ + "neighbors":{ + "192.168.0.1":[ + { + "priority":1, + "state":"Full\/Backup" + } + ], + "192.168.0.2":[ + { + "priority":1, + "state":"Full\/Backup" + } + ] + } +} diff --git a/tests/topotests/bgp_features/r3/ospfd.conf b/tests/topotests/bgp_features/r3/ospfd.conf new file mode 100644 index 0000000000..a8d66f1ed3 --- /dev/null +++ b/tests/topotests/bgp_features/r3/ospfd.conf @@ -0,0 +1,12 @@ +log file ospfd.log +! +debug ospf event +debug ospf zebra +! +router ospf + ospf router-id 192.168.0.3 + log-adjacency-changes + network 192.168.0.0/20 area 0.0.0.0 +! +line vty +! diff --git a/tests/topotests/bgp_features/r3/zebra.conf b/tests/topotests/bgp_features/r3/zebra.conf new file mode 100644 index 0000000000..62ba04d81b --- /dev/null +++ b/tests/topotests/bgp_features/r3/zebra.conf @@ -0,0 +1,23 @@ +! +hostname r3 +log file zebra.log +! +interface lo + ip address 192.168.0.3/32 + ipv6 address fc00::3/128 +! +interface r3-eth0 + description SW8 Stub Network + ip address 192.168.8.1/24 + ipv6 address fc00:0:0:8::1/64 +! +interface r3-eth1 + description SW1 R2-R3 OSPF Network + ip address 192.168.2.2/24 + ipv6 address fc00:0:0:2::2/64 +! +interface r3-eth2 + description SW2 R1-R3 OSPF Network + ip address 192.168.3.2/24 + ipv6 address fc00:0:0:3::2/64 +! diff --git a/tests/topotests/bgp_features/r4/bgp_shutdown_summary.json b/tests/topotests/bgp_features/r4/bgp_shutdown_summary.json new file mode 100644 index 0000000000..c22cbdadcd --- /dev/null +++ b/tests/topotests/bgp_features/r4/bgp_shutdown_summary.json @@ -0,0 +1,15 @@ +{ +"ipv4Unicast":{ + "routerId":"192.168.100.1", + "as":65100, + "vrfId":0, + "vrfName":"default", + "peerCount":1, + "peers":{ + "192.168.101.1":{ + "remoteAs":65000, + "state":"Active" } + }, + "totalPeers":1 +} +} diff --git a/tests/topotests/bgp_features/r4/bgp_summary.json b/tests/topotests/bgp_features/r4/bgp_summary.json new file mode 100644 index 0000000000..d147602c74 --- /dev/null +++ b/tests/topotests/bgp_features/r4/bgp_summary.json @@ -0,0 +1,19 @@ +{ +"ipv4Unicast":{ + "routerId":"192.168.100.1", + "as":65100, + "vrfId":0, + "vrfName":"default", + "peerCount":1, + "peers":{ + "192.168.101.1":{ + "hostname":"r1", + "remoteAs":65000, + "outq":0, + "inq":0, + "pfxRcd":6, + "state":"Established" } + }, + "totalPeers":1 +} +} diff --git a/tests/topotests/bgp_features/r4/bgpd.conf b/tests/topotests/bgp_features/r4/bgpd.conf new file mode 100644 index 0000000000..83b452b86d --- /dev/null +++ b/tests/topotests/bgp_features/r4/bgpd.conf @@ -0,0 +1,30 @@ +! +hostname r4 +log file bgpd.log +! +router bgp 65100 + bgp router-id 192.168.100.1 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 192.168.101.1 remote-as 65000 + neighbor 192.168.101.1 description Router R1 (eBGP AS 65000) + ! + address-family ipv4 unicast + network 192.168.100.0/24 + network 192.168.101.0/24 + network 192.168.102.0/24 + neighbor 192.168.101.1 default-originate + neighbor 192.168.101.1 route-map testmap-in in + neighbor 192.168.101.1 route-map testmap-out out + exit-address-family +! +! +! +route-map testmap-in permit 999 +! +route-map testmap-out permit 999 +! +! +line vty +! + diff --git a/tests/topotests/bgp_features/r4/zebra.conf b/tests/topotests/bgp_features/r4/zebra.conf new file mode 100644 index 0000000000..08e3e1aec9 --- /dev/null +++ b/tests/topotests/bgp_features/r4/zebra.conf @@ -0,0 +1,18 @@ +! +hostname r4 +log file zebra.log +! +interface lo + ip address 192.168.100.1/32 + ipv6 address fc00:100::1/128 +! +interface r4-eth0 + description SW5 Stub Network + ip address 192.168.102.1/24 + ipv6 address fc00:100:0:2::1/64 +! +interface r4-eth1 + description SW0 R1-R2 OSPF & BGP Network + ip address 192.168.101.2/24 + ipv6 address fc00:100:0:1::2/64 +! diff --git a/tests/topotests/bgp_features/r5/bgp_summary.json b/tests/topotests/bgp_features/r5/bgp_summary.json new file mode 100644 index 0000000000..f303aa6c72 --- /dev/null +++ b/tests/topotests/bgp_features/r5/bgp_summary.json @@ -0,0 +1,20 @@ +{ +"ipv4Unicast":{ + "routerId":"192.168.200.1", + "as":65200, + "vrfId":0, + "vrfName":"default", + "peerCount":1, + "peers":{ + "192.168.201.1":{ + "hostname":"r2", + "remoteAs":65000, + "outq":0, + "inq":0, + "pfxRcd":6, + "state":"Established" + } + }, + "totalPeers":1 +} +} diff --git a/tests/topotests/bgp_features/r5/bgpd.conf b/tests/topotests/bgp_features/r5/bgpd.conf new file mode 100644 index 0000000000..a6a42a007c --- /dev/null +++ b/tests/topotests/bgp_features/r5/bgpd.conf @@ -0,0 +1,30 @@ +! +hostname r5 +log file bgpd.log +! +router bgp 65200 + bgp router-id 192.168.200.1 + bgp log-neighbor-changes + no bgp ebgp-requires-policy + neighbor 192.168.201.1 remote-as 65000 + neighbor 192.168.201.1 description Router R2 (eBGP AS 65000) + ! + address-family ipv4 unicast + network 192.168.200.0/24 + network 192.168.201.0/24 + network 192.168.202.0/24 + neighbor 192.168.101.1 default-originate + neighbor 192.168.201.1 route-map testmap-in in + neighbor 192.168.201.1 route-map testmap-out out + exit-address-family +! +! +! +route-map testmap-in permit 999 +! +route-map testmap-out permit 999 +! +! +line vty +! + diff --git a/tests/topotests/bgp_features/r5/zebra.conf b/tests/topotests/bgp_features/r5/zebra.conf new file mode 100644 index 0000000000..4d9064a593 --- /dev/null +++ b/tests/topotests/bgp_features/r5/zebra.conf @@ -0,0 +1,18 @@ +! +hostname r5 +log file zebra.log +! +interface lo + ip address 192.168.200.1/32 + ipv6 address fc00:200::1/128 +! +interface r5-eth0 + description SW6 Stub Network + ip address 192.168.202.1/24 + ipv6 address fc00:200:0:2::1/64 +! +interface r5-eth1 + description SW0 R1-R2 OSPF & BGP Network + ip address 192.168.201.2/24 + ipv6 address fc00:200:0:1::2/64 +! diff --git a/tests/topotests/bgp_features/test_bgp_features.dot b/tests/topotests/bgp_features/test_bgp_features.dot new file mode 100644 index 0000000000..70b126ce8b --- /dev/null +++ b/tests/topotests/bgp_features/test_bgp_features.dot @@ -0,0 +1,83 @@ +## GraphViz file for test_all_protocol_startup +## +## Color coding: +######################### +## Main FRR: #f08080 red +## No protocol: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #33ff99 light green +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +## LDP IPv4 #fedbe2 light pink +##### Colors (see http://www.color-hex.com/) + +graph test_all_protocol_startup { + overlap=false; + constraint=false; + + // title + labelloc="t"; + label="Test Topologoy BGP Features"; + rankdir = TB; + + ###################### + # Routers + ###################### + + # Main FRR Router with all protocols + R4 [shape=doubleoctagon, label="R4 FRR\nAS 65100\nlo: 192.168.100.1/32\nfc00:100::1/128", fillcolor="#f08080", style=filled]; + R5 [shape=doubleoctagon, label="R5 FRR\nAS 65200\nlo: 192.168.200.1/32\nfc00:200::1/128", fillcolor="#f08080", style=filled]; + #{ rank = same {R4, R5}} + + R1 [shape=doubleoctagon, label="R1 FRR\nAS 65000\nlo: 192.168.0.1/32\nfc00::1/128", fillcolor="#f08080", style=filled]; + R2 [shape=doubleoctagon, label="R2 FRR\nAS 65000\nlo: 192.168.0.1/32\nfc00::1/128", fillcolor="#f08080", style=filled]; + #{ rank = same { R1, R2}} + + R3 [shape=doubleoctagon, label="R3 FRR\nAS 65000\nlo: 192.168.0.1/32\nfc00::1/128", fillcolor="#f08080", style=filled]; + + ###################### + # Network Lists + ###################### + + SW1_R1_R2 [label="SW1 OSPF & iBGP\n192.168.1.0/24\nfc00:0:0:1::/64", fillcolor="#32b835", style=filled]; + SW2_R2_R3 [label="SW2 OSPF\n192.168.2.0/24\nfc00:0:0:2::/64", fillcolor="#19e3d9", style=filled]; + SW3_R3_R1 [label="SW3 OSPF\n192.168.3.0/24\nfc00:0:0:3::/64", fillcolor="#19e3d9", style=filled]; + + SW4_R4_R1 [label="SW4 eBGP\n192.168.101.0/24\nfc00:100:0:1::/64", fillcolor="#fedbe2", style=filled]; + SW5_R5_R2 [label="SW5 eBGP\n192.168.201.0/24\nfc00:200:0:1::/64", fillcolor="#fedbe2", style=filled]; + #{ rank = same {SW4_R4_R1, SW5_R5_R2}} + + SW6_STUB_R1 [label="SW6\n192.168.6.0/24\nfc00:0:0:6::/64", fillcolor="#d0e0d0", style=filled]; + SW7_STUB_R2 [label="SW7\n192.168.7.0/24\nfc00:0:0:7::/64", fillcolor="#d0e0d0", style=filled]; + SW8_STUB_R3 [label="SW8\n192.168.8.0/24\nfc00:0:0:8::/64", fillcolor="#d0e0d0", style=filled]; + SW9_STUB_R4 [label="SW9\n192.168.102.0/24\nfc00:100:0:2::/64", fillcolor="#d0e0d0", style=filled]; + SW10_STUB_R5 [label="SW10\n192.168.202.0/24\nfc00:200:0:2::/64", fillcolor="#d0e0d0", style=filled]; + + + ###################### + # Network Connections + ###################### + + R1 -- SW6_STUB_R1 [label = "eth0\n.1\n::1"]; + R2 -- SW7_STUB_R2 [label = "eth0\n.1\n::1"]; + R3 -- SW8_STUB_R3 [label = "eth0\n.1\n::1"]; + R4 -- SW9_STUB_R4 [label = "eth0\n.1\n::1"]; + R5 -- SW10_STUB_R5 [label = "eth0\n.1\n::1"]; + + R1 -- SW1_R1_R2 [label = "eth1\n.1\n::1"]; + R1 -- SW3_R3_R1 [label = "eth2\n.1\n::1"]; + R2 -- SW1_R1_R2 [label = "eth1\n.2\n::2"]; + R2 -- SW2_R2_R3 [label = "eth2\n.1\n::1"]; + R3 -- SW2_R2_R3 [label = "eth1\n.2\n::2"]; + R3 -- SW3_R3_R1 [label = "eth2\n.2\n::2"]; + + R1 -- SW4_R4_R1 [label = "eth3\n.1\n::1"]; + R2 -- SW5_R5_R2 [label = "eth3\n.1\n::1"]; + R4 -- SW4_R4_R1 [label = "eth1\n.2\n::2"]; + R5 -- SW5_R5_R2 [label = "eth1\n.2\n::2"]; + +} diff --git a/tests/topotests/bgp_features/test_bgp_features.pdf b/tests/topotests/bgp_features/test_bgp_features.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cb52a54762081d1a7fa23d6efe5c03abf8ac2f4a GIT binary patch literal 20710 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