summaryrefslogtreecommitdiffstats
path: root/tests/topotests/bgp_multiview_topo1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
commit2c7cac91ed6e7db0f6937923d2b57f97dbdbc337 (patch)
treec05dc0f8e6aa3accc84e3e5cffc933ed94941383 /tests/topotests/bgp_multiview_topo1
parentInitial commit. (diff)
downloadfrr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.tar.xz
frr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.zip
Adding upstream version 8.4.4.upstream/8.4.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/topotests/bgp_multiview_topo1')
-rw-r--r--tests/topotests/bgp_multiview_topo1/README.md125
-rw-r--r--tests/topotests/bgp_multiview_topo1/exabgp.env54
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer1/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer1/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer2/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer2/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer3/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer3/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer4/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer4/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer5/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer5/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer6/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer6/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer7/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer7/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_multiview_topo1/peer8/exa-send.py31
-rw-r--r--tests/topotests/bgp_multiview_topo1/peer8/exabgp.cfg21
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/bgpd.conf61
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/view_1.json728
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/view_2.json489
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/view_3.json728
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/zebra.conf23
-rw-r--r--tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py238
24 files changed, 2862 insertions, 0 deletions
diff --git a/tests/topotests/bgp_multiview_topo1/README.md b/tests/topotests/bgp_multiview_topo1/README.md
new file mode 100644
index 0000000..c1a1445
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/README.md
@@ -0,0 +1,125 @@
+# Simple FRRouting Route-Server Test
+
+## Topology
+ +----------+ +----------+ +----------+ +----------+ +----------+
+ | peer1 | | peer2 | | peer3 | | peer4 | | peer5 |
+ | AS 65001 | | AS 65002 | | AS 65003 | | AS 65004 | | AS 65005 |
+ +-----+----+ +-----+----+ +-----+----+ +-----+----+ +-----+----+
+ | .1 | .2 | .3 | .4 | .5
+ | ______/ / / _________/
+ \ / ________________/ / /
+ | | / _________________________/ / +----------+
+ | | | / __________________________/ ___| peer6 |
+ | | | | / ____________________________/.6 | AS 65006 |
+ | | | | | / _________________________ +----------+
+ | | | | | | / __________________ \ +----------+
+ | | | | | | | / \ \___| peer7 |
+ | | | | | | | | \ .7 | AS 65007 |
+ ~~~~~~~~~~~~~~~~~~~~~ \ +----------+
+ ~~ SW1 ~~ \ +----------+
+ ~~ Switch ~~ \_____| peer8 |
+ ~~ 172.16.1.0/24 ~~ .8 | AS 65008 |
+ ~~~~~~~~~~~~~~~~~~~~~ +----------+
+ |
+ | .254
+ +---------+---------+
+ | FRR R1 |
+ | BGP Multi-View |
+ | Peer 1-3 > View 1 |
+ | Peer 4-5 > View 2 |
+ | Peer 6-8 > View 3 |
+ +---------+---------+
+ | .1
+ |
+ ~~~~~~~~~~~~~ Stub Network is redistributed
+ ~~ SW0 ~~ into each BGP view with different
+ ~~ 172.20.0.1/28 ~~ attributes (using route-map)
+ ~~ Stub Switch ~~
+ ~~~~~~~~~~~~~
+
+## FRR Configuration
+
+Full config as used is in r1 subdirectory
+
+Simplified `R1` config:
+
+ 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
+ !
+ 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
+ !
+
+## Tests executed
+
+### Check if FRR is running
+
+Test is executed by running
+
+ vtysh -c "show logging" | grep "Logging configuration for"
+
+on router `R1`. This should return the logging information for all daemons registered
+to Zebra and the list of running daemons is compared to the daemons started for this
+test (`zebra` and `bgpd`)
+
+### Verify for BGP to converge
+
+BGP is expected to converge on each view within 60s total time. Convergence is verified by executing
+
+ vtysh -c "show ip bgp view 1 summary"
+ vtysh -c "show ip bgp view 2 summary"
+ vtysh -c "show ip bgp view 3 summary"
+
+and expecting 11 routes seen in the last column for each peer. (Each peer sends 11 routes)
+
+### Verifying BGP Routing Tables
+
+Routing table is verified by running
+
+ vtysh -c "show ip bgp view 1"
+ vtysh -c "show ip bgp view 2"
+ vtysh -c "show ip bgp view 3"
+
+and comparing the result against the stored table in the r1/show_ip_bgp_view_NN.ref files
+(with NN 1, 2, 3) (A few header and trailer lines are cut/adjusted ahead of the compare to
+adjust for different output based on recent changes)
+
+
diff --git a/tests/topotests/bgp_multiview_topo1/exabgp.env b/tests/topotests/bgp_multiview_topo1/exabgp.env
new file mode 100644
index 0000000..a328e04
--- /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-send.py b/tests/topotests/bgp_multiview_topo1/peer1/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer1/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..20e71c8
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer1/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 1 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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-send.py b/tests/topotests/bgp_multiview_topo1/peer2/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer2/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..1e8eef1
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer2/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 2 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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-send.py b/tests/topotests/bgp_multiview_topo1/peer3/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer3/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..ef1b249
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer3/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 3 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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-send.py b/tests/topotests/bgp_multiview_topo1/peer4/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer4/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..7c50f73
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer4/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 4 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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-send.py b/tests/topotests/bgp_multiview_topo1/peer5/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer5/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..22163c7
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer5/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 5 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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-send.py b/tests/topotests/bgp_multiview_topo1/peer6/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer6/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..40b54c3
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer6/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 6 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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-send.py b/tests/topotests/bgp_multiview_topo1/peer7/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer7/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..33312d0
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer7/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 7 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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-send.py b/tests/topotests/bgp_multiview_topo1/peer8/exa-send.py
new file mode 100755
index 0000000..09f6ea5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer8/exa-send.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+
+"""
+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 med %i next-hop 172.16.1.%i\n" % (peer, 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 0000000..173ccb9
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/peer8/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa-send.py 8 10";
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/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 0000000..cd7f44a
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf
@@ -0,0 +1,61 @@
+!
+! Zebra configuration saved from vty
+! 2015/12/24 21:46:33
+!
+log file bgpd.log
+!
+!debug bgp events
+!debug bgp keepalives
+!debug bgp updates
+!debug bgp fsm
+!debug bgp filters
+!debug bgp zebra
+!
+router bgp 100 view 1
+ bgp router-id 172.30.1.1
+ bgp always-compare-med
+ no bgp ebgp-requires-policy
+ 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.1 timers 3 10
+ neighbor 172.16.1.2 remote-as 65002
+ neighbor 172.16.1.2 timers 3 10
+ neighbor 172.16.1.5 remote-as 65005
+ neighbor 172.16.1.5 timers 3 10
+!
+router bgp 100 view 2
+ bgp router-id 172.30.1.1
+ bgp always-compare-med
+ no bgp ebgp-requires-policy
+ 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.3 timers 3 10
+ neighbor 172.16.1.4 remote-as 65004
+ neighbor 172.16.1.4 timers 3 10
+!
+router bgp 100 view 3
+ bgp router-id 172.30.1.1
+ bgp always-compare-med
+ no bgp ebgp-requires-policy
+ network 172.20.0.0/28
+ timers bgp 60 180
+ neighbor 172.16.1.6 remote-as 65006
+ neighbor 172.16.1.6 timers 3 10
+ neighbor 172.16.1.7 remote-as 65007
+ neighbor 172.16.1.7 timers 3 10
+ neighbor 172.16.1.8 remote-as 65008
+ neighbor 172.16.1.8 timers 3 10
+!
+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/view_1.json b/tests/topotests/bgp_multiview_topo1/r1/view_1.json
new file mode 100644
index 0000000..137b8a3
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/r1/view_1.json
@@ -0,0 +1,728 @@
+{
+ "vrfName": "1",
+ "routerId": "172.30.1.1",
+ "defaultLocPrf": 100,
+ "localAS": 100,
+ "routes": {
+ "10.0.1.0/24": [
+ {
+ "valid": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 5,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ },
+ {
+ "valid": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 2,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ },
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 1,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.0.0",
+ "prefixLen": 24,
+ "network": "10.101.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.1.0",
+ "prefixLen": 24,
+ "network": "10.101.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.2.0",
+ "prefixLen": 24,
+ "network": "10.101.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.3.0",
+ "prefixLen": 24,
+ "network": "10.101.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.4.0",
+ "prefixLen": 24,
+ "network": "10.101.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.5.0",
+ "prefixLen": 24,
+ "network": "10.101.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.6.0",
+ "prefixLen": 24,
+ "network": "10.101.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.7.0",
+ "prefixLen": 24,
+ "network": "10.101.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.8.0",
+ "prefixLen": 24,
+ "network": "10.101.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.101.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.101.9.0",
+ "prefixLen": 24,
+ "network": "10.101.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.1",
+ "path": "65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.1",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.0.0",
+ "prefixLen": 24,
+ "network": "10.102.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.1.0",
+ "prefixLen": 24,
+ "network": "10.102.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.2.0",
+ "prefixLen": 24,
+ "network": "10.102.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.3.0",
+ "prefixLen": 24,
+ "network": "10.102.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.4.0",
+ "prefixLen": 24,
+ "network": "10.102.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.5.0",
+ "prefixLen": 24,
+ "network": "10.102.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.6.0",
+ "prefixLen": 24,
+ "network": "10.102.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.7.0",
+ "prefixLen": 24,
+ "network": "10.102.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.8.0",
+ "prefixLen": 24,
+ "network": "10.102.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.102.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.102.9.0",
+ "prefixLen": 24,
+ "network": "10.102.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.2",
+ "path": "65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.0.0",
+ "prefixLen": 24,
+ "network": "10.105.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.1.0",
+ "prefixLen": 24,
+ "network": "10.105.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.2.0",
+ "prefixLen": 24,
+ "network": "10.105.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.3.0",
+ "prefixLen": 24,
+ "network": "10.105.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.4.0",
+ "prefixLen": 24,
+ "network": "10.105.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.5.0",
+ "prefixLen": 24,
+ "network": "10.105.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.6.0",
+ "prefixLen": 24,
+ "network": "10.105.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.7.0",
+ "prefixLen": 24,
+ "network": "10.105.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.8.0",
+ "prefixLen": 24,
+ "network": "10.105.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.105.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.105.9.0",
+ "prefixLen": 24,
+ "network": "10.105.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.5",
+ "path": "65005",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.5",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_multiview_topo1/r1/view_2.json b/tests/topotests/bgp_multiview_topo1/r1/view_2.json
new file mode 100644
index 0000000..2ad28c5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/r1/view_2.json
@@ -0,0 +1,489 @@
+{
+ "vrfName": "2",
+ "routerId": "172.30.1.1",
+ "defaultLocPrf": 100,
+ "localAS": 100,
+ "routes": {
+ "10.0.1.0/24": [
+ {
+ "valid": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 4,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ },
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 3,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.0.0",
+ "prefixLen": 24,
+ "network": "10.103.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.1.0",
+ "prefixLen": 24,
+ "network": "10.103.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.2.0",
+ "prefixLen": 24,
+ "network": "10.103.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.3.0",
+ "prefixLen": 24,
+ "network": "10.103.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.4.0",
+ "prefixLen": 24,
+ "network": "10.103.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.5.0",
+ "prefixLen": 24,
+ "network": "10.103.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.6.0",
+ "prefixLen": 24,
+ "network": "10.103.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.7.0",
+ "prefixLen": 24,
+ "network": "10.103.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.8.0",
+ "prefixLen": 24,
+ "network": "10.103.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.103.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.103.9.0",
+ "prefixLen": 24,
+ "network": "10.103.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.3",
+ "path": "65003",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.0.0",
+ "prefixLen": 24,
+ "network": "10.104.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.1.0",
+ "prefixLen": 24,
+ "network": "10.104.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.2.0",
+ "prefixLen": 24,
+ "network": "10.104.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.3.0",
+ "prefixLen": 24,
+ "network": "10.104.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.4.0",
+ "prefixLen": 24,
+ "network": "10.104.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.5.0",
+ "prefixLen": 24,
+ "network": "10.104.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.6.0",
+ "prefixLen": 24,
+ "network": "10.104.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.7.0",
+ "prefixLen": 24,
+ "network": "10.104.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.8.0",
+ "prefixLen": 24,
+ "network": "10.104.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.104.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.104.9.0",
+ "prefixLen": 24,
+ "network": "10.104.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.4",
+ "path": "65004",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.4",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_multiview_topo1/r1/view_3.json b/tests/topotests/bgp_multiview_topo1/r1/view_3.json
new file mode 100644
index 0000000..d49694e
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/r1/view_3.json
@@ -0,0 +1,728 @@
+{
+ "vrfName": "3",
+ "routerId": "172.30.1.1",
+ "defaultLocPrf": 100,
+ "localAS": 100,
+ "routes": {
+ "10.0.1.0/24": [
+ {
+ "valid": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 8,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ },
+ {
+ "valid": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 7,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ },
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.0.1.0",
+ "prefixLen": 24,
+ "network": "10.0.1.0/24",
+ "metric": 6,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.0.0",
+ "prefixLen": 24,
+ "network": "10.106.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.1.0",
+ "prefixLen": 24,
+ "network": "10.106.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.2.0",
+ "prefixLen": 24,
+ "network": "10.106.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.3.0",
+ "prefixLen": 24,
+ "network": "10.106.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.4.0",
+ "prefixLen": 24,
+ "network": "10.106.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.5.0",
+ "prefixLen": 24,
+ "network": "10.106.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.6.0",
+ "prefixLen": 24,
+ "network": "10.106.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.7.0",
+ "prefixLen": 24,
+ "network": "10.106.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.8.0",
+ "prefixLen": 24,
+ "network": "10.106.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.106.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.106.9.0",
+ "prefixLen": 24,
+ "network": "10.106.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.6",
+ "path": "65006",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.6",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.0.0",
+ "prefixLen": 24,
+ "network": "10.107.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.1.0",
+ "prefixLen": 24,
+ "network": "10.107.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.2.0",
+ "prefixLen": 24,
+ "network": "10.107.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.3.0",
+ "prefixLen": 24,
+ "network": "10.107.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.4.0",
+ "prefixLen": 24,
+ "network": "10.107.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.5.0",
+ "prefixLen": 24,
+ "network": "10.107.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.6.0",
+ "prefixLen": 24,
+ "network": "10.107.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.7.0",
+ "prefixLen": 24,
+ "network": "10.107.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.8.0",
+ "prefixLen": 24,
+ "network": "10.107.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.107.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.107.9.0",
+ "prefixLen": 24,
+ "network": "10.107.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.7",
+ "path": "65007",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.7",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.0.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.0.0",
+ "prefixLen": 24,
+ "network": "10.108.0.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.1.0",
+ "prefixLen": 24,
+ "network": "10.108.1.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.2.0",
+ "prefixLen": 24,
+ "network": "10.108.2.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.3.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.3.0",
+ "prefixLen": 24,
+ "network": "10.108.3.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.4.0",
+ "prefixLen": 24,
+ "network": "10.108.4.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.5.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.5.0",
+ "prefixLen": 24,
+ "network": "10.108.5.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.6.0",
+ "prefixLen": 24,
+ "network": "10.108.6.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.7.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.7.0",
+ "prefixLen": 24,
+ "network": "10.108.7.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.8.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.8.0",
+ "prefixLen": 24,
+ "network": "10.108.8.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "10.108.9.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "pathFrom": "external",
+ "prefix": "10.108.9.0",
+ "prefixLen": 24,
+ "network": "10.108.9.0/24",
+ "metric": 100,
+ "weight": 0,
+ "peerId": "172.16.1.8",
+ "path": "65008",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "172.16.1.8",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
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 0000000..86343f5
--- /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 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 100644
index 0000000..77619e5
--- /dev/null
+++ b/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py
@@ -0,0 +1,238 @@
+#!/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.
+#
+
+r"""
+test_bgp_multiview_topo1.py: Simple FRR Route-Server Test
+
++----------+ +----------+ +----------+ +----------+ +----------+
+| peer1 | | peer2 | | peer3 | | peer4 | | peer5 |
+| AS 65001 | | AS 65002 | | AS 65003 | | AS 65004 | | AS 65005 |
++-----+----+ +-----+----+ +-----+----+ +-----+----+ +-----+----+
+ | .1 | .2 | .3 | .4 | .5
+ | ______/ / / _________/
+ \ / ________________/ / /
+ | | / _________________________/ / +----------+
+ | | | / __________________________/ ___| peer6 |
+ | | | | / ____________________________/.6 | AS 65006 |
+ | | | | | / _________________________ +----------+
+ | | | | | | / __________________ \ +----------+
+ | | | | | | | / \ \___| peer7 |
+ | | | | | | | | \ .7 | AS 65007 |
+ ~~~~~~~~~~~~~~~~~~~~~ \ +----------+
+ ~~ SW1 ~~ \ +----------+
+ ~~ Switch ~~ \_____| peer8 |
+ ~~ 172.16.1.0/24 ~~ .8 | AS 65008 |
+ ~~~~~~~~~~~~~~~~~~~~~ +----------+
+ |
+ | .254
+ +---------+---------+
+ | FRR R1 |
+ | BGP Multi-View |
+ | Peer 1-3 > View 1 |
+ | Peer 4-5 > View 2 |
+ | Peer 6-8 > View 3 |
+ +---------+---------+
+ | .1
+ |
+ ~~~~~~~~~~~~~ Stub Network is redistributed
+ ~~ SW0 ~~ into each BGP view with different
+ ~~ 172.20.0.1/28 ~~ attributes (using route-map)
+ ~~ Stub Switch ~~
+ ~~~~~~~~~~~~~
+"""
+
+import json
+import os
+import sys
+import pytest
+import json
+from time import sleep
+
+from functools import partial
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from lib import topotest
+from lib.topogen import get_topogen, Topogen
+from lib.common_config import step
+
+
+pytestmark = [pytest.mark.bgpd]
+
+
+fatal_error = ""
+
+
+#####################################################
+##
+## Network Topology Definition
+##
+#####################################################
+
+
+def build_topo(tgen):
+ # Setup Routers
+ router = tgen.add_router("r1")
+
+ # Setup Provider BGP peers
+ peer = {}
+ for i in range(1, 9):
+ peer[i] = tgen.add_exabgp_peer(
+ "peer%s" % i, ip="172.16.1.%s/24" % i, defaultRoute="via 172.16.1.254"
+ )
+
+ # First switch is for a dummy interface (for local network)
+ switch = tgen.add_switch("sw0")
+ switch.add_link(router, nodeif="r1-stub")
+
+ # Second switch is for connection to all peering routers
+ switch = tgen.add_switch("sw1")
+ switch.add_link(router, nodeif="r1-eth0")
+ for j in range(1, 9):
+ switch.add_link(peer[j], nodeif="peer%s-eth0" % j)
+
+
+#####################################################
+##
+## Tests starting
+##
+#####################################################
+
+
+def setup_module(module):
+ thisDir = os.path.dirname(os.path.realpath(__file__))
+ tgen = Topogen(build_topo, module.__name__)
+ tgen.start_topology()
+
+ # Starting Routers
+ router = tgen.net["r1"]
+ router.loadConf("zebra", "%s/r1/zebra.conf" % thisDir)
+ router.loadConf("bgpd", "%s/r1/bgpd.conf" % thisDir)
+ tgen.gears["r1"].start()
+
+ # Starting PE Hosts and init ExaBGP on each of them
+ peer_list = tgen.exabgp_peers()
+ for pname, peer in peer_list.items():
+ peer_dir = os.path.join(thisDir, pname)
+ env_file = os.path.join(thisDir, "exabgp.env")
+ peer.start(peer_dir, env_file)
+
+
+def teardown_module(module):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_router_running():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+
+def test_bgp_converge():
+ "Check for BGP converged on all peers and BGP views"
+
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Wait for BGP to converge (All Neighbors in either Full or TwoWay State)
+ step("Verify for BGP to converge")
+
+ timeout = 125
+ 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 = tgen.net["r%s" % i].cmd(
+ r'vtysh -c "show ip bgp view %s summary" 2> /dev/null | grep ^[0-9] | grep -vP " 11\s+(\d+)"'
+ % 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 = tgen.net["r%s" % i].cmd(
+ 'vtysh -c "show ip bgp view %s summary"' % view
+ )
+ assert False, "BGP did not converge:\n%s" % bgpStatus
+
+ tgen.routers_have_failure()
+
+
+def test_bgp_routingTable():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ thisDir = os.path.dirname(os.path.realpath(__file__))
+
+ step("Verifying BGP Routing Tables")
+
+ router = tgen.gears["r1"]
+ for view in range(1, 4):
+ json_file = "{}/{}/view_{}.json".format(thisDir, router.name, view)
+ expected = json.loads(open(json_file).read())
+ test_func = partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip bgp view {} json".format(view),
+ expected,
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=5, wait=1)
+ assertmsg = "Routing Table verification failed for router {}, view {}".format(
+ router.name, view
+ )
+ assert result is None, assertmsg
+
+ tgen.routers_have_failure()
+
+
+def test_shutdown_check_memleak():
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ # 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)