From: Martin Winter Date: Thu, 24 Nov 2016 11:58:47 +0000 (-0800) Subject: bgp_multiview_topo1: Add "bgp multiview" simple topology to test. Initial commit X-Git-Tag: frr-7.1-dev~151^2~372 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=586e15c4fbab6faa7de237312b5f682672661aca;p=mirror%2Ffrr.git bgp_multiview_topo1: Add "bgp multiview" simple topology to test. Initial commit --- diff --git a/tests/topotests/bgp_multiview_topo1/exabgp.env b/tests/topotests/bgp_multiview_topo1/exabgp.env new file mode 100644 index 0000000000..a328e04962 --- /dev/null +++ b/tests/topotests/bgp_multiview_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_multiview_topo1/peer1/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer1/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer1/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer1/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer1/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer1/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer1/exabgp.cfg new file mode 100644 index 0000000000..8991610e8a --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.1; + local-address 172.16.1.1; + local-as 65001; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/peer2/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer2/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer2/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer2/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer2/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer2/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer2/exabgp.cfg new file mode 100644 index 0000000000..efddec5cc9 --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.2; + local-address 172.16.1.2; + local-as 65002; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/peer3/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer3/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer3/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer3/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer3/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer3/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer3/exabgp.cfg new file mode 100644 index 0000000000..abffe32f81 --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.3; + local-address 172.16.1.3; + local-as 65003; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/peer4/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer4/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer4/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer4/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer4/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer4/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer4/exabgp.cfg new file mode 100644 index 0000000000..27dfef902e --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.4; + local-address 172.16.1.4; + local-as 65004; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/peer5/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer5/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer5/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer5/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer5/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer5/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer5/exabgp.cfg new file mode 100644 index 0000000000..9326aed19f --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.5; + local-address 172.16.1.5; + local-as 65005; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/peer6/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer6/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer6/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer6/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer6/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer6/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer6/exabgp.cfg new file mode 100644 index 0000000000..f99976b65b --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.6; + local-address 172.16.1.6; + local-as 65006; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/peer7/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer7/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer7/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer7/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer7/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer7/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer7/exabgp.cfg new file mode 100644 index 0000000000..2dea4c9797 --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.7; + local-address 172.16.1.7; + local-as 65007; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/peer8/exa-receive.py b/tests/topotests/bgp_multiview_topo1/peer8/exa-receive.py new file mode 100755 index 0000000000..8e65f1ae9a --- /dev/null +++ b/tests/topotests/bgp_multiview_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' % 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_multiview_topo1/peer8/exa-send.py b/tests/topotests/bgp_multiview_topo1/peer8/exa-send.py new file mode 100755 index 0000000000..2de2bce40a --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/peer8/exa-send.py @@ -0,0 +1,28 @@ +#!/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]) + +# Announce numRoutes different routes per PE +for i in range(0, numRoutes): + stdout.write('announce route 10.%s.%s.0/24 med 100 community %i:1 next-hop 172.16.1.%i\n' % ((peer+100), i, peer, peer)) + stdout.flush() + +# Announce 1 overlapping route per peer +stdout.write('announce route 10.0.1.0/24 next-hop 172.16.1.%i\n' % peer) +stdout.flush() + +#Loop endlessly to allow ExaBGP to continue running +while True: + sleep(1) diff --git a/tests/topotests/bgp_multiview_topo1/peer8/exabgp.cfg b/tests/topotests/bgp_multiview_topo1/peer8/exabgp.cfg new file mode 100644 index 0000000000..ae3c5eb44c --- /dev/null +++ b/tests/topotests/bgp_multiview_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 172.16.1.254 { + router-id 172.16.1.8; + local-address 172.16.1.8; + local-as 65008; + peer-as 100; + graceful-restart; + } + +} diff --git a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf new file mode 100644 index 0000000000..7cfcb6c9aa --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf @@ -0,0 +1,49 @@ +! +! Zebra configuration saved from vty +! 2015/12/24 21:46:33 +! +log file /tmp/r1-bgpd.log +! +!debug bgp events +!debug bgp keepalives +!debug bgp updates +!debug bgp fsm +!debug bgp filters +!debug bgp zebra +! +bgp multiple-instance +! +router bgp 100 view 1 + bgp router-id 172.30.1.1 + network 172.20.0.0/28 route-map local1 + timers bgp 60 180 + neighbor 172.16.1.1 remote-as 65001 + neighbor 172.16.1.2 remote-as 65002 + neighbor 172.16.1.5 remote-as 65005 +! +router bgp 100 view 2 + bgp router-id 172.30.1.1 + network 172.20.0.0/28 route-map local2 + timers bgp 60 180 + neighbor 172.16.1.3 remote-as 65003 + neighbor 172.16.1.4 remote-as 65004 +! +router bgp 100 view 3 + bgp router-id 172.30.1.1 + network 172.20.0.0/28 + timers bgp 60 180 + neighbor 172.16.1.6 remote-as 65006 + neighbor 172.16.1.7 remote-as 65007 + neighbor 172.16.1.8 remote-as 65008 +! +route-map local1 permit 10 + set community 100:9999 additive + set metric 0 +! +route-map local2 permit 10 + set as-path prepend 100 100 100 100 100 + set community 100:1 additive + set metric 9999 +! +line vty +! diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1.ref new file mode 100644 index 0000000000..0e8bf842fd --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_1.ref @@ -0,0 +1,40 @@ +BGP table version is 0, local router ID is 172.30.1.1 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +* 10.0.1.0/24 172.16.1.5 0 65005 i +* 172.16.1.2 0 65002 i +*> 172.16.1.1 0 65001 i +*> 10.101.0.0/24 172.16.1.1 100 0 65001 i +*> 10.101.1.0/24 172.16.1.1 100 0 65001 i +*> 10.101.2.0/24 172.16.1.1 100 0 65001 i +*> 10.101.3.0/24 172.16.1.1 100 0 65001 i +*> 10.101.4.0/24 172.16.1.1 100 0 65001 i +*> 10.101.5.0/24 172.16.1.1 100 0 65001 i +*> 10.101.6.0/24 172.16.1.1 100 0 65001 i +*> 10.101.7.0/24 172.16.1.1 100 0 65001 i +*> 10.101.8.0/24 172.16.1.1 100 0 65001 i +*> 10.101.9.0/24 172.16.1.1 100 0 65001 i +*> 10.102.0.0/24 172.16.1.2 100 0 65002 i +*> 10.102.1.0/24 172.16.1.2 100 0 65002 i +*> 10.102.2.0/24 172.16.1.2 100 0 65002 i +*> 10.102.3.0/24 172.16.1.2 100 0 65002 i +*> 10.102.4.0/24 172.16.1.2 100 0 65002 i +*> 10.102.5.0/24 172.16.1.2 100 0 65002 i +*> 10.102.6.0/24 172.16.1.2 100 0 65002 i +*> 10.102.7.0/24 172.16.1.2 100 0 65002 i +*> 10.102.8.0/24 172.16.1.2 100 0 65002 i +*> 10.102.9.0/24 172.16.1.2 100 0 65002 i +*> 10.105.0.0/24 172.16.1.5 100 0 65005 i +*> 10.105.1.0/24 172.16.1.5 100 0 65005 i +*> 10.105.2.0/24 172.16.1.5 100 0 65005 i +*> 10.105.3.0/24 172.16.1.5 100 0 65005 i +*> 10.105.4.0/24 172.16.1.5 100 0 65005 i +*> 10.105.5.0/24 172.16.1.5 100 0 65005 i +*> 10.105.6.0/24 172.16.1.5 100 0 65005 i +*> 10.105.7.0/24 172.16.1.5 100 0 65005 i +*> 10.105.8.0/24 172.16.1.5 100 0 65005 i +*> 10.105.9.0/24 172.16.1.5 100 0 65005 i +*> 172.20.0.0/28 0.0.0.0 0 32768 i diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2.ref new file mode 100644 index 0000000000..cfdbaeb99d --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_2.ref @@ -0,0 +1,29 @@ +BGP table version is 0, local router ID is 172.30.1.1 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +* 10.0.1.0/24 172.16.1.4 0 65004 i +*> 172.16.1.3 0 65003 i +*> 10.103.0.0/24 172.16.1.3 100 0 65003 i +*> 10.103.1.0/24 172.16.1.3 100 0 65003 i +*> 10.103.2.0/24 172.16.1.3 100 0 65003 i +*> 10.103.3.0/24 172.16.1.3 100 0 65003 i +*> 10.103.4.0/24 172.16.1.3 100 0 65003 i +*> 10.103.5.0/24 172.16.1.3 100 0 65003 i +*> 10.103.6.0/24 172.16.1.3 100 0 65003 i +*> 10.103.7.0/24 172.16.1.3 100 0 65003 i +*> 10.103.8.0/24 172.16.1.3 100 0 65003 i +*> 10.103.9.0/24 172.16.1.3 100 0 65003 i +*> 10.104.0.0/24 172.16.1.4 100 0 65004 i +*> 10.104.1.0/24 172.16.1.4 100 0 65004 i +*> 10.104.2.0/24 172.16.1.4 100 0 65004 i +*> 10.104.3.0/24 172.16.1.4 100 0 65004 i +*> 10.104.4.0/24 172.16.1.4 100 0 65004 i +*> 10.104.5.0/24 172.16.1.4 100 0 65004 i +*> 10.104.6.0/24 172.16.1.4 100 0 65004 i +*> 10.104.7.0/24 172.16.1.4 100 0 65004 i +*> 10.104.8.0/24 172.16.1.4 100 0 65004 i +*> 10.104.9.0/24 172.16.1.4 100 0 65004 i +*> 172.20.0.0/28 0.0.0.0 9999 32768 100 100 100 100 100 i diff --git a/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3.ref b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3.ref new file mode 100644 index 0000000000..f0f471db8e --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/show_ip_bgp_view_3.ref @@ -0,0 +1,40 @@ +BGP table version is 0, local router ID is 172.30.1.1 +Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, + i internal, r RIB-failure, S Stale, R Removed +Origin codes: i - IGP, e - EGP, ? - incomplete + + Network Next Hop Metric LocPrf Weight Path +* 10.0.1.0/24 172.16.1.8 0 65008 i +* 172.16.1.7 0 65007 i +*> 172.16.1.6 0 65006 i +*> 10.106.0.0/24 172.16.1.6 100 0 65006 i +*> 10.106.1.0/24 172.16.1.6 100 0 65006 i +*> 10.106.2.0/24 172.16.1.6 100 0 65006 i +*> 10.106.3.0/24 172.16.1.6 100 0 65006 i +*> 10.106.4.0/24 172.16.1.6 100 0 65006 i +*> 10.106.5.0/24 172.16.1.6 100 0 65006 i +*> 10.106.6.0/24 172.16.1.6 100 0 65006 i +*> 10.106.7.0/24 172.16.1.6 100 0 65006 i +*> 10.106.8.0/24 172.16.1.6 100 0 65006 i +*> 10.106.9.0/24 172.16.1.6 100 0 65006 i +*> 10.107.0.0/24 172.16.1.7 100 0 65007 i +*> 10.107.1.0/24 172.16.1.7 100 0 65007 i +*> 10.107.2.0/24 172.16.1.7 100 0 65007 i +*> 10.107.3.0/24 172.16.1.7 100 0 65007 i +*> 10.107.4.0/24 172.16.1.7 100 0 65007 i +*> 10.107.5.0/24 172.16.1.7 100 0 65007 i +*> 10.107.6.0/24 172.16.1.7 100 0 65007 i +*> 10.107.7.0/24 172.16.1.7 100 0 65007 i +*> 10.107.8.0/24 172.16.1.7 100 0 65007 i +*> 10.107.9.0/24 172.16.1.7 100 0 65007 i +*> 10.108.0.0/24 172.16.1.8 100 0 65008 i +*> 10.108.1.0/24 172.16.1.8 100 0 65008 i +*> 10.108.2.0/24 172.16.1.8 100 0 65008 i +*> 10.108.3.0/24 172.16.1.8 100 0 65008 i +*> 10.108.4.0/24 172.16.1.8 100 0 65008 i +*> 10.108.5.0/24 172.16.1.8 100 0 65008 i +*> 10.108.6.0/24 172.16.1.8 100 0 65008 i +*> 10.108.7.0/24 172.16.1.8 100 0 65008 i +*> 10.108.8.0/24 172.16.1.8 100 0 65008 i +*> 10.108.9.0/24 172.16.1.8 100 0 65008 i +*> 172.20.0.0/28 0.0.0.0 0 32768 i diff --git a/tests/topotests/bgp_multiview_topo1/r1/zebra.conf b/tests/topotests/bgp_multiview_topo1/r1/zebra.conf new file mode 100644 index 0000000000..6aebf56f03 --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/r1/zebra.conf @@ -0,0 +1,23 @@ +! +! Zebra configuration saved from vty +! 2015/12/24 16:48:27 +! +log file /tmp/r1-zebra.log +! +hostname r1 +! +interface r1-stub + description Stub Network + ip address 172.20.0.1/28 + no link-detect +! +interface r1-eth0 + description to PE router - vlan1 + ip address 172.16.1.254/24 + no link-detect +! +ip forwarding +! +! +line vty +! diff --git a/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py b/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py new file mode 100755 index 0000000000..3af993dfad --- /dev/null +++ b/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py @@ -0,0 +1,366 @@ +#!/usr/bin/env python + +# +# test_bgp_multiview_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2016 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_multiview_topo1.py: Simple Quagga Route-Server Test + +See Topology Diagram bgp-routeserver-1.pdf +""" + +import os +import re +import sys +import difflib +import StringIO + +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 +from time import sleep + +import pytest + +def int2dpid(dpid): + "Converting Integer to DPID" + + try: + dpid = hex(dpid)[2:] + dpid = '0'*(16-len(dpid))+dpid + return dpid + except IndexError: + raise Exception('Unable to derive default datapath ID - ' + 'please either specify a dpid or use a ' + 'canonical switch name such as s23.') + +class LinuxRouter(Node): + "A Node with IPv4/IPv6 forwarding enabled." + + def config(self, **params): + super(LinuxRouter, self).config(**params) + # Enable forwarding on the router + self.cmd('sysctl net.ipv4.ip_forward=1') + self.cmd('sysctl net.ipv6.conf.all.forwarding=1') + def terminate(self): + """ + Terminate generic LinuxRouter Mininet instance + """ + self.cmd('sysctl net.ipv4.ip_forward=0') + self.cmd('sysctl net.ipv6.conf.all.forwarding=0') + super(LinuxRouter, self).terminate() + +class QuaggaRouter(Node): + "A Node with IPv4/IPv6 forwarding enabled and Quagga as Routing Engine" + + def config(self, **params): + super(QuaggaRouter, self).config(**params) + # Enable forwarding on the router + self.cmd('sysctl net.ipv4.ip_forward=1') + self.cmd('sysctl net.ipv6.conf.all.forwarding=1') + self.cmd('chown quagga:quaggavty /etc/quagga') + self.daemons = {'zebra': 0, 'ripd': 0, 'ripngd': 0, 'ospfd': 0, + 'ospf6d': 0, 'isisd': 0, 'bgpd': 0, 'pimd': 0} + def terminate(self): + # Delete Running Quagga Daemons + rundaemons = self.cmd('ls -1 /var/run/quagga/*.pid') + for d in StringIO.StringIO(rundaemons): + self.cmd('kill -7 `cat %s`' % d.rstrip()) + self.waitOutput() + # Disable forwarding + self.cmd('sysctl net.ipv4.ip_forward=0') + self.cmd('sysctl net.ipv6.conf.all.forwarding=0') + super(QuaggaRouter, self).terminate() + def removeIPs(self): + for interface in self.intfNames(): + self.cmd('ip address flush', interface) + def loadConf(self, daemon, source=None): + # print "Daemons before:", self.daemons + if daemon in self.daemons.keys(): + self.daemons[daemon] = 1 + if source is None: + self.cmd('touch /etc/quagga/%s.conf' % daemon) + self.waitOutput() + else: + self.cmd('cp %s /etc/quagga/%s.conf' % (source, daemon)) + self.waitOutput() + self.cmd('chmod 640 /etc/quagga/%s.conf' % daemon) + self.waitOutput() + self.cmd('chown quagga:quagga /etc/quagga/%s.conf' % daemon) + self.waitOutput() + else: + print("No daemon %s known" % daemon) + # print "Daemons after:", self.daemons + def startQuagga(self): + # Disable integrated-vtysh-config + self.cmd('echo "no service integrated-vtysh-config" > /etc/quagga/vtysh.conf') + with open("/etc/quagga/vtysh.conf", "w") as vtyshfile: + vtyshfile.write('no service integrated-vtysh-config') + self.cmd('chown quagga:quaggavty /etc/quagga/vtysh.conf') + # Remove IP addresses from OS first - we have them in zebra.conf + self.removeIPs() + # Start Zebra first + if self.daemons['zebra'] == 1: + self.cmd('/usr/lib/quagga/zebra -d') + self.waitOutput() + print('%s: zebra started' % self) + sleep(1) + # Fix Link-Local Addresses + # Somehow (on Mininet only), Zebra removes the IPv6 Link-Local addresses on start. Fix this + self.cmd('for i in `ls /sys/class/net/` ; do mac=`cat /sys/class/net/$i/address`; IFS=\':\'; set $mac; unset IFS; ip address add dev $i scope link fe80::$(printf %02x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6/64; done') + # Now start all the other daemons + for daemon in self.daemons: + if (self.daemons[daemon] == 1) and (daemon != 'zebra'): + self.cmd('/usr/lib/quagga/%s -d' % daemon) + self.waitOutput() + print('%s: %s started' % (self, daemon)) + def checkQuaggaRunning(self): + daemonsRunning = self.cmd('vtysh -c "show log" | grep "Logging configuration for"') + for daemon in self.daemons: + if (self.daemons[daemon] == 1): + assert daemon in daemonsRunning, "Daemon %s not running" % daemon + + +class LegacySwitch(OVSSwitch): + "A Legacy Switch without OpenFlow" + + def __init__(self, name, **params): + OVSSwitch.__init__(self, name, failMode='standalone', **params) + self.switchIP = None + + +##################################################### +## +## Network Topology Definition +## +##################################################### + +class NetworkTopo(Topo): + "A LinuxRouter connecting three IP subnets" + + def build(self, **_opts): + + quaggaPrivateDirs = ['/etc/quagga', + '/var/run/quagga', + '/var/log', + '/var/run/ssh'] + exabgpPrivateDirs = ['/etc/exabgp', + '/var/run/exabgp', + '/var/log'] + + # Setup Routers + quagga = {} + for i in range(1, 2): + quagga[i] = self.addNode('r%s' % i, cls=QuaggaRouter, + privateDirs=quaggaPrivateDirs) + + # Setup Provider BGP peers + peer = {} + for i in range(1, 9): + peer[i] = self.addHost('peer%s' % i, ip='172.16.1.%s/24' % i, + defaultRoute='via 172.16.1.254', + privateDirs=exabgpPrivateDirs) + + # Setup Switches + switch = {} + # First switch is for a dummy interface (for local network) + switch[0] = self.addSwitch('sw0', cls=LegacySwitch) + self.addLink(switch[0], quagga[1], intfName2='r1-stub') + # Second switch is for connection to all peering routers + switch[1] = self.addSwitch('sw1', cls=LegacySwitch) + self.addLink(switch[1], quagga[1], intfName2='r1-eth0') + for j in range(1, 9): + self.addLink(switch[1], peer[j], intfName2='peer%s-eth0' % j) + + +##################################################### +## +## 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].startQuagga() + + # Starting PE Hosts and init ExaBGP on each of them + print('*** Starting BGP on all 8 Peers in 10s') + sleep(10) + for i in range(1, 9): + 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 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, 9): + net['peer%s' % i].cmd('kill `cat /var/run/exabgp/exabgp.pid`') + + # End - Shutdown network + net.stop() + +def test_quagga_running(): + global net + + print("\n\n** Check if Quagga is running on each Router node") + print("******************************************\n") + sleep(5) + + # Starting Routers + for i in range(1, 2): + net['r%s' % i].checkQuaggaRunning() + +def test_bgp_converge(): + "Check for BGP converged on all peers and BGP views" + + global net + + # Wait for BGP to converge (All Neighbors in either Full or TwoWay State) + print("\n\n** Verify for BGP to converge") + print("******************************************\n") + timeout = 60 + while timeout > 0: + print("Timeout in %s: " % timeout), + sys.stdout.flush() + # Look for any node not yet converged + for i in range(1, 2): + for view in range(1, 4): + notConverged = net['r%s' % i].cmd('vtysh -c "show ip bgp view %s summary" 2> /dev/null | grep ^[0-9] | grep -v " 11$"' % view) + if notConverged: + print('Waiting for r%s, view %s' % (i, view)) + sys.stdout.flush() + break + if notConverged: + break + if notConverged: + sleep(5) + timeout -= 5 + else: + print('Done') + break + else: + # Bail out with error if a router fails to converge + bgpStatus = net['r%s' % i].cmd('show ip bgp view %s summary"') + + assert False, "BGP did not converge:\n%s" % bgpStatus + + print("BGP converged.") + + # if timeout < 60: + # # Only wait if we actually went through a convergence + # print("\nwaiting 15s for routes to populate") + # sleep(15) + + # For debugging after starting Quagga daemons, uncomment the next line + # CLI(net) + +def test_bgp_routingTable(): + global net + + thisDir = os.path.dirname(os.path.realpath(__file__)) + + # Verify OSPFv3 Routing Table + print("\n\n** Verifing BGP Routing Tables") + print("******************************************\n") + failures = 0 + for i in range(1, 2): + for view in range(1, 4): + refTableFile = '%s/r%s/show_ip_bgp_view_%s.ref' % (thisDir, i, view) + if os.path.isfile(refTableFile): + # Read expected result from file + expected = open(refTableFile).read().rstrip() + # Fix newlines (make them all the same) + expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1) + + # Actual output from router + actual = net['r%s' % i].cmd('vtysh -c "show ip bgp view %s" 2> /dev/null' % view).rstrip() + + # Fix inconsitent spaces between 0.99.24 and newer versions of Quagga... + actual = re.sub('0 0', '0 0', actual) + actual = re.sub(r'([0-9]) 32768', r'\1 32768', actual) + # Remove summary line (changed recently) + actual = re.sub(r'Total number.*', '', actual) + actual = re.sub(r'Displayed.*', '', actual) + actual = actual.rstrip() + + # Fix newlines (make them all the same) + actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1) + + # Generate Diff + diff = ''.join(difflib.unified_diff(actual, expected)) + # Empty string if it matches, otherwise diff contains unified diff + + if diff: + sys.stderr.write('r%s failed Routing Table Check for view %s:\n%s\n' + % (i, view, diff)) + failures += 1 + else: + print("r%s ok" % i) + + assert failures == 0, "Routing Table verification failed for router r%s, view %s:\n%s" % (i, view, diff) + + # For debugging after starting Quagga daemons, uncomment the next line + # CLI(net) + + +if __name__ == '__main__': + + setLogLevel('info') + retval = pytest.main(["-s"]) + sys.exit(retval)