From ac1087fa7bd428479c6f391f65376c196399d85d Mon Sep 17 00:00:00 2001 From: Martin Winter Date: Fri, 7 Jul 2017 02:49:55 -0700 Subject: [PATCH] bgp-ecmp-topo1: Add BGP Topology for rcmp testing Signed-off-by: Martin Winter --- tests/topotests/bgp-ecmp-topo1/__init__.py | 0 .../bgp-ecmp-topo1/bgp-ecmp-topo1.dot | 206 ++++++++++++++++++ .../bgp-ecmp-topo1/bgp-ecmp-topo1.pdf | Bin 0 -> 21367 bytes tests/topotests/bgp-ecmp-topo1/exabgp.env | 54 +++++ .../bgp-ecmp-topo1/peer1/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer1/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer1/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer10/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer10/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer10/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer11/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer11/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer11/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer12/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer12/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer12/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer13/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer13/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer13/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer14/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer14/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer14/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer15/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer15/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer15/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer16/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer16/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer16/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer17/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer17/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer17/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer18/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer18/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer18/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer19/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer19/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer19/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer2/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer2/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer2/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer20/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer20/exa-send.py | 49 +++++ .../bgp-ecmp-topo1/peer20/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer3/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer3/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer3/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer4/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer4/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer4/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer5/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer5/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer5/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer6/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer6/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer6/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer7/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer7/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer7/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer8/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer8/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer8/exabgp.cfg | 21 ++ .../bgp-ecmp-topo1/peer9/exa-receive.py | 38 ++++ .../bgp-ecmp-topo1/peer9/exa-send.py | 49 +++++ .../topotests/bgp-ecmp-topo1/peer9/exabgp.cfg | 21 ++ tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf | 30 +++ tests/topotests/bgp-ecmp-topo1/r1/zebra.conf | 16 ++ .../bgp-ecmp-topo1/test_bgp_ecmp_topo1.py | 175 +++++++++++++++ 67 files changed, 2641 insertions(+) create mode 100644 tests/topotests/bgp-ecmp-topo1/__init__.py create mode 100644 tests/topotests/bgp-ecmp-topo1/bgp-ecmp-topo1.dot create mode 100644 tests/topotests/bgp-ecmp-topo1/bgp-ecmp-topo1.pdf create mode 100644 tests/topotests/bgp-ecmp-topo1/exabgp.env create mode 100755 tests/topotests/bgp-ecmp-topo1/peer1/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer1/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer1/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer10/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer10/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer10/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer11/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer11/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer11/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer12/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer12/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer12/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer13/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer13/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer13/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer14/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer14/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer14/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer15/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer15/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer15/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer16/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer16/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer16/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer17/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer17/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer17/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer18/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer18/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer18/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer19/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer19/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer19/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer2/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer2/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer2/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer20/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer20/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer20/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer3/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer3/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer3/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer4/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer4/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer4/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer5/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer5/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer5/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer6/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer6/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer6/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer7/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer7/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer7/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer8/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer8/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer8/exabgp.cfg create mode 100755 tests/topotests/bgp-ecmp-topo1/peer9/exa-receive.py create mode 100755 tests/topotests/bgp-ecmp-topo1/peer9/exa-send.py create mode 100644 tests/topotests/bgp-ecmp-topo1/peer9/exabgp.cfg create mode 100644 tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf create mode 100644 tests/topotests/bgp-ecmp-topo1/r1/zebra.conf create mode 100755 tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py diff --git a/tests/topotests/bgp-ecmp-topo1/__init__.py b/tests/topotests/bgp-ecmp-topo1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/topotests/bgp-ecmp-topo1/bgp-ecmp-topo1.dot b/tests/topotests/bgp-ecmp-topo1/bgp-ecmp-topo1.dot new file mode 100644 index 0000000000..90295e199d --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/bgp-ecmp-topo1.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 ecmp topo1 - eBGP with different AS numbers"; + 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-ecmp-topo1/bgp-ecmp-topo1.pdf b/tests/topotests/bgp-ecmp-topo1/bgp-ecmp-topo1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b4d4f6a5e594424e8fe8161fb61bccc8307c73e5 GIT binary patch literal 21367 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 literal 0 HcmV?d00001 diff --git a/tests/topotests/bgp-ecmp-topo1/exabgp.env b/tests/topotests/bgp-ecmp-topo1/exabgp.env new file mode 100644 index 0000000000..a328e04962 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/exabgp.env @@ -0,0 +1,54 @@ + +[exabgp.api] +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-ecmp-topo1/peer1/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer1/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer1/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer1/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer1/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer1/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer1/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer1/exabgp.cfg new file mode 100644 index 0000000000..85314a84f3 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer1/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 1 10"; + } + + process receive-routes { + run "./exa-receive.py 1"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer10/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer10/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer10/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer10/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer10/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer10/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer10/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer10/exabgp.cfg new file mode 100644 index 0000000000..e0529181af --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer10/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 10 10"; + } + + process receive-routes { + run "./exa-receive.py 10"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer11/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer11/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer11/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer11/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer11/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer11/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer11/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer11/exabgp.cfg new file mode 100644 index 0000000000..e4a14ead60 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer11/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 11 10"; + } + + process receive-routes { + run "./exa-receive.py 11"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer12/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer12/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer12/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer12/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer12/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer12/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer12/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer12/exabgp.cfg new file mode 100644 index 0000000000..2fbef70cba --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer12/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 12 10"; + } + + process receive-routes { + run "./exa-receive.py 12"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer13/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer13/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer13/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer13/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer13/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer13/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer13/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer13/exabgp.cfg new file mode 100644 index 0000000000..0d6e746bef --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer13/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 13 10"; + } + + process receive-routes { + run "./exa-receive.py 13"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer14/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer14/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer14/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer14/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer14/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer14/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer14/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer14/exabgp.cfg new file mode 100644 index 0000000000..5ad7740311 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer14/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 14 10"; + } + + process receive-routes { + run "./exa-receive.py 14"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer15/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer15/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer15/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer15/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer15/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer15/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer15/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer15/exabgp.cfg new file mode 100644 index 0000000000..fb7ecc4429 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer15/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 15 10"; + } + + process receive-routes { + run "./exa-receive.py 15"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer16/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer16/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer16/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer16/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer16/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer16/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer16/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer16/exabgp.cfg new file mode 100644 index 0000000000..ab8edbee65 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer16/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 16 10"; + } + + process receive-routes { + run "./exa-receive.py 16"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer17/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer17/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer17/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer17/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer17/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer17/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer17/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer17/exabgp.cfg new file mode 100644 index 0000000000..49555439b4 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer17/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 17 10"; + } + + process receive-routes { + run "./exa-receive.py 17"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer18/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer18/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer18/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer18/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer18/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer18/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer18/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer18/exabgp.cfg new file mode 100644 index 0000000000..f44ff1bdb9 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer18/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 18 10"; + } + + process receive-routes { + run "./exa-receive.py 18"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer19/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer19/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer19/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer19/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer19/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer19/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer19/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer19/exabgp.cfg new file mode 100644 index 0000000000..16d2cfca40 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer19/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 19 10"; + } + + process receive-routes { + run "./exa-receive.py 19"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer2/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer2/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer2/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer2/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer2/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer2/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer2/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer2/exabgp.cfg new file mode 100644 index 0000000000..b9b5ee6232 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer2/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 2 10"; + } + + process receive-routes { + run "./exa-receive.py 2"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer20/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer20/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer20/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer20/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer20/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer20/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer20/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer20/exabgp.cfg new file mode 100644 index 0000000000..e8e49db26d --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer20/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 20 10"; + } + + process receive-routes { + run "./exa-receive.py 20"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer3/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer3/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer3/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer3/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer3/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer3/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer3/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer3/exabgp.cfg new file mode 100644 index 0000000000..26f25892e0 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer3/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 3 10"; + } + + process receive-routes { + run "./exa-receive.py 3"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer4/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer4/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer4/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer4/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer4/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer4/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer4/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer4/exabgp.cfg new file mode 100644 index 0000000000..b3aeb12492 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer4/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 4 10"; + } + + process receive-routes { + run "./exa-receive.py 4"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer5/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer5/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer5/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer5/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer5/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer5/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer5/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer5/exabgp.cfg new file mode 100644 index 0000000000..3de72cf53c --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer5/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 5 10"; + } + + process receive-routes { + run "./exa-receive.py 5"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer6/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer6/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer6/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer6/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer6/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer6/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer6/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer6/exabgp.cfg new file mode 100644 index 0000000000..1b07fb7ef0 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer6/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 6 10"; + } + + process receive-routes { + run "./exa-receive.py 6"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer7/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer7/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer7/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer7/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer7/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer7/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer7/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer7/exabgp.cfg new file mode 100644 index 0000000000..6d0e82a0b4 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer7/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 7 10"; + } + + process receive-routes { + run "./exa-receive.py 7"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer8/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer8/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer8/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer8/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer8/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer8/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer8/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer8/exabgp.cfg new file mode 100644 index 0000000000..934e1c8f59 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer8/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 8 10"; + } + + process receive-routes { + run "./exa-receive.py 8"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/peer9/exa-receive.py b/tests/topotests/bgp-ecmp-topo1/peer9/exa-receive.py new file mode 100755 index 0000000000..5334ea5369 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer9/exa-receive.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +""" +exa-receive.py: Save received routes form ExaBGP into file +""" + +from sys import stdin,argv +from datetime import datetime + +# 1st arg is peer number +peer = int(argv[1]) + +# When the parent dies we are seeing continual newlines, so we only access so many before stopping +counter = 0 + +routesavefile = open('/tmp/peer%s-received.log' % peer, 'w') + +while True: + try: + line = stdin.readline() + timestamp = datetime.now().strftime('%Y%m%d_%H:%M:%S - ') + routesavefile.write(timestamp + line) + routesavefile.flush() + + if line == "": + counter += 1 + if counter > 100: + break + continue + + counter = 0 + except KeyboardInterrupt: + pass + except IOError: + # most likely a signal during readline + pass + +routesavefile.close() diff --git a/tests/topotests/bgp-ecmp-topo1/peer9/exa-send.py b/tests/topotests/bgp-ecmp-topo1/peer9/exa-send.py new file mode 100755 index 0000000000..647c254250 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer9/exa-send.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +""" +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, (((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, (((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, (((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, (((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, (((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, (((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-ecmp-topo1/peer9/exabgp.cfg b/tests/topotests/bgp-ecmp-topo1/peer9/exabgp.cfg new file mode 100644 index 0000000000..245bd29173 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/peer9/exabgp.cfg @@ -0,0 +1,21 @@ +group controller { + + process announce-routes { + run "./exa-send.py 9 10"; + } + + process receive-routes { + run "./exa-receive.py 9"; + receive-routes; + 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; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf b/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf new file mode 100644 index 0000000000..1488fe9381 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf @@ -0,0 +1,30 @@ +! +hostname r1 +log file /tmp/r1-bgpd.log +! +router bgp 100 + bgp router-id 10.0.255.1 + bgp bestpath as-path multipath-relax + neighbor 10.0.1.101 remote-as 99 + neighbor 10.0.1.102 remote-as 99 + neighbor 10.0.1.103 remote-as 99 + neighbor 10.0.1.104 remote-as 99 + neighbor 10.0.1.105 remote-as 99 + neighbor 10.0.2.106 remote-as 99 + neighbor 10.0.2.107 remote-as 99 + neighbor 10.0.2.108 remote-as 99 + neighbor 10.0.2.109 remote-as 99 + neighbor 10.0.2.110 remote-as 99 + neighbor 10.0.3.111 remote-as 111 + neighbor 10.0.3.112 remote-as 112 + neighbor 10.0.3.113 remote-as 113 + neighbor 10.0.3.114 remote-as 114 + neighbor 10.0.3.115 remote-as 115 + neighbor 10.0.4.116 remote-as 116 + neighbor 10.0.4.117 remote-as 117 + neighbor 10.0.4.118 remote-as 118 + neighbor 10.0.4.119 remote-as 119 + neighbor 10.0.4.120 remote-as 120 + ! +! + diff --git a/tests/topotests/bgp-ecmp-topo1/r1/zebra.conf b/tests/topotests/bgp-ecmp-topo1/r1/zebra.conf new file mode 100644 index 0000000000..3022913dd1 --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/r1/zebra.conf @@ -0,0 +1,16 @@ +! +hostname r1 +log file /tmp/r1-zebra.log +! +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 +! diff --git a/tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py b/tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py new file mode 100755 index 0000000000..cd6445229c --- /dev/null +++ b/tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python + +# +# test_bgp_ecmp_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2017 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_bgp_ecmp_topo1.py: Test BGP topology with ECMP (Equal Cost MultiPath). +""" + +import os +import re +import sys +import pytest +from time import sleep + +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import Node, OVSSwitch, Host +from mininet.log import setLogLevel, info +from mininet.cli import CLI +from mininet.link import Intf + +from functools import partial + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from lib import topotest + +fatal_error = "" + +total_ebgp_peers = 20 + +##################################################### +## +## Network Topology Definition +## +##################################################### + +class NetworkTopo(Topo): + "BGP ECMP Topology 1" + + def build(self, **_opts): + + exabgpPrivateDirs = ['/etc/exabgp', + '/var/run/exabgp', + '/var/log'] + + # Setup Router + router = {} + router[1] = topotest.addRouter(self, 'r1') + + # Setup Switches - 1 switch per 5 peering routers + switch = {} + for swNum in range(1, (total_ebgp_peers+4)/5 +1): + print("Create switch s%d", swNum) + switch[swNum] = self.addSwitch('s%d' % (swNum), cls=topotest.LegacySwitch) + self.addLink(switch[swNum], router[1], intfName2='r1-eth%d' % (swNum-1)) + + # Add 'total_ebgp_peers' number of eBGP ExaBGP neighbors + peer = {} + for peerNum in range(1, total_ebgp_peers+1): + swNum = ((peerNum -1) / 5 + 1) + + peer[peerNum] = self.addHost('peer%s' % peerNum, ip='10.0.%s.%s/24' % (swNum, (peerNum+100)), + defaultRoute='via 10.0.%s.1' % swNum, + privateDirs=exabgpPrivateDirs) + self.addLink(switch[swNum], peer[peerNum], intfName2='peer%s-eth0' % peerNum) + + +##################################################### +## +## Tests starting +## +##################################################### + +def setup_module(module): + global topo, net + + print("\n\n** %s: Setup Topology" % module.__name__) + print("******************************************\n") + + print("Cleanup old Mininet runs") + os.system('sudo mn -c > /dev/null 2>&1') + + thisDir = os.path.dirname(os.path.realpath(__file__)) + topo = NetworkTopo() + + net = Mininet(controller=None, topo=topo) + net.start() + + # Starting Routers + for i in range(1, 2): + net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i)) + net['r%s' % i].loadConf('bgpd', '%s/r%s/bgpd.conf' % (thisDir, i)) + net['r%s' % i].startRouter() + + # Starting Hosts and init ExaBGP on each of them + print('*** Starting BGP on all %d Peers in 10s' % total_ebgp_peers) + sleep(10) + for i in range(1, total_ebgp_peers+1): + net['peer%s' % i].cmd('cp %s/exabgp.env /etc/exabgp/exabgp.env' % thisDir) + net['peer%s' % i].cmd('cp %s/peer%s/* /etc/exabgp/' % (thisDir, i)) + net['peer%s' % i].cmd('chmod 644 /etc/exabgp/*') + net['peer%s' % i].cmd('chmod 755 /etc/exabgp/*.py') + net['peer%s' % i].cmd('chown -R exabgp:exabgp /etc/exabgp') + net['peer%s' % i].cmd('exabgp -e /etc/exabgp/exabgp.env /etc/exabgp/exabgp.cfg') + print('peer%s' % i), + print('') + + # For debugging after starting Quagga/FRR daemons, uncomment the next line + CLI(net) + + +def teardown_module(module): + global net + + print("\n\n** %s: Shutdown Topology" % module.__name__) + print("******************************************\n") + + # Shutdown - clean up everything + print('*** Killing BGP on Peer routers') + # Killing ExaBGP + for i in range(1, total_ebgp_peers+1): + net['peer%s' % i].cmd('kill `cat /var/run/exabgp/exabgp.pid`') + + # End - Shutdown network + net.stop() + + +def test_router_running(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + print("\n\n** Check if FRR/Quagga is running on each Router node") + print("******************************************\n") + sleep(5) + + # Starting Routers + for i in range(1, 2): + fatal_error = net['r%s' % i].checkRouterRunning() + assert fatal_error == "", fatal_error + + # For debugging after starting FRR/Quagga daemons, uncomment the next line + # CLI(net) + + +if __name__ == '__main__': + + setLogLevel('info') + # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli + # retval = pytest.main(["-s", "--tb=no"]) + retval = pytest.main(["-s"]) + sys.exit(retval) -- 2.39.5