summaryrefslogtreecommitdiffstats
path: root/tests/topotests/bgp_vpnv4_asbr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
commite2bbf175a2184bd76f6c54ccf8456babeb1a46fc (patch)
treef0b76550d6e6f500ada964a3a4ee933a45e5a6f1 /tests/topotests/bgp_vpnv4_asbr
parentInitial commit. (diff)
downloadfrr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.tar.xz
frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.zip
Adding upstream version 9.1.upstream/9.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/topotests/bgp_vpnv4_asbr')
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/__init__.py0
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/h1/zebra.conf7
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/h2/zebra.conf6
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/h3/zebra.conf6
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r1/bgp_ipv4_routes.json49
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r1/bgpd.conf29
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r1/zebra.conf10
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r2/bgpd.conf31
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r2/ipv4_vpn_summary.json24
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r2/zebra.conf13
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r3/bgpd.conf25
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/r3/zebra.conf14
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/rr100/bgpd.conf29
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/rr100/zebra.conf7
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/rs200/bgpd.conf19
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/rs200/zebra.conf4
-rw-r--r--tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py917
17 files changed, 1190 insertions, 0 deletions
diff --git a/tests/topotests/bgp_vpnv4_asbr/__init__.py b/tests/topotests/bgp_vpnv4_asbr/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/__init__.py
diff --git a/tests/topotests/bgp_vpnv4_asbr/h1/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/h1/zebra.conf
new file mode 100644
index 0000000..2237224
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/h1/zebra.conf
@@ -0,0 +1,7 @@
+log stdout
+ip route 172.31.1.0/24 172.31.0.1
+ip route 172.31.2.0/24 172.31.0.1
+interface h1-eth0
+ ip address 172.31.0.10/24
+!
+
diff --git a/tests/topotests/bgp_vpnv4_asbr/h2/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/h2/zebra.conf
new file mode 100644
index 0000000..d650bc8
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/h2/zebra.conf
@@ -0,0 +1,6 @@
+log stdout
+ip route 172.31.0.0/24 172.31.1.1
+interface h2-eth0
+ ip address 172.31.1.10/24
+!
+
diff --git a/tests/topotests/bgp_vpnv4_asbr/h3/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/h3/zebra.conf
new file mode 100644
index 0000000..5676485
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/h3/zebra.conf
@@ -0,0 +1,6 @@
+log stdout
+ip route 172.31.0.0/24 172.31.2.1
+interface h3-eth0
+ ip address 172.31.2.10/24
+!
+
diff --git a/tests/topotests/bgp_vpnv4_asbr/r1/bgp_ipv4_routes.json b/tests/topotests/bgp_vpnv4_asbr/r1/bgp_ipv4_routes.json
new file mode 100644
index 0000000..184ab31
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r1/bgp_ipv4_routes.json
@@ -0,0 +1,49 @@
+{
+ "vrfName": "vrf1",
+ "localAS": 65500,
+ "routes":
+ {
+ "172.31.0.10/32": [
+ {
+ "prefix": "172.31.0.10",
+ "prefixLen": 32,
+ "network": "172.31.0.10\/32",
+ "nhVrfName": "default",
+ "nexthops": [
+ {
+ "ip": "192.168.0.3",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ },
+ {
+ "prefix": "172.31.0.10",
+ "prefixLen": 32,
+ "network": "172.31.0.10\/32",
+ "nhVrfName": "default",
+ "nexthops": [
+ {
+ "ip": "192.168.0.2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "172.31.0.1/32": [
+ {
+ "prefix": "172.31.0.1",
+ "prefixLen": 32,
+ "network": "172.31.0.1\/32",
+ "nexthops": [
+ {
+ "ip": "0.0.0.0",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_vpnv4_asbr/r1/bgpd.conf b/tests/topotests/bgp_vpnv4_asbr/r1/bgpd.conf
new file mode 100644
index 0000000..3bbcc20
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r1/bgpd.conf
@@ -0,0 +1,29 @@
+router bgp 65500
+ bgp router-id 192.0.2.1
+ no bgp ebgp-requires-policy
+ neighbor 192.0.2.100 remote-as 65500
+ neighbor 192.0.2.100 update-source lo
+ neighbor 192.168.0.100 remote-as 65500
+ address-family ipv4 unicast
+ no neighbor 192.168.0.100 activate
+ no neighbor 192.0.2.100 activate
+ network 192.0.2.1/32
+ exit-address-family
+ address-family ipv4 labeled-unicast
+ neighbor 192.168.0.100 activate
+ exit-address-family
+ address-family ipv4 vpn
+ neighbor 192.0.2.100 activate
+ exit-address-family
+!
+router bgp 65500 vrf vrf1
+ bgp router-id 192.0.2.1
+ address-family ipv4 unicast
+ redistribute connected
+ label vpn export 101
+ rd vpn export 444:1
+ rt vpn both 52:100
+ export vpn
+ import vpn
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/r1/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/r1/zebra.conf
new file mode 100644
index 0000000..2f12b72
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r1/zebra.conf
@@ -0,0 +1,10 @@
+log stdout
+interface lo
+ ip address 192.0.2.1/32
+!
+interface r1-eth1 vrf vrf1
+ ip address 172.31.0.1/24
+!
+interface r1-eth0
+ ip address 192.168.0.1/24
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/r2/bgpd.conf b/tests/topotests/bgp_vpnv4_asbr/r2/bgpd.conf
new file mode 100644
index 0000000..4c84d52
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r2/bgpd.conf
@@ -0,0 +1,31 @@
+debug bgp nht
+debug bgp zebra
+debug bgp labelpool
+router bgp 65500
+ bgp router-id 192.0.2.2
+ no bgp ebgp-requires-policy
+ neighbor 192.0.2.100 remote-as 65500
+ neighbor 192.0.2.100 update-source lo
+ neighbor 192.168.0.100 remote-as 65500
+ neighbor 192.168.1.200 remote-as 65502
+ address-family ipv4 unicast
+ no neighbor 192.168.0.100 activate
+ no neighbor 192.168.1.200 activate
+ network 192.0.2.2/32
+ exit-address-family
+ address-family ipv4 labeled-unicast
+ neighbor 192.168.0.100 activate
+ exit-address-family
+ address-family ipv4 vpn
+ neighbor 192.0.2.100 activate
+ neighbor 192.0.2.100 next-hop-self
+ neighbor 192.168.1.200 activate
+ exit-address-family
+!
+interface r2-eth1
+ mpls bgp forwarding
+ mpls bgp l3vpn-multi-domain-switching
+!
+interface r2-eth0
+ mpls bgp l3vpn-multi-domain-switching
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/r2/ipv4_vpn_summary.json b/tests/topotests/bgp_vpnv4_asbr/r2/ipv4_vpn_summary.json
new file mode 100644
index 0000000..d33c5f5
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r2/ipv4_vpn_summary.json
@@ -0,0 +1,24 @@
+{
+ "routerId":"192.0.2.2",
+ "as":65500,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":2,
+ "peers":{
+ "192.0.2.100":{
+ "remoteAs":65500,
+ "localAs":65500,
+ "version":4,
+ "state":"Established",
+ "peerState":"OK"
+ },
+ "192.168.1.200":{
+ "remoteAs":65502,
+ "localAs":65500,
+ "version":4,
+ "state":"Established",
+ "peerState":"OK"
+ }
+ },
+ "totalPeers":2
+}
diff --git a/tests/topotests/bgp_vpnv4_asbr/r2/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/r2/zebra.conf
new file mode 100644
index 0000000..43508a4
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r2/zebra.conf
@@ -0,0 +1,13 @@
+log stdout
+ip route 192.168.1.3/32 r2-eth1
+interface lo
+ ip address 192.0.2.2/32
+!
+interface r2-eth0
+ ip address 192.168.0.2/24
+ mpls enable
+!
+interface r2-eth1
+ ip address 192.168.1.2/24
+ mpls enable
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/r3/bgpd.conf b/tests/topotests/bgp_vpnv4_asbr/r3/bgpd.conf
new file mode 100644
index 0000000..c5d5727
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r3/bgpd.conf
@@ -0,0 +1,25 @@
+router bgp 65501
+ bgp router-id 192.0.2.3
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.200 remote-as 65502
+ address-family ipv4 unicast
+ no neighbor 192.168.1.200 activate
+ exit-address-family
+ address-family ipv4 vpn
+ neighbor 192.168.1.200 activate
+ exit-address-family
+!
+router bgp 65501 vrf vrf1
+ bgp router-id 192.0.2.3
+ address-family ipv4 unicast
+ redistribute connected
+ label vpn export 102
+ rd vpn export 444:3
+ rt vpn both 52:100
+ export vpn
+ import vpn
+ exit-address-family
+!
+interface r3-eth0
+ mpls bgp forwarding
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/r3/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/r3/zebra.conf
new file mode 100644
index 0000000..6376785
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/r3/zebra.conf
@@ -0,0 +1,14 @@
+log stdout
+ip route 192.168.1.3/32 r3-eth0
+interface r3-eth1 vrf vrf1
+ ip address 172.31.1.1/24
+!
+interface r3-eth2 vrf vrf1
+ ip address 172.31.2.1/24
+!
+interface r3-eth3 vrf vrf1
+ ip address 172.31.3.1/24
+!
+interface r3-eth0
+ ip address 192.168.1.3/24
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/rr100/bgpd.conf b/tests/topotests/bgp_vpnv4_asbr/rr100/bgpd.conf
new file mode 100644
index 0000000..845d71b
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/rr100/bgpd.conf
@@ -0,0 +1,29 @@
+router bgp 65500
+ bgp router-id 192.0.2.100
+ no bgp ebgp-requires-policy
+ neighbor 192.0.2.2 remote-as 65500
+ neighbor 192.0.2.2 update-source lo
+ neighbor 192.168.0.2 remote-as 65500
+ neighbor 192.0.2.1 remote-as 65500
+ neighbor 192.0.2.1 update-source lo
+ neighbor 192.168.0.1 remote-as 65500
+ address-family ipv4 unicast
+ no neighbor 192.168.0.1 activate
+ no neighbor 192.0.2.1 activate
+ no neighbor 192.168.0.2 activate
+ no neighbor 192.0.2.2 activate
+ network 192.0.2.100/32
+ exit-address-family
+ address-family ipv4 labeled-unicast
+ neighbor 192.168.0.1 activate
+ neighbor 192.168.0.2 activate
+ neighbor 192.168.0.1 route-reflector-client
+ neighbor 192.168.0.2 route-reflector-client
+ exit-address-family
+ address-family ipv4 vpn
+ neighbor 192.0.2.1 activate
+ neighbor 192.0.2.2 activate
+ neighbor 192.0.2.1 route-reflector-client
+ neighbor 192.0.2.2 route-reflector-client
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/rr100/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/rr100/zebra.conf
new file mode 100644
index 0000000..2fa5285
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/rr100/zebra.conf
@@ -0,0 +1,7 @@
+log stdout
+interface lo
+ ip address 192.0.2.100/32
+!
+interface rr100-eth0
+ ip address 192.168.0.100/24
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/rs200/bgpd.conf b/tests/topotests/bgp_vpnv4_asbr/rs200/bgpd.conf
new file mode 100644
index 0000000..fa3cb54
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/rs200/bgpd.conf
@@ -0,0 +1,19 @@
+debug bgp nht
+debug bgp zebra
+debug bgp labelpool
+router bgp 65502
+ bgp router-id 192.0.2.200
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.3 remote-as 65501
+ neighbor 192.168.1.2 remote-as 65500
+ address-family ipv4 unicast
+ no neighbor 192.168.1.2 activate
+ no neighbor 192.168.1.3 activate
+ exit-address-family
+ address-family ipv4 vpn
+ neighbor 192.168.1.3 activate
+ neighbor 192.168.1.2 activate
+ neighbor 192.168.1.3 route-server-client
+ neighbor 192.168.1.2 route-server-client
+ exit-address-family
+! \ No newline at end of file
diff --git a/tests/topotests/bgp_vpnv4_asbr/rs200/zebra.conf b/tests/topotests/bgp_vpnv4_asbr/rs200/zebra.conf
new file mode 100644
index 0000000..98793ca
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/rs200/zebra.conf
@@ -0,0 +1,4 @@
+log stdout
+interface rs200-eth0
+ ip address 192.168.1.200/24
+!
diff --git a/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py
new file mode 100644
index 0000000..a908e74
--- /dev/null
+++ b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py
@@ -0,0 +1,917 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+
+#
+# test_bgp_vpnv4_asbr.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2023 by 6WIND
+#
+
+"""
+ test_bgp_vpnv4_asbr.py: Test the FRR BGP daemon with rfc4364 option 10b
+ r1, r2, and r100 are in an iBGP AS, while r2, r3 do an eBGP peering
+ h1 is a host behind r1 VRF1, and {h2,h3} are hosts behind r3 VRF1
+ The test demonstrates the connectivity across the network between h1 and h3.
+
+
+ +----------+ +----+--------+ +--------+ +--------+-----+
+ | |172.31.0.0|vrf | r1 |192.168.0.0/24| r2 |192.168.1.0/24|r3 | vrf |
+ | h1 +----------+ | 1+------+-------+ +------+-------+3 | +--- 172.31.3.0/24
+ | 10 | |VRF1|AS65500 | | | AS65500| | |AS65501 |VRF1 |
+ +----------+ +-------------+ | +--------+ | +--------+--+-++
+ 192.0.2.1 | 192.0.2.2 | 172| |
+ +----------+ +----+--------+ 31| |
+ |rr100 | |rs200/AS65502| 1| |
+ +----------+ +-------------+ 0| |
+ 192.0.2.100 +--------+ /24| |
+ | | +----------+----+ |
+ |h3 | | | |
+ |10 | | h2 | |
+ +---+----+ | 10 | |
+ | +----------+ |
+ |172.31.2.0/24 |
+ +--------------------------------+
+"""
+
+import os
+import sys
+import json
+from functools import partial
+import pytest
+import functools
+
+# 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
+
+
+# Required to instantiate the topology builder class.
+
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+ "Build function"
+
+ # Allocate 8 devices
+ tgen.add_router("r1")
+ tgen.add_router("r2")
+ tgen.add_router("r3")
+ tgen.add_router("h1")
+ tgen.add_router("h2")
+ tgen.add_router("h3")
+ tgen.add_router("rr100")
+ tgen.add_router("rs200")
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["rr100"])
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["h1"])
+
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r3"])
+ switch.add_link(tgen.gears["rs200"])
+
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["r3"])
+ switch.add_link(tgen.gears["h2"])
+
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["r3"])
+ switch.add_link(tgen.gears["h3"])
+
+ switch = tgen.add_switch("s6")
+ switch.add_link(tgen.gears["r3"])
+
+
+def _populate_iface():
+ tgen = get_topogen()
+ cmds_list = [
+ "ip link add vrf1 type vrf table 10",
+ "echo 100000 > /proc/sys/net/mpls/platform_labels",
+ "ip link set dev vrf1 up",
+ "ip link set dev {0}-eth1 master vrf1",
+ "echo 1 > /proc/sys/net/mpls/conf/{0}-eth0/input",
+ ]
+
+ for rname in ("r1", "r3"):
+ for cmd in cmds_list:
+ input = cmd.format(rname)
+ logger.info("input: " + cmd)
+ output = tgen.net[rname].cmd(cmd.format(rname))
+ logger.info("output: " + output)
+
+ cmds_list = [
+ "ip link set dev {0}-eth2 master vrf1",
+ "ip link set dev {0}-eth3 master vrf1",
+ ]
+ for cmd in cmds_list:
+ input = cmd.format("r3")
+ logger.info("input: " + input)
+ output = tgen.net["r3"].cmd(input)
+ logger.info("output: " + output)
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(build_topo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+ _populate_iface()
+
+ for rname, router in router_list.items():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ if rname in ("r1", "r2", "r3", "rr100", "rs200"):
+ 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 bgp_vpnv4_prefix_check(router, rd, prefix, label, nexthop):
+ """
+ Dump and check 'show bgp ipv4 vpn <prefix> json' output. An assert is triggered in case test fails
+ * 'router': the router to check
+ * 'rd': The route distinguisher expected
+ * 'prefix': The prefix expected
+ * 'label': The label expected associated with the ('rd','prefix') tuple
+ * 'nexthop': The nexthop expected associated with the ('rd','prefix') tuple
+ """
+
+ def _check(router, prefix, rd, label, nexthop):
+ dump = router.vtysh_cmd("show bgp ipv4 vpn {} json".format(prefix), isjson=True)
+ if not dump:
+ return "{0}, {1}, route distinguisher {2} not present".format(
+ router.name, prefix, rd
+ )
+ for dumped_rd, pathes in dump.items():
+ if dumped_rd != rd:
+ continue
+ for path in pathes["paths"]:
+ if "remoteLabel" not in path.keys():
+ return "{0}, {1}, rd {2}, remoteLabel not present".format(
+ router.name, prefix, rd
+ )
+ if str(path["remoteLabel"]) != label:
+ continue
+
+ if "nexthops" not in path.keys():
+ return "{0}, {1}, rd {2}, no nexthops present".format(
+ router.name, prefix, rd
+ )
+
+ for nh in path["nexthops"]:
+ if "ip" not in nh.keys():
+ return "{0}, {1}, rd {2}, no ipv4 nexthop available".format(
+ router.name, prefix, rd
+ )
+ if nh["ip"] != nexthop:
+ continue
+ return None
+ return "{0}, {1}, rd {2}, remoteLabel {3}, nexthop {4} not found".format(
+ router.name, prefix, rd, label, nexthop
+ )
+
+ func = functools.partial(_check, router, prefix, rd, label, nexthop)
+ success, result = topotest.run_and_expect(func, None, count=20, wait=0.5)
+ assert_msg = "{}, show bgp ipv4 vpn {}, rd {}, label {} nexthop {}".format(
+ router.name, prefix, rd, label, nexthop
+ )
+ assert result is None, assert_msg + " not found"
+ logger.info(assert_msg + " found")
+
+
+def mpls_table_get_entry(router, out_label, out_nexthop):
+ """
+ Get the in_label from tuple (out_label, out_nexthop)
+ * 'router': the router to check
+ * 'out_label': The outgoing label expected
+ * 'out_nexthop': The outgoing nexthop expected
+ """
+ dump = router.vtysh_cmd("show mpls table json", isjson=True)
+ for in_label, label_info in dump.items():
+ for nh in label_info["nexthops"]:
+ if nh["type"] != "BGP" or "installed" not in nh.keys():
+ continue
+ if "nexthop" in nh.keys():
+ if nh["nexthop"] != out_nexthop:
+ continue
+ if "outLabelStack" in nh.keys():
+ if out_label not in nh["outLabelStack"]:
+ continue
+ return in_label
+ return None
+
+
+def mpls_table_check_entry(router, out_label, out_nexthop):
+ """
+ Dump and check 'show mpls table json' output. An assert is triggered in case test fails
+ * 'router': the router to check
+ * 'out_label': The outgoing label expected
+ * 'out_nexthop': The outgoing nexthop expected
+ """
+ logger.info("Checking MPLS labels on {}".format(router.name))
+ dump = router.vtysh_cmd("show mpls table json", isjson=True)
+ for in_label, label_info in dump.items():
+ for nh in label_info["nexthops"]:
+ if nh["type"] != "BGP" or "installed" not in nh.keys():
+ continue
+ if "nexthop" in nh.keys():
+ if nh["nexthop"] != out_nexthop:
+ continue
+ if "outLabelStack" in nh.keys():
+ if out_label not in nh["outLabelStack"]:
+ continue
+ logger.info(
+ "{}, show mpls table, entry in_label {} out_label {} out_nexthop {} found".format(
+ router.name, in_label, nh["outLabelStack"], nh["nexthop"]
+ )
+ )
+ return None
+ return "{}, show mpls table, entry matching in_label {} out_label {} out_nexthop {} not found".format(
+ router.name, in_label, out_label, out_nexthop
+ )
+
+
+def check_show_bgp_vpn_prefix_found(
+ router, ipversion, prefix, rd, label=None, nexthop=None
+):
+ """
+ Check if a given vpn prefix is present in the BGP RIB
+ * 'router': the router to check BGP VPN RIB
+ * 'ipversion': The ip version to check: ipv4 or ipv6
+ * 'prefix': the IP prefix to check
+ * 'rd': the route distinguisher to check
+ * 'label: the label to check
+ """
+ output = json.loads(
+ router.vtysh_cmd("show bgp {} vpn {} json".format(ipversion, prefix))
+ )
+ if label:
+ if nexthop:
+ expected = {
+ rd: {
+ "prefix": prefix,
+ "paths": [{"remoteLabel": label, "nexthops": [{"ip": nexthop}]}],
+ }
+ }
+ else:
+ expected = {rd: {"prefix": prefix, "paths": [{"remoteLabel": label}]}}
+ else:
+ if nexthop:
+ expected = {
+ rd: {"prefix": prefix, "paths": [{"nexthops": [{"ip": nexthop}]}]}
+ }
+ else:
+ expected = {rd: {"prefix": prefix}}
+ return topotest.json_cmp(output, expected)
+
+
+def check_show_bgp_vpn_prefix_not_found(router, ipversion, prefix, rd, label=None):
+ """
+ Check if a given vpn prefix is not present in the BGP RIB
+ * 'router': the router to check BGP VPN RIB
+ * 'ipversion': The ip version to check: ipv4 or ipv6
+ * 'prefix': the IP prefix to check
+ * 'rd': the route distinguisher to check
+ * 'label: the label to check
+ """
+ output = json.loads(
+ router.vtysh_cmd("show bgp {} vpn {} json".format(ipversion, prefix))
+ )
+ if label:
+ expected = {rd: {"prefix": prefix, "paths": [{"remoteLabel": label}]}}
+ else:
+ expected = {rd: {"prefix": prefix}}
+ ret = topotest.json_cmp(output, expected)
+ if ret is None:
+ return "not good"
+ return None
+
+
+def check_show_mpls_table_entry_label_not_found(router, inlabel):
+ output = json.loads(router.vtysh_cmd("show mpls table {} json".format(inlabel)))
+ expected = {"inLabel": inlabel, "installed": True}
+ ret = topotest.json_cmp(output, expected)
+ if ret is None:
+ return "not good"
+ return None
+
+
+def check_show_bgp_vpn_ok(router, vpnv4_entries):
+ """
+ Check on router that BGP l3vpn entries are present
+ Check there is an MPLS entry bound to that BGP L3VPN entry
+ Extract the Label value and check on the distributed router the BGP L3VPN entry
+ If check fail, an assert is triggered.
+ * 'router': the router to check BGP VPN RIB
+ * 'vpnv4_entries': dictionary that contains the list of prefixes, and the distributed router to look after
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ vpnv4_nexthops = {"r1": "192.0.2.2", "r3": "192.168.1.2"}
+ vpnv4_nht = {"192.0.2.1": "192.168.0.1", "192.168.1.3": "192.168.1.3"}
+ label_ip_entries = {}
+
+ def _return_remote_label_nh_rd(router, prefix):
+ dump = router.vtysh_cmd("show bgp ipv4 vpn {} json".format(prefix), isjson=True)
+ assert_msg = (
+ "{}, prefix {} not available or label not found",
+ router.name,
+ prefix,
+ )
+ assert dump, assert_msg
+ for rd, pathes in dump.items():
+ for path in pathes["paths"]:
+ if "remoteLabel" not in path.keys():
+ assert 0, assert_msg
+ for nh in path["nexthops"]:
+ if "ip" in nh.keys():
+ return path["remoteLabel"], nh["ip"], rd
+ assert 0, assert_msg
+
+ def _check_nexthop_available(router, prefix):
+ dump = router.vtysh_cmd("show bgp ipv4 vpn {} json".format(prefix), isjson=True)
+ if not dump:
+ return "{0}, {1}, route distinguisher not present".format(
+ router.name, prefix
+ )
+ for rd, pathes in dump.items():
+ for path in pathes["paths"]:
+ if "remoteLabel" not in path.keys():
+ return "{0}, {1}, remoteLabel not present".format(
+ router.name, prefix
+ )
+ if "nexthops" not in path.keys():
+ return "{0}, {1}, no nexthop available".format(router.name, prefix)
+ return None
+
+ for prefix, rname_to_test in vpnv4_entries.items():
+ func = functools.partial(_check_nexthop_available, router, prefix)
+ success, result = topotest.run_and_expect(func, None, count=20, wait=0.5)
+ assert result is None, "Failed to detect prefix {} on router {}".format(
+ prefix, router.name
+ )
+
+ for prefix, rname_to_test in vpnv4_entries.items():
+ l3vpn_label, l3vpn_nh, l3vpn_rd = _return_remote_label_nh_rd(router, prefix)
+ logger.info(
+ "{0}, {1}, label value is {2}, nh is {3}".format(
+ router.name, prefix, l3vpn_label, l3vpn_nh
+ )
+ )
+ test_func = functools.partial(
+ mpls_table_check_entry, router, l3vpn_label, vpnv4_nht[l3vpn_nh]
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, result
+
+ in_label = mpls_table_get_entry(router, l3vpn_label, vpnv4_nht[l3vpn_nh])
+ label_ip_entries[prefix] = in_label
+
+ bgp_vpnv4_prefix_check(
+ tgen.gears[rname_to_test],
+ l3vpn_rd,
+ prefix,
+ in_label,
+ vpnv4_nexthops[rname_to_test],
+ )
+
+ return label_ip_entries
+
+
+def test_protocols_convergence():
+ """
+ Assert that all protocols have converged
+ Check that Labels are as expected in r1, r2,and r3
+ Check ping connectivity between h1 and h2
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # check that r2 peerings are ok
+ logger.info("Checking BGP ipv4 vpn summary for r2")
+ router = tgen.gears["r2"]
+ json_file = "{}/{}/ipv4_vpn_summary.json".format(CWD, router.name)
+ expected = json.loads(open(json_file).read())
+ test_func = partial(
+ topotest.router_json_cmp,
+ router,
+ "show bgp ipv4 vpn summary json",
+ expected,
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=20, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+
+def test_mpls_setup_ok():
+ """
+ tests for the r1 to r3 direction: checks for prefix=('172.31.1.0/24','172.31.2.0/24','172.31.3.0/24')
+ r2. get label from 'prefix'
+ check that r2. show mpls table has an entry with outbound label set to the label from 172.31.1.0/24
+ r2. get label from mpls entry
+ check that r1: show bgp ipv4 vpn 172.31.1.0/24 has label from r2.mpls entry
+ tests for the r3 to r1 direction
+ r2. get label from 172.31.0.0/24
+ check that r2. show mpls table has an entry with outbound label set that includes the label from 172.31.0.0/24
+ r2. get label from mpls entry
+ check that r3: show bgp ipv4 vpn 172.31.0.0/24 has label from r2.mpls entry
+ check that h1. ping 172.31.1.10 (h2) is ok.
+ check that h1. ping 172.31.2.10 (h3) is ok.
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+ router = tgen.gears["r2"]
+
+ # diagnostic
+ logger.info("Dumping mplsvpn nexthop table")
+ router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False)
+
+ vpnv4_checks = {
+ "172.31.1.0/24": "r1",
+ "172.31.2.0/24": "r1",
+ "172.31.3.0/24": "r1",
+ "172.31.0.0/24": "r3",
+ }
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on all devices".format(
+ router.name
+ )
+ )
+ check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+ logger.info("h1, check that ping from h1 to (h2,h3) is ok")
+ check_ping("h1", "172.31.1.10", True, 20, 0.5)
+ check_ping("h1", "172.31.2.10", True, 20, 0.5)
+
+
+def test_r3_prefixes_removed():
+ """
+ Remove BGP redistributed updates from r3.
+ Check that the BGP VPN updates from the updates are not present on r2.
+ Check that the 'show bgp ipv4 vpn' and 'show mpls table' are ok for 172.31.3.0/24
+ Remove the 172.31.3.0/24 update from BGP on r3.
+ Check that the BGP VPN updates from r3 are not present on r2.
+ Check that the 'show mpls table' entry previously seen disappeared
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+ router = tgen.gears["r3"]
+ logger.info("{}, keeping only 172.31.3.0/24 network".format(router.name))
+ router.vtysh_cmd("configure terminal\ninterface r3-eth1 vrf vrf1\nshutdown\n")
+ router.vtysh_cmd("configure terminal\ninterface r3-eth2 vrf vrf1\nshutdown\n")
+
+ router = tgen.gears["r2"]
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' has only 172.31.3.0/24 network from r3".format(
+ router.name
+ )
+ )
+
+ for prefix in ("172.31.1.0/24", "172.31.2.0/24"):
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_not_found,
+ router,
+ "ipv4",
+ prefix,
+ "444:3",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, vpnv4 update {} still present".format(router.name, prefix)
+
+ # diagnostic
+ logger.info("Dumping mplsvpn nexthop table")
+ router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False)
+
+ prefix = "172.31.3.0/24"
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format(
+ router.name
+ )
+ )
+ vpnv4_checks = {
+ prefix: "r1",
+ }
+ label_ip_entries = check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+ router = tgen.gears["r3"]
+ logger.info("{}, removing {} network".format(router.name, prefix))
+ router.vtysh_cmd("configure terminal\ninterface r3-eth3 vrf vrf1\nshutdown\n")
+
+ router = tgen.gears["r2"]
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' has not {} network from r3".format(
+ router.name, prefix
+ )
+ )
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_not_found,
+ router,
+ "ipv4",
+ prefix,
+ "444:3",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, vpnv4 update {} still present".format(router.name, prefix)
+
+ logger.info(
+ "{}, check that 'show mpls table {}' is not present".format(
+ router.name, label_ip_entries[prefix]
+ )
+ )
+ test_func = functools.partial(
+ check_show_mpls_table_entry_label_not_found, router, label_ip_entries[prefix]
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "r1, mpls entry with in_label {} still present".format(
+ label_ip_entries[prefix]
+ )
+
+
+def test_r3_prefixes_added_back():
+ """
+ Add back the 172.31.3.0/24 network from r3
+ Check on r2 that MPLS switching entry appears when the 1st BGP update is received
+ Check the IP connectivity (h1,h2) and (h1,h3)
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+ router = tgen.gears["r3"]
+ prefix = "172.31.3.0/24"
+ logger.info("{}, restoring the {} network from r3".format(router.name, prefix))
+ router.vtysh_cmd("configure terminal\ninterface r3-eth3 vrf vrf1\nno shutdown\n")
+
+ router = tgen.gears["r2"]
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' has {} network from r3".format(
+ router.name, prefix
+ )
+ )
+
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_found,
+ router,
+ "ipv4",
+ prefix,
+ "444:3",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, vpnv4 update {} not present".format(router.name, prefix)
+
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format(
+ router.name
+ )
+ )
+ vpnv4_checks = {
+ prefix: "r1",
+ }
+ check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+ router = tgen.gears["r3"]
+ logger.info(
+ "{}, restoring the redistribute connected prefixes from r3".format(router.name)
+ )
+ router.vtysh_cmd("configure terminal\ninterface r3-eth1 vrf vrf1\nno shutdown\n")
+ router.vtysh_cmd("configure terminal\ninterface r3-eth2 vrf vrf1\nno shutdown\n")
+ router = tgen.gears["r2"]
+ for prefix in ("172.31.1.0/24", "172.31.2.0/24"):
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_found,
+ router,
+ "ipv4",
+ prefix,
+ "444:3",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, vpnv4 update {} not present".format(router.name, prefix)
+
+ # diagnostic
+ logger.info("Dumping mplsvpn nexthop table")
+ tgen.gears["r2"].vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False)
+
+
+def test_unconfigure_nexthop_change_nexthop_self():
+ """
+ Get the list of labels advertised from r2 to r1
+ On r2, disable next-hop-self for 192.0.2.100 neighbor
+ Check that the list of labels are not present in 'show mpls table'
+ Check that r1 received the prefixes with the original (next-hop,label)
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r2"]
+ vpnv4_checks = {
+ "172.31.1.0/24": "r1",
+ "172.31.2.0/24": "r1",
+ "172.31.3.0/24": "r1",
+ }
+ logger.info(
+ "{}, Get the list of labels allocated for prefixes from r3".format(router.name)
+ )
+ label_ip_entries = check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+ logger.info(
+ "{}, disable next-hop-self for 192.0.2.100 neighbor".format(router.name)
+ )
+ router = tgen.gears["r2"]
+ router.vtysh_cmd(
+ "configure terminal\nrouter bgp 65500\naddress-family ipv4 vpn\nno neighbor 192.0.2.100 next-hop-self\n"
+ )
+
+ for prefix, label in label_ip_entries.items():
+ logger.info(
+ "{}, check mpls entry for {} with in_label {} is not present'".format(
+ router.name, prefix, label
+ )
+ )
+ test_func = functools.partial(
+ check_show_mpls_table_entry_label_not_found, router, label
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "r1, mpls entry for {} with in_label {} still present".format(
+ prefix, label
+ )
+
+ router = tgen.gears["r1"]
+ for prefix, label in label_ip_entries.items():
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_not_found,
+ router,
+ "ipv4",
+ prefix,
+ "444:3",
+ label=label,
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, mpls vpn update {} label {} is present".format(
+ router.name, prefix, label
+ )
+ for prefix, label in label_ip_entries.items():
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_found,
+ router,
+ "ipv4",
+ prefix,
+ "444:3",
+ nexthop="192.168.1.3",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, mpls vpn update {} label {} is present".format(
+ router.name, prefix, label
+ )
+
+ # diagnostic
+ logger.info("Dumping mplsvpn nexthop table")
+ tgen.gears["r2"].vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False)
+
+
+def test_reconfigure_nexthop_change_nexthop_self():
+ """
+ Get the list of labels advertised from r2 to r1
+ On r2, enable next-hop-self for 192.0.2.100 neighbor
+ Check that the list of labels are present in 'show mpls table'
+ Check that r1 received the prefixes with the original (next-hop,label)
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r2"]
+ logger.info("{}, enable next-hop-self for 192.0.2.100 neighbor".format(router.name))
+ router.vtysh_cmd(
+ "configure terminal\nrouter bgp 65500\naddress-family ipv4 vpn\nneighbor 192.0.2.100 next-hop-self\n"
+ )
+ vpnv4_checks = {
+ "172.31.1.0/24": "r1",
+ "172.31.2.0/24": "r1",
+ "172.31.3.0/24": "r1",
+ }
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format(
+ router.name
+ )
+ )
+ check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+ logger.info("h1, check that ping from h1 to (h2,h3) is ok")
+ check_ping("h1", "172.31.1.10", True, 20, 0.5)
+ check_ping("h1", "172.31.2.10", True, 20, 0.5)
+ # diagnostic
+ logger.info("Dumping mplsvpn nexthop table")
+ router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False)
+
+
+def test_declare_vpn_network_with_different_label():
+ """
+ declare a vpnv4 network on r3.
+ check that a new VPNv4 entry is received on r2.
+ Check that the list of labels are present in 'show mpls table'
+ Check that r1 received the prefixes with the new (next-hop,label)
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r3"]
+ logger.info(
+ "{}, declare static 33.33.33.33/32 network rd 33:33 label 33".format(
+ router.name
+ )
+ )
+ router.vtysh_cmd(
+ "configure terminal\nrouter bgp 65501\nno bgp network import-check\n"
+ )
+ router.vtysh_cmd(
+ "configure terminal\nrouter bgp 65501\naddress-family ipv4 vpn\nnetwork 33.33.33.33/32 rd 444:3 label 33\n"
+ )
+
+ router = tgen.gears["r2"]
+ vpnv4_entries = {
+ "172.31.1.0/24": None,
+ "172.31.2.0/24": None,
+ "172.31.3.0/24": None,
+ "33.33.33.33/32": 33,
+ }
+
+ for prefix, label in vpnv4_entries.items():
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_found,
+ router,
+ "ipv4",
+ prefix,
+ "444:3",
+ label=label,
+ nexthop="192.168.1.3",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, vpnv4 update {}, label {} not present".format(
+ router.name, prefix, label
+ )
+
+ vpnv4_checks = {
+ "172.31.1.0/24": "r1",
+ "172.31.2.0/24": "r1",
+ "172.31.3.0/24": "r1",
+ "33.33.33.33/32": "r1",
+ }
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r1".format(
+ router.name
+ )
+ )
+ check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+
+def test_filter_vpn_network_from_r1():
+ """
+ Get the list of labels in 'show mpls table'
+ filter network from r1
+ check that the vpnv4 entry on r2 is not present
+ Check that the associated mpls entry is not present
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r2"]
+
+ vpnv4_checks = {
+ "172.31.0.0/24": "r3",
+ }
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on r2 and on r3".format(
+ router.name
+ )
+ )
+ label_ip_entries = check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+ for prefix, label in label_ip_entries.items():
+ logger.info("{}, filter prefix {} from r1".format(router.name, prefix))
+ router.vtysh_cmd(
+ "configure terminal\nroute-map rmap deny 1\nmatch ip next-hop address 192.0.2.1\n"
+ )
+ router.vtysh_cmd(
+ "configure terminal\nrouter bgp 65500\naddress-family ipv4 vpn\nneighbor 192.0.2.100 route-map rmap in\n"
+ )
+ logger.info(
+ "{}, check that prefix {} is not present".format(router.name, prefix)
+ )
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_not_found,
+ router,
+ "ipv4",
+ "172.31.0.0/24",
+ "444:1",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, vpnv4 update {}, is still present".format(
+ router.name, prefix
+ )
+
+ # diagnostic
+ logger.info("Dumping mplsvpn nexthop table")
+ router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False)
+
+ logger.info(
+ "{}, check that show mpls table {} is not present".format(
+ router.name, label
+ )
+ )
+ test_func = functools.partial(
+ check_show_mpls_table_entry_label_not_found, router, int(label)
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "r1, mpls entry for {} with in_label {} still present".format(
+ prefix, label
+ )
+
+
+def test_unfilter_vpn_network_from_r1():
+ """
+ unfilter network from r1
+ check that the vpnv4 entry on r2 is present
+ Check that the list of labels are present in 'show mpls table'
+ Check that r3 received the prefixes with the new (next-hop,label)
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r2"]
+ prefix = "172.31.0.0/24"
+
+ logger.info("{}, filter prefix {} from r1".format(router.name, prefix))
+ router.vtysh_cmd(
+ "configure terminal\nrouter bgp 65500\naddress-family ipv4 vpn\nno neighbor 192.0.2.100 route-map rmap in\n"
+ )
+
+ logger.info("{}, check that prefix {} is present".format(router.name, prefix))
+ test_func = functools.partial(
+ check_show_bgp_vpn_prefix_found, router, "ipv4", prefix, "444:1"
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert success, "{}, vpnv4 update {}, is not present".format(router.name, prefix)
+
+ vpnv4_checks = {
+ "172.31.0.0/24": "r3",
+ }
+ logger.info(
+ "{}, check that 'show bgp ipv4 vpn' and 'show mpls table' are set accordingly on all devices".format(
+ router.name
+ )
+ )
+ check_show_bgp_vpn_ok(router, vpnv4_checks)
+
+ # diagnostic
+ logger.info("Dumping mplsvpn nexthop table")
+ router.vtysh_cmd("show bgp mplsvpn-nh-label-bind detail", isjson=False)
+
+
+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))