]> git.puffer.fish Git - matthieu/frr.git/commitdiff
topotests: add an ebgp 6vpe test
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 13 Mar 2023 09:47:16 +0000 (10:47 +0100)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Wed, 28 Feb 2024 09:35:34 +0000 (09:35 +0000)
This test uses the connected ipv4 mapped ipv6 prefix
to resolve the received BGP routes.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Signed-off-by: François Dumontet <francois.dumontet@6wind.com>
(cherry picked from commit 4d7df91752d7414d9719a361a2fd4cc30943dc96)

15 files changed:
tests/topotests/bgp_6vpe_ebgp_topo1/__init__.py [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/h1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/h2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgp_summary.json [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgp_vrf_ipv6.json [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe1/ipv6_routes_vrf.json [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe1/isisd.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgp_summary.json [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgp_vrf_ipv6.json [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe2/isisd.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/pe2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_6vpe_ebgp_topo1/test_bgp_6vpe_ebgp_topo1.py [new file with mode: 0644]

diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/__init__.py b/tests/topotests/bgp_6vpe_ebgp_topo1/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/h1/zebra.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/h1/zebra.conf
new file mode 100644 (file)
index 0000000..06a23bb
--- /dev/null
@@ -0,0 +1,4 @@
+ipv6 route fd00:200::/64 fd00:100::2
+interface eth-pe1
+ ipv6 address fd00:100::1/64
+!
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/h2/zebra.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/h2/zebra.conf
new file mode 100644 (file)
index 0000000..2dadfc4
--- /dev/null
@@ -0,0 +1,8 @@
+ipv6 route fd00:100::/64 fd00:200::5
+interface eth-pe2
+ ipv6 address fd00:200::6/64
+ ipv6 address fd00:201::6/64
+ ipv6 address fd00:300::6/64
+ ipv6 address fd00:400::6/64
+ ipv6 address fd01:200::6/64
+!
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgp_summary.json b/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgp_summary.json
new file mode 100644 (file)
index 0000000..c2100ad
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "ipv6Vpn": {
+    "routerId": "198.51.100.2",
+    "as": 65500,
+    "peers": {
+      "192.0.2.5": {
+        "remoteAs": 65501,
+        "state": "Established",
+        "peerState": "OK"
+      }
+    }
+  }
+}
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgp_vrf_ipv6.json b/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgp_vrf_ipv6.json
new file mode 100644 (file)
index 0000000..c6e776d
--- /dev/null
@@ -0,0 +1,116 @@
+{
+  "vrfName": "vrf1",
+  "routerId": "198.51.100.2",
+  "defaultLocPrf": 100,
+  "localAS": 65500,
+  "routes": {
+    "fd00:100::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:100::/64",
+        "metric": 0,
+        "weight": 32768,
+        "path": "",
+        "nexthops": [
+          {
+            "ip": "::",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:200::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:200::/64",
+        "metric": 0,
+        "weight": 0,
+        "path": "65501",
+        "nexthops": [
+          {
+            "ip": "::ffff:c000:205",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:201::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:201::/64",
+        "metric": 0,
+        "weight": 0,
+        "path": "65501",
+        "nexthops": [
+          {
+            "ip": "::ffff:c000:205",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:300::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:300::/64",
+        "metric": 0,
+        "weight": 0,
+        "path": "65501",
+        "nexthops": [
+          {
+            "ip": "::ffff:c000:205",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:400::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:400::/64",
+        "metric": 0,
+        "weight": 0,
+        "path": "65501",
+        "nexthops": [
+          {
+            "ip": "::ffff:c000:205",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd01:200::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd01:200::/64",
+        "metric": 0,
+        "weight": 0,
+        "path": "65501",
+        "nexthops": [
+          {
+            "ip": "::ffff:c000:205",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgpd.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/bgpd.conf
new file mode 100644 (file)
index 0000000..26e94d4
--- /dev/null
@@ -0,0 +1,32 @@
+!
+!debug bgp zebra
+router bgp 65500
+ bgp router-id 198.51.100.2
+ no bgp ebgp-requires-policy
+  neighbor 192.0.2.5 remote-as 65501
+  neighbor 192.0.2.5 capability extended-nexthop
+ address-family ipv4 unicast
+  no neighbor 192.0.2.5 activate
+ exit-address-family
+ address-family ipv6 vpn
+  neighbor 192.0.2.5 activate
+  neighbor 192.0.2.5 route-map rmap in
+ exit-address-family
+exit
+router bgp 65500 vrf vrf1
+ bgp router-id 198.51.100.2
+ address-family ipv6 unicast
+  redistribute connected
+  label vpn export 101
+  rd vpn export 444:1
+  rt vpn both 52:100
+  export vpn
+  import vpn
+ exit-address-family
+!
+interface eth-pe2
+ mpls bgp forwarding
+!
+route-map rmap permit 1
+ set ipv6 next-hop prefer-global
+!
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/ipv6_routes_vrf.json b/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/ipv6_routes_vrf.json
new file mode 100644 (file)
index 0000000..1545749
--- /dev/null
@@ -0,0 +1,142 @@
+{
+  "fd00:100::/64": [
+    {
+      "prefix": "fd00:100::/64",
+      "protocol": "connected",
+      "vrfName": "vrf1",
+      "selected": true,
+      "destSelected": true,
+      "distance": 0,
+      "metric": 0,
+      "installed": true,
+      "nexthops": [
+        {
+          "fib": true,
+          "directlyConnected": true,
+          "interfaceName": "eth-h1",
+          "active": true
+        }
+      ]
+    }
+  ],
+  "fd00:200::/64": [
+    {
+      "prefix": "fd00:200::/64",
+      "protocol": "bgp",
+      "vrfName": "vrf1",
+      "selected": true,
+      "destSelected": true,
+      "distance": 20,
+      "metric": 0,
+      "installed": true,
+      "nexthops": [
+        {
+          "ip": "::ffff:c000:205",
+          "afi": "ipv6",
+          "vrf": "default",
+          "active": true,
+          "labels": [
+            102
+          ],
+          "weight": 1
+        }
+      ]
+    }
+  ],
+  "fd00:201::/64": [
+    {
+      "prefix": "fd00:201::/64",
+      "protocol": "bgp",
+      "vrfName": "vrf1",
+      "selected": true,
+      "destSelected": true,
+      "distance": 20,
+      "metric": 0,
+      "installed": true,
+      "nexthops": [
+        {
+          "ip": "::ffff:c000:205",
+          "afi": "ipv6",
+          "vrf": "default",
+          "active": true,
+          "labels": [
+            102
+          ],
+          "weight": 1
+        }
+      ]
+    }
+  ],
+  "fd00:300::/64": [
+    {
+      "prefix": "fd00:300::/64",
+      "protocol": "bgp",
+      "vrfName": "vrf1",
+      "selected": true,
+      "destSelected": true,
+      "distance": 20,
+      "metric": 0,
+      "installed": true,
+      "nexthops": [
+        {
+          "ip": "::ffff:c000:205",
+          "afi": "ipv6",
+          "vrf": "default",
+          "active": true,
+          "labels": [
+            102
+          ],
+          "weight": 1
+        }
+      ]
+    }
+  ],
+  "fd00:400::/64": [
+    {
+      "prefix": "fd00:400::/64",
+      "protocol": "bgp",
+      "vrfName": "vrf1",
+      "selected": true,
+      "destSelected": true,
+      "distance": 20,
+      "metric": 0,
+      "installed": true,
+      "nexthops": [
+        {
+          "ip": "::ffff:c000:205",
+          "afi": "ipv6",
+          "vrf": "default",
+          "active": true,
+          "labels": [
+            102
+          ],
+          "weight": 1
+        }
+      ]
+    }
+  ],
+  "fd01:200::/64": [
+    {
+      "prefix": "fd01:200::/64",
+      "protocol": "bgp",
+      "vrfName": "vrf1",
+      "selected": true,
+      "destSelected": true,
+      "distance": 20,
+      "metric": 0,
+      "installed": true,
+      "nexthops": [
+        {
+          "ip": "::ffff:c000:205",
+          "afi": "ipv6",
+          "vrf": "default",
+          "active": true,
+          "labels": [
+            102
+          ],
+          "weight": 1
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/isisd.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/isisd.conf
new file mode 100644 (file)
index 0000000..61f2fe7
--- /dev/null
@@ -0,0 +1,23 @@
+!
+interface lo
+ ip router isis 1
+ isis hello-interval 1
+ isis hello-multiplier 3
+!
+interface eth-pe2
+ ip router isis 1
+ isis hello-interval 1
+ isis hello-multiplier 3
+!
+router isis 1
+ net 49.0000.0007.e901.2222.00
+ is-type level-1
+ lsp-gen-interval 1
+ mpls-te on
+ mpls-te router-address 198.51.100.2
+ segment-routing on
+ segment-routing node-msd 8
+ segment-routing global-block 1000 10000 local-block 30000 30999
+ segment-routing prefix 198.51.100.2/32 index 22
+!
+
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/zebra.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/pe1/zebra.conf
new file mode 100644 (file)
index 0000000..7ddd98f
--- /dev/null
@@ -0,0 +1,11 @@
+!
+interface eth-h1
+ ipv6 address fd00:100::2/64
+!
+interface eth-pe2
+ ip address 192.0.2.2/24
+ ipv6 address ::ffff:192.0.2.2/120
+!
+interface lo
+ ip address 198.51.100.2/32
+!
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgp_summary.json b/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgp_summary.json
new file mode 100644 (file)
index 0000000..d740794
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "ipv6Vpn": {
+    "routerId": "198.51.100.5",
+    "as": 65501,
+    "peers": {
+      "192.0.2.2": {
+        "remoteAs": 65500,
+        "state": "Established",
+        "peerState": "OK"
+      }
+    }
+  }
+}
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgp_vrf_ipv6.json b/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgp_vrf_ipv6.json
new file mode 100644 (file)
index 0000000..ec42999
--- /dev/null
@@ -0,0 +1,116 @@
+{
+  "vrfName": "vrf1",
+  "routerId": "198.51.100.5",
+  "defaultLocPrf": 100,
+  "localAS": 65501,
+  "routes": {
+    "fd00:100::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:100::/64",
+        "metric": 0,
+        "weight": 0,
+        "path": "65500",
+        "nexthops": [
+          {
+            "ip": "::ffff:c000:202",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:200::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:200::/64",
+        "metric": 0,
+        "weight": 32768,
+        "path": "",
+        "nexthops": [
+          {
+            "ip": "::",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:201::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:201::/64",
+        "metric": 0,
+        "weight": 32768,
+        "path": "",
+        "nexthops": [
+          {
+            "ip": "::",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:300::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:300::/64",
+        "metric": 0,
+        "weight": 32768,
+        "path": "",
+        "nexthops": [
+          {
+            "ip": "::",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd00:400::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd00:400::/64",
+        "metric": 0,
+        "weight": 32768,
+        "path": "",
+        "nexthops": [
+          {
+            "ip": "::",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ],
+    "fd01:200::/64": [
+      {
+        "valid": true,
+        "bestpath": true,
+        "network": "fd01:200::/64",
+        "metric": 0,
+        "weight": 32768,
+        "path": "",
+        "nexthops": [
+          {
+            "ip": "::",
+            "afi": "ipv6",
+            "scope": "global",
+            "used": true
+          }
+        ]
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgpd.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/bgpd.conf
new file mode 100644 (file)
index 0000000..03b63af
--- /dev/null
@@ -0,0 +1,31 @@
+!
+router bgp 65501
+ bgp router-id 198.51.100.5
+ no bgp ebgp-requires-policy
+  neighbor 192.0.2.2 remote-as 65500
+  neighbor 192.0.2.2 capability extended-nexthop
+ address-family ipv4 unicast
+  no neighbor 192.0.2.2 activate
+ exit-address-family
+ address-family ipv6 vpn
+  neighbor 192.0.2.2 activate
+  neighbor 192.0.2.2 route-map rmap in
+ exit-address-family
+exit
+router bgp 65501 vrf vrf1
+ bgp router-id 198.51.100.5
+ address-family ipv6 unicast
+  redistribute connected
+  label vpn export 102
+  rd vpn export 444:2
+  rt vpn both 52:100
+  export vpn
+  import vpn
+exit-address-family
+!
+interface eth-pe1
+ mpls bgp forwarding
+!
+route-map rmap permit 1
+ set ipv6 next-hop prefer-global
+!
\ No newline at end of file
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/isisd.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/isisd.conf
new file mode 100644 (file)
index 0000000..f210554
--- /dev/null
@@ -0,0 +1,22 @@
+!
+interface lo
+ ip router isis 1
+ isis hello-interval 1
+ isis hello-multiplier 3
+!
+interface eth-pe1
+ ip router isis 1
+ isis hello-interval 1
+ isis hello-multiplier 3
+!
+router isis 1
+ net 49.0000.0007.e901.5555.00
+ is-type level-1
+ lsp-gen-interval 1
+ mpls-te on
+ mpls-te router-address 198.51.100.5
+ segment-routing on
+ segment-routing node-msd 8
+ segment-routing global-block 1000 10000 local-block 33000 33999
+ segment-routing prefix 198.51.100.5/32 index 55
+!
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/zebra.conf b/tests/topotests/bgp_6vpe_ebgp_topo1/pe2/zebra.conf
new file mode 100644 (file)
index 0000000..bf20638
--- /dev/null
@@ -0,0 +1,15 @@
+!
+interface eth-h2
+ ipv6 address fd00:200::5/64
+ ipv6 address fd00:201::5/64
+ ipv6 address fd00:300::5/64
+ ipv6 address fd00:400::5/64
+ ipv6 address fd01:200::5/64
+!
+interface eth-pe1
+ ip address 192.0.2.5/24
+ ipv6 address ::ffff:192.0.2.5/120
+!
+interface lo
+ ip address 198.51.100.5/32
+!
diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/test_bgp_6vpe_ebgp_topo1.py b/tests/topotests/bgp_6vpe_ebgp_topo1/test_bgp_6vpe_ebgp_topo1.py
new file mode 100644 (file)
index 0000000..cbed8f0
--- /dev/null
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+
+#
+# Copyright (c) 2023 by 6WIND
+#
+
+"""
+Test the FRR BGP 6VPE functionality
+"""
+
+import os
+import sys
+import json
+import functools
+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
+from lib.checkping import check_ping
+
+pytestmark = [pytest.mark.bgpd, pytest.mark.isisd]
+
+
+def build_topo(tgen):
+    """
+    +---+    +---+    +---+    +---+
+    | h1|----|pe1|----|pe2|----| h2|
+    +---+    +---+    +---+    +---+
+    """
+
+    def connect_routers(tgen, left, right):
+        pe = None
+        host = None
+        for rname in [left, right]:
+            if rname not in tgen.routers().keys():
+                tgen.add_router(rname)
+            if "pe" in rname:
+                pe = tgen.gears[rname]
+            if "h" in rname:
+                host = tgen.gears[rname]
+
+        switch = tgen.add_switch("s-{}-{}".format(left, right))
+        switch.add_link(tgen.gears[left], nodeif="eth-{}".format(right))
+        switch.add_link(tgen.gears[right], nodeif="eth-{}".format(left))
+
+        if pe and host:
+            pe.cmd("ip link add vrf1 type vrf table 10")
+            pe.cmd("ip link set vrf1 up")
+            pe.cmd("ip link set dev eth-{} master vrf1".format(host.name))
+
+        if "p" in left and "p" in right:
+            # PE <-> P or P <-> P
+            tgen.gears[left].run("sysctl -w net.mpls.conf.eth-{}.input=1".format(right))
+            tgen.gears[right].run("sysctl -w net.mpls.conf.eth-{}.input=1".format(left))
+
+    connect_routers(tgen, "h1", "pe1")
+    connect_routers(tgen, "pe1", "pe2")
+    connect_routers(tgen, "pe2", "h2")
+
+
+def setup_module(mod):
+    "Sets up the pytest environment"
+
+    tgen = Topogen(build_topo, mod.__name__)
+    tgen.start_topology()
+    logger.info("setup_module")
+
+    for rname, router in tgen.routers().items():
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        if "h" in rname:
+            # hosts
+            continue
+
+        router.load_config(
+            TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
+        )
+
+        router.load_config(
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+        )
+
+    # Initialize all routers.
+    tgen.start_router()
+
+
+def teardown_module(_mod):
+    "Teardown the pytest environment"
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_convergence():
+    "Assert that BGP is converging."
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info("waiting for bgp peers to go up")
+
+    router_list = ["pe1", "pe2"]
+
+    for name in router_list:
+        router = tgen.gears[name]
+        ref_file = "{}/{}/bgp_summary.json".format(CWD, router.name)
+        expected = json.loads(open(ref_file).read())
+        test_func = partial(
+            topotest.router_json_cmp, router, "show bgp summary json", expected
+        )
+        _, res = topotest.run_and_expect(test_func, None, count=90, wait=1)
+        assertmsg = "{}: bgp did not converge".format(router.name)
+        assert res is None, assertmsg
+
+
+def test_bgp_ipv6_vpn():
+    "Assert that BGP is exchanging BGP route."
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info("waiting for bgp peers exchanging UPDATES")
+
+    router_list = ["pe1", "pe2"]
+
+    for name in router_list:
+        router = tgen.gears[name]
+        ref_file = "{}/{}/bgp_vrf_ipv6.json".format(CWD, router.name)
+        expected = json.loads(open(ref_file).read())
+        test_func = partial(
+            topotest.router_json_cmp,
+            router,
+            "show bgp vrf vrf1 ipv6 unicast json",
+            expected,
+        )
+        _, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
+        assertmsg = "{}: BGP UPDATE exchange failure".format(router.name)
+        assert res is None, assertmsg
+
+
+def test_zebra_ipv6_installed():
+    "Assert that routes are installed."
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    pe1 = tgen.gears["pe1"]
+    logger.info("check ipv6 routes installed on pe1")
+
+    ref_file = "{}/{}/ipv6_routes_vrf.json".format(CWD, pe1.name)
+    expected = json.loads(open(ref_file).read())
+    test_func = partial(
+        topotest.router_json_cmp, pe1, "show ipv6 route vrf vrf1 json", expected
+    )
+    _, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
+    assertmsg = "{}: Zebra Installation failure on vrf vrf1".format(pe1.name)
+    assert res is None, assertmsg
+
+
+def test_bgp_ping6_ok():
+    "Check that h1 pings h2"
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    check_ping("h1", "fd00:200::6", True, 5, 1)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))