mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 16:52:25 +00:00
bgp_multiview_topo1: Add "bgp multiview" simple topology to test. Initial commit
This commit is contained in:
parent
68a655673f
commit
586e15c4fb
54
tests/topotests/bgp_multiview_topo1/exabgp.env
Normal file
54
tests/topotests/bgp_multiview_topo1/exabgp.env
Normal file
@ -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
|
38
tests/topotests/bgp_multiview_topo1/peer1/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer1/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer1/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer1/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer1/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer1/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
tests/topotests/bgp_multiview_topo1/peer2/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer2/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer2/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer2/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer2/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer2/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
tests/topotests/bgp_multiview_topo1/peer3/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer3/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer3/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer3/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer3/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer3/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
tests/topotests/bgp_multiview_topo1/peer4/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer4/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer4/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer4/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer4/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer4/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
tests/topotests/bgp_multiview_topo1/peer5/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer5/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer5/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer5/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer5/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer5/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
tests/topotests/bgp_multiview_topo1/peer6/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer6/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer6/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer6/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer6/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer6/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
tests/topotests/bgp_multiview_topo1/peer7/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer7/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer7/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer7/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer7/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer7/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
tests/topotests/bgp_multiview_topo1/peer8/exa-receive.py
Executable file
38
tests/topotests/bgp_multiview_topo1/peer8/exa-receive.py
Executable file
@ -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()
|
28
tests/topotests/bgp_multiview_topo1/peer8/exa-send.py
Executable file
28
tests/topotests/bgp_multiview_topo1/peer8/exa-send.py
Executable file
@ -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)
|
21
tests/topotests/bgp_multiview_topo1/peer8/exabgp.cfg
Normal file
21
tests/topotests/bgp_multiview_topo1/peer8/exabgp.cfg
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
tests/topotests/bgp_multiview_topo1/r1/bgpd.conf
Normal file
49
tests/topotests/bgp_multiview_topo1/r1/bgpd.conf
Normal file
@ -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
|
||||||
|
!
|
@ -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
|
@ -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
|
@ -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
|
23
tests/topotests/bgp_multiview_topo1/r1/zebra.conf
Normal file
23
tests/topotests/bgp_multiview_topo1/r1/zebra.conf
Normal file
@ -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
|
||||||
|
!
|
366
tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py
Executable file
366
tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py
Executable file
@ -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)
|
Loading…
Reference in New Issue
Block a user