]> git.proxmox.com Git - mirror_frr.git/commitdiff
ripng_topo1: Adding new test for RIPng Topology
authorMartin Winter <mwinter@opensourcerouting.org>
Fri, 7 Apr 2017 23:40:47 +0000 (16:40 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 28 Nov 2018 01:22:11 +0000 (20:22 -0500)
Signed-off-by: Martin Winter <mwinter@opensourcerouting.org>
18 files changed:
tests/topotests/ripng-topo1/r1/ripng_status.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r1/ripngd.conf [new file with mode: 0644]
tests/topotests/ripng-topo1/r1/show_ipv6_ripng.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r1/zebra.conf [new file with mode: 0644]
tests/topotests/ripng-topo1/r2/ripng_status.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r2/ripngd.conf [new file with mode: 0644]
tests/topotests/ripng-topo1/r2/show_ipv6_ripng.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r2/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r2/zebra.conf [new file with mode: 0644]
tests/topotests/ripng-topo1/r3/ripng_status.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r3/ripngd.conf [new file with mode: 0644]
tests/topotests/ripng-topo1/r3/show_ipv6_ripng.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r3/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/ripng-topo1/r3/zebra.conf [new file with mode: 0644]
tests/topotests/ripng-topo1/test_ripng_topo1.dot [new file with mode: 0644]
tests/topotests/ripng-topo1/test_ripng_topo1.pdf [new file with mode: 0644]
tests/topotests/ripng-topo1/test_ripng_topo1.py [new file with mode: 0755]

diff --git a/tests/topotests/ripng-topo1/r1/ripng_status.ref b/tests/topotests/ripng-topo1/r1/ripng_status.ref
new file mode 100644 (file)
index 0000000..48816c1
--- /dev/null
@@ -0,0 +1,16 @@
+Routing Protocol is "RIPng"
+  Sending updates every 30 seconds with +/-50%, next due in XX seconds
+  Timeout after 180 seconds, garbage collect after 120 seconds
+  Outgoing update filter list for all interface is not set
+  Incoming update filter list for all interface is not set
+  Default redistribution metric is 1
+  Redistributing:
+  Default version control: send version 1, receive version 1 
+    Interface        Send  Recv
+    r1-eth1          1     1  
+  Routing for Networks:
+    fc00:5::/64
+  Routing Information Sources:
+    Gateway          BadPackets BadRoutes  Distance Last Update
+    fe80::XXXX:XXXX:XXXX:XXXX 
+                        0          0        120      XX:XX:XX
diff --git a/tests/topotests/ripng-topo1/r1/ripngd.conf b/tests/topotests/ripng-topo1/r1/ripngd.conf
new file mode 100644 (file)
index 0000000..64a6f84
--- /dev/null
@@ -0,0 +1,12 @@
+log file /tmp/r1-ripngd.log
+!
+debug ripng events
+debug ripng packet
+debug ripng zebra
+!
+router ripng
+ network fc00:5::/64
+!
+line vty
+!
+
diff --git a/tests/topotests/ripng-topo1/r1/show_ipv6_ripng.ref b/tests/topotests/ripng-topo1/r1/show_ipv6_ripng.ref
new file mode 100644 (file)
index 0000000..18d026a
--- /dev/null
@@ -0,0 +1,14 @@
+Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP
+Sub-codes:
+      (n) - normal, (s) - static, (d) - default, (r) - redistribute,
+      (i) - interface, (a/S) - aggregated/Suppressed
+
+   Network      Next Hop                      Via     Metric Tag Time
+C(i) fc00:5::/64
+                  ::                          self       1    0
+R(n) fc00:6::/62
+                  fe80::XXXX:XXXX:XXXX:XXXX   r1-eth1    2    0  XX:XX
+R(n) fc00:7::/64
+                  fe80::XXXX:XXXX:XXXX:XXXX   r1-eth1    3    0  XX:XX
+R(n) fc00:7:1111::/64
+                  fe80::XXXX:XXXX:XXXX:XXXX   r1-eth1    3    0  XX:XX
diff --git a/tests/topotests/ripng-topo1/r1/show_ipv6_route.ref b/tests/topotests/ripng-topo1/r1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..7e5fc3f
--- /dev/null
@@ -0,0 +1,3 @@
+R>* fc00:6::/62 [120/2] via fe80::XXXX:XXXX:XXXX:XXXX, r1-eth1
+R>* fc00:7::/64 [120/3] via fe80::XXXX:XXXX:XXXX:XXXX, r1-eth1
+R>* fc00:7:1111::/64 [120/3] via fe80::XXXX:XXXX:XXXX:XXXX, r1-eth1
diff --git a/tests/topotests/ripng-topo1/r1/zebra.conf b/tests/topotests/ripng-topo1/r1/zebra.conf
new file mode 100644 (file)
index 0000000..f315e90
--- /dev/null
@@ -0,0 +1,19 @@
+log file /tmp/r1-zebra.log
+!
+hostname r1
+!
+interface r1-eth0
+ ipv6 address fc00:0:0:1::1/64
+!
+interface r1-eth1
+ description to sw2 - RIPng interface
+ ipv6 address fc00:5::1/64
+ no link-detect
+!
+ip forwarding
+ipv6 forwarding
+!
+!
+line vty
+!
+
diff --git a/tests/topotests/ripng-topo1/r2/ripng_status.ref b/tests/topotests/ripng-topo1/r2/ripng_status.ref
new file mode 100644 (file)
index 0000000..fddcf63
--- /dev/null
@@ -0,0 +1,20 @@
+Routing Protocol is "RIPng"
+  Sending updates every 30 seconds with +/-50%, next due in XX seconds
+  Timeout after 180 seconds, garbage collect after 120 seconds
+  Outgoing update filter list for all interface is not set
+  Incoming update filter list for all interface is not set
+  Default redistribution metric is 1
+  Redistributing:
+  Default version control: send version 1, receive version 1 
+    Interface        Send  Recv
+    r2-eth0          1     1  
+    r2-eth1          1     1  
+  Routing for Networks:
+    fc00:5::/64
+    fc00:6::/62
+  Routing Information Sources:
+    Gateway          BadPackets BadRoutes  Distance Last Update
+    fe80::XXXX:XXXX:XXXX:XXXX 
+                        0          0        120      XX:XX:XX
+    fe80::XXXX:XXXX:XXXX:XXXX 
+                        0          0        120      XX:XX:XX
diff --git a/tests/topotests/ripng-topo1/r2/ripngd.conf b/tests/topotests/ripng-topo1/r2/ripngd.conf
new file mode 100644 (file)
index 0000000..919a64f
--- /dev/null
@@ -0,0 +1,12 @@
+log file /tmp/r2-ripngd.log
+!
+debug ripng events
+debug ripng packet
+debug ripng zebra
+!
+router ripng
+ network fc00:5::/64
+ network fc00:6::/62
+!
+line vty
+!
diff --git a/tests/topotests/ripng-topo1/r2/show_ipv6_ripng.ref b/tests/topotests/ripng-topo1/r2/show_ipv6_ripng.ref
new file mode 100644 (file)
index 0000000..765efd0
--- /dev/null
@@ -0,0 +1,14 @@
+Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP
+Sub-codes:
+      (n) - normal, (s) - static, (d) - default, (r) - redistribute,
+      (i) - interface, (a/S) - aggregated/Suppressed
+
+   Network      Next Hop                      Via     Metric Tag Time
+C(i) fc00:5::/64
+                  ::                          self       1    0
+C(i) fc00:6::/62
+                  ::                          self       1    0
+R(n) fc00:7::/64
+                  fe80::XXXX:XXXX:XXXX:XXXX   r2-eth1    2    0  XX:XX
+R(n) fc00:7:1111::/64
+                  fe80::XXXX:XXXX:XXXX:XXXX   r2-eth1    2    0  XX:XX
diff --git a/tests/topotests/ripng-topo1/r2/show_ipv6_route.ref b/tests/topotests/ripng-topo1/r2/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..688e77e
--- /dev/null
@@ -0,0 +1,2 @@
+R>* fc00:7::/64 [120/2] via fe80::XXXX:XXXX:XXXX:XXXX, r2-eth1
+R>* fc00:7:1111::/64 [120/2] via fe80::XXXX:XXXX:XXXX:XXXX, r2-eth1
diff --git a/tests/topotests/ripng-topo1/r2/zebra.conf b/tests/topotests/ripng-topo1/r2/zebra.conf
new file mode 100644 (file)
index 0000000..cb3ff37
--- /dev/null
@@ -0,0 +1,21 @@
+log file /tmp/r2-zebra.log
+!
+hostname r2
+!
+interface r2-eth0
+ description to sw2 - RIPng interface
+ ipv6 address fc00:5::2/64
+ no link-detect
+!
+interface r2-eth1
+ description to sw3 - RIPng interface
+ ipv6 address fc00:6::2/62
+ no link-detect
+!
+ip forwarding
+ipv6 forwarding
+!
+!
+line vty
+!
+
diff --git a/tests/topotests/ripng-topo1/r3/ripng_status.ref b/tests/topotests/ripng-topo1/r3/ripng_status.ref
new file mode 100644 (file)
index 0000000..1a8dabb
--- /dev/null
@@ -0,0 +1,16 @@
+Routing Protocol is "RIPng"
+  Sending updates every 30 seconds with +/-50%, next due in XX seconds
+  Timeout after 180 seconds, garbage collect after 120 seconds
+  Outgoing update filter list for all interface is not set
+  Incoming update filter list for all interface is not set
+  Default redistribution metric is 1
+  Redistributing:    connected    static
+  Default version control: send version 1, receive version 1 
+    Interface        Send  Recv
+    r3-eth1          1     1  
+  Routing for Networks:
+    fc00:6::/62
+  Routing Information Sources:
+    Gateway          BadPackets BadRoutes  Distance Last Update
+    fe80::XXXX:XXXX:XXXX:XXXX 
+                        0          0        120      XX:XX:XX
diff --git a/tests/topotests/ripng-topo1/r3/ripngd.conf b/tests/topotests/ripng-topo1/r3/ripngd.conf
new file mode 100644 (file)
index 0000000..ad49464
--- /dev/null
@@ -0,0 +1,14 @@
+log file /tmp/r3-ripngd.log
+!
+debug ripng events
+debug ripng packet
+debug ripng zebra
+!
+router ripng
+ network fc00:6::/62
+ redistribute connected
+ redistribute static
+!
+line vty
+!
+
diff --git a/tests/topotests/ripng-topo1/r3/show_ipv6_ripng.ref b/tests/topotests/ripng-topo1/r3/show_ipv6_ripng.ref
new file mode 100644 (file)
index 0000000..81e76b9
--- /dev/null
@@ -0,0 +1,14 @@
+Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP
+Sub-codes:
+      (n) - normal, (s) - static, (d) - default, (r) - redistribute,
+      (i) - interface, (a/S) - aggregated/Suppressed
+
+   Network      Next Hop                      Via     Metric Tag Time
+R(n) fc00:5::/64
+                  fe80::XXXX:XXXX:XXXX:XXXX   r3-eth1    2    0  XX:XX
+C(i) fc00:6::/62
+                  ::                          self       1    0
+C(r) fc00:7::/64
+                  ::                          self       1    0
+S(r) fc00:7:1111::/64
+                  ::                          self       1    0
diff --git a/tests/topotests/ripng-topo1/r3/show_ipv6_route.ref b/tests/topotests/ripng-topo1/r3/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..8e46e39
--- /dev/null
@@ -0,0 +1 @@
+R>* fc00:5::/64 [120/2] via fe80::XXXX:XXXX:XXXX:XXXX, r3-eth1
diff --git a/tests/topotests/ripng-topo1/r3/zebra.conf b/tests/topotests/ripng-topo1/r3/zebra.conf
new file mode 100644 (file)
index 0000000..cedb6ca
--- /dev/null
@@ -0,0 +1,22 @@
+log file /tmp/r3-zebra.log
+!
+hostname r3
+!
+interface r3-eth0
+ description to sw2 - Stub interface
+ ipv6 address fc00:7::1/64
+ no link-detect
+!
+interface r3-eth1
+ description to sw3 - RIPng interface
+ ipv6 address fc00:6::2/62
+ no link-detect
+!
+ipv6 route fc00:7:1111::/64 fc00:7::10
+!
+ip forwarding
+ipv6 forwarding
+!
+!
+line vty
+!
diff --git a/tests/topotests/ripng-topo1/test_ripng_topo1.dot b/tests/topotests/ripng-topo1/test_ripng_topo1.dot
new file mode 100644 (file)
index 0000000..f5d32a0
--- /dev/null
@@ -0,0 +1,59 @@
+## GraphViz file for test_all_protocol_topo1
+##
+## 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 test_ripng_topo1 {
+
+    // title
+    labelloc="t";
+    label="Test Topologoy RIPng Topo1";
+
+       ######################
+       # Routers       
+       ######################
+
+       # Main FRR Router with all protocols
+       R1 [shape=doubleoctagon, label="R1 FRR\nMain Router", fillcolor="#f08080", style=filled];
+       
+       # RIPng Routers
+       R2 [shape=doubleoctagon, label="R2 FRR\nRIPng Router", fillcolor="#fcb314", style=filled];
+       R3 [shape=doubleoctagon, label="R3 FRR\nRIPng Router", fillcolor="#fcb314", style=filled];
+
+       ######################
+       # Network Lists
+       ######################
+
+    SW1_R1_stub [label="SW1\nfc00:0:0:1::/64", fillcolor="#d0e0d0", style=filled];
+
+    # RIPng Networks
+    SW2_R1_R2 [label="SW2\nRIPng\nfc00:5:0:0::/64", fillcolor="#d0e0d0", style=filled];
+    SW3_R2_R3 [label="SW3\nRIPng\nfc00:6:0:0::/62", fillcolor="#d0e0d0", style=filled];
+    SW4_R3 [label="SW4\nfc00::7/128", fillcolor="#d0e0d0", style=filled];
+    Net_R3_remote [label="Static Net\nfc00:7:1111::/64"];
+
+       ######################
+       # Network Connections
+       ######################
+    R1 -- SW1_R1_stub [label = "eth0\n.1\n::1"];
+       
+       # RIPng Network
+       R1 -- SW2_R1_R2 [label = "eth2\n::1"];
+       SW2_R1_R2 -- R2 [label = "eth0\n::2"];
+       R2 -- SW3_R2_R3 [label = "eth1\n::1"];
+       SW3_R2_R3 -- R3 [label = "eth1\n::2"];
+       R3 -- SW4_R3 [label = "eth0\n::1"];
+       SW4_R3 -- Net_R3_remote [label = ":10"];
+
+}
diff --git a/tests/topotests/ripng-topo1/test_ripng_topo1.pdf b/tests/topotests/ripng-topo1/test_ripng_topo1.pdf
new file mode 100644 (file)
index 0000000..f998c46
Binary files /dev/null and b/tests/topotests/ripng-topo1/test_ripng_topo1.pdf differ
diff --git a/tests/topotests/ripng-topo1/test_ripng_topo1.py b/tests/topotests/ripng-topo1/test_ripng_topo1.py
new file mode 100755 (executable)
index 0000000..f40a241
--- /dev/null
@@ -0,0 +1,362 @@
+#!/usr/bin/env python
+
+#
+# test_ripng_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2017 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_ripng_topo1.py: Test of RIPng Topology
+
+"""
+
+import os
+import re
+import sys
+import difflib
+import pytest
+import unicodedata
+from time import sleep
+
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Node, OVSSwitch, Host
+from mininet.log import setLogLevel, info
+from mininet.cli import CLI
+from mininet.link import Intf
+
+from functools import partial
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from lib import topotest
+
+fatal_error = ""
+
+
+#####################################################
+##
+##   Network Topology Definition
+##
+#####################################################
+
+class NetworkTopo(Topo):
+    "RIPng Topology 1"
+
+    def build(self, **_opts):
+
+        # Setup Routers
+        router = {}
+        #
+        # Setup Main Router
+        router[1] = topotest.addRouter(self, 'r1')
+        #
+        # Setup RIPng Routers
+        for i in range(2, 4):
+            router[i] = topotest.addRouter(self, 'r%s' % i)
+
+        # Setup Switches
+        switch = {}
+        #
+        # On main router
+        # First switch is for a dummy interface (for local network)
+        switch[1] = self.addSwitch('sw1', cls=topotest.LegacySwitch)
+        self.addLink(switch[1], router[1], intfName2='r1-eth0')
+        #
+        # Switches for RIPng
+        # switch 2 switch is for connection to RIP router
+        switch[2] = self.addSwitch('sw2', cls=topotest.LegacySwitch)
+        self.addLink(switch[2], router[1], intfName2='r1-eth1')
+        self.addLink(switch[2], router[2], intfName2='r2-eth0')
+        # switch 3 is between RIP routers
+        switch[3] = self.addSwitch('sw3', cls=topotest.LegacySwitch)
+        self.addLink(switch[3], router[2], intfName2='r2-eth1')
+        self.addLink(switch[3], router[3], intfName2='r3-eth1')
+        # switch 4 is stub on remote RIP router
+        switch[4] = self.addSwitch('sw4', cls=topotest.LegacySwitch)
+        self.addLink(switch[4], router[3], intfName2='r3-eth0')
+
+
+
+#####################################################
+##
+##   Tests starting
+##
+#####################################################
+
+def setup_module(module):
+    global topo, net
+
+    print("\n\n** %s: Setup Topology" % module.__name__)
+    print("******************************************\n")
+
+    print("Cleanup old Mininet runs")
+    os.system('sudo mn -c > /dev/null 2>&1')
+
+    thisDir = os.path.dirname(os.path.realpath(__file__))
+    topo = NetworkTopo()
+
+    net = Mininet(controller=None, topo=topo)
+    net.start()
+
+    # Starting Routers
+    #
+    for i in range(1, 4):
+        net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i))
+        net['r%s' % i].loadConf('ripngd', '%s/r%s/ripngd.conf' % (thisDir, i))
+        net['r%s' % i].startRouter()
+
+    # For debugging after starting Quagga/FRR daemons, uncomment the next line
+    # CLI(net)
+
+
+def teardown_module(module):
+    global net
+
+    print("\n\n** %s: Shutdown Topology" % module.__name__)
+    print("******************************************\n")
+
+    # End - Shutdown network
+    net.stop()
+
+
+def test_router_running():
+    global fatal_error
+    global net
+
+    # Skip if previous fatal error condition is raised
+    if (fatal_error != ""):
+        pytest.skip(fatal_error)
+
+    print("\n\n** Check if FRR/Quagga is running on each Router node")
+    print("******************************************\n")
+    sleep(5)
+
+    # Starting Routers
+    for i in range(1, 4):
+        fatal_error = net['r%s' % i].checkRouterRunning()
+        assert fatal_error == "", fatal_error
+
+    # For debugging after starting FRR/Quagga daemons, uncomment the next line
+    # CLI(net)
+
+
+def test_converge_protocols():
+    global fatal_error
+    global net
+
+    # Skip if previous fatal error condition is raised
+    if (fatal_error != ""):
+        pytest.skip(fatal_error)
+
+    thisDir = os.path.dirname(os.path.realpath(__file__))
+
+    print("\n\n** Waiting for protocols convergence")
+    print("******************************************\n")
+
+    # Not really implemented yet - just sleep 60 secs for now
+    sleep(60)
+
+    # For debugging after starting FRR/Quagga daemons, uncomment the next line
+    #CLI(net)
+
+
+def test_ripng_status():
+    global fatal_error
+    global net
+
+    # Skip if previous fatal error condition is raised
+    if (fatal_error != ""):
+        pytest.skip(fatal_error)
+
+    thisDir = os.path.dirname(os.path.realpath(__file__))
+
+    # Verify RIP Status
+    print("\n\n** Verifing RIPng status")
+    print("******************************************\n")
+    failures = 0
+    for i in range(1, 4):
+        refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i)
+        if os.path.isfile(refTableFile):
+            # Read expected result from file
+            expected = open(refTableFile).read().rstrip()
+            # Fix newlines (make them all the same)
+            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+
+            # Actual output from router
+            actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
+            # Mask out Link-Local mac address portion. They are random...
+            actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
+            # Drop time in next due 
+            actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
+            # Drop time in last update
+            actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
+            # Fix newlines (make them all the same)
+            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+
+            # Generate Diff
+            diff = ''.join(difflib.context_diff(actual, expected, 
+                fromfile="actual IPv6 RIPng status", 
+                tofile="expected IPv6 RIPng status"))
+
+            # Empty string if it matches, otherwise diff contains unified diff
+            if diff:
+                sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff))
+                failures += 1
+            else:
+                print("r%s ok" % i)
+
+            assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff)
+
+    # For debugging after starting FRR/Quagga daemons, uncomment the next line
+    # CLI(net)
+
+
+def test_ripng_routes():
+    global fatal_error
+    global net
+
+    # Skip if previous fatal error condition is raised
+    if (fatal_error != ""):
+        pytest.skip(fatal_error)
+
+    thisDir = os.path.dirname(os.path.realpath(__file__))
+
+    # Verify RIPng Status
+    print("\n\n** Verifing RIPng routes")
+    print("******************************************\n")
+    failures = 0
+    for i in range(1, 4):
+        refTableFile = '%s/r%s/show_ipv6_ripng.ref' % (thisDir, i)
+        if os.path.isfile(refTableFile):
+            # Read expected result from file
+            expected = open(refTableFile).read().rstrip()
+            # Fix newlines (make them all the same)
+            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+
+            # Actual output from router
+            actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng" 2> /dev/null').rstrip()
+            # Drop Time
+            actual = re.sub(r" [0-9][0-9]:[0-5][0-9]", " XX:XX", actual)
+            # Mask out Link-Local mac address portion. They are random...
+            actual = re.sub(r" fe80::[0-9a-f: ]+", " fe80::XXXX:XXXX:XXXX:XXXX   ", actual)
+            # Remove trailing spaces on all lines
+            actual = '\n'.join([line.rstrip() for line in actual.splitlines()])
+
+            # Fix newlines (make them all the same)
+            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+
+            # Generate Diff
+            diff = ''.join(difflib.context_diff(actual, expected, 
+                fromfile="actual SHOW IPv6 RIPng", 
+                tofile="expected SHOW IPv6 RIPng"))
+
+            # Empty string if it matches, otherwise diff contains unified diff
+            if diff:
+                sys.stderr.write('r%s failed SHOW IPv6 RIPng check:\n%s\n' % (i, diff))
+                failures += 1
+            else:
+                print("r%s ok" % i)
+
+            assert failures == 0, "SHOW IPv6 RIPng failed for router r%s:\n%s" % (i, diff)
+
+    # For debugging after starting FRR/Quagga daemons, uncomment the next line
+    # CLI(net)
+
+
+def test_zebra_ipv6_routingTable():
+    global fatal_error
+    global net
+
+    # Skip if previous fatal error condition is raised
+    if (fatal_error != ""):
+        pytest.skip(fatal_error)
+
+    thisDir = os.path.dirname(os.path.realpath(__file__))
+
+    # Verify OSPFv3 Routing Table
+    print("\n\n** Verifing Zebra IPv6 Routing Table")
+    print("******************************************\n")
+    failures = 0
+    for i in range(1, 4):
+        refTableFile = '%s/r%s/show_ipv6_route.ref' % (thisDir, i)
+        if os.path.isfile(refTableFile):
+            # Read expected result from file
+            expected = open(refTableFile).read().rstrip()
+            # Fix newlines (make them all the same)
+            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+
+            # Actual output from router
+            actual = net['r%s' % i].cmd('vtysh -c "show ipv6 route" 2> /dev/null | grep "^R"').rstrip()
+            # Mask out Link-Local mac address portion. They are random...
+            actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
+            # Drop timers on end of line (older Quagga Versions)
+            actual = re.sub(r", [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", "", actual)
+            # Fix newlines (make them all the same)
+            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+
+            # Generate Diff
+            diff = ''.join(difflib.context_diff(actual, expected, 
+                fromfile="actual Zebra IPv6 routing table", 
+                tofile="expected Zebra IPv6 routing table"))
+
+            # Empty string if it matches, otherwise diff contains unified diff
+            if diff:
+                sys.stderr.write('r%s failed Zebra IPv6 Routing Table Check:\n%s\n' % (i, diff))
+                failures += 1
+            else:
+                print("r%s ok" % i)
+
+            assert failures == 0, "Zebra IPv6 Routing Table verification failed for router r%s:\n%s" % (i, diff)
+
+    # For debugging after starting FRR/Quagga daemons, uncomment the next line
+    # CLI(net)
+
+
+def test_shutdown_check_stderr():
+    global fatal_error
+    global net
+
+    # Skip if previous fatal error condition is raised
+    if (fatal_error != ""):
+        pytest.skip(fatal_error)
+
+    if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
+        pytest.skip('Skipping test for Stderr output and memory leaks')
+
+    thisDir = os.path.dirname(os.path.realpath(__file__))
+
+    print("\n\n** Verifing unexpected STDERR output from daemons")
+    print("******************************************\n")
+
+    net['r1'].stopRouter()
+
+    log = net['r1'].getStdErr('ripngd')
+    print("\nRIPngd StdErr Log:\n" + log)
+    log = net['r1'].getStdErr('zebra')
+    print("\nZebra StdErr Log:\n" + log)
+
+
+if __name__ == '__main__':
+
+    setLogLevel('info')
+    # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
+    # retval = pytest.main(["-s", "--tb=no"])
+    retval = pytest.main(["-s"])
+    sys.exit(retval)