]> git.puffer.fish Git - matthieu/frr.git/commitdiff
topotests: add vpnv4 ecmp test
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 9 Jan 2023 15:29:25 +0000 (16:29 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Sun, 26 Feb 2023 08:44:16 +0000 (09:44 +0100)
This test ensures that BGP VRF instance is able to import ECMP
paths, and is able to install 2 labelled routes accordingly.

The test also ensures that the imported 172.31.0.10/32 prefix
is selected and that the reason why the 172.31.0.10/32 prefix is
selected is not 'Locally configured route'. Actually, imported
routes do not figure out correctly the peer, and the reason is
falsely mentioned as local.

This test also uses IP ranges used for documentation and for
testing.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
tests/topotests/bgp_vpnv4_ebgp/r1/bgp_ipv4_routes.json [new file with mode: 0644]
tests/topotests/bgp_vpnv4_ebgp/r1/bgpd.conf
tests/topotests/bgp_vpnv4_ebgp/r1/ipv4_routes.json
tests/topotests/bgp_vpnv4_ebgp/r1/zebra.conf
tests/topotests/bgp_vpnv4_ebgp/r2/bgp_ipv4_routes.json
tests/topotests/bgp_vpnv4_ebgp/r2/bgpd.conf
tests/topotests/bgp_vpnv4_ebgp/r2/zebra.conf
tests/topotests/bgp_vpnv4_ebgp/r3/bgp_ipv4_routes.json [new file with mode: 0644]
tests/topotests/bgp_vpnv4_ebgp/r3/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_vpnv4_ebgp/r3/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py

diff --git a/tests/topotests/bgp_vpnv4_ebgp/r1/bgp_ipv4_routes.json b/tests/topotests/bgp_vpnv4_ebgp/r1/bgp_ipv4_routes.json
new file mode 100644 (file)
index 0000000..184ab31
--- /dev/null
@@ -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
+                        }
+                    ]
+                }
+            ]
+         }
+}
index 2eebe5e6dd1aa57117db267dbc913cc22afa4f12..0249279c65d2cb547a4d515f754478f74c760865 100644 (file)
@@ -1,16 +1,19 @@
 router bgp 65500
- bgp router-id 1.1.1.1
+ bgp router-id 192.0.2.1
  no bgp ebgp-requires-policy
- neighbor 10.125.0.2 remote-as 65501
+ neighbor 192.168.0.2 remote-as 65501
+ neighbor 192.168.0.3 remote-as 65501
  address-family ipv4 unicast
-  no neighbor 10.125.0.2 activate
+  no neighbor 192.168.0.3 activate
+  no neighbor 192.168.0.2 activate
  exit-address-family
  address-family ipv4 vpn
-  neighbor 10.125.0.2 activate
+  neighbor 192.168.0.2 activate
+  neighbor 192.168.0.3 activate
  exit-address-family
 !
 router bgp 65500 vrf vrf1
- bgp router-id 1.1.1.1
+ bgp router-id 192.0.2.1
  address-family ipv4 unicast
   redistribute connected
   label vpn export 101
index da7d2818330c4467595d5b6359dcf5aadb69c73f..79b020af7689055ebbd6ca1fff783fa25e158098 100644 (file)
@@ -1,8 +1,8 @@
 {
-    "10.200.0.0/24": [
+    "172.31.0.10/32": [
         {
-            "prefix": "10.200.0.0/24",
-            "prefixLen": 24,
+            "prefix": "172.31.0.10/32",
+            "prefixLen": 32,
             "protocol": "bgp",
             "vrfName": "vrf1",
             "selected": true,
                 {
                     "flags": 3,
                     "fib": true,
-                    "ip": "10.125.0.2",
+                    "ip": "192.168.0.2",
+                    "afi": "ipv4",
+                    "interfaceName": "r1-eth0",
+                    "vrf": "default",
+                    "active": true,
+                   "labels":[
+                       102
+                   ]
+                },
+                {
+                    "flags": 3,
+                    "fib": true,
+                    "ip": "192.168.0.3",
                     "afi": "ipv4",
                     "interfaceName": "r1-eth0",
                     "vrf": "default",
             ]
         }
     ],
-    "10.201.0.0/24": [
+    "172.31.0.1/32": [
         {
-            "prefix": "10.201.0.0/24",
-            "prefixLen": 24,
+            "prefix": "172.31.0.1/32",
+            "prefixLen": 32,
             "protocol": "connected",
             "vrfName": "vrf1",
             "selected": true,
index e9ae4e9831de1b16c243bf55b253155f1876737b..f626e448a757eb256fa3c981d8fb4db822bfe763 100644 (file)
@@ -1,7 +1,7 @@
 log stdout
 interface r1-eth1 vrf vrf1
- ip address 10.201.0.1/24
+ ip address 172.31.0.1/32
 !
 interface r1-eth0
- ip address 10.125.0.1/24
+ ip address 192.168.0.1/24
 !
index 19797dd561a86ccae8e4942f779565b8254ecd84..1fc3a4b89c308ff871ce2966d214f1ebccbdeb7b 100644 (file)
@@ -3,28 +3,28 @@
      "localAS": 65501,
      "routes":
          {
-            "10.201.0.0/24": [
+            "172.31.0.1/32": [
                 {
-                    "prefix": "10.201.0.0",
-                    "prefixLen": 24,
-                    "network": "10.201.0.0\/24",
+                    "prefix": "172.31.0.1",
+                    "prefixLen": 32,
+                    "network": "172.31.0.1\/32",
                     "nhVrfName": "default",
                     "nexthops": [
                         {
-                            "ip": "10.125.0.1",
+                            "ip": "192.168.0.1",
                             "afi": "ipv4",
                             "used": true
                         }
                     ]
                 }
             ],
-            "10.200.0.0/24": [
+            "172.31.0.10/32": [
                 {
                     "valid": true,
                     "bestpath": true,
-                    "prefix": "10.200.0.0",
-                    "prefixLen": 24,
-                    "network": "10.200.0.0\/24",
+                    "prefix": "172.31.0.10",
+                    "prefixLen": 32,
+                    "network": "172.31.0.10\/32",
                     "nexthops": [
                         {
                             "ip": "0.0.0.0",
index e38c99d69cb5e1376bd414e0a2dd85756cf08c8b..e873469d7932230498b5591ec3e3f5c2e0e34c0c 100644 (file)
@@ -1,16 +1,16 @@
 router bgp 65501
- bgp router-id 2.2.2.2
+ bgp router-id 192.0.2.2
  no bgp ebgp-requires-policy
- neighbor 10.125.0.1 remote-as 65500
+ neighbor 192.168.0.1 remote-as 65500
  address-family ipv4 unicast
-  no neighbor 10.125.0.1 activate
+  no neighbor 192.168.0.1 activate
  exit-address-family
  address-family ipv4 vpn
-  neighbor 10.125.0.1 activate
+  neighbor 192.168.0.1 activate
  exit-address-family
 !
 router bgp 65501 vrf vrf1
- bgp router-id 2.2.2.2
+ bgp router-id 192.0.2.2
  address-family ipv4 unicast
   redistribute connected
   label vpn export 102
index 6c433aef2be601ec83b4e26b2c4f26c7fc2ac606..bbc524065d72406ebfd3eb26df1b012ce6534f04 100644 (file)
@@ -1,7 +1,7 @@
 log stdout
 interface r2-eth1 vrf vrf1
- ip address 10.200.0.2/24
+ ip address 172.31.0.10/32
 !
 interface r2-eth0
- ip address 10.125.0.2/24
+ ip address 192.168.0.2/24
 !
diff --git a/tests/topotests/bgp_vpnv4_ebgp/r3/bgp_ipv4_routes.json b/tests/topotests/bgp_vpnv4_ebgp/r3/bgp_ipv4_routes.json
new file mode 100644 (file)
index 0000000..19797dd
--- /dev/null
@@ -0,0 +1,38 @@
+{
+     "vrfName": "vrf1",
+     "localAS": 65501,
+     "routes":
+         {
+            "10.201.0.0/24": [
+                {
+                    "prefix": "10.201.0.0",
+                    "prefixLen": 24,
+                    "network": "10.201.0.0\/24",
+                    "nhVrfName": "default",
+                    "nexthops": [
+                        {
+                            "ip": "10.125.0.1",
+                            "afi": "ipv4",
+                            "used": true
+                        }
+                    ]
+                }
+            ],
+            "10.200.0.0/24": [
+                {
+                    "valid": true,
+                    "bestpath": true,
+                    "prefix": "10.200.0.0",
+                    "prefixLen": 24,
+                    "network": "10.200.0.0\/24",
+                    "nexthops": [
+                        {
+                            "ip": "0.0.0.0",
+                            "afi": "ipv4",
+                            "used": true
+                        }
+                    ]
+                }
+            ]
+         }
+}
diff --git a/tests/topotests/bgp_vpnv4_ebgp/r3/bgpd.conf b/tests/topotests/bgp_vpnv4_ebgp/r3/bgpd.conf
new file mode 100644 (file)
index 0000000..a327638
--- /dev/null
@@ -0,0 +1,25 @@
+router bgp 65501
+ bgp router-id 192.0.2.3
+ no bgp ebgp-requires-policy
+ neighbor 192.168.0.1 remote-as 65500
+ address-family ipv4 unicast
+  no neighbor 192.168.0.1 activate
+ exit-address-family
+ address-family ipv4 vpn
+  neighbor 192.168.0.1 activate
+ exit-address-family
+!
+router bgp 65502 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_ebgp/r3/zebra.conf b/tests/topotests/bgp_vpnv4_ebgp/r3/zebra.conf
new file mode 100644 (file)
index 0000000..4412c04
--- /dev/null
@@ -0,0 +1,7 @@
+log stdout
+interface r3-eth1 vrf vrf1
+ ip address 172.31.0.10/32
+!
+interface r3-eth0
+ ip address 192.168.0.3/24
+!
index 342bad20abe3c8857761fa86a00fdc105e4118c0..61e1163c18fe1467b4d61db18a82c5a40f8a30b8 100644 (file)
@@ -40,10 +40,12 @@ def build_topo(tgen):
     # Create 2 routers.
     tgen.add_router("r1")
     tgen.add_router("r2")
+    tgen.add_router("r3")
 
     switch = tgen.add_switch("s1")
     switch.add_link(tgen.gears["r1"])
     switch.add_link(tgen.gears["r2"])
+    switch.add_link(tgen.gears["r3"])
 
     switch = tgen.add_switch("s2")
     switch.add_link(tgen.gears["r1"])
@@ -51,27 +53,38 @@ def build_topo(tgen):
     switch = tgen.add_switch("s3")
     switch.add_link(tgen.gears["r2"])
 
+    switch = tgen.add_switch("s4")
+    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',
+        "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 cmd in cmds_list:
-        input = cmd.format('r1', '1', '2')
-        logger.info('input: ' + cmd)
-        output = tgen.net['r1'].cmd(cmd.format('r1', '1', '2'))
-        logger.info('output: ' + output)
+        input = cmd.format("r1")
+        logger.info("input: " + cmd)
+        output = tgen.net["r1"].cmd(cmd.format("r1"))
+        logger.info("output: " + output)
+
+    for cmd in cmds_list:
+        input = cmd.format("r2")
+        logger.info("input: " + cmd)
+        output = tgen.net["r2"].cmd(cmd.format("r2"))
+        logger.info("output: " + output)
 
     for cmd in cmds_list:
-        input = cmd.format('r2', '2', '1')
-        logger.info('input: ' + cmd)
-        output = tgen.net['r2'].cmd(cmd.format('r2', '2', '1'))
-        logger.info('output: ' + output)
+        input = cmd.format("r3")
+        logger.info("input: " + cmd)
+        output = tgen.net["r3"].cmd(cmd.format("r3"))
+        logger.info("output: " + output)
+
 
 def setup_module(mod):
     "Sets up the pytest environment"
@@ -109,13 +122,13 @@ def test_protocols_convergence():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    router = tgen.gears['r1']
+    router = tgen.gears["r1"]
     logger.info("Dump some context for r1")
     router.vtysh_cmd("show bgp ipv4 vpn")
     router.vtysh_cmd("show bgp summary")
     router.vtysh_cmd("show bgp vrf vrf1 ipv4")
     router.vtysh_cmd("show running-config")
-    router = tgen.gears['r2']
+    router = tgen.gears["r2"]
     logger.info("Dump some context for r2")
     router.vtysh_cmd("show bgp ipv4 vpn")
     router.vtysh_cmd("show bgp summary")
@@ -124,11 +137,11 @@ def test_protocols_convergence():
 
     # Check IPv4 routing tables on r1
     logger.info("Checking IPv4 routes for convergence on r1")
-    router = tgen.gears['r1']
+    router = tgen.gears["r1"]
     json_file = "{}/{}/ipv4_routes.json".format(CWD, router.name)
     if not os.path.isfile(json_file):
         logger.info("skipping file {}".format(json_file))
-        assert 0, 'ipv4_routes.json file not found'
+        assert 0, "ipv4_routes.json file not found"
         return
 
     expected = json.loads(open(json_file).read())
@@ -142,12 +155,52 @@ def test_protocols_convergence():
     assertmsg = '"{}" JSON output mismatches'.format(router.name)
     assert result is None, assertmsg
 
+    # Check BGP IPv4 routing tables on r1
+    logger.info("Checking BGP IPv4 routes for convergence on r1")
+    router = tgen.gears["r1"]
+    json_file = "{}/{}/bgp_ipv4_routes.json".format(CWD, router.name)
+    if not os.path.isfile(json_file):
+        assert 0, "bgp_ipv4_routes.json file not found"
+
+    expected = json.loads(open(json_file).read())
+    test_func = partial(
+        topotest.router_json_cmp,
+        router,
+        "show bgp vrf vrf1 ipv4 json",
+        expected,
+    )
+    _, result = topotest.run_and_expect(test_func, None, count=40, wait=2)
+    assertmsg = '"{}" JSON output mismatches'.format(router.name)
+    assert result is None, assertmsg
+
+    # Check BGP IPv4 imported entry is not detected as local
+    # "selectionReason": "Locally configured route"
+    donna = tgen.gears["r1"].vtysh_cmd(
+        "show bgp vrf vrf1 ipv4 172.31.0.10/32 json", isjson=True
+    )
+    routes = donna["paths"]
+    selectionReasonFound = False
+    for route in routes:
+        if "bestpath" not in route.keys():
+            continue
+        if "selectionReason" not in route["bestpath"].keys():
+            continue
+
+        if "Locally configured route" == route["bestpath"]["selectionReason"]:
+            assert 0, "imported prefix has wrong reason detected"
+
+        selectionReasonFound = True
+
+    if not selectionReasonFound:
+        assertmsg = '"{}" imported prefix has wrong reason detected'.format(router.name)
+        assert False, assertmsg
+
     # Check BGP IPv4 routing tables on r2 not installed
     logger.info("Checking BGP IPv4 routes for convergence on r2")
-    router = tgen.gears['r2']
+    router = tgen.gears["r2"]
     json_file = "{}/{}/bgp_ipv4_routes.json".format(CWD, router.name)
     if not os.path.isfile(json_file):
-        assert 0, 'bgp_ipv4_routes.json file not found'
+        assert 0, "bgp_ipv4_routes.json file not found"
 
     expected = json.loads(open(json_file).read())
     test_func = partial(
@@ -159,7 +212,8 @@ def test_protocols_convergence():
     _, result = topotest.run_and_expect(test_func, None, count=40, wait=2)
     assertmsg = '"{}" JSON output mismatches'.format(router.name)
     assert result is None, assertmsg
-    
+
+
 def test_memory_leak():
     "Run the memory leak test and report results."
     tgen = get_topogen()