]> git.puffer.fish Git - matthieu/frr.git/commitdiff
tests: Introduce BFD IS-IS topotests
authorGalaxyGorilla <sascha@netdef.org>
Tue, 12 May 2020 11:49:58 +0000 (11:49 +0000)
committerGalaxyGorilla <sascha@netdef.org>
Fri, 3 Jul 2020 08:42:34 +0000 (08:42 +0000)
The tests work with the default settings of BFD meaning that bfdd is
able to recognize a 'down' link after ~900ms so a route recovery should
be visible in the RIB after 1 second.

In the current state only IPv4 is used (when using IPv6
autoconfiguration) within BFD, even though the recovery also affects
IPv6 routes. This is different to the current state of ospfd/ospf6d in
combination with BFD since both IPv4 and IPv6 sessions are used there.

The following topology is used:

                        +---------+
                        |         |
           eth-rt2 (.1) |   RT1   | eth-rt3 (.1)
             +----------+ 1.1.1.1 +----------+
             |          |         |          |
             |          +---------+          |
             |                               |
             |                   10.0.2.0/24 |
             |                               |
             |                       eth-rt1 | (.2)
             | 10.0.1.0/24              +----+----+
             |                          |         |
             |                          |   RT3   |
             |                          | 3.3.3.3 |
             |                          |         |
        (.2) | eth-rt1                  +----+----+
        +----+----+                  eth-rt4 | (.1)
        |         |                          |
        |   RT2   |                          |
        | 2.2.2.2 |              10.0.4.0/24 |
        |         |                          |
        +----+----+                          |
        (.1) | eth-rt5               eth-rt3 | (.2)
             |                          +----+----+
             |                          |         |
             |                          |   RT4   |
             |                          | 4.4.4.4 |
             |                          |         |
             |                          +----+----+
             | 10.0.3.0/24           eth-rt5 | (.1)
             |                               |
             |                               |
             |                   10.0.5.0/24 |
             |                               |
             |          +---------+          |
             |          |         |          |
             +----------+   RT5   +----------+
           eth-rt2 (.2) | 5.5.5.5 | eth-rt4 (.2)
                        |         |
                        +---------+

Route recovery is tested on RT1. The focus here lies on the two
different routes to RT5. Link failures are generated by taking
down interfaces via the mininet Python interface on RT2 and RT3.
Hence routes are supposed to be adjusted to use RT3 when a link
failure happens on RT2 or vice versa.

Note that only failure recognition and recovery is "fast". BFD
does not monitor a link becoming available again.

Signed-off-by: GalaxyGorilla <sascha@netdef.org>
32 files changed:
doc/user/bfd.rst
tests/topotests/bfd-isis-topo1/__init__.py [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/bfdd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/isisd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step1/show_ip_route.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step2/show_bfd_peers.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_healthy.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_rt2_down.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_rt3_down.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_healthy.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_rt2_down.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_rt3_down.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_healthy.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_rt2_down.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_rt3_down.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt1/zebra.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt2/bfdd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt2/isisd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt2/step2/show_bfd_peers.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt2/zebra.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt3/bfdd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt3/isisd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt3/step2/show_bfd_peers.ref [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt3/zebra.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt4/bfdd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt4/isisd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt4/zebra.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt5/bfdd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt5/isisd.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/rt5/zebra.conf [new file with mode: 0644]
tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py [new file with mode: 0755]

index b34bcba34df1e692798d1c340e5836a06d4625e4..b6ac297fd9f3f16c188f60d13f3a89d29cda7db5 100644 (file)
@@ -143,7 +143,7 @@ BFD peers and profiles share the same BFD session configuration commands.
 .. clicmd:: transmit-interval (10-60000)
 
    The minimum transmission interval (less jitter) that this system
-   wants to use to send BFD control packets.
+   wants to use to send BFD control packets. Defaults to 300ms.
 
 .. index:: echo-interval (10-60000)
 .. clicmd:: echo-interval (10-60000)
@@ -159,7 +159,7 @@ BFD peers and profiles share the same BFD session configuration commands.
 
    It is recommended that the transmission interval of control packets
    to be increased after enabling echo-mode to reduce bandwidth usage.
-   For example: `transmission-interval 2000`.
+   For example: `transmit-interval 2000`.
 
    Echo mode is not supported on multi-hop setups (see :rfc:`5883`
    section 3).
@@ -246,6 +246,30 @@ The following commands are available inside the BGP configuration node.
    Removes the BFD profile configuration from peer session(s).
 
 
+.. _bfd-isis-peer-config:
+
+IS-IS BFD Configuration
+-----------------------
+
+The following commands are available inside the interface configuration node.
+
+.. index:: isis bfd
+.. clicmd:: ip isis bfd
+
+   Listen for BFD events on peers created on the interface. Every time
+   a new neighbor is found a BFD peer is created to monitor the link
+   status for fast convergence.
+
+.. index:: no isis bfd
+.. clicmd:: no isis bfd
+
+   Removes any notification registration for this interface peers.
+
+   Note that there will be just one BFD session per interface. In case both
+   IPv4 and IPv6 support are configured then just a IPv6 based session is
+   created.
+
+
 .. _bfd-ospf-peer-config:
 
 OSPF BFD Configuration
diff --git a/tests/topotests/bfd-isis-topo1/__init__.py b/tests/topotests/bfd-isis-topo1/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bfd-isis-topo1/rt1/bfdd.conf b/tests/topotests/bfd-isis-topo1/rt1/bfdd.conf
new file mode 100644 (file)
index 0000000..4793155
--- /dev/null
@@ -0,0 +1,17 @@
+!
+debug bfd network
+debug bfd peer
+debug bfd zebra
+!
+bfd
+ peer 10.0.1.2 interface eth-rt2
+  detect-multiplier 3
+  receive-interval 300
+  transmit-interval 300
+ !
+ peer 10.0.2.2 interface eth-rt3
+  detect-multiplier 3
+  receive-interval 300
+  transmit-interval 300
+ !
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt1/isisd.conf b/tests/topotests/bfd-isis-topo1/rt1/isisd.conf
new file mode 100644 (file)
index 0000000..3219371
--- /dev/null
@@ -0,0 +1,35 @@
+log file isisd.log
+log timestamp precision 3
+!
+hostname rt1
+!
+password 1
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+debug isis adj-packets
+debug isis lsp-sched
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt2
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+ isis bfd
+!
+interface eth-rt3
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+ isis network point-to-point
+ isis bfd
+!
+router isis 1
+ net 49.0000.0000.0000.0001.00
+ is-type level-1
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step1/show_ip_route.ref b/tests/topotests/bfd-isis-topo1/rt1/step1/show_ip_route.ref
new file mode 100644 (file)
index 0000000..af6e45c
--- /dev/null
@@ -0,0 +1,74 @@
+{
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/bfd-isis-topo1/rt1/step1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..68d3fe2
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "::ffff:202:202\/128":[
+    {
+      "prefix":"::ffff:202:202\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:303:303\/128":[
+    {
+      "prefix":"::ffff:303:303\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:404:404\/128":[
+    {
+      "prefix":"::ffff:404:404\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:505:505\/128":[
+    {
+      "prefix":"::ffff:505:505\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step2/show_bfd_peers.ref b/tests/topotests/bfd-isis-topo1/rt1/step2/show_bfd_peers.ref
new file mode 100644 (file)
index 0000000..cb4083d
--- /dev/null
@@ -0,0 +1,16 @@
+[
+  {
+    "peer": "10.0.2.2",
+    "interface": "eth-rt3",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  },
+  {
+    "peer": "10.0.1.2",
+    "interface": "eth-rt2",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  }
+]
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_healthy.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_healthy.ref
new file mode 100644 (file)
index 0000000..cb4083d
--- /dev/null
@@ -0,0 +1,16 @@
+[
+  {
+    "peer": "10.0.2.2",
+    "interface": "eth-rt3",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  },
+  {
+    "peer": "10.0.1.2",
+    "interface": "eth-rt2",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  }
+]
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_rt2_down.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_rt2_down.ref
new file mode 100644 (file)
index 0000000..f00b9f3
--- /dev/null
@@ -0,0 +1,9 @@
+[
+  {
+    "peer": "10.0.2.2",
+    "interface": "eth-rt3",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  }
+]
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_rt3_down.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_bfd_peers_rt3_down.ref
new file mode 100644 (file)
index 0000000..f5bd276
--- /dev/null
@@ -0,0 +1,9 @@
+[
+  {
+    "peer": "10.0.1.2",
+    "interface": "eth-rt2",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  }
+]
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_healthy.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_healthy.ref
new file mode 100644 (file)
index 0000000..af6e45c
--- /dev/null
@@ -0,0 +1,74 @@
+{
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_rt2_down.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_rt2_down.ref
new file mode 100644 (file)
index 0000000..b8366bc
--- /dev/null
@@ -0,0 +1,74 @@
+{
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_rt3_down.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_ip_route_rt3_down.ref
new file mode 100644 (file)
index 0000000..42bd6ab
--- /dev/null
@@ -0,0 +1,74 @@
+{
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_healthy.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_healthy.ref
new file mode 100644 (file)
index 0000000..68d3fe2
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "::ffff:202:202\/128":[
+    {
+      "prefix":"::ffff:202:202\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:303:303\/128":[
+    {
+      "prefix":"::ffff:303:303\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:404:404\/128":[
+    {
+      "prefix":"::ffff:404:404\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:505:505\/128":[
+    {
+      "prefix":"::ffff:505:505\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_rt2_down.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_rt2_down.ref
new file mode 100644 (file)
index 0000000..200053c
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "::ffff:202:202\/128":[
+    {
+      "prefix":"::ffff:202:202\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:303:303\/128":[
+    {
+      "prefix":"::ffff:303:303\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:404:404\/128":[
+    {
+      "prefix":"::ffff:404:404\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:505:505\/128":[
+    {
+      "prefix":"::ffff:505:505\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_rt3_down.ref b/tests/topotests/bfd-isis-topo1/rt1/step3/show_ipv6_route_rt3_down.ref
new file mode 100644 (file)
index 0000000..4297f16
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "::ffff:202:202\/128":[
+    {
+      "prefix":"::ffff:202:202\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:303:303\/128":[
+    {
+      "prefix":"::ffff:303:303\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:404:404\/128":[
+    {
+      "prefix":"::ffff:404:404\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "::ffff:505:505\/128":[
+    {
+      "prefix":"::ffff:505:505\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bfd-isis-topo1/rt1/zebra.conf b/tests/topotests/bfd-isis-topo1/rt1/zebra.conf
new file mode 100644 (file)
index 0000000..6003125
--- /dev/null
@@ -0,0 +1,25 @@
+log file zebra.log
+log timestamp precision 3
+!
+hostname rt1
+!
+debug zebra kernel
+debug zebra packet
+debug zebra events
+debug zebra rib
+!
+interface lo
+ ip address 1.1.1.1/32
+ ipv6 address ::ffff:0101:0101/128
+!
+interface eth-rt2
+ ip address 10.0.1.1/24
+!
+interface eth-rt3
+ ip address 10.0.2.1/24
+!
+ip forwarding
+ipv6 forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt2/bfdd.conf b/tests/topotests/bfd-isis-topo1/rt2/bfdd.conf
new file mode 100644 (file)
index 0000000..a49cd4f
--- /dev/null
@@ -0,0 +1,12 @@
+!
+debug bfd network
+debug bfd peer
+debug bfd zebra
+!
+bfd
+ peer 10.0.1.1 interface eth-rt1
+  detect-multiplier 3
+  receive-interval 300
+  transmit-interval 300
+ !
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt2/isisd.conf b/tests/topotests/bfd-isis-topo1/rt2/isisd.conf
new file mode 100644 (file)
index 0000000..63ccb64
--- /dev/null
@@ -0,0 +1,30 @@
+log file isisd.log
+!
+hostname rt2
+!
+password 1
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt1
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+ isis bfd
+!
+interface eth-rt5
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+!
+router isis 1
+ net 49.0000.0000.0000.0002.00
+ is-type level-1
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt2/step2/show_bfd_peers.ref b/tests/topotests/bfd-isis-topo1/rt2/step2/show_bfd_peers.ref
new file mode 100644 (file)
index 0000000..8a90649
--- /dev/null
@@ -0,0 +1,9 @@
+[
+  {
+    "peer": "10.0.1.1",
+    "interface": "eth-rt1",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  }
+]
diff --git a/tests/topotests/bfd-isis-topo1/rt2/zebra.conf b/tests/topotests/bfd-isis-topo1/rt2/zebra.conf
new file mode 100644 (file)
index 0000000..5fc7fc5
--- /dev/null
@@ -0,0 +1,22 @@
+log file zebra.log
+!
+hostname rt2
+!
+debug zebra kernel
+debug zebra packet
+!
+interface lo
+ ip address 2.2.2.2/32
+ ipv6 address ::ffff:0202:0202/128
+!
+interface eth-rt1
+ ip address 10.0.1.2/24
+!
+interface eth-rt5
+ ip address 10.0.3.1/24
+!
+ip forwarding
+ipv6 forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt3/bfdd.conf b/tests/topotests/bfd-isis-topo1/rt3/bfdd.conf
new file mode 100644 (file)
index 0000000..600054a
--- /dev/null
@@ -0,0 +1,12 @@
+!
+debug bfd network
+debug bfd peer
+debug bfd zebra
+!
+bfd
+ peer 10.0.2.1 interface eth-rt1
+  detect-multiplier 3
+  receive-interval 300
+  transmit-interval 300
+ !
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt3/isisd.conf b/tests/topotests/bfd-isis-topo1/rt3/isisd.conf
new file mode 100644 (file)
index 0000000..928f1e1
--- /dev/null
@@ -0,0 +1,32 @@
+log file isisd.log
+!
+hostname rt3
+!
+password 1
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt1
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+ isis network point-to-point
+ isis bfd
+!
+interface eth-rt4
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+!
+router isis 1
+ net 49.0000.0000.0000.0003.00
+ is-type level-1
+!
+
diff --git a/tests/topotests/bfd-isis-topo1/rt3/step2/show_bfd_peers.ref b/tests/topotests/bfd-isis-topo1/rt3/step2/show_bfd_peers.ref
new file mode 100644 (file)
index 0000000..13eb2a2
--- /dev/null
@@ -0,0 +1,9 @@
+[
+  {
+    "peer": "10.0.2.1",
+    "interface": "eth-rt1",
+    "status": "up",
+    "diagnostic": "ok",
+    "remote-diagnostic": "ok"
+  }
+]
diff --git a/tests/topotests/bfd-isis-topo1/rt3/zebra.conf b/tests/topotests/bfd-isis-topo1/rt3/zebra.conf
new file mode 100644 (file)
index 0000000..d368de9
--- /dev/null
@@ -0,0 +1,22 @@
+log file zebra.log
+!
+hostname rt3
+!
+debug zebra kernel
+debug zebra packet
+!
+interface lo
+ ip address 3.3.3.3/32
+ ipv6 address ::ffff:0303:0303/128
+!
+interface eth-rt1
+ ip address 10.0.2.2/24
+!
+interface eth-rt4
+ ip address 10.0.4.1/24
+!
+ip forwarding
+ipv6 forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt4/bfdd.conf b/tests/topotests/bfd-isis-topo1/rt4/bfdd.conf
new file mode 100644 (file)
index 0000000..f35e772
--- /dev/null
@@ -0,0 +1,5 @@
+!
+debug bfd network
+debug bfd peer
+debug bfd zebra
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt4/isisd.conf b/tests/topotests/bfd-isis-topo1/rt4/isisd.conf
new file mode 100644 (file)
index 0000000..fde9747
--- /dev/null
@@ -0,0 +1,29 @@
+log file isisd.log
+!
+hostname rt4
+!
+password 1
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt3
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+!
+interface eth-rt5
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+!
+router isis 1
+ net 49.0000.0000.0000.0004.00
+ is-type level-1
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt4/zebra.conf b/tests/topotests/bfd-isis-topo1/rt4/zebra.conf
new file mode 100644 (file)
index 0000000..7b053ba
--- /dev/null
@@ -0,0 +1,22 @@
+log file zebra.log
+!
+hostname rt4
+!
+debug zebra kernel
+debug zebra packet
+!
+interface lo
+ ip address 4.4.4.4/32
+ ipv6 address ::ffff:0404:0404/128
+!
+interface eth-rt3
+ ip address 10.0.4.2/24
+!
+interface eth-rt5
+ ip address 10.0.5.1/24
+!
+ip forwarding
+ipv6 forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt5/bfdd.conf b/tests/topotests/bfd-isis-topo1/rt5/bfdd.conf
new file mode 100644 (file)
index 0000000..f35e772
--- /dev/null
@@ -0,0 +1,5 @@
+!
+debug bfd network
+debug bfd peer
+debug bfd zebra
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt5/isisd.conf b/tests/topotests/bfd-isis-topo1/rt5/isisd.conf
new file mode 100644 (file)
index 0000000..fd00cb1
--- /dev/null
@@ -0,0 +1,29 @@
+log file isisd.log
+!
+hostname rt5
+!
+password 1
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt2
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+!
+interface eth-rt4
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+!
+router isis 1
+ net 49.0000.0000.0000.0005.00
+ is-type level-1
+!
diff --git a/tests/topotests/bfd-isis-topo1/rt5/zebra.conf b/tests/topotests/bfd-isis-topo1/rt5/zebra.conf
new file mode 100644 (file)
index 0000000..0b7c9e0
--- /dev/null
@@ -0,0 +1,22 @@
+log file zebra.log
+!
+hostname rt5
+!
+debug zebra kernel
+debug zebra packet
+!
+interface lo
+ ip address 5.5.5.5/32
+ ipv6 address ::ffff:0505:0505/128
+!
+interface eth-rt2
+ ip address 10.0.3.2/24
+!
+interface eth-rt4
+ ip address 10.0.5.2/24
+!
+ip forwarding
+ipv6 forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py b/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py
new file mode 100755 (executable)
index 0000000..a1ed0cc
--- /dev/null
@@ -0,0 +1,304 @@
+#!/usr/bin/env python
+
+#
+# test_bfd_isis_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2020 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_bfd_isis_topo1.py:
+
+                        +---------+
+                        |         |
+           eth-rt2 (.1) |   RT1   | eth-rt3 (.1)
+             +----------+ 1.1.1.1 +----------+
+             |          |         |          |
+             |          +---------+          |
+             |                               |
+             |                   10.0.2.0/24 |
+             |                               |
+             |                       eth-rt1 | (.2)
+             | 10.0.1.0/24              +----+----+
+             |                          |         |
+             |                          |   RT3   |
+             |                          | 3.3.3.3 |
+             |                          |         |
+        (.2) | eth-rt1                  +----+----+
+        +----+----+                  eth-rt4 | (.1)
+        |         |                          |
+        |   RT2   |                          |
+        | 2.2.2.2 |              10.0.4.0/24 |
+        |         |                          |
+        +----+----+                          |
+        (.1) | eth-rt5               eth-rt3 | (.2)
+             |                          +----+----+
+             |                          |         |
+             |                          |   RT4   |
+             |                          | 4.4.4.4 |
+             |                          |         |
+             |                          +----+----+
+             | 10.0.3.0/24           eth-rt5 | (.1)
+             |                               |
+             |                               |
+             |                   10.0.5.0/24 |
+             |                               |
+             |          +---------+          |
+             |          |         |          |
+             +----------+   RT5   +----------+
+           eth-rt2 (.2) | 5.5.5.5 | eth-rt4 (.2)
+                        |         |
+                        +---------+
+
+"""
+
+import os
+import sys
+import pytest
+import json
+import re
+from time import sleep
+from time import time
+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
+# 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
+
+
+class TemplateTopo(Topo):
+    "Test topology builder"
+
+    def build(self, *_args, **_opts):
+        "Build function"
+        tgen = get_topogen(self)
+
+        #
+        # Define FRR Routers
+        #
+        for router in ["rt1", "rt2", "rt3", "rt4", "rt5"]:
+            tgen.add_router(router)
+
+        #
+        # Define connections
+        #
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["rt1"], nodeif="eth-rt2")
+        switch.add_link(tgen.gears["rt2"], nodeif="eth-rt1")
+
+        switch = tgen.add_switch("s2")
+        switch.add_link(tgen.gears["rt1"], nodeif="eth-rt3")
+        switch.add_link(tgen.gears["rt3"], nodeif="eth-rt1")
+
+        switch = tgen.add_switch("s3")
+        switch.add_link(tgen.gears["rt2"], nodeif="eth-rt5")
+        switch.add_link(tgen.gears["rt5"], nodeif="eth-rt2")
+
+        switch = tgen.add_switch("s4")
+        switch.add_link(tgen.gears["rt3"], nodeif="eth-rt4")
+        switch.add_link(tgen.gears["rt4"], nodeif="eth-rt3")
+
+        switch = tgen.add_switch("s5")
+        switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5")
+        switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4")
+
+
+def setup_module(mod):
+    "Sets up the pytest environment"
+    tgen = Topogen(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    # For all registered routers, load the zebra configuration file
+    for rname, router in router_list.iteritems():
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BFD, os.path.join(CWD, "{}/bfdd.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
+        )
+
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    "Teardown the pytest environment"
+    tgen = get_topogen()
+
+    # This function tears down the whole topology.
+    tgen.stop_topology()
+
+
+def print_cmd_result(rname, command):
+    print(get_topogen().gears[rname].vtysh_cmd(command, isjson=False))
+
+
+def router_compare_json_output(rname, command, reference, count=120, wait=0.5):
+    "Compare router JSON output"
+
+    logger.info('Comparing router "%s" "%s" output', rname, command)
+
+    tgen = get_topogen()
+    filename = "{}/{}/{}".format(CWD, rname, reference)
+    expected = json.loads(open(filename).read())
+
+    # 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=count, wait=wait)
+    assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
+    assert diff is None, assertmsg
+
+
+## TEST STEPS
+
+
+def test_rib_isis_step1():
+    logger.info("Test (step 1): verify RIB (IPv4 and IPv6) for IS-IS")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router_compare_json_output(
+        "rt1", "show ip route isis json", "step1/show_ip_route.ref"
+    )
+    router_compare_json_output(
+        "rt1", "show ipv6 route isis json", "step1/show_ipv6_route.ref"
+    )
+
+
+def test_bfd_isis_sessions_step2():
+    logger.info("Test (step 2): verify BFD peers for IS-IS")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    # BFD is just used on three routers
+    for rt in ["rt1", "rt2", "rt3"]:
+        router_compare_json_output(
+            rt, "show bfd peers json", "step2/show_bfd_peers.ref"
+        )
+
+
+def test_bfd_isis_interface_failure_rt2_step3():
+    logger.info("Test (step 2): check failover handling when RT2 goes down")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    # Let's kill the interface on rt2 and see what happens with the RIB and BFD on rt1
+    tgen.gears["rt2"].link_enable("eth-rt1", enabled=False)
+
+    # By default BFD provides a recovery time of 900ms plus jitter, so let's wait
+    # initial 2 seconds to let the CI not suffer.
+    # TODO: add check for array size
+    sleep(2)
+    router_compare_json_output(
+        "rt1", "show ip route isis json", "step3/show_ip_route_rt2_down.ref", 1, 0
+    )
+    router_compare_json_output(
+        "rt1", "show ipv6 route isis json", "step3/show_ipv6_route_rt2_down.ref", 1, 0
+    )
+    router_compare_json_output(
+        "rt1", "show bfd peers json", "step3/show_bfd_peers_rt2_down.ref", 1, 0
+    )
+
+    # Check recovery, this can take some time
+    tgen.gears["rt2"].link_enable("eth-rt1", enabled=True)
+
+    router_compare_json_output(
+        "rt1", "show ip route isis json", "step3/show_ip_route_healthy.ref"
+    )
+    router_compare_json_output(
+        "rt1", "show ipv6 route isis json", "step3/show_ipv6_route_healthy.ref"
+    )
+    router_compare_json_output(
+        "rt1", "show bfd peers json", "step3/show_bfd_peers_healthy.ref"
+    )
+
+
+def test_bfd_isis_interface_failure_rt3_step3():
+    logger.info("Test (step 2): check failover handling when RT2 goes down")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    # Let's kill the interface on rt3 and see what happens with the RIB and BFD on rt1
+    tgen.gears["rt3"].link_enable("eth-rt1", enabled=False)
+
+    # By default BFD provides a recovery time of 900ms plus jitter, so let's wait
+    # initial 2 seconds to let the CI not suffer.
+    # TODO: add check for array size
+    sleep(2)
+    router_compare_json_output(
+        "rt1", "show ip route isis json", "step3/show_ip_route_rt3_down.ref", 1, 0
+    )
+    router_compare_json_output(
+        "rt1", "show ipv6 route isis json", "step3/show_ipv6_route_rt3_down.ref", 1, 0
+    )
+    router_compare_json_output(
+        "rt1", "show bfd peers json", "step3/show_bfd_peers_rt3_down.ref", 1, 0
+    )
+
+    # Check recovery, this can take some time
+    tgen.gears["rt3"].link_enable("eth-rt1", enabled=True)
+
+    router_compare_json_output(
+        "rt1", "show ip route isis json", "step3/show_ip_route_healthy.ref"
+    )
+    router_compare_json_output(
+        "rt1", "show ipv6 route isis json", "step3/show_ipv6_route_healthy.ref"
+    )
+    router_compare_json_output(
+        "rt1", "show bfd peers json", "step3/show_bfd_peers_healthy.ref"
+    )
+
+
+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))