From b45520c4ac9e3fc382869e32a305419ae81764f5 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Thu, 19 Sep 2024 15:46:56 -0400 Subject: [PATCH] tests: add bgp peer-shutdown topotest Add a simple topotest using multiple bgp peers; based on the ecmp_topo1 test. Signed-off-by: Mark Stapp --- tests/topotests/bgp_peer_shut/__init__.py | 0 .../topotests/bgp_peer_shut/bgp-peer-shut.dot | 206 ++++++++++++++++++ .../topotests/bgp_peer_shut/bgp-peer-shut.pdf | Bin 0 -> 11891 bytes tests/topotests/bgp_peer_shut/exabgp.env | 55 +++++ .../topotests/bgp_peer_shut/peer1/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer1/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer10/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer10/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer11/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer11/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer12/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer12/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer13/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer13/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer14/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer14/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer15/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer15/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer16/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer16/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer17/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer17/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer18/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer18/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer19/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer19/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer2/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer2/exabgp.cfg | 18 ++ .../bgp_peer_shut/peer20/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer20/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer3/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer3/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer4/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer4/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer5/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer5/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer6/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer6/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer7/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer7/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer8/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer8/exabgp.cfg | 18 ++ .../topotests/bgp_peer_shut/peer9/exa-send.py | 66 ++++++ .../topotests/bgp_peer_shut/peer9/exabgp.cfg | 18 ++ tests/topotests/bgp_peer_shut/r1/bgpd.conf | 51 +++++ tests/topotests/bgp_peer_shut/r1/summary.txt | 131 +++++++++++ tests/topotests/bgp_peer_shut/r1/zebra.conf | 16 ++ .../bgp_peer_shut/test_bgp_peer_shut.py | 180 +++++++++++++++ 48 files changed, 2319 insertions(+) create mode 100644 tests/topotests/bgp_peer_shut/__init__.py create mode 100644 tests/topotests/bgp_peer_shut/bgp-peer-shut.dot create mode 100644 tests/topotests/bgp_peer_shut/bgp-peer-shut.pdf create mode 100644 tests/topotests/bgp_peer_shut/exabgp.env create mode 100755 tests/topotests/bgp_peer_shut/peer1/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer1/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer10/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer10/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer11/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer11/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer12/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer12/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer13/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer13/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer14/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer14/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer15/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer15/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer16/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer16/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer17/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer17/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer18/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer18/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer19/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer19/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer2/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer2/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer20/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer20/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer3/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer3/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer4/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer4/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer5/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer5/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer6/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer6/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer7/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer7/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer8/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer8/exabgp.cfg create mode 100755 tests/topotests/bgp_peer_shut/peer9/exa-send.py create mode 100644 tests/topotests/bgp_peer_shut/peer9/exabgp.cfg create mode 100644 tests/topotests/bgp_peer_shut/r1/bgpd.conf create mode 100644 tests/topotests/bgp_peer_shut/r1/summary.txt create mode 100644 tests/topotests/bgp_peer_shut/r1/zebra.conf create mode 100644 tests/topotests/bgp_peer_shut/test_bgp_peer_shut.py diff --git a/tests/topotests/bgp_peer_shut/__init__.py b/tests/topotests/bgp_peer_shut/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_peer_shut/bgp-peer-shut.dot b/tests/topotests/bgp_peer_shut/bgp-peer-shut.dot new file mode 100644 index 000000000000..290b31509df4 --- /dev/null +++ b/tests/topotests/bgp_peer_shut/bgp-peer-shut.dot @@ -0,0 +1,206 @@ +## Color coding: +######################### +## Main FRR: #f08080 red +## Switches: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #fcb314 dark yellow +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +##### Colors (see http://www.color-hex.com/) + +graph ospf_ecmp_iBGP_topo1 { + label="bgp peer shut - eBGP peer shut"; + labelloc="t"; + + # Routers + r1 [ + label="r1\nrtr-id 10.0.255.1/32", + shape=doubleoctagon, + fillcolor="#f08080", + style=filled, + ]; + + # 4 Switches for eBGP Peers + s1 [ + label="s1\n10.0.1.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s2 [ + label="s2\n10.0.2.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s3 [ + label="s3\n10.0.3.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + s4 [ + label="s4\n10.0.4.0/24", + shape=oval, + fillcolor="#d0e0d0", + style=filled, + ]; + + # 20 ExaBGP Peers AS 101...120 + peer1 [ + label="eBGP peer1\nAS99\nrtr-id 10.0.1.101/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer2 [ + label="eBGP peer2\nAS99\nrtr-id 10.0.1.102/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer3 [ + label="eBGP peer3\nAS99\nrtr-id 10.0.1.103/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer4 [ + label="eBGP peer4\nAS99\nrtr-id 10.0.1.104/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer5 [ + label="eBGP peer5\nAS99\nrtr-id 10.0.1.105/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer6 [ + label="eBGP peer6\nAS99\nrtr-id 10.0.2.106/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer7 [ + label="eBGP peer7\nAS99\nrtr-id 10.0.2.107/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer8 [ + label="eBGP peer8\nAS99\nrtr-id 10.0.2.108/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer9 [ + label="eBGP peer9\nAS99\nrtr-id 10.0.2.109/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer10 [ + label="eBGP peer10\nAS99\nrtr-id 10.0.2.110/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer11 [ + label="eBGP peer11\nAS111\nrtr-id 10.0.3.111/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer12 [ + label="eBGP peer12\nAS112\nrtr-id 10.0.3.112/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer13 [ + label="eBGP peer13\nAS113\nrtr-id 10.0.3.113/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer14 [ + label="eBGP peer14\nAS114\nrtr-id 10.0.3.114/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer15 [ + label="eBGP peer15\nAS115\nrtr-id 10.0.3.115/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer16 [ + label="eBGP peer16\nAS116\nrtr-id 10.0.4.116/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer17 [ + label="eBGP peer17\nAS117\nrtr-id 10.0.4.117/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer18 [ + label="eBGP peer18\nAS118\nrtr-id 10.0.4.118/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer19 [ + label="eBGP peer19\nAS119\nrtr-id 10.0.4.119/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + peer20 [ + label="eBGP peer20\nAS120\nrtr-id 10.0.4.120/32", + shape=rectangle, + fillcolor="#eee3d3", + style=filled, + ]; + + # Connections + r1 -- s1 [label="eth0\n.1"]; + r1 -- s2 [label="eth1\n.1"]; + r1 -- s3 [label="eth2\n.1"]; + r1 -- s4 [label="eth3\n.1"]; + + peer1 -- s1 [label="eth0\n.101"]; + peer2 -- s1 [label="eth0\n.102"]; + peer3 -- s1 [label="eth0\n.103"]; + peer4 -- s1 [label="eth0\n.104"]; + peer5 -- s1 [label="eth0\n.105"]; + peer6 -- s2 [label="eth0\n.106"]; + peer7 -- s2 [label="eth0\n.107"]; + peer8 -- s2 [label="eth0\n.108"]; + peer9 -- s2 [label="eth0\n.109"]; + peer10 -- s2 [label="eth0\n.110"]; + peer11 -- s3 [label="eth0\n.111"]; + peer12 -- s3 [label="eth0\n.112"]; + peer13 -- s3 [label="eth0\n.113"]; + peer14 -- s3 [label="eth0\n.114"]; + peer15 -- s3 [label="eth0\n.115"]; + peer16 -- s4 [label="eth0\n.116"]; + peer17 -- s4 [label="eth0\n.117"]; + peer18 -- s4 [label="eth0\n.118"]; + peer19 -- s4 [label="eth0\n.119"]; + peer20 -- s4 [label="eth0\n.120"]; + + # Arrange network to make cleaner diagram + { rank=same peer1 peer2 peer3 peer4 peer5 } -- s1 -- { rank=same peer6 peer7 peer8 peer9 peer10 } -- s2 + -- { rank=same peer11 peer12 peer13 peer14 peer15 } -- s3 -- { rank=same peer16 peer17 peer18 peer19 peer20 } -- s4 + -- { rank=same r1 } [style=invis] +} diff --git a/tests/topotests/bgp_peer_shut/bgp-peer-shut.pdf b/tests/topotests/bgp_peer_shut/bgp-peer-shut.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fff66bb39bcf873005e6405f5dac7ec68e7ffcae GIT binary patch literal 11891 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