summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/lib/test_printfrr.c115
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/exabgp.env53
-rwxr-xr-xtests/topotests/bgp_peer-type_multipath-relax/peer1/exa-receive.py38
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer1/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer1/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_peer-type_multipath-relax/peer2/exa-receive.py38
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer2/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer2/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_peer-type_multipath-relax/peer3/exa-receive.py38
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer3/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer3/exabgp.cfg21
-rwxr-xr-xtests/topotests/bgp_peer-type_multipath-relax/peer4/exa-receive.py38
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer4/exa_readpipe.py19
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/peer4/exabgp.cfg21
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/bgpd.conf16
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/multipath.json50
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/not-multipath.json50
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-confed.json33
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-iBGP.json33
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-no-recursive.json35
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-recursive.json36
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1.json33
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-ip-route.json23
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-no-recursive.json21
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-recursive.json23
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r1/zebra.conf27
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r2/bgpd.conf19
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r2/staticd.conf4
-rw-r--r--tests/topotests/bgp_peer-type_multipath-relax/r2/zebra.conf19
-rwxr-xr-xtests/topotests/bgp_peer-type_multipath-relax/test_bgp_peer-type_multipath-relax.py386
-rwxr-xr-xtests/topotests/ospf-te-topo1/__init__.py0
-rw-r--r--tests/topotests/ospf-te-topo1/r1/ospfd.conf23
-rw-r--r--tests/topotests/ospf-te-topo1/r1/zebra.conf21
-rw-r--r--tests/topotests/ospf-te-topo1/r2/ospfd.conf34
-rw-r--r--tests/topotests/ospf-te-topo1/r2/zebra.conf33
-rw-r--r--tests/topotests/ospf-te-topo1/r3/ospfd.conf24
-rw-r--r--tests/topotests/ospf-te-topo1/r3/zebra.conf22
-rw-r--r--tests/topotests/ospf-te-topo1/r4/ospfd.conf22
-rw-r--r--tests/topotests/ospf-te-topo1/r4/zebra.conf12
-rw-r--r--tests/topotests/ospf-te-topo1/reference/ted_step1.json577
-rw-r--r--tests/topotests/ospf-te-topo1/reference/ted_step2.json477
-rw-r--r--tests/topotests/ospf-te-topo1/reference/ted_step3.json409
-rw-r--r--tests/topotests/ospf-te-topo1/reference/ted_step4.json490
-rw-r--r--tests/topotests/ospf-te-topo1/reference/ted_step5.json614
-rw-r--r--tests/topotests/ospf-te-topo1/reference/ted_step6.json615
-rw-r--r--tests/topotests/ospf-te-topo1/reference/ted_step7.json456
-rw-r--r--tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py314
-rw-r--r--tests/topotests/ospf6-topo2/r1/ospf6d.conf9
-rw-r--r--tests/topotests/ospf6-topo2/r1/zebra.conf5
-rw-r--r--tests/topotests/ospf6-topo2/r2/ospf6d.conf17
-rw-r--r--tests/topotests/ospf6-topo2/r2/zebra.conf8
-rw-r--r--tests/topotests/ospf6-topo2/r3/ospf6d.conf10
-rw-r--r--tests/topotests/ospf6-topo2/r3/zebra.conf8
-rw-r--r--tests/topotests/ospf6-topo2/test_ospf6_topo2.dot71
-rw-r--r--tests/topotests/ospf6-topo2/test_ospf6_topo2.pngbin0 -> 31523 bytes
-rw-r--r--tests/topotests/ospf6-topo2/test_ospf6_topo2.py177
56 files changed, 5732 insertions, 4 deletions
diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c
index 24de3fa88d..21b3a916b8 100644
--- a/tests/lib/test_printfrr.c
+++ b/tests/lib/test_printfrr.c
@@ -59,21 +59,88 @@ static void printcmp(const char *fmt, ...)
errors++;
}
-static void printchk(const char *ref, const char *fmt, ...) PRINTFRR(2, 3);
-static void printchk(const char *ref, const char *fmt, ...)
+static int printchk(const char *ref, const char *fmt, ...) PRINTFRR(2, 3);
+static int printchk(const char *ref, const char *fmt, ...)
{
va_list ap;
char bufrr[256];
+ bool truncfail = false;
+ size_t i;
+ size_t expectlen;
+
memset(bufrr, 0xcc, sizeof(bufrr));
va_start(ap, fmt);
- vsnprintfrr(bufrr, sizeof(bufrr), fmt, ap);
+ expectlen = vsnprintfrr(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ va_start(ap, fmt);
+ vsnprintfrr(bufrr, 7, fmt, ap);
va_end(ap);
- printf("fmt: \"%s\"\nref: \"%s\"\nfrr: \"%s\"\n%s\n\n",
+ if (strnlen(bufrr, 7) == 7)
+ truncfail = true;
+ if (strnlen(bufrr, 7) < 7 && strncmp(ref, bufrr, 6) != 0)
+ truncfail = true;
+ for (i = 7; i < sizeof(bufrr); i++)
+ if (bufrr[i] != (char)0xcc) {
+ truncfail = true;
+ break;
+ }
+
+ if (truncfail) {
+ printf("truncation test FAILED:\n"
+ "fmt: \"%s\"\nref: \"%s\"\nfrr[:7]: \"%s\"\n%s\n\n",
+ fmt, ref, bufrr, strcmp(ref, bufrr) ? "ERROR" : "ok");
+ errors++;
+ }
+
+ struct fmt_outpos outpos[16];
+ struct fbuf fb = {
+ .buf = bufrr,
+ .pos = bufrr,
+ .len = sizeof(bufrr) - 1,
+ .outpos = outpos,
+ .outpos_n = array_size(outpos),
+ };
+
+ va_start(ap, fmt);
+ vbprintfrr(&fb, fmt, ap);
+ fb.pos[0] = '\0';
+ va_end(ap);
+
+ printf("fmt: \"%s\"\nref: \"%s\"\nfrr: \"%s\"\n%s\n",
fmt, ref, bufrr, strcmp(ref, bufrr) ? "ERROR" : "ok");
if (strcmp(ref, bufrr))
errors++;
+ if (strlen(bufrr) != expectlen) {
+ printf("return value <> length mismatch\n");
+ errors++;
+ }
+
+ for (size_t i = 0; i < fb.outpos_i; i++)
+ printf("\t[%zu: %u..%u] = \"%.*s\"\n", i,
+ outpos[i].off_start,
+ outpos[i].off_end,
+ (int)(outpos[i].off_end - outpos[i].off_start),
+ bufrr + outpos[i].off_start);
+ printf("\n");
+ return 0;
+}
+
+static void test_va(const char *ref, const char *fmt, ...) PRINTFRR(2, 3);
+static void test_va(const char *ref, const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vaf.fmt = fmt;
+ vaf.va = &ap;
+
+ printchk(ref, "VA [%pVA] %s", &vaf, "--");
+
+ va_end(ap);
}
int main(int argc, char **argv)
@@ -112,9 +179,12 @@ int main(int argc, char **argv)
inet_aton("192.168.1.2", &ip);
printchk("192.168.1.2", "%pI4", &ip);
printchk(" 192.168.1.2", "%20pI4", &ip);
+ printchk("192.168.1.2 ", "%-20pI4", &ip);
printcmp("%p", &ip);
+ test_va("VA [192.168.1.2 1234] --", "%pI4 %u", &ip, 1234);
+
snprintfrr(buf, sizeof(buf), "test%s", "#1");
csnprintfrr(buf, sizeof(buf), "test%s", "#2");
assert(strcmp(buf, "test#1test#2") == 0);
@@ -146,5 +216,42 @@ int main(int argc, char **argv)
sg.src.s_addr = INADDR_ANY;
printchk("(*,224.1.2.3)", "%pSG4", &sg);
+ uint8_t randhex[] = { 0x12, 0x34, 0x00, 0xca, 0xfe, 0x00, 0xaa, 0x55 };
+
+ FMT_NSTD(printchk("12 34 00 ca fe 00 aa 55", "%.8pHX", randhex));
+ FMT_NSTD(printchk("12 34 00 ca fe 00 aa 55", "%.*pHX",
+ (int)sizeof(randhex), randhex));
+ FMT_NSTD(printchk("12 34 00 ca", "%.4pHX", randhex));
+
+ printchk("12 34 00 ca fe 00 aa 55", "%8pHX", randhex);
+ printchk("12 34 00 ca fe 00 aa 55", "%*pHX",
+ (int)sizeof(randhex), randhex);
+ printchk("12 34 00 ca", "%4pHX", randhex);
+
+ printchk("", "%pHX", randhex);
+
+ printchk("12:34:00:ca:fe:00:aa:55", "%8pHXc", randhex);
+ printchk("123400cafe00aa55", "%8pHXn", randhex);
+
+ printchk("/test/pa\\ th/\\~spe\\ncial\\x01/file.name", "%pSE",
+ "/test/pa th/~spe\ncial\x01/file.name");
+ printchk("/test/pa\\ th/\\~spe\\n", "%17pSE",
+ "/test/pa th/~spe\ncial\x01/file.name");
+
+ char nulltest[] = { 'n', 'u', 0, 'l', 'l' };
+
+ printchk("nu\\x00ll", "%5pSE", nulltest);
+ printchk("nu\\x00ll", "%*pSE", 5, nulltest);
+
+ printchk("bl\\\"ah\\x01te[st\\nab]c", "%pSQ",
+ "bl\"ah\x01te[st\nab]c");
+ printchk("\"bl\\\"ah\\x01te[st\\nab]c\"", "%pSQq",
+ "bl\"ah\x01te[st\nab]c");
+ printchk("\"bl\\\"ah\\x01te[st\\x0aab\\]c\"", "%pSQqs",
+ "bl\"ah\x01te[st\nab]c");
+ printchk("\"\"", "%pSQqn", "");
+ printchk("\"\"", "%pSQqn", (char *)NULL);
+ printchk("(null)", "%pSQq", (char *)NULL);
+
return !!errors;
}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/exabgp.env b/tests/topotests/bgp_peer-type_multipath-relax/exabgp.env
new file mode 100644
index 0000000000..6c554f5fa8
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/exabgp.env
@@ -0,0 +1,53 @@
+
+[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'
+
+[exabgp.log]
+all = false
+configuration = true
+daemon = true
+destination = '/var/log/exabgp.log'
+enable = true
+level = INFO
+message = false
+network = true
+packets = false
+parser = false
+processes = true
+reactor = true
+rib = false
+routes = false
+short = false
+timers = false
+
+[exabgp.pdb]
+enable = false
+
+[exabgp.profile]
+enable = false
+file = ''
+
+[exabgp.reactor]
+speed = 1.0
+
+[exabgp.tcp]
+acl = false
+bind = ''
+delay = 0
+once = false
+port = 179
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer1/exa-receive.py b/tests/topotests/bgp_peer-type_multipath-relax/peer1/exa-receive.py
new file mode 100755
index 0000000000..031ff455ca
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer1/exa-receive.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+"""
+exa-receive.py: Save received routes form ExaBGP into file
+"""
+
+from sys import stdin, argv
+from datetime import datetime
+
+# 1st arg is peer number
+peer = int(argv[1])
+
+# When the parent dies we are seeing continual newlines, so we only access so many before stopping
+counter = 0
+
+routesavefile = open("/tmp/peer%s-received.log" % peer, "w")
+
+while True:
+ try:
+ line = stdin.readline()
+ timestamp = datetime.now().strftime("%Y%m%d_%H:%M:%S - ")
+ routesavefile.write(timestamp + line)
+ routesavefile.flush()
+
+ if line == "":
+ counter += 1
+ if counter > 100:
+ break
+ continue
+
+ counter = 0
+ except KeyboardInterrupt:
+ pass
+ except IOError:
+ # most likely a signal during readline
+ pass
+
+routesavefile.close()
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer1/exa_readpipe.py b/tests/topotests/bgp_peer-type_multipath-relax/peer1/exa_readpipe.py
new file mode 100644
index 0000000000..9e689a27e3
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer1/exa_readpipe.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+"Helper script to read api commands from a pipe and feed them to ExaBGP"
+
+import sys
+
+if len(sys.argv) != 2:
+ sys.exit(1)
+fifo = sys.argv[1]
+
+while True:
+ pipe = open(fifo, "r")
+ with pipe:
+ line = pipe.readline().strip()
+ if line != "":
+ sys.stdout.write("{}\n".format(line))
+ sys.stdout.flush()
+ pipe.close()
+
+sys.exit(0)
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer1/exabgp.cfg b/tests/topotests/bgp_peer-type_multipath-relax/peer1/exabgp.cfg
new file mode 100644
index 0000000000..4a7dc48126
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer1/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer1.in";
+ encoder text;
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/exa-receive.py 1";
+ receive-routes;
+ encoder text;
+ }
+
+ neighbor 10.0.1.1 {
+ router-id 10.0.1.2;
+ local-address 10.0.1.2;
+ local-as 64510;
+ peer-as 64510;
+ }
+
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer2/exa-receive.py b/tests/topotests/bgp_peer-type_multipath-relax/peer2/exa-receive.py
new file mode 100755
index 0000000000..031ff455ca
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer2/exa-receive.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+"""
+exa-receive.py: Save received routes form ExaBGP into file
+"""
+
+from sys import stdin, argv
+from datetime import datetime
+
+# 1st arg is peer number
+peer = int(argv[1])
+
+# When the parent dies we are seeing continual newlines, so we only access so many before stopping
+counter = 0
+
+routesavefile = open("/tmp/peer%s-received.log" % peer, "w")
+
+while True:
+ try:
+ line = stdin.readline()
+ timestamp = datetime.now().strftime("%Y%m%d_%H:%M:%S - ")
+ routesavefile.write(timestamp + line)
+ routesavefile.flush()
+
+ if line == "":
+ counter += 1
+ if counter > 100:
+ break
+ continue
+
+ counter = 0
+ except KeyboardInterrupt:
+ pass
+ except IOError:
+ # most likely a signal during readline
+ pass
+
+routesavefile.close()
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer2/exa_readpipe.py b/tests/topotests/bgp_peer-type_multipath-relax/peer2/exa_readpipe.py
new file mode 100644
index 0000000000..9e689a27e3
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer2/exa_readpipe.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+"Helper script to read api commands from a pipe and feed them to ExaBGP"
+
+import sys
+
+if len(sys.argv) != 2:
+ sys.exit(1)
+fifo = sys.argv[1]
+
+while True:
+ pipe = open(fifo, "r")
+ with pipe:
+ line = pipe.readline().strip()
+ if line != "":
+ sys.stdout.write("{}\n".format(line))
+ sys.stdout.flush()
+ pipe.close()
+
+sys.exit(0)
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer2/exabgp.cfg b/tests/topotests/bgp_peer-type_multipath-relax/peer2/exabgp.cfg
new file mode 100644
index 0000000000..b53b054550
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer2/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer2.in";
+ encoder text;
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/exa-receive.py 2";
+ receive-routes;
+ encoder text;
+ }
+
+ neighbor 10.0.2.1 {
+ router-id 10.0.2.2;
+ local-address 10.0.2.2;
+ local-as 64511;
+ peer-as 64511;
+ }
+
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer3/exa-receive.py b/tests/topotests/bgp_peer-type_multipath-relax/peer3/exa-receive.py
new file mode 100755
index 0000000000..031ff455ca
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer3/exa-receive.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+"""
+exa-receive.py: Save received routes form ExaBGP into file
+"""
+
+from sys import stdin, argv
+from datetime import datetime
+
+# 1st arg is peer number
+peer = int(argv[1])
+
+# When the parent dies we are seeing continual newlines, so we only access so many before stopping
+counter = 0
+
+routesavefile = open("/tmp/peer%s-received.log" % peer, "w")
+
+while True:
+ try:
+ line = stdin.readline()
+ timestamp = datetime.now().strftime("%Y%m%d_%H:%M:%S - ")
+ routesavefile.write(timestamp + line)
+ routesavefile.flush()
+
+ if line == "":
+ counter += 1
+ if counter > 100:
+ break
+ continue
+
+ counter = 0
+ except KeyboardInterrupt:
+ pass
+ except IOError:
+ # most likely a signal during readline
+ pass
+
+routesavefile.close()
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer3/exa_readpipe.py b/tests/topotests/bgp_peer-type_multipath-relax/peer3/exa_readpipe.py
new file mode 100644
index 0000000000..9e689a27e3
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer3/exa_readpipe.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+"Helper script to read api commands from a pipe and feed them to ExaBGP"
+
+import sys
+
+if len(sys.argv) != 2:
+ sys.exit(1)
+fifo = sys.argv[1]
+
+while True:
+ pipe = open(fifo, "r")
+ with pipe:
+ line = pipe.readline().strip()
+ if line != "":
+ sys.stdout.write("{}\n".format(line))
+ sys.stdout.flush()
+ pipe.close()
+
+sys.exit(0)
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer3/exabgp.cfg b/tests/topotests/bgp_peer-type_multipath-relax/peer3/exabgp.cfg
new file mode 100644
index 0000000000..6a1cc2fb3f
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer3/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer3.in";
+ encoder text;
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/exa-receive.py 3";
+ receive-routes;
+ encoder text;
+ }
+
+ neighbor 10.0.3.1 {
+ router-id 10.0.3.2;
+ local-address 10.0.3.2;
+ local-as 64502;
+ peer-as 64501;
+ }
+
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer4/exa-receive.py b/tests/topotests/bgp_peer-type_multipath-relax/peer4/exa-receive.py
new file mode 100755
index 0000000000..031ff455ca
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer4/exa-receive.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+"""
+exa-receive.py: Save received routes form ExaBGP into file
+"""
+
+from sys import stdin, argv
+from datetime import datetime
+
+# 1st arg is peer number
+peer = int(argv[1])
+
+# When the parent dies we are seeing continual newlines, so we only access so many before stopping
+counter = 0
+
+routesavefile = open("/tmp/peer%s-received.log" % peer, "w")
+
+while True:
+ try:
+ line = stdin.readline()
+ timestamp = datetime.now().strftime("%Y%m%d_%H:%M:%S - ")
+ routesavefile.write(timestamp + line)
+ routesavefile.flush()
+
+ if line == "":
+ counter += 1
+ if counter > 100:
+ break
+ continue
+
+ counter = 0
+ except KeyboardInterrupt:
+ pass
+ except IOError:
+ # most likely a signal during readline
+ pass
+
+routesavefile.close()
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer4/exa_readpipe.py b/tests/topotests/bgp_peer-type_multipath-relax/peer4/exa_readpipe.py
new file mode 100644
index 0000000000..9e689a27e3
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer4/exa_readpipe.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+"Helper script to read api commands from a pipe and feed them to ExaBGP"
+
+import sys
+
+if len(sys.argv) != 2:
+ sys.exit(1)
+fifo = sys.argv[1]
+
+while True:
+ pipe = open(fifo, "r")
+ with pipe:
+ line = pipe.readline().strip()
+ if line != "":
+ sys.stdout.write("{}\n".format(line))
+ sys.stdout.flush()
+ pipe.close()
+
+sys.exit(0)
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/peer4/exabgp.cfg b/tests/topotests/bgp_peer-type_multipath-relax/peer4/exabgp.cfg
new file mode 100644
index 0000000000..2cc26cb80f
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/peer4/exabgp.cfg
@@ -0,0 +1,21 @@
+group controller {
+
+ process announce-routes {
+ run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer4.in";
+ encoder text;
+ }
+
+ process receive-routes {
+ run "/etc/exabgp/exa-receive.py 4";
+ receive-routes;
+ encoder text;
+ }
+
+ neighbor 10.0.4.1 {
+ router-id 10.0.4.2;
+ local-address 10.0.4.2;
+ local-as 64503;
+ peer-as 64501;
+ }
+
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/bgpd.conf b/tests/topotests/bgp_peer-type_multipath-relax/r1/bgpd.conf
new file mode 100644
index 0000000000..038f108aa8
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/bgpd.conf
@@ -0,0 +1,16 @@
+!
+router bgp 64510
+ bgp router-id 10.0.1.1
+ no bgp ebgp-requires-policy
+ bgp confederation identifier 64501
+ bgp confederation peers 64511
+ bgp bestpath as-path multipath-relax
+ bgp bestpath compare-routerid
+ bgp bestpath peer-type multipath-relax
+ neighbor 10.0.1.2 remote-as 64510
+ neighbor 10.0.3.2 remote-as 64502
+ neighbor 10.0.4.2 remote-as 64503
+ neighbor 10.0.5.2 remote-as 64511
+!
+line vty
+!
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/multipath.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/multipath.json
new file mode 100644
index 0000000000..11dad786f2
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/multipath.json
@@ -0,0 +1,50 @@
+{
+ "routes": { "203.0.113.0/30": [
+ {
+ "valid":true,
+ "multipath":true,
+ "pathFrom":"external",
+ "peerId":"10.0.5.2"
+ },
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"Peer Type",
+ "pathFrom":"external",
+ "peerId":"10.0.4.2"
+ },
+ {
+ "valid":true,
+ "multipath":true,
+ "pathFrom":"internal",
+ "peerId":"10.0.1.2"
+ }
+],"203.0.113.4/30": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"Confed Peer Type",
+ "pathFrom":"external",
+ "peerId":"10.0.5.2"
+ },
+ {
+ "valid":true,
+ "multipath":true,
+ "pathFrom":"internal",
+ "peerId":"10.0.1.2"
+ }
+],"203.0.113.8/30": [
+ {
+ "valid":true,
+ "multipath":true,
+ "pathFrom":"external",
+ "peerId":"10.0.4.2"
+ },
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"Router ID",
+ "pathFrom":"external",
+ "peerId":"10.0.3.2"
+ }
+] } }
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/not-multipath.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/not-multipath.json
new file mode 100644
index 0000000000..c621832157
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/not-multipath.json
@@ -0,0 +1,50 @@
+{
+ "routes": { "203.0.113.0/30": [
+ {
+ "valid":true,
+ "multipath":null,
+ "pathFrom":"external",
+ "peerId":"10.0.5.2"
+ },
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"Peer Type",
+ "pathFrom":"external",
+ "peerId":"10.0.4.2"
+ },
+ {
+ "valid":true,
+ "multipath":null,
+ "pathFrom":"internal",
+ "peerId":"10.0.1.2"
+ }
+],"203.0.113.4/30": [
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"Confed Peer Type",
+ "pathFrom":"external",
+ "peerId":"10.0.5.2"
+ },
+ {
+ "valid":true,
+ "multipath":null,
+ "pathFrom":"internal",
+ "peerId":"10.0.1.2"
+ }
+],"203.0.113.8/30": [
+ {
+ "valid":true,
+ "multipath":true,
+ "pathFrom":"external",
+ "peerId":"10.0.4.2"
+ },
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"Router ID",
+ "pathFrom":"external",
+ "peerId":"10.0.3.2"
+ }
+] } }
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-confed.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-confed.json
new file mode 100644
index 0000000000..22ec2c298b
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-confed.json
@@ -0,0 +1,33 @@
+{
+ "203.0.113.0\/30":[
+ {
+ "prefix":"203.0.113.0\/30",
+ "protocol":"bgp",
+ "installed":true,
+ "internalNextHopNum":4,
+ "internalNextHopActiveNum":4,
+ "nexthops":[
+ {
+ "ip":"198.51.100.2",
+ "active":true,
+ "recursive":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "active":true
+ },
+ {
+ "ip":"198.51.100.10",
+ "active":true,
+ "recursive":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-iBGP.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-iBGP.json
new file mode 100644
index 0000000000..facddcda46
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-eBGP-iBGP.json
@@ -0,0 +1,33 @@
+{
+ "203.0.113.0\/30":[
+ {
+ "prefix":"203.0.113.0\/30",
+ "protocol":"bgp",
+ "installed":true,
+ "internalNextHopNum":4,
+ "internalNextHopActiveNum":4,
+ "nexthops":[
+ {
+ "ip":"198.51.100.1",
+ "active":true,
+ "recursive":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "active":true
+ },
+ {
+ "ip":"198.51.100.10",
+ "active":true,
+ "recursive":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-no-recursive.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-no-recursive.json
new file mode 100644
index 0000000000..5399ceefcc
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-no-recursive.json
@@ -0,0 +1,35 @@
+{
+ "prefix":"203.0.113.0\/30",
+ "paths":[
+ {
+ "valid":false,
+ "peer":{
+ "peerId":"10.0.4.2",
+ "routerId":"10.0.4.2",
+ "type":"external"
+ }
+ },
+ {
+ "valid":true,
+ "multipath":true,
+ "bestpath":{
+ "overall":true,
+ "selectionReason":"Confed Peer Type"
+ },
+ "peer":{
+ "peerId":"10.0.5.2",
+ "routerId":"10.0.5.2",
+ "type":"confed-external"
+ }
+ },
+ {
+ "valid":true,
+ "multipath":true,
+ "peer":{
+ "peerId":"10.0.1.2",
+ "routerId":"10.0.1.2",
+ "type":"confed-internal"
+ }
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-recursive.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-recursive.json
new file mode 100644
index 0000000000..7da95aed1c
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1-recursive.json
@@ -0,0 +1,36 @@
+{
+ "prefix":"203.0.113.0\/30",
+ "paths":[
+ {
+ "valid":true,
+ "multipath":true,
+ "bestpath":{
+ "overall":true,
+ "selectionReason":"Peer Type"
+ },
+ "peer":{
+ "peerId":"10.0.4.2",
+ "routerId":"10.0.4.2",
+ "type":"external"
+ }
+ },
+ {
+ "valid":true,
+ "multipath":true,
+ "peer":{
+ "peerId":"10.0.5.2",
+ "routerId":"10.0.5.2",
+ "type":"confed-external"
+ }
+ },
+ {
+ "valid":true,
+ "multipath":true,
+ "peer":{
+ "peerId":"10.0.1.2",
+ "routerId":"10.0.1.2",
+ "type":"confed-internal"
+ }
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1.json
new file mode 100644
index 0000000000..a90669a474
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix1.json
@@ -0,0 +1,33 @@
+{
+ "prefix":"203.0.113.0\/30",
+ "paths":[
+ {
+ "multipath":true,
+ "peer":{
+ "peerId":"10.0.5.2",
+ "routerId":"10.0.5.2",
+ "type":"confed-external"
+ }
+ },
+ {
+ "multipath":true,
+ "bestpath":{
+ "overall":true,
+ "selectionReason":"Peer Type"
+ },
+ "peer":{
+ "peerId":"10.0.4.2",
+ "routerId":"10.0.4.2",
+ "type":"external"
+ }
+ },
+ {
+ "multipath":true,
+ "peer":{
+ "peerId":"10.0.1.2",
+ "routerId":"10.0.1.2",
+ "type":"confed-internal"
+ }
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-ip-route.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-ip-route.json
new file mode 100644
index 0000000000..1bf38efcc5
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-ip-route.json
@@ -0,0 +1,23 @@
+{
+ "203.0.113.8\/30":[
+ {
+ "prefix":"203.0.113.8\/30",
+ "protocol":"bgp",
+ "installed":true,
+ "internalNextHopNum":2,
+ "internalNextHopActiveNum":1,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "active":true
+ },
+ {
+ "fib":null,
+ "ip":"198.51.100.10",
+ "active":null
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-no-recursive.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-no-recursive.json
new file mode 100644
index 0000000000..33d0f2d1ce
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-no-recursive.json
@@ -0,0 +1,21 @@
+{
+ "prefix":"203.0.113.8\/30",
+ "paths":[
+ {
+ "valid":false,
+ "peer":{
+ "peerId":"10.0.4.2",
+ "routerId":"10.0.4.2",
+ "type":"external"
+ }
+ },
+ {
+ "valid":true,
+ "peer":{
+ "peerId":"10.0.3.2",
+ "routerId":"10.0.3.2",
+ "type":"external"
+ }
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-recursive.json b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-recursive.json
new file mode 100644
index 0000000000..6ac2512a60
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/prefix3-recursive.json
@@ -0,0 +1,23 @@
+{
+ "prefix":"203.0.113.8\/30",
+ "paths":[
+ {
+ "valid":true,
+ "multipath":true,
+ "peer":{
+ "peerId":"10.0.4.2",
+ "routerId":"10.0.4.2",
+ "type":"external"
+ }
+ },
+ {
+ "valid":true,
+ "multipath":true,
+ "peer":{
+ "peerId":"10.0.3.2",
+ "routerId":"10.0.3.2",
+ "type":"external"
+ }
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r1/zebra.conf b/tests/topotests/bgp_peer-type_multipath-relax/r1/zebra.conf
new file mode 100644
index 0000000000..911aa1c39d
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r1/zebra.conf
@@ -0,0 +1,27 @@
+!
+hostname r1
+!
+interface r1-eth0
+ description ExaBGP iBGP peer1
+ ip address 10.0.1.1/24
+ no link-detect
+!
+interface r1-eth1
+ description ExaBGP peer3
+ ip address 10.0.3.1/24
+ no link-detect
+!
+interface r1-eth2
+ description ExaBGP peer4
+ ip address 10.0.4.1/24
+ no link-detect
+!
+interface r1-eth3
+ description r2 confed peer
+ ip address 10.0.5.1/24
+ no link-detect
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r2/bgpd.conf b/tests/topotests/bgp_peer-type_multipath-relax/r2/bgpd.conf
new file mode 100644
index 0000000000..2362a19f26
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r2/bgpd.conf
@@ -0,0 +1,19 @@
+!
+!log file bgpd.log
+!
+router bgp 64511
+ bgp confederation identifier 64501
+ bgp confederation peers 64510
+ bgp router-id 10.0.5.2
+ no bgp ebgp-requires-policy
+ neighbor 10.0.2.2 remote-as 64511
+ neighbor 10.0.5.1 remote-as 64510
+ !
+ address-family ipv4 unicast
+ neighbor 10.0.5.1 route-map dropall in
+ exit-address-family
+!
+route-map dropall deny 10
+!
+line vty
+!
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r2/staticd.conf b/tests/topotests/bgp_peer-type_multipath-relax/r2/staticd.conf
new file mode 100644
index 0000000000..35ebe0dc66
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r2/staticd.conf
@@ -0,0 +1,4 @@
+hostname r2
+!
+ip route 198.51.100.0/24 10.0.2.2
+!
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/r2/zebra.conf b/tests/topotests/bgp_peer-type_multipath-relax/r2/zebra.conf
new file mode 100644
index 0000000000..900e7d4fbc
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/r2/zebra.conf
@@ -0,0 +1,19 @@
+!
+!
+hostname r2
+!
+interface r2-eth0
+ description ExaBGP peer
+ ip address 10.0.2.1/24
+ no link-detect
+!
+interface r2-eth1
+ description r1 confed peer
+ ip address 10.0.5.2/24
+ no link-detect
+!
+ip forwarding
+!
+!
+line vty
+!
diff --git a/tests/topotests/bgp_peer-type_multipath-relax/test_bgp_peer-type_multipath-relax.py b/tests/topotests/bgp_peer-type_multipath-relax/test_bgp_peer-type_multipath-relax.py
new file mode 100755
index 0000000000..39a0beeb11
--- /dev/null
+++ b/tests/topotests/bgp_peer-type_multipath-relax/test_bgp_peer-type_multipath-relax.py
@@ -0,0 +1,386 @@
+#!/usr/bin/env python
+
+#
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2021 Arista Networks, Inc.
+#
+# 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 Arista Networks 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_peer-type_multipath-relax.py:
+
+Test the effects of the "bgp bestpath peer-type multipath-relax" command
+
+- enabling the command allows eBGP, iBGP, and confed routes to be multipath
+- the choice of best path is not affected
+- disabling the command removes iBGP/confed routes from multipath
+- enabling the command does not forgive eBGP routes of the requirement
+ (when enabled) that next hops resolve over connected routes
+- a mixed-type multipath next hop, when published to zebra, does not
+ require resolving next hops over connected routes
+- with the command enabled, an all-eBGP multipath next hop still requires
+ resolving next hops over connected routes when published to zebra
+
+Topology used by the test:
+
+ eBGP +------+ iBGP
+ peer1 ---- | r1 | ---- peer3
+ | |
+peer2 ---- r2 ---- | | ---- peer4
+ iBGP confed +------+ eBGP
+
+r2 is present in this topology because ExaBGP does not currently support
+confederations so we use FRR to advertise the required AS_CONFED_SEQUENCE.
+
+Routes are advertised from different peers to form interesting multipaths.
+
+ peer1 peer2 peer3 peer4 multipath on r1
+
+203.0.113.0/30 x x x all 3
+203.0.113.4/30 x x confed-iBGP
+203.0.113.8/30 x x eBGP-only
+
+There is also a BGP-advertised route used only for recursively resolving
+next hops.
+"""
+
+import functools
+import json
+import os
+import pytest
+import sys
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class PeerTypeRelaxTopo(Topo):
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # Set up routers
+ tgen.add_router("r1") # DUT
+ tgen.add_router("r2")
+
+ # Set up peers
+ for peern in range(1, 5):
+ peer = tgen.add_exabgp_peer(
+ "peer{}".format(peern),
+ ip="10.0.{}.2/24".format(peern),
+ defaultRoute="via 10.0.{}.1".format(peern),
+ )
+ if peern == 2:
+ tgen.add_link(tgen.gears["r2"], peer)
+ else:
+ tgen.add_link(tgen.gears["r1"], peer)
+ tgen.add_link(tgen.gears["r1"], tgen.gears["r2"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(PeerTypeRelaxTopo, mod.__name__)
+ tgen.start_topology()
+
+ # For all registered routers, load the zebra configuration file
+ for rname, router in tgen.routers().items():
+ router.run("/bin/bash {}/setup_vrfs".format(CWD))
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_STATIC, os.path.join(CWD, "{}/staticd.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ # After loading the configurations, this function loads configured daemons.
+ tgen.start_router()
+
+ # Start up exabgp peers
+ peers = tgen.exabgp_peers()
+ for peer in peers:
+ fifo_in = "/var/run/exabgp_{}.in".format(peer)
+ if os.path.exists(fifo_in):
+ os.remove(fifo_in)
+ os.mkfifo(fifo_in, 0o777)
+ logger.info("Starting ExaBGP on peer {}".format(peer))
+ peer_dir = os.path.join(CWD, peer)
+ env_file = os.path.join(CWD, "exabgp.env")
+ peers[peer].start(peer_dir, env_file)
+
+
+def teardown_module(mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ tgen.stop_topology()
+
+
+def test_bgp_peer_type_multipath_relax():
+ tgen = get_topogen()
+
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ def exabgp_cmd(peer, cmd):
+ pipe = open("/run/exabgp_{}.in".format(peer), "w")
+ with pipe:
+ pipe.write(cmd)
+ pipe.close()
+
+ # Prefixes used in the test
+ prefix1 = "203.0.113.0/30"
+ prefix2 = "203.0.113.4/30"
+ prefix3 = "203.0.113.8/30"
+ # Next hops used for iBGP/confed routes
+ resolved_nh1 = "198.51.100.1"
+ resolved_nh2 = "198.51.100.2"
+ # BGP route used for recursive resolution
+ bgp_resolving_prefix = "198.51.100.0/24"
+ # Next hop that will require non-connected recursive resolution
+ ebgp_resolved_nh = "198.51.100.10"
+
+ # Send a non-connected route to resolve others
+ exabgp_cmd(
+ "peer3", "announce route {} next-hop self\n".format(bgp_resolving_prefix)
+ )
+ router = tgen.gears["r1"]
+
+ # It seems that if you write to the exabgp socket too quickly in
+ # succession, requests get lost. So verify prefix1 now instead of
+ # after all the prefixes are advertised.
+ logger.info("Create and verify mixed-type multipaths")
+ exabgp_cmd(
+ "peer1",
+ "announce route {} next-hop {} as-path [ 64499 ]\n".format(
+ prefix1, resolved_nh1
+ ),
+ )
+ exabgp_cmd(
+ "peer2",
+ "announce route {} next-hop {} as-path [ 64499 ]\n".format(
+ prefix1, resolved_nh2
+ ),
+ )
+ exabgp_cmd("peer4", "announce route {} next-hop self\n".format(prefix1))
+ reffile = os.path.join(CWD, "r1/prefix1.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip bgp {} json".format(prefix1),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Mixed-type multipath not found"
+ assert res is None, assertMsg
+
+ logger.info("Create and verify eBGP and iBGP+confed multipaths")
+ exabgp_cmd(
+ "peer1",
+ "announce route {} next-hop {} as-path [ 64499 ]\n".format(
+ prefix2, resolved_nh1
+ ),
+ )
+ exabgp_cmd(
+ "peer2",
+ "announce route {} next-hop {} as-path [ 64499 ]\n".format(
+ prefix2, resolved_nh2
+ ),
+ )
+ exabgp_cmd("peer3", "announce route {} next-hop self".format(prefix3))
+ exabgp_cmd("peer4", "announce route {} next-hop self".format(prefix3))
+ reffile = os.path.join(CWD, "r1/multipath.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show ip bgp json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Not all expected multipaths found"
+ assert res is None, assertMsg
+
+ logger.info("Toggle peer-type multipath-relax and verify the changes")
+ router.vtysh_cmd(
+ "conf\n router bgp 64510\n no bgp bestpath peer-type multipath-relax\n"
+ )
+ # This file verifies "multipath" is not set
+ reffile = os.path.join(CWD, "r1/not-multipath.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show ip bgp json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Disabling peer-type multipath-relax did not take effect"
+ assert res is None, assertMsg
+
+ router.vtysh_cmd(
+ "conf\n router bgp 64510\n bgp bestpath peer-type multipath-relax\n"
+ )
+ reffile = os.path.join(CWD, "r1/multipath.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show ip bgp json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Reenabling peer-type multipath-relax did not take effect"
+ assert res is None, assertMsg
+
+ logger.info("Check recursive resolution of eBGP next hops is not affected")
+ # eBGP next hop resolution rejects recursively resolved next hops by
+ # default, even with peer-type multipath-relax
+ exabgp_cmd(
+ "peer4", "announce route {} next-hop {}\n".format(prefix3, ebgp_resolved_nh)
+ )
+ reffile = os.path.join(CWD, "r1/prefix3-no-recursive.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip bgp {} json".format(prefix3),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Recursive eBGP next hop not as expected for {}".format(prefix3)
+ assert res is None, assertMsg
+
+ exabgp_cmd(
+ "peer4", "announce route {} next-hop {}\n".format(prefix1, ebgp_resolved_nh)
+ )
+ reffile = os.path.join(CWD, "r1/prefix1-no-recursive.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip bgp {} json".format(prefix1),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Recursive eBGP next hop not as expected for {}".format(prefix1)
+ assert res is None, assertMsg
+
+ # When other config allows recursively resolved eBGP next hops,
+ # such next hops in all-eBGP multipaths should be valid
+ router.vtysh_cmd("conf\n router bgp 64510\n neighbor 10.0.4.2 ebgp-multihop\n")
+ reffile = os.path.join(CWD, "r1/prefix3-recursive.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip bgp {} json".format(prefix3),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Recursive eBGP next hop not as expected for {}".format(prefix3)
+ assert res is None, assertMsg
+
+ reffile = os.path.join(CWD, "r1/prefix1-recursive.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip bgp {} json".format(prefix1),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "Recursive eBGP next hop not as expected for {}".format(prefix1)
+ assert res is None, assertMsg
+
+ logger.info("Check mixed-type multipath next hop recursive resolution in FIB")
+ # There are now two eBGP-learned routes with a recursively resolved next;
+ # hop; one is all-eBGP multipath, and the other is iBGP/eBGP/
+ # confed-external. The peer-type multipath-relax feature only enables
+ # recursive resolution in FIB if any next hop is iBGP/confed-learned. The
+ # all-eBGP multipath will have only one valid next hop in the FIB.
+ reffile = os.path.join(CWD, "r1/prefix3-ip-route.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip route {} json".format(prefix3),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "FIB next hops mismatch for all-eBGP multipath"
+ assert res is None, assertMsg
+
+ # check confed-external enables recursively resolved next hops by itself
+ exabgp_cmd(
+ "peer1",
+ "withdraw route {} next-hop {} as-path [ 64499 ]\n".format(
+ prefix1, resolved_nh1
+ ),
+ )
+ reffile = os.path.join(CWD, "r1/prefix1-eBGP-confed.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip route {} json".format(prefix1),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "FIB next hops mismatch for eBGP+confed-external multipath"
+ assert res is None, assertMsg
+
+ # check iBGP by itself
+ exabgp_cmd(
+ "peer1",
+ "announce route {} next-hop {} as-path [ 64499 ]\n".format(
+ prefix1, resolved_nh1
+ ),
+ )
+ exabgp_cmd(
+ "peer2",
+ "withdraw route {} next-hop {} as-path [ 64499 ]\n".format(
+ prefix1, resolved_nh2
+ ),
+ )
+ reffile = os.path.join(CWD, "r1/prefix1-eBGP-iBGP.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip route {} json".format(prefix1),
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=10, wait=1)
+ assertMsg = "FIB next hops mismatch for eBGP+iBGP multipath"
+ assert res is None, assertMsg
+
+
+def test_memory_leak():
+ "Run the memory leak test and report results."
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/ospf-te-topo1/__init__.py b/tests/topotests/ospf-te-topo1/__init__.py
new file mode 100755
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/__init__.py
diff --git a/tests/topotests/ospf-te-topo1/r1/ospfd.conf b/tests/topotests/ospf-te-topo1/r1/ospfd.conf
new file mode 100644
index 0000000000..312dd2697e
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r1/ospfd.conf
@@ -0,0 +1,23 @@
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface r1-eth0
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface r1-eth1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 10.0.255.1
+ capability opaque
+ mpls-te on
+ mpls-te router-address 10.0.255.1
+!
+
diff --git a/tests/topotests/ospf-te-topo1/r1/zebra.conf b/tests/topotests/ospf-te-topo1/r1/zebra.conf
new file mode 100644
index 0000000000..7c5dc3ffe0
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r1/zebra.conf
@@ -0,0 +1,21 @@
+!
+interface lo
+ ip address 10.0.255.1/32
+!
+interface r1-eth0
+ ip address 10.0.0.1/24
+ link-params
+ metric 20
+ delay 10000
+ ava-bw 1.25e+08
+ enable
+ exit-link-params
+!
+interface r1-eth1
+ ip address 10.0.1.1/24
+ link-params
+ enable
+ exit-link-params
+!
+ip forwarding
+!
diff --git a/tests/topotests/ospf-te-topo1/r2/ospfd.conf b/tests/topotests/ospf-te-topo1/r2/ospfd.conf
new file mode 100644
index 0000000000..e9c3f65bc2
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r2/ospfd.conf
@@ -0,0 +1,34 @@
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface r2-eth0
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface r2-eth1
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+interface r2-eth2
+ ip ospf network point-to-point
+ ip ospf area 0.0.0.0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+interface r2-eth3
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+router ospf
+ ospf router-id 10.0.255.2
+ capability opaque
+ mpls-te on
+ mpls-te router-address 10.0.255.2
+!
diff --git a/tests/topotests/ospf-te-topo1/r2/zebra.conf b/tests/topotests/ospf-te-topo1/r2/zebra.conf
new file mode 100644
index 0000000000..69e10191f3
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r2/zebra.conf
@@ -0,0 +1,33 @@
+!
+interface lo
+ ip address 10.0.255.2/32
+!
+interface r2-eth0
+ ip address 10.0.0.2/24
+ link-params
+ enable
+ exit-link-params
+!
+interface r2-eth1
+ ip address 10.0.1.2/24
+ link-params
+ enable
+ exit-link-params
+!
+interface r2-eth2
+ ip address 10.0.3.2/24
+ link-params
+ enable
+ exit-link-params
+!
+interface r2-eth3
+ ip address 10.0.4.2/24
+ link-params
+ metric 30
+ delay 25000
+ use-bw 1.25e+8
+ enable
+ exit-link-params
+!
+ip forwarding
+!
diff --git a/tests/topotests/ospf-te-topo1/r3/ospfd.conf b/tests/topotests/ospf-te-topo1/r3/ospfd.conf
new file mode 100644
index 0000000000..caa5f1e1eb
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r3/ospfd.conf
@@ -0,0 +1,24 @@
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface r3-eth0
+ ip ospf network point-to-point
+ ip ospf area 0.0.0.0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+interface r3-eth1
+ ip ospf network point-to-point
+ ip ospf area 0.0.0.0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+!
+router ospf
+ ospf router-id 10.0.255.3
+ capability opaque
+ mpls-te on
+ mpls-te router-address 10.0.255.3
+ mpls-te inter-as as
+!
diff --git a/tests/topotests/ospf-te-topo1/r3/zebra.conf b/tests/topotests/ospf-te-topo1/r3/zebra.conf
new file mode 100644
index 0000000000..4cf9077085
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r3/zebra.conf
@@ -0,0 +1,22 @@
+!
+interface lo
+ ip address 10.0.255.3/32
+!
+interface r3-eth0
+ ip address 10.0.3.1/24
+ link-params
+ enable
+ admin-grp 0x20
+ exit-link-params
+!
+interface r3-eth1
+ ip address 10.0.5.1/24
+ link-params
+ enable
+ metric 10
+ delay 50000
+ neighbor 10.0.255.5 as 65535
+ exit-link-params
+!
+ip forwarding
+!
diff --git a/tests/topotests/ospf-te-topo1/r4/ospfd.conf b/tests/topotests/ospf-te-topo1/r4/ospfd.conf
new file mode 100644
index 0000000000..e454673153
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r4/ospfd.conf
@@ -0,0 +1,22 @@
+!
+interface lo
+ ip ospf area 0.0.0.0
+!
+interface r4-eth0
+ ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+ ip ospf area 0.0.0.0
+!
+!
+router ospf
+ ospf router-id 10.0.255.4
+ capability opaque
+ mpls-te on
+ mpls-te router-address 10.0.255.4
+ segment-routing on
+ segment-routing local-block 5000 5999
+ segment-routing global-block 10000 19999
+ segment-routing node-msd 12
+ segment-routing prefix 10.0.255.4/32 index 400 no-php-flag
+!
diff --git a/tests/topotests/ospf-te-topo1/r4/zebra.conf b/tests/topotests/ospf-te-topo1/r4/zebra.conf
new file mode 100644
index 0000000000..18c003b230
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/r4/zebra.conf
@@ -0,0 +1,12 @@
+!
+interface lo
+ ip address 10.0.255.4/32
+!
+interface r4-eth0
+ ip address 10.0.4.1/24
+ link-params
+ enable
+ exit-link-params
+!
+ip forwarding
+!
diff --git a/tests/topotests/ospf-te-topo1/reference/ted_step1.json b/tests/topotests/ospf-te-topo1/reference/ted_step1.json
new file mode 100644
index 0000000000..9624292ccd
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/reference/ted_step1.json
@@ -0,0 +1,577 @@
+{
+ "ted":{
+ "name":"OSPF",
+ "key":1,
+ "verticesCount":5,
+ "edgesCount":9,
+ "subnetsCount":14,
+ "vertices":[
+ {
+ "vertex-id":167837441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.1",
+ "vertex-type":"Standard"
+ },
+ {
+ "vertex-id":167837442,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.2",
+ "vertex-type":"Standard"
+ },
+ {
+ "vertex-id":167837443,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.3",
+ "vertex-type":"ASBR"
+ },
+ {
+ "vertex-id":167837444,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.4",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":10000,
+ "srgb-lower":10000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":5000,
+ "msd":12
+ }
+ },
+ {
+ "vertex-id":167837445,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.5",
+ "vertex-type":"Remote ASBR",
+ "asn":65535
+ }
+ ],
+ "edges":[
+ {
+ "edge-id":167772161,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":20,
+ "local-address":"10.0.0.1",
+ "remote-address":"10.0.0.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":10000,
+ "available-bandwidth":125000000.0
+ }
+ },
+ {
+ "edge-id":167772162,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.0.2",
+ "remote-address":"10.0.0.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772417,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.1",
+ "remote-address":"10.0.1.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772418,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.2",
+ "remote-address":"10.0.1.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772929,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "admin-group":32,
+ "local-address":"10.0.3.1",
+ "remote-address":"10.0.3.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772930,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837443,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.3.2",
+ "remote-address":"10.0.3.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167773185,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "local-vertex-id":167837444,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.4.1",
+ "remote-address":"10.0.4.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773186,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837444,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":30,
+ "local-address":"10.0.4.2",
+ "remote-address":"10.0.4.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":25000,
+ "utilized-bandwidth":125000000.0
+ }
+ },
+ {
+ "edge-id":167773441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837445,
+ "metric":0,
+ "edge-attributes":{
+ "te-metric":10,
+ "local-address":"10.0.5.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "remote-asn":65535,
+ "remote-as-address":"10.0.255.5",
+ "delay":50000
+ }
+ }
+ ],
+ "subnets":[
+ {
+ "subnet-id":"10.0.0.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.0.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.5.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.255.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.3\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.4\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":400,
+ "algo":0,
+ "flags":"0x40"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.5\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.5",
+ "vertex-id":167837445,
+ "metric":10
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ospf-te-topo1/reference/ted_step2.json b/tests/topotests/ospf-te-topo1/reference/ted_step2.json
new file mode 100644
index 0000000000..623d1dc7e0
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/reference/ted_step2.json
@@ -0,0 +1,477 @@
+{
+ "ted":{
+ "name":"OSPF",
+ "key":1,
+ "verticesCount":5,
+ "edgesCount":7,
+ "subnetsCount":12,
+ "vertices":[
+ {
+ "vertex-id":167837441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.1",
+ "vertex-type":"Standard"
+ },
+ {
+ "vertex-id":167837442,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.2",
+ "vertex-type":"Standard"
+ },
+ {
+ "vertex-id":167837443,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.3",
+ "vertex-type":"ASBR"
+ },
+ {
+ "vertex-id":167837444,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.4",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":10000,
+ "srgb-lower":10000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":5000,
+ "msd":12
+ }
+ },
+ {
+ "vertex-id":167837445,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.5",
+ "vertex-type":"Remote ASBR",
+ "asn":65535
+ }
+ ],
+ "edges":[
+ {
+ "edge-id":167772161,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":20,
+ "local-address":"10.0.0.1",
+ "remote-address":"10.0.0.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":10000,
+ "available-bandwidth":125000000.0
+ }
+ },
+ {
+ "edge-id":167772162,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.0.2",
+ "remote-address":"10.0.0.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772929,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "admin-group":32,
+ "local-address":"10.0.3.1",
+ "remote-address":"10.0.3.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772930,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837443,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.3.2",
+ "remote-address":"10.0.3.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167773185,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "local-vertex-id":167837444,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.4.1",
+ "remote-address":"10.0.4.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773186,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837444,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":30,
+ "local-address":"10.0.4.2",
+ "remote-address":"10.0.4.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":25000,
+ "utilized-bandwidth":125000000.0
+ }
+ },
+ {
+ "edge-id":167773441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837445,
+ "metric":0,
+ "edge-attributes":{
+ "te-metric":10,
+ "local-address":"10.0.5.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "remote-asn":65535,
+ "remote-as-address":"10.0.255.5",
+ "delay":50000
+ }
+ }
+ ],
+ "subnets":[
+ {
+ "subnet-id":"10.0.0.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.0.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.5.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.255.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.3\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.4\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":400,
+ "algo":0,
+ "flags":"0x40"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.5\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.5",
+ "vertex-id":167837445,
+ "metric":10
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ospf-te-topo1/reference/ted_step3.json b/tests/topotests/ospf-te-topo1/reference/ted_step3.json
new file mode 100644
index 0000000000..117011a43a
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/reference/ted_step3.json
@@ -0,0 +1,409 @@
+{
+ "ted":{
+ "name":"OSPF",
+ "key":1,
+ "verticesCount":4,
+ "edgesCount":6,
+ "subnetsCount":10,
+ "vertices":[
+ {
+ "vertex-id":167837441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.1",
+ "vertex-type":"Standard"
+ },
+ {
+ "vertex-id":167837442,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.2",
+ "vertex-type":"Standard"
+ },
+ {
+ "vertex-id":167837443,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.3",
+ "vertex-type":"ASBR"
+ },
+ {
+ "vertex-id":167837444,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.4",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":10000,
+ "srgb-lower":10000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":5000,
+ "msd":12
+ }
+ }
+ ],
+ "edges":[
+ {
+ "edge-id":167772161,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":20,
+ "local-address":"10.0.0.1",
+ "remote-address":"10.0.0.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":10000,
+ "available-bandwidth":125000000.0
+ }
+ },
+ {
+ "edge-id":167772162,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.0.2",
+ "remote-address":"10.0.0.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772929,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "admin-group":32,
+ "local-address":"10.0.3.1",
+ "remote-address":"10.0.3.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772930,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837443,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.3.2",
+ "remote-address":"10.0.3.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167773185,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "local-vertex-id":167837444,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.4.1",
+ "remote-address":"10.0.4.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773186,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837444,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":30,
+ "local-address":"10.0.4.2",
+ "remote-address":"10.0.4.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":25000,
+ "utilized-bandwidth":125000000.0
+ }
+ }
+ ],
+ "subnets":[
+ {
+ "subnet-id":"10.0.0.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.0.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.255.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.3\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.4\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":400,
+ "algo":0,
+ "flags":"0x40"
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ospf-te-topo1/reference/ted_step4.json b/tests/topotests/ospf-te-topo1/reference/ted_step4.json
new file mode 100644
index 0000000000..5c2dee1e4b
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/reference/ted_step4.json
@@ -0,0 +1,490 @@
+{
+ "ted":{
+ "name":"OSPF",
+ "key":1,
+ "verticesCount":4,
+ "edgesCount":6,
+ "subnetsCount":10,
+ "vertices":[
+ {
+ "vertex-id":167837441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.1",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":4000,
+ "srgb-lower":20000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":15000
+ }
+ },
+ {
+ "vertex-id":167837442,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.2",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":8000,
+ "srgb-lower":16000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":2000,
+ "srlb-lower":5000,
+ "msd":16
+ }
+ },
+ {
+ "vertex-id":167837443,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.3",
+ "vertex-type":"ASBR"
+ },
+ {
+ "vertex-id":167837444,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.4",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":10000,
+ "srgb-lower":10000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":5000,
+ "msd":12
+ }
+ }
+ ],
+ "edges":[
+ {
+ "edge-id":167772161,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":20,
+ "local-address":"10.0.0.1",
+ "remote-address":"10.0.0.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":10000,
+ "available-bandwidth":125000000.0
+ },
+ "segment-routing":[
+ {
+ "adj-sid":15001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":15000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772162,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.0.2",
+ "remote-address":"10.0.0.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772929,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "admin-group":32,
+ "local-address":"10.0.3.1",
+ "remote-address":"10.0.3.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772930,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837443,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.3.2",
+ "remote-address":"10.0.3.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5003,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5002,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773185,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "local-vertex-id":167837444,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.4.1",
+ "remote-address":"10.0.4.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773186,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837444,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":30,
+ "local-address":"10.0.4.2",
+ "remote-address":"10.0.4.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":25000,
+ "utilized-bandwidth":125000000.0
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5005,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5004,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ }
+ ],
+ "subnets":[
+ {
+ "subnet-id":"10.0.0.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.0.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.255.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":10,
+ "algo":0,
+ "flags":"0x0"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":20,
+ "algo":0,
+ "flags":"0x50"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.3\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.4\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":400,
+ "algo":0,
+ "flags":"0x40"
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ospf-te-topo1/reference/ted_step5.json b/tests/topotests/ospf-te-topo1/reference/ted_step5.json
new file mode 100644
index 0000000000..47e747f3ca
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/reference/ted_step5.json
@@ -0,0 +1,614 @@
+{
+ "ted":{
+ "name":"OSPF",
+ "key":1,
+ "verticesCount":4,
+ "edgesCount":8,
+ "subnetsCount":12,
+ "vertices":[
+ {
+ "vertex-id":167837441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.1",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":4000,
+ "srgb-lower":20000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":15000
+ }
+ },
+ {
+ "vertex-id":167837442,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.2",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":8000,
+ "srgb-lower":16000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":2000,
+ "srlb-lower":5000,
+ "msd":16
+ }
+ },
+ {
+ "vertex-id":167837443,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.3",
+ "vertex-type":"ASBR"
+ },
+ {
+ "vertex-id":167837444,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.4",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":10000,
+ "srgb-lower":10000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":5000,
+ "msd":12
+ }
+ }
+ ],
+ "edges":[
+ {
+ "edge-id":167772161,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":20,
+ "local-address":"10.0.0.1",
+ "remote-address":"10.0.0.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":10000,
+ "available-bandwidth":125000000.0
+ },
+ "segment-routing":[
+ {
+ "adj-sid":15001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":15000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772162,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.0.2",
+ "remote-address":"10.0.0.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772417,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.1",
+ "remote-address":"10.0.1.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":15003,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":15002,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772418,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.2",
+ "remote-address":"10.0.1.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5007,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5006,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772929,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "admin-group":32,
+ "local-address":"10.0.3.1",
+ "remote-address":"10.0.3.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772930,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837443,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.3.2",
+ "remote-address":"10.0.3.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5003,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5002,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773185,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "local-vertex-id":167837444,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.4.1",
+ "remote-address":"10.0.4.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773186,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837444,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":30,
+ "local-address":"10.0.4.2",
+ "remote-address":"10.0.4.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":25000,
+ "utilized-bandwidth":125000000.0
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5005,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5004,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ }
+ ],
+ "subnets":[
+ {
+ "subnet-id":"10.0.0.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.0.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.255.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":10,
+ "algo":0,
+ "flags":"0x0"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":20,
+ "algo":0,
+ "flags":"0x50"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.3\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.4\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":400,
+ "algo":0,
+ "flags":"0x40"
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ospf-te-topo1/reference/ted_step6.json b/tests/topotests/ospf-te-topo1/reference/ted_step6.json
new file mode 100644
index 0000000000..74bd83fbdb
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/reference/ted_step6.json
@@ -0,0 +1,615 @@
+{
+ "ted":{
+ "name":"OSPF",
+ "key":1,
+ "verticesCount":4,
+ "edgesCount":8,
+ "subnetsCount":12,
+ "vertices":[
+ {
+ "vertex-id":167837441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.1",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":4000,
+ "srgb-lower":20000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":15000
+ }
+ },
+ {
+ "vertex-id":167837442,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.2",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":8000,
+ "srgb-lower":16000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":2000,
+ "srlb-lower":5000,
+ "msd":16
+ }
+ },
+ {
+ "vertex-id":167837443,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.3",
+ "vertex-type":"ASBR"
+ },
+ {
+ "vertex-id":167837444,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.4",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":10000,
+ "srgb-lower":10000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":5000,
+ "msd":12
+ }
+ }
+ ],
+ "edges":[
+ {
+ "edge-id":167772161,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":20,
+ "local-address":"10.0.0.1",
+ "remote-address":"10.0.0.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":10000,
+ "available-bandwidth":125000000.0
+ },
+ "segment-routing":[
+ {
+ "adj-sid":15001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":15000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772162,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.0.2",
+ "remote-address":"10.0.0.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772417,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.1",
+ "remote-address":"10.0.1.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":15003,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":15002,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772418,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.2",
+ "remote-address":"10.0.1.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5007,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5006,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772929,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "admin-group":32,
+ "local-address":"10.0.3.1",
+ "remote-address":"10.0.3.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772930,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837443,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.3.2",
+ "remote-address":"10.0.3.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5003,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5002,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773185,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "local-vertex-id":167837444,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.4.1",
+ "remote-address":"10.0.4.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":20000,
+ "jitter":10000
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167773186,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837444,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":30,
+ "local-address":"10.0.4.2",
+ "remote-address":"10.0.4.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":25000
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5005,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5004,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ }
+ ],
+ "subnets":[
+ {
+ "subnet-id":"10.0.0.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.0.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.4.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.255.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":10,
+ "algo":0,
+ "flags":"0x0"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":20,
+ "algo":0,
+ "flags":"0x50"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.3\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":0
+ },
+ {
+ "subnet-id":"10.0.255.4\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.4",
+ "vertex-id":167837444,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":400,
+ "algo":0,
+ "flags":"0x40"
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ospf-te-topo1/reference/ted_step7.json b/tests/topotests/ospf-te-topo1/reference/ted_step7.json
new file mode 100644
index 0000000000..1cea9f0455
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/reference/ted_step7.json
@@ -0,0 +1,456 @@
+{
+ "ted":{
+ "name":"OSPF",
+ "key":1,
+ "verticesCount":3,
+ "edgesCount":6,
+ "subnetsCount":9,
+ "vertices":[
+ {
+ "vertex-id":167837441,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.1",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":4000,
+ "srgb-lower":20000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":1000,
+ "srlb-lower":15000
+ }
+ },
+ {
+ "vertex-id":167837442,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.2",
+ "vertex-type":"Standard",
+ "segment-routing":{
+ "srgb-size":8000,
+ "srgb-lower":16000,
+ "algorithms":[
+ {
+ "0":"SPF"
+ }
+ ],
+ "srlb-size":2000,
+ "srlb-lower":5000,
+ "msd":16
+ }
+ },
+ {
+ "vertex-id":167837443,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "router-id":"10.0.255.3",
+ "vertex-type":"ASBR"
+ }
+ ],
+ "edges":[
+ {
+ "edge-id":167772161,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":20,
+ "local-address":"10.0.0.1",
+ "remote-address":"10.0.0.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ],
+ "delay":10000,
+ "available-bandwidth":125000000.0
+ },
+ "segment-routing":[
+ {
+ "adj-sid":15001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":15000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772162,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.0.2",
+ "remote-address":"10.0.0.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5001,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5000,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772417,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "local-vertex-id":167837441,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.1",
+ "remote-address":"10.0.1.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":15003,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":15002,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772418,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837441,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.1.2",
+ "remote-address":"10.0.1.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5007,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5006,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ },
+ {
+ "edge-id":167772929,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "local-vertex-id":167837443,
+ "remote-vertex-id":167837442,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "admin-group":32,
+ "local-address":"10.0.3.1",
+ "remote-address":"10.0.3.2",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ }
+ },
+ {
+ "edge-id":167772930,
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "local-vertex-id":167837442,
+ "remote-vertex-id":167837443,
+ "metric":10,
+ "edge-attributes":{
+ "te-metric":0,
+ "local-address":"10.0.3.2",
+ "remote-address":"10.0.3.1",
+ "max-link-bandwidth":176258176.0,
+ "max-resv-link-bandwidth":176258176.0,
+ "unreserved-bandwidth":[
+ {
+ "class-type-0":176258176.0
+ },
+ {
+ "class-type-1":176258176.0
+ },
+ {
+ "class-type-2":176258176.0
+ },
+ {
+ "class-type-3":176258176.0
+ },
+ {
+ "class-type-4":176258176.0
+ },
+ {
+ "class-type-5":176258176.0
+ },
+ {
+ "class-type-6":176258176.0
+ },
+ {
+ "class-type-7":176258176.0
+ }
+ ]
+ },
+ "segment-routing":[
+ {
+ "adj-sid":5003,
+ "flags":"0x60",
+ "weight":0
+ },
+ {
+ "adj-sid":5002,
+ "flags":"0xe0",
+ "weight":0
+ }
+ ]
+ }
+ ],
+ "subnets":[
+ {
+ "subnet-id":"10.0.0.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.0.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.1.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.3.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":10
+ },
+ {
+ "subnet-id":"10.0.255.1\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.1",
+ "vertex-id":167837441,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":10,
+ "algo":0,
+ "flags":"0x0"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.2\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.2",
+ "vertex-id":167837442,
+ "metric":0,
+ "segment-routing":{
+ "pref-sid":20,
+ "algo":0,
+ "flags":"0x50"
+ }
+ },
+ {
+ "subnet-id":"10.0.255.3\/32",
+ "status":"Sync",
+ "origin":"OSPFv2",
+ "advertised-router":"10.0.255.3",
+ "vertex-id":167837443,
+ "metric":0
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py b/tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py
new file mode 100644
index 0000000000..1d69f5d699
--- /dev/null
+++ b/tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py
@@ -0,0 +1,314 @@
+#!/usr/bin/env python
+
+#
+# test_ospf_te_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2021 by Orange
+# Author: Olivier Dugeon <olivier.dugeon@orange.com>
+#
+# 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_ospf_te_topo1.py: Test the FRR OSPF with Traffic Engineering.
+
+ +------------+
+ | |
+ | R1 |
+ | 10.0.225.1 |
+ | |
+ +------------+
+ r1-eth0| |r1-eth1
+ | |
+ 10.0.0.0/24| |10.0.1.0/24
+ | |
+ r2-eth0| |r2-eth1
+ +------------+ +------------+
+ | | | |
+ | R2 |r2-eth2 r3-eth0| R3 |
+ | 10.0.255.2 +------------------+ 10.0.255.3 |
+ | | 10.0.3.0/24 | |
+ +------------+ +------+-----+
+ r2-eth3| r3-eth1|
+ | |
+ 10.0.4.0/24| 10.0.5.0/24|
+ | |
+ r4-eth0| V
+ +------------+ ASBR 10.0.255.5
+ | |
+ | R4 |
+ | 10.0.255.4 |
+ | |
+ +------------+
+
+"""
+
+import os
+import sys
+import json
+from functools import partial
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+# and Finally pytest
+import pytest
+
+pytestmark = [pytest.mark.ospfd]
+
+class OspfTeTopo(Topo):
+ "Test topology builder"
+
+ def build(self):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # Create 4 routers
+ for routern in range(1, 5):
+ tgen.add_router("r{}".format(routern))
+
+ # Interconect router 1 and 2 with 2 links
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ # Interconect router 3 and 2
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["r3"])
+ switch.add_link(tgen.gears["r2"])
+
+ # Interconect router 4 and 2
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["r4"])
+ switch.add_link(tgen.gears["r2"])
+
+ # Interconnect router 3 with next AS
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["r3"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+
+ logger.info("\n\n---- Starting OSPF TE tests ----\n")
+
+ tgen = Topogen(OspfTeTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for rname, router in router_list.items():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
+ )
+
+ # Initialize all routers.
+ tgen.start_router()
+
+
+def teardown_module():
+ "Teardown the pytest environment"
+
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+ logger.info("\n\n---- OSPF TE tests End ----\n")
+
+
+def compare_ted_json_output(tgen, rname, fileref):
+ "Compare TED JSON output"
+
+ logger.info('Comparing router "%s" TED output', rname)
+
+ filename = "{}/reference/{}".format(CWD, fileref)
+ expected = json.loads(open(filename).read())
+ command = "show ip ospf mpls-te database json"
+
+ # Run test function until we get an result. Wait at most 60 seconds.
+ test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
+ _, diff = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = '"{}" TED JSON output mismatches the expected result'.format(rname)
+ assert diff is None, assertmsg
+
+
+def setup_testcase(msg):
+ "Setup test case"
+
+ logger.info(msg)
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ return tgen
+
+
+# Note that all routers must discover the same Network Topology, so the same TED.
+
+def test_step1():
+ "Step1: Check initial topology"
+
+ tgen = setup_testcase("Step1: test initial OSPF TE Data Base")
+
+ for rname in ["r1", "r2", "r3", "r4"]:
+ compare_ted_json_output(tgen, rname, "ted_step1.json")
+
+
+def test_step2():
+ "Step2: Shutdown interface between r1 and r2 and verify that \
+ corresponding Edges are removed from the TED on all routers "
+
+ tgen = setup_testcase("Step2: Shutdown interface between r1 & r2")
+
+ tgen.net["r1"].cmd(
+ 'vtysh -c "conf t" -c "interface r1-eth1" -c "shutdown"'
+ )
+ tgen.net["r2"].cmd(
+ 'vtysh -c "conf t" -c "interface r2-eth1" -c "shutdown"'
+ )
+
+ for rname in ["r1", "r2", "r3", "r4"]:
+ compare_ted_json_output(tgen, rname, "ted_step2.json")
+
+
+def test_step3():
+ "Step3: Disable Inter-AS on r3 and verify that corresponding Edge and \
+ remote ASBR are removed from the TED on all routers"
+
+ tgen = setup_testcase("Step3: Disable Inter-AS on r3")
+
+ tgen.net["r3"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "no mpls-te inter-as"'
+ )
+ for rname in ["r1", "r2", "r3", "r4"]:
+ compare_ted_json_output(tgen, rname, "ted_step3.json")
+
+
+def test_step4():
+ "Step4: Enable Segment Routing on r1 and r2 and verify that corresponding \
+ Edges are updated with Adjacency SID and Subnets with Prefix SID in the \
+ TED on all routers"
+
+ tgen = setup_testcase("Step4: Enable Segment Routing on r1 & r2")
+
+ tgen.net["r1"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "segment-routing on"'
+ )
+ tgen.net["r1"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "segment-routing global-block 20000 23999"'
+ )
+ tgen.net["r1"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "segment-routing prefix 10.0.255.1/32 index 10"'
+ )
+ tgen.net["r2"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "segment-routing on"'
+ )
+ tgen.net["r2"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "segment-routing node-msd 16"'
+ )
+ tgen.net["r2"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "segment-routing local-block 5000 6999"'
+ )
+ tgen.net["r2"].cmd(
+ 'vtysh -c "conf t" -c "router ospf" -c "segment-routing prefix 10.0.255.2/32 index 20 explicit-null"'
+ )
+
+ for rname in ["r1", "r2", "r3", "r4"]:
+ compare_ted_json_output(tgen, rname, "ted_step4.json")
+
+
+def test_step5():
+ "Step5: Re-enable interface between r1 & r2 and verify that corresponding \
+ Edges are added in the TED on all routers"
+
+ tgen = setup_testcase("Step5: Re-enable interface between r1 & r2")
+
+ tgen.net["r1"].cmd(
+ 'vtysh -c "conf t" -c "interface r1-eth1" -c "no shutdown"'
+ )
+ tgen.net["r2"].cmd(
+ 'vtysh -c "conf t" -c "interface r2-eth1" -c "no shutdown"'
+ )
+
+ for rname in ["r1", "r2", "r3", "r4"]:
+ compare_ted_json_output(tgen, rname, "ted_step5.json")
+
+
+def test_step6():
+ "Step6: Set delay and jitter for interface r4-eth0 on r4, remove use-bw \
+ for interface r2-eth3 on r2 and verify that corresponding Edges are \
+ updated in the TED on all routers"
+
+ tgen = setup_testcase("Step6: Modify link parameters on r2 & r4")
+
+ tgen.net["r2"].cmd(
+ 'vtysh -c "conf t" -c "interface r2-eth3" -c "link-params" -c "no use-bw"'
+ )
+ tgen.net["r4"].cmd(
+ 'vtysh -c "conf t" -c "interface r4-eth0" -c "link-params" -c "delay 20000"'
+ )
+ tgen.net["r4"].cmd(
+ 'vtysh -c "conf t" -c "interface r4-eth0" -c "link-params" -c "delay-variation 10000"'
+ )
+
+ for rname in ["r1", "r2", "r3", "r4"]:
+ compare_ted_json_output(tgen, rname, "ted_step6.json")
+
+
+def test_step7():
+ "Step7: Disable OSPF on r4 and verify that corresponding Vertex, Edges and \
+ Subnets are removed from the TED on all remaining routers"
+
+ tgen = setup_testcase("Step7: Disable OSPF on r4")
+
+ tgen.net["r4"].cmd(
+ 'vtysh -c "conf t" -c "no router ospf"'
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ compare_ted_json_output(tgen, rname, "ted_step7.json")
+
+
+def test_memory_leak():
+ "Run the memory leak test and report results."
+
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/ospf6-topo2/r1/ospf6d.conf b/tests/topotests/ospf6-topo2/r1/ospf6d.conf
new file mode 100644
index 0000000000..c403fcd8dc
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/r1/ospf6d.conf
@@ -0,0 +1,9 @@
+interface r1-eth0
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+router ospf6
+ ospf6 router-id 10.254.254.1
+ area 0.0.0.1 stub
+ interface r1-eth0 area 0.0.0.1
+!
diff --git a/tests/topotests/ospf6-topo2/r1/zebra.conf b/tests/topotests/ospf6-topo2/r1/zebra.conf
new file mode 100644
index 0000000000..7fee2da8ba
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/r1/zebra.conf
@@ -0,0 +1,5 @@
+ipv6 forwarding
+!
+interface r1-eth0
+ ipv6 address 2001:db8:1::2/64
+!
diff --git a/tests/topotests/ospf6-topo2/r2/ospf6d.conf b/tests/topotests/ospf6-topo2/r2/ospf6d.conf
new file mode 100644
index 0000000000..d4bb0e2a41
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/r2/ospf6d.conf
@@ -0,0 +1,17 @@
+interface r2-eth0
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+interface r2-eth1
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+router ospf6
+ ospf6 router-id 10.254.254.2
+ redistribute connected
+ redistribute static
+ default-information originate always metric 123
+ area 0.0.0.1 stub
+ interface r2-eth0 area 0.0.0.1
+ interface r2-eth1 area 0.0.0.0
+!
diff --git a/tests/topotests/ospf6-topo2/r2/zebra.conf b/tests/topotests/ospf6-topo2/r2/zebra.conf
new file mode 100644
index 0000000000..891945a4e7
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/r2/zebra.conf
@@ -0,0 +1,8 @@
+ipv6 forwarding
+!
+interface r2-eth0
+ ipv6 address 2001:db8:1::1/64
+!
+interface r2-eth1
+ ipv6 address 2001:db8:2::2/64
+!
diff --git a/tests/topotests/ospf6-topo2/r3/ospf6d.conf b/tests/topotests/ospf6-topo2/r3/ospf6d.conf
new file mode 100644
index 0000000000..aaef00d5bb
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/r3/ospf6d.conf
@@ -0,0 +1,10 @@
+interface r3-eth0
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+router ospf6
+ ospf6 router-id 10.254.254.3
+ redistribute connected
+ redistribute static
+ interface r3-eth0 area 0.0.0.0
+!
diff --git a/tests/topotests/ospf6-topo2/r3/zebra.conf b/tests/topotests/ospf6-topo2/r3/zebra.conf
new file mode 100644
index 0000000000..dea2fe4778
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/r3/zebra.conf
@@ -0,0 +1,8 @@
+ipv6 forwarding
+!
+interface r3-eth0
+ ipv6 address 2001:db8:2::1/64
+!
+ipv6 route fc00:1::/64 fc00:100::1234
+ipv6 route fc00:2::/64 fc00:100::1234
+ipv6 route fc00:3::/64 fc00:100::1234
diff --git a/tests/topotests/ospf6-topo2/test_ospf6_topo2.dot b/tests/topotests/ospf6-topo2/test_ospf6_topo2.dot
new file mode 100644
index 0000000000..ba7a36f2b5
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/test_ospf6_topo2.dot
@@ -0,0 +1,71 @@
+## Color coding:
+#########################
+## Main FRR: #f08080 red
+## Switches: #d0e0d0 gray
+## RIP: #19e3d9 Cyan
+## RIPng: #fcb314 dark yellow
+## OSPFv2: #32b835 Green
+## OSPFv3: #19e3d9 Cyan
+## ISIS IPv4 #fcb314 dark yellow
+## ISIS IPv6 #9a81ec purple
+## BGP IPv4 #eee3d3 beige
+## BGP IPv6 #fdff00 yellow
+##### Colors (see http://www.color-hex.com/)
+
+graph template {
+ label="ospf6-topo2";
+
+ # Routers
+ r1 [
+ shape=doubleoctagon,
+ label="r1",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r2 [
+ shape=doubleoctagon
+ label="r2",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r3 [
+ shape=doubleoctagon
+ label="r3",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+
+ # Switches
+ sw1 [
+ shape=oval,
+ label="sw1\n2001:db8:1::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ sw2 [
+ shape=oval,
+ label="sw2\n2001:db8:2::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ sw3 [
+ shape=oval,
+ label="sw3\n2001:db8:3::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+
+ # Connections
+ subgraph cluster0 {
+ label="area 0.0.0.1";
+ r1 -- sw1 [label="eth0\n.2"];
+ }
+
+ subgraph cluster1 {
+ label="area 0.0.0.0";
+ r2 -- sw1 [label="eth0\n.1"];
+ r2 -- sw2 [label="eth1\n.2"];
+ r3 -- sw2 [label="eth0\n.1"];
+ r3 -- sw3 [label="eth1\n.2"];
+ }
+}
diff --git a/tests/topotests/ospf6-topo2/test_ospf6_topo2.png b/tests/topotests/ospf6-topo2/test_ospf6_topo2.png
new file mode 100644
index 0000000000..ee1de60736
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/test_ospf6_topo2.png
Binary files differ
diff --git a/tests/topotests/ospf6-topo2/test_ospf6_topo2.py b/tests/topotests/ospf6-topo2/test_ospf6_topo2.py
new file mode 100644
index 0000000000..32aff05982
--- /dev/null
+++ b/tests/topotests/ospf6-topo2/test_ospf6_topo2.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+
+#
+# test_ospf6_topo2.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2021 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_ospf6_topo2.py: Test the FRR OSPFv3 daemon.
+"""
+
+import os
+import sys
+from functools import partial
+import pytest
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+pytestmark = [pytest.mark.ospf6d]
+
+
+class OSPFv3Topo2(Topo):
+ "Test topology builder"
+
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # Create 3 routers
+ for routern in range(1, 4):
+ tgen.add_router("r{}".format(routern))
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r3"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(OSPFv3Topo2, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+ for rname, router in router_list.items():
+ daemon_file = "{}/{}/zebra.conf".format(CWD, rname)
+ if os.path.isfile(daemon_file):
+ router.load_config(TopoRouter.RD_ZEBRA, daemon_file)
+
+ daemon_file = "{}/{}/ospf6d.conf".format(CWD, rname)
+ if os.path.isfile(daemon_file):
+ router.load_config(TopoRouter.RD_OSPF6, daemon_file)
+
+ # Initialize all routers.
+ tgen.start_router()
+
+
+def test_wait_protocol_convergence():
+ "Wait for OSPFv3 to converge"
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("waiting for protocols to converge")
+
+ def expect_neighbor_full(router, neighbor):
+ "Wait until OSPFv3 convergence."
+ logger.info("waiting OSPFv3 router '{}'".format(router))
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[router],
+ "show ipv6 ospf6 neighbor json",
+ {"neighbors": [{"neighborId": neighbor, "state": "Full"}]},
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+ assertmsg = '"{}" convergence failure'.format(router)
+ assert result is None, assertmsg
+
+ expect_neighbor_full("r1", "10.254.254.2")
+ expect_neighbor_full("r2", "10.254.254.1")
+ expect_neighbor_full("r2", "10.254.254.3")
+ expect_neighbor_full("r3", "10.254.254.2")
+
+
+def test_ospf6_default_route():
+ "Wait for OSPFv3 default route in stub area."
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("waiting for default route")
+
+ def expect_route(router, route, metric):
+ "Test OSPF6 route existence."
+ logger.info("waiting OSPFv3 router '{}' routes".format(router))
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[router],
+ "show ipv6 route json",
+ {route: [{"metric": metric}]},
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=4, wait=1)
+ assertmsg = '"{}" convergence failure'.format(router)
+ assert result is None, assertmsg
+
+ def expect_lsa(router, area, prefix, metric):
+ "Test OSPF6 LSA existence."
+ logger.info("waiting OSPFv3 router '{}' LSA".format(router))
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[router],
+ "show ipv6 ospf6 database inter-prefix detail json",
+ {"areaScopedLinkStateDb": [{
+ "areaId": area,
+ "lsa": [{
+ "prefix": prefix,
+ "metric": metric,
+ }]}]},
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=4, wait=1)
+ assertmsg = '"{}" convergence failure'.format(router)
+ assert result is None, assertmsg
+
+ metric = 123
+ expect_lsa("r1", "0.0.0.1", "::/0", metric)
+ expect_route("r1", "::/0", metric + 10)
+
+
+def teardown_module(_mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_memory_leak():
+ "Run the memory leak test and report results."
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))