]> git.puffer.fish Git - mirror/frr.git/commitdiff
tests: add bgp peer-shutdown topotest
authorMark Stapp <mjs@cisco.com>
Thu, 19 Sep 2024 19:46:56 +0000 (15:46 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Wed, 12 Mar 2025 16:42:07 +0000 (12:42 -0400)
Add a simple topotest using multiple bgp peers; based on the
ecmp_topo1 test.

Signed-off-by: Mark Stapp <mjs@cisco.com>
47 files changed:
tests/topotests/bgp_peer_shut/__init__.py [new file with mode: 0644]
tests/topotests/bgp_peer_shut/bgp-peer-shut.dot [new file with mode: 0644]
tests/topotests/bgp_peer_shut/bgp-peer-shut.pdf [new file with mode: 0644]
tests/topotests/bgp_peer_shut/exabgp.env [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer1/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer1/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer10/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer10/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer11/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer11/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer12/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer12/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer13/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer13/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer14/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer14/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer15/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer15/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer16/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer16/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer17/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer17/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer18/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer18/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer19/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer19/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer2/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer2/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer20/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer20/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer3/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer3/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer4/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer4/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer5/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer5/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer6/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer6/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer7/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer7/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer8/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer8/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/peer9/exa-send.py [new file with mode: 0755]
tests/topotests/bgp_peer_shut/peer9/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_peer_shut/r1/frr.conf [new file with mode: 0644]
tests/topotests/bgp_peer_shut/r1/summary.txt [new file with mode: 0644]
tests/topotests/bgp_peer_shut/test_bgp_peer_shut.py [new file with mode: 0644]

diff --git a/tests/topotests/bgp_peer_shut/__init__.py b/tests/topotests/bgp_peer_shut/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
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 (file)
index 0000000..290b315
--- /dev/null
@@ -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 (file)
index 0000000..fff66bb
Binary files /dev/null and b/tests/topotests/bgp_peer_shut/bgp-peer-shut.pdf differ
diff --git a/tests/topotests/bgp_peer_shut/exabgp.env b/tests/topotests/bgp_peer_shut/exabgp.env
new file mode 100644 (file)
index 0000000..ec978c6
--- /dev/null
@@ -0,0 +1,55 @@
+
+[exabgp.api]
+ack = false
+encoder = text
+highres = false
+respawn = false
+socket = ''
+
+[exabgp.bgp]
+openwait = 60
+
+[exabgp.cache]
+attributes = true
+nexthops = true
+
+[exabgp.daemon]
+daemonize = true
+pid = '/var/run/exabgp/exabgp.pid'
+user = 'exabgp'
+##daemonize = false
+
+[exabgp.log]
+all = false
+configuration = true
+daemon = true
+destination = '/var/log/exabgp.log'
+enable = true
+level = INFO
+message = false
+network = true
+packets = false
+parser = false
+processes = true
+reactor = true
+rib = false
+routes = false
+short = false
+timers = false
+
+[exabgp.pdb]
+enable = false
+
+[exabgp.profile]
+enable = false
+file = ''
+
+[exabgp.reactor]
+speed = 1.0
+
+[exabgp.tcp]
+acl = false
+bind = ''
+delay = 0
+once = false
+port = 179
diff --git a/tests/topotests/bgp_peer_shut/peer1/exa-send.py b/tests/topotests/bgp_peer_shut/peer1/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer1/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer1/exabgp.cfg
new file mode 100644 (file)
index 0000000..97a024c
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 1 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 1;
+    encoder text;
+}
+
+neighbor 10.0.1.1 {
+    router-id 10.0.1.101;
+    local-address 10.0.1.101;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer10/exa-send.py b/tests/topotests/bgp_peer_shut/peer10/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer10/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer10/exabgp.cfg
new file mode 100644 (file)
index 0000000..e318162
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 10 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 10;
+    encoder text;
+}
+
+neighbor 10.0.2.1 {
+    router-id 10.0.2.110;
+    local-address 10.0.2.110;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer11/exa-send.py b/tests/topotests/bgp_peer_shut/peer11/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer11/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer11/exabgp.cfg
new file mode 100644 (file)
index 0000000..ea5bdcc
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 11 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 11;
+    encoder text;
+}
+
+neighbor 10.0.3.1 {
+    router-id 10.0.3.111;
+    local-address 10.0.3.111;
+    local-as 111;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer12/exa-send.py b/tests/topotests/bgp_peer_shut/peer12/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer12/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer12/exabgp.cfg
new file mode 100644 (file)
index 0000000..81fb503
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 12 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 12;
+    encoder text;
+}
+
+neighbor 10.0.3.1 {
+    router-id 10.0.3.112;
+    local-address 10.0.3.112;
+    local-as 112;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer13/exa-send.py b/tests/topotests/bgp_peer_shut/peer13/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer13/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer13/exabgp.cfg
new file mode 100644 (file)
index 0000000..4007841
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 13 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 13;
+    encoder text;
+}
+
+neighbor 10.0.3.1 {
+    router-id 10.0.3.113;
+    local-address 10.0.3.113;
+    local-as 113;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer14/exa-send.py b/tests/topotests/bgp_peer_shut/peer14/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer14/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer14/exabgp.cfg
new file mode 100644 (file)
index 0000000..afb8741
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 14 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 14;
+    encoder text;
+}
+
+neighbor 10.0.3.1 {
+    router-id 10.0.3.114;
+    local-address 10.0.3.114;
+    local-as 114;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer15/exa-send.py b/tests/topotests/bgp_peer_shut/peer15/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer15/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer15/exabgp.cfg
new file mode 100644 (file)
index 0000000..9a4ca7f
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 15 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 15;
+    encoder text;
+}
+
+neighbor 10.0.3.1 {
+    router-id 10.0.3.115;
+    local-address 10.0.3.115;
+    local-as 115;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer16/exa-send.py b/tests/topotests/bgp_peer_shut/peer16/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer16/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer16/exabgp.cfg
new file mode 100644 (file)
index 0000000..a0bb88a
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 16 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 16;
+    encoder text;
+}
+
+neighbor 10.0.4.1 {
+    router-id 10.0.4.116;
+    local-address 10.0.4.116;
+    local-as 116;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer17/exa-send.py b/tests/topotests/bgp_peer_shut/peer17/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer17/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer17/exabgp.cfg
new file mode 100644 (file)
index 0000000..870d33d
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 17 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 17;
+    encoder text;
+}
+
+neighbor 10.0.4.1 {
+    router-id 10.0.4.117;
+    local-address 10.0.4.117;
+    local-as 117;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer18/exa-send.py b/tests/topotests/bgp_peer_shut/peer18/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer18/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer18/exabgp.cfg
new file mode 100644 (file)
index 0000000..c5a1ca6
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 18 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 18;
+    encoder text;
+}
+
+neighbor 10.0.4.1 {
+    router-id 10.0.4.118;
+    local-address 10.0.4.118;
+    local-as 118;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer19/exa-send.py b/tests/topotests/bgp_peer_shut/peer19/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer19/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer19/exabgp.cfg
new file mode 100644 (file)
index 0000000..f662ccf
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 19 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 19;
+    encoder text;
+}
+
+neighbor 10.0.4.1 {
+    router-id 10.0.4.119;
+    local-address 10.0.4.119;
+    local-as 119;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer2/exa-send.py b/tests/topotests/bgp_peer_shut/peer2/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer2/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer2/exabgp.cfg
new file mode 100644 (file)
index 0000000..673d6ec
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 2 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 2;
+    encoder text;
+}
+
+neighbor 10.0.1.1 {
+    router-id 10.0.1.102;
+    local-address 10.0.1.102;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer20/exa-send.py b/tests/topotests/bgp_peer_shut/peer20/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer20/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer20/exabgp.cfg
new file mode 100644 (file)
index 0000000..5ea2c91
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 20 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 20;
+    encoder text;
+}
+
+neighbor 10.0.4.1 {
+    router-id 10.0.4.120;
+    local-address 10.0.4.120;
+    local-as 120;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer3/exa-send.py b/tests/topotests/bgp_peer_shut/peer3/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer3/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer3/exabgp.cfg
new file mode 100644 (file)
index 0000000..47a25ca
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 3 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 3;
+    encoder text;
+}
+
+neighbor 10.0.1.1 {
+    router-id 10.0.1.103;
+    local-address 10.0.1.103;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer4/exa-send.py b/tests/topotests/bgp_peer_shut/peer4/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer4/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer4/exabgp.cfg
new file mode 100644 (file)
index 0000000..376ac5f
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 4 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 4;
+    encoder text;
+}
+
+neighbor 10.0.1.1 {
+    router-id 10.0.1.104;
+    local-address 10.0.1.104;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer5/exa-send.py b/tests/topotests/bgp_peer_shut/peer5/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer5/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer5/exabgp.cfg
new file mode 100644 (file)
index 0000000..878d728
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 5 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 5;
+    encoder text;
+}
+
+neighbor 10.0.1.1 {
+    router-id 10.0.1.105;
+    local-address 10.0.1.105;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer6/exa-send.py b/tests/topotests/bgp_peer_shut/peer6/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer6/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer6/exabgp.cfg
new file mode 100644 (file)
index 0000000..fc70267
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 6 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 6;
+    encoder text;
+}
+
+neighbor 10.0.2.1 {
+    router-id 10.0.2.106;
+    local-address 10.0.2.106;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer7/exa-send.py b/tests/topotests/bgp_peer_shut/peer7/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer7/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer7/exabgp.cfg
new file mode 100644 (file)
index 0000000..09827a8
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 7 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 7;
+    encoder text;
+}
+
+neighbor 10.0.2.1 {
+    router-id 10.0.2.107;
+    local-address 10.0.2.107;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer8/exa-send.py b/tests/topotests/bgp_peer_shut/peer8/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer8/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer8/exabgp.cfg
new file mode 100644 (file)
index 0000000..37c01da
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 8 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 8;
+    encoder text;
+}
+
+neighbor 10.0.2.1 {
+    router-id 10.0.2.108;
+    local-address 10.0.2.108;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/peer9/exa-send.py b/tests/topotests/bgp_peer_shut/peer9/exa-send.py
new file mode 100755 (executable)
index 0000000..d39c65d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+"""
+exa-send.py: Send a few testroutes with ExaBGP
+"""
+
+from sys import stdout, argv
+from time import sleep
+
+sleep(5)
+
+# 1st arg is peer number
+# 2nd arg is number of routes to send
+peer = int(argv[1])
+numRoutes = int(argv[2])
+if peer <= 10:
+    asnum = 99
+else:
+    asnum = peer + 100
+
+# Announce numRoutes equal routes per PE - different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.201.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes per PE - different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.202.%s.0/24 med 100 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.203.%s.0/24 med %i next-hop 10.0.%i.%i origin igp\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100)
+    )
+    stdout.flush()
+
+# Announce numRoutes equal routes with different med per PE and different neighbor AS, but same source AS
+for i in range(0, numRoutes):
+    stdout.write(
+        "announce route 10.204.%s.0/24 med %i next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+        % (i, peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+    )
+    stdout.flush()
+
+# Announce 2 different route per peer
+stdout.write(
+    "announce route 10.205.%i.0/24 next-hop 10.0.%i.%i origin igp\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100)
+)
+stdout.write(
+    "announce route 10.206.%i.0/24 next-hop 10.0.%i.%i origin igp as-path [ %i 200 ]\n"
+    % (peer, int(((peer - 1) / 5) + 1), peer + 100, asnum)
+)
+stdout.flush()
+
+# Loop endlessly to allow ExaBGP to continue running
+while True:
+    sleep(1)
diff --git a/tests/topotests/bgp_peer_shut/peer9/exabgp.cfg b/tests/topotests/bgp_peer_shut/peer9/exabgp.cfg
new file mode 100644 (file)
index 0000000..8fb5c58
--- /dev/null
@@ -0,0 +1,18 @@
+process announce-routes {
+    run /etc/exabgp/exa-send.py 9 10;
+    encoder text;
+}
+
+process receive-routes {
+    run /etc/exabgp/exa-receive.py 9;
+    encoder text;
+}
+
+neighbor 10.0.2.1 {
+    router-id 10.0.2.109;
+    local-address 10.0.2.109;
+    local-as 99;
+    peer-as 100;
+    capability {graceful-restart;}
+    api {processes [ announce-routes, receive-routes ];}
+}
diff --git a/tests/topotests/bgp_peer_shut/r1/frr.conf b/tests/topotests/bgp_peer_shut/r1/frr.conf
new file mode 100644 (file)
index 0000000..3fdfdd8
--- /dev/null
@@ -0,0 +1,60 @@
+!
+interface r1-eth0
+ ip address 10.0.1.1/24
+!
+interface r1-eth1
+ ip address 10.0.2.1/24
+!
+interface r1-eth2
+ ip address 10.0.3.1/24
+!
+interface r1-eth3
+ ip address 10.0.4.1/24
+!
+!
+router bgp 100
+ bgp router-id 10.0.255.1
+ bgp bestpath as-path multipath-relax
+ no bgp ebgp-requires-policy
+ neighbor 10.0.1.101 remote-as 99
+ neighbor 10.0.1.101 timers 3 10
+ neighbor 10.0.1.102 remote-as 99
+ neighbor 10.0.1.102 timers 3 10
+ neighbor 10.0.1.103 remote-as 99
+ neighbor 10.0.1.103 timers 3 10
+ neighbor 10.0.1.104 remote-as 99
+ neighbor 10.0.1.104 timers 3 10
+ neighbor 10.0.1.105 remote-as 99
+ neighbor 10.0.1.105 timers 3 10
+ neighbor 10.0.2.106 remote-as 99
+ neighbor 10.0.2.106 timers 3 10
+ neighbor 10.0.2.107 remote-as 99
+ neighbor 10.0.2.107 timers 3 10
+ neighbor 10.0.2.108 remote-as 99
+ neighbor 10.0.2.108 timers 3 10
+ neighbor 10.0.2.109 remote-as 99
+ neighbor 10.0.2.109 timers 3 10
+ neighbor 10.0.2.110 remote-as 99
+ neighbor 10.0.2.110 timers 3 10
+ neighbor 10.0.3.111 remote-as 111
+ neighbor 10.0.3.111 timers 3 10
+ neighbor 10.0.3.112 remote-as 112
+ neighbor 10.0.3.112 timers 3 10
+ neighbor 10.0.3.113 remote-as 113
+ neighbor 10.0.3.113 timers 3 10
+ neighbor 10.0.3.114 remote-as 114
+ neighbor 10.0.3.114 timers 3 10
+ neighbor 10.0.3.115 remote-as 115
+ neighbor 10.0.3.115 timers 3 10
+ neighbor 10.0.4.116 remote-as 116
+ neighbor 10.0.4.116 timers 3 10
+ neighbor 10.0.4.117 remote-as 117
+ neighbor 10.0.4.117 timers 3 10
+ neighbor 10.0.4.118 remote-as 118
+ neighbor 10.0.4.118 timers 3 10
+ neighbor 10.0.4.119 remote-as 119
+ neighbor 10.0.4.119 timers 3 10
+ neighbor 10.0.4.120 remote-as 120
+ neighbor 10.0.4.120 timers 3 10
+ !
+!
diff --git a/tests/topotests/bgp_peer_shut/r1/summary.txt b/tests/topotests/bgp_peer_shut/r1/summary.txt
new file mode 100644 (file)
index 0000000..68de28a
--- /dev/null
@@ -0,0 +1,131 @@
+{
+"ipv4Unicast":{
+  "routerId":"10.0.255.1",
+  "as":100,
+  "vrfName":"default",
+  "peerCount":20,
+  "peers":{
+    "10.0.1.101":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.1.102":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.1.103":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.1.104":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.1.105":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.2.106":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.2.107":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.2.108":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.2.109":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.2.110":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.3.111":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.3.112":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.3.113":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.3.114":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.3.115":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.4.116":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.4.117":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.4.118":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.4.119":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    },
+    "10.0.4.120":{
+      "outq":0,
+      "inq":0,
+      "pfxRcd":42,
+      "state":"Established"
+    }
+  },
+  "totalPeers":20
+}
+}
diff --git a/tests/topotests/bgp_peer_shut/test_bgp_peer_shut.py b/tests/topotests/bgp_peer_shut/test_bgp_peer_shut.py
new file mode 100644 (file)
index 0000000..23f92ba
--- /dev/null
@@ -0,0 +1,178 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: ISC
+
+#
+# test_bgp_peer_shut.py
+# Part of FRR Topology Tests
+#
+# Copyright (c) 2017, 2024 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+
+"""
+test_bgp_peer_shut.py: Test BGP peer shutdown
+"""
+
+import json
+import functools
+import os
+import sys
+import pytest
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+
+pytestmark = [pytest.mark.bgpd]
+
+
+total_ebgp_peers = 20
+
+#####################################################
+#
+#   Network Topology Definition
+#
+#####################################################
+
+
+def build_topo(tgen):
+    router = tgen.add_router("r1")
+
+    # Setup Switches - 1 switch per 5 peering routers
+    for swNum in range(1, (total_ebgp_peers + 4) // 5 + 1):
+        switch = tgen.add_switch("s{}".format(swNum))
+        switch.add_link(router)
+
+    # Add 'total_ebgp_peers' number of eBGP ExaBGP neighbors
+    for peerNum in range(1, total_ebgp_peers + 1):
+        swNum = (peerNum - 1) // 5 + 1
+
+        peer_ip = "10.0.{}.{}".format(swNum, peerNum + 100)
+        peer_route = "via 10.0.{}.1".format(swNum)
+        peer = tgen.add_exabgp_peer(
+            "peer{}".format(peerNum), ip=peer_ip, defaultRoute=peer_route
+        )
+
+        switch = tgen.gears["s{}".format(swNum)]
+        switch.add_link(peer)
+
+
+#####################################################
+#
+#   Tests starting
+#
+#####################################################
+
+
+def setup_module(module):
+    tgen = Topogen(build_topo, module.__name__)
+    tgen.start_topology()
+
+    # Starting Routers
+    router_list = tgen.routers()
+    for rname, router in router_list.items():
+        router.load_frr_config(
+            os.path.join(CWD, "{}/frr.conf".format(rname)),
+            [(TopoRouter.RD_ZEBRA, None), (TopoRouter.RD_BGP, None)],
+        )
+        router.start()
+
+    # Starting Hosts and init ExaBGP on each of them
+    topotest.sleep(10, "starting BGP on all {} peers".format(total_ebgp_peers))
+    peer_list = tgen.exabgp_peers()
+    for pname, peer in peer_list.items():
+        peer_dir = os.path.join(CWD, pname)
+        env_file = os.path.join(CWD, "exabgp.env")
+        peer.start(peer_dir, env_file)
+        logger.info(pname)
+
+
+def teardown_module(module):
+    del module
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_convergence():
+    "Test for BGP topology convergence"
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    # Expected result
+    router = tgen.gears["r1"]
+    reffile = os.path.join(CWD, "r1/summary.txt")
+
+    expected = json.loads(open(reffile).read())
+
+    def _output_summary_cmp(router, cmd, data):
+        """
+        Runs `cmd` that returns JSON data (normally the command ends
+        with 'json') and compare with `data` contents.
+        """
+        output = router.vtysh_cmd(cmd, isjson=True)
+        return topotest.json_cmp(output, data)
+
+    test_func = functools.partial(
+        _output_summary_cmp, router, "show ip bgp summary json", expected
+    )
+    _, res = topotest.run_and_expect(test_func, None, count=30, wait=1.0)
+    assertmsg = "BGP router network did not converge"
+    assert res is None, assertmsg
+
+
+def test_bgp_peer_shut():
+    "Test shutdown of all exabgp peers"
+
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info("=== Checking for bgp routes ===")
+
+    expect = {
+        "routerId": "10.0.255.1",
+        "routes": {},
+    }
+
+    for net in range(1, 5):
+        for subnet in range(0, 10):
+            netkey = "10.20{}.{}.0/24".format(net, subnet)
+            expect["routes"][netkey] = []
+            for _ in range(0, 10):
+                peer = {"multipath": True, "valid": True}
+                expect["routes"][netkey].append(peer)
+
+    test_func = functools.partial(
+        topotest.router_json_cmp, tgen.gears["r1"], "show ip bgp json", expect
+    )
+    _, res = topotest.run_and_expect(test_func, None, count=40, wait=0.5)
+    assertmsg = 'expected multipath routes in "show ip bgp" output'
+    assert res is None, assertmsg
+
+    logger.info("=== Stopping all dynamic peers ===")
+
+    # Stop the dynamic peers
+    epeers = tgen.exabgp_peers()
+    for key in epeers:
+        epeers[key].stop()
+
+    # for debugging
+    #tgen.cli()
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))