]> git.proxmox.com Git - mirror_frr.git/blobdiff - tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py
*: auto-convert to SPDX License IDs
[mirror_frr.git] / tests / topotests / ospfv3_basic_functionality / test_ospfv3_routemaps.py
index d8cf3bd02dac78893cef4d6db7be94ae32356270..b2cd0da24e786eb93f4bc0021e75c606ef88a36f 100644 (file)
@@ -1,24 +1,11 @@
 #!/usr/bin/python
+# SPDX-License-Identifier: ISC
 
 #
 # Copyright (c) 2021 by VMware, Inc. ("VMware")
 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
 # ("NetDEF") in this file.
 #
-# 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 VMWARE DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE 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.
-#
 
 
 """OSPF Basic Functionality Automation."""
@@ -26,10 +13,6 @@ import os
 import sys
 import time
 import pytest
-import json
-from copy import deepcopy
-from ipaddress import IPv4Address
-from lib.topotest import frr_unicode
 
 # Save the Current Working Directory to find configuration files.
 CWD = os.path.dirname(os.path.realpath(__file__))
@@ -38,9 +21,7 @@ sys.path.append(os.path.join(CWD, "../lib/"))
 
 # pylint: disable=C0413
 # Import topogen and topotest helpers
-from mininet.topo import Topo
 from lib.topogen import Topogen, get_topogen
-import ipaddress
 
 # Import topoJson from lib, to create topology and initial configuration
 from lib.common_config import (
@@ -54,24 +35,16 @@ from lib.common_config import (
     step,
     create_route_maps,
     verify_prefix_lists,
-    get_frr_ipv6_linklocal,
-    topo_daemons,
 )
 from lib.topolog import logger
-from lib.topojson import build_topo_from_json, build_config_from_json
+from lib.topojson import build_config_from_json
 
 from lib.ospf import (
     verify_ospf6_neighbor,
-    config_ospf_interface,
-    clear_ospf,
     verify_ospf6_rib,
     create_router_ospf,
-    verify_ospf6_interface,
-    verify_ospf6_database,
-    config_ospf6_interface,
 )
 
-from ipaddress import IPv6Address
 
 pytestmark = [pytest.mark.ospfd, pytest.mark.staticd]
 
@@ -79,13 +52,6 @@ pytestmark = [pytest.mark.ospfd, pytest.mark.staticd]
 # Global variables
 topo = None
 
-# Reading the data from JSON File for topology creation
-jsonFile = "{}/ospfv3_routemaps.json".format(CWD)
-try:
-    with open(jsonFile, "r") as topoJson:
-        topo = json.load(topoJson)
-except IOError:
-    assert False, "Could not read file {}".format(jsonFile)
 
 NETWORK = {
     "ipv4": [
@@ -132,28 +98,12 @@ TESTCASES =
  """
 
 
-class CreateTopo(Topo):
-    """
-    Test topology builder.
-
-    * `Topo`: Topology object
-    """
-
-    def build(self, *_args, **_opts):
-        """Build function."""
-        tgen = get_topogen(self)
-
-        # Building topology from json file
-        build_topo_from_json(tgen, topo)
-
-
 def setup_module(mod):
     """
     Sets up the pytest environment
 
     * `mod`: module name
     """
-    global topo
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
     logger.info("=" * 40)
@@ -161,15 +111,15 @@ def setup_module(mod):
     logger.info("Running setup_module to create topology")
 
     # This function initiates the topology build with Topogen...
-    tgen = Topogen(CreateTopo, mod.__name__)
+    json_file = "{}/ospfv3_routemaps.json".format(CWD)
+    tgen = Topogen(json_file, mod.__name__)
+    global topo
+    topo = tgen.json_topo
     # ... and here it calls Mininet initialization functions.
 
-    # get list of daemons needs to be started for this suite.
-    daemons = topo_daemons(tgen, topo)
-
     # Starting topology, create tmp files which are loaded to routers
-    #  to start deamons and then start routers
-    start_topology(tgen, daemons)
+    #  to start daemons and then start routers
+    start_topology(tgen)
 
     # Creating configuration from JSON
     build_config_from_json(tgen, topo)
@@ -211,6 +161,312 @@ def teardown_module(mod):
 # ##################################
 
 
+def test_ospfv3_routemaps_functionality_tc19_p0(request):
+    """
+    OSPF Route map - Verify OSPF route map support functionality.
+
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+    global topo
+    step("Bring up the base config as per the topology")
+    reset_config_on_routers(tgen)
+
+    step("Create static routes(10.0.20.1/32 and 10.0.20.2/32) in R0")
+    # Create Static routes
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {
+                    "network": NETWORK["ipv6"][0],
+                    "no_of_ip": 5,
+                    "next_hop": "Null0",
+                }
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_red_r1 = {"r0": {"ospf6": {"redistribute": [{"redist_type": "static"}]}}}
+    result = create_router_ospf(tgen, topo, ospf_red_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r1"
+    lsid = NETWORK["ipv6"][0].split("/")[0]
+    rid = routerids[0]
+
+    protocol = "ospf"
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_red_r1 = {
+        "r0": {
+            "ospf6": {"redistribute": [{"redist_type": "static", "del_action": True}]}
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_red_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Create prefix-list in R0 to permit 10.0.20.1/32 prefix &" " deny 10.0.20.2/32"
+    )
+
+    # Create ip prefix list
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][0],
+                            "action": "permit",
+                        },
+                        {"seqid": 11, "network": "any", "action": "deny"},
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("verify that prefix-list is created in R0.")
+    result = verify_prefix_lists(tgen, pfx_list)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n, prefix list creation failed. Error: {}".format(
+        tc_name, result
+    )
+
+    # Create route map
+    routemaps = {
+        "r0": {
+            "route_maps": {
+                "rmap_ipv6": [
+                    {
+                        "action": "permit",
+                        "match": {"ipv6": {"prefix_lists": "pf_list_1_ipv6"}},
+                    }
+                ]
+            }
+        }
+    }
+    result = create_route_maps(tgen, routemaps)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step(
+        "Configure route map rmap1 and redistribute static routes to"
+        " ospf using route map rmap1"
+    )
+
+    ospf_red_r1 = {
+        "r0": {
+            "ospf6": {
+                "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_red_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+    step("Verify that route map is activated in OSPF.")
+
+    step("Verify that route 10.0.20.1 is allowed and 10.0.20.2 is denied.")
+    dut = "r1"
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    dut = "r1"
+    lsid = NETWORK["ipv6"][1].split("/")[0]
+    rid = routerids[0]
+
+    step("Change prefix rules to permit 10.0.20.2 and deny 10.0.20.1")
+    # Create ip prefix list
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][1],
+                            "action": "permit",
+                        },
+                        {"seqid": 11, "network": "any", "action": "deny"},
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that route 10.0.20.2 is allowed and 10.0.20.1 is denied.")
+    dut = "r1"
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][1], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB,  Error: {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    step("Delete and reconfigure prefix list.")
+    # Create ip prefix list
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][1],
+                            "action": "permit",
+                            "delete": True,
+                        },
+                        {
+                            "seqid": 11,
+                            "network": "any",
+                            "action": "deny",
+                            "delete": True,
+                        },
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    pfx_list = {
+        "r0": {
+            "prefix_lists": {
+                "ipv6": {
+                    "pf_list_1_ipv6": [
+                        {
+                            "seqid": 10,
+                            "network": NETWORK["ipv6"][1],
+                            "action": "permit",
+                        },
+                        {"seqid": 11, "network": "any", "action": "deny"},
+                    ]
+                }
+            }
+        }
+    }
+    result = create_prefix_lists(tgen, pfx_list)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that route 10.0.20.2 is allowed and 10.0.20.1 is denied.")
+    dut = "r1"
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][1], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "next_hop": "Null0"}
+            ]
+        }
+    }
+    result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    result = verify_rib(
+        tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
+    )
+    assert (
+        result is not True
+    ), "Testcase {} : Failed \n Route found in the RIB, Error: {}".format(
+        tc_name, result
+    )
+
+    write_test_footer(tc_name)
+
+
 def test_ospfv3_routemaps_functionality_tc20_p0(request):
     """
     OSPF route map support functionality.
@@ -494,7 +750,7 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
                     {
                         "action": "permit",
                         "seq_id": "20",
-                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv4"}},
+                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv6"}},
                     },
                 ]
             }
@@ -507,7 +763,7 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
     input_dict_2 = {
         "r0": {
             "prefix_lists": {
-                "ipv4": {
+                "ipv6": {
                     "pf_list_1_ipv6": [
                         {"seqid": 10, "network": NETWORK["ipv6"][0], "action": "permit"}
                     ]
@@ -522,8 +778,8 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
     input_dict_2 = {
         "r0": {
             "prefix_lists": {
-                "ipv4": {
-                    "pf_list_2_ipv4": [
+                "ipv6": {
+                    "pf_list_2_ipv6": [
                         {"seqid": 10, "network": NETWORK["ipv6"][1], "action": "permit"}
                     ]
                 }
@@ -600,7 +856,7 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
                     {
                         "action": "deny",
                         "seq_id": "20",
-                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv4"}},
+                        "match": {"ipv6": {"prefix_lists": "pf_list_2_ipv6"}},
                     }
                 ]
             }
@@ -657,6 +913,106 @@ def test_ospfv3_routemaps_functionality_tc22_p0(request):
     write_test_footer(tc_name)
 
 
+def test_ospfv3_routemaps_functionality_tc23_p0(request):
+    """
+    OSPF Route map - Multiple set clauses.
+
+    Verify OSPF route map support functionality when we add/remove route-maps
+    with multiple set clauses and without any match statement.(Set only)
+
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+    global topo
+    step("Bring up the base config as per the topology")
+
+    reset_config_on_routers(tgen)
+
+    step(
+        " Create static routes(10.0.20.1/32) in R1 and "
+        "redistribute to OSPF using route map."
+    )
+    # Create Static routes
+    input_dict = {
+        "r0": {
+            "static_routes": [
+                {
+                    "network": NETWORK["ipv6"][0],
+                    "no_of_ip": 5,
+                    "next_hop": "Null0",
+                }
+            ]
+        }
+    }
+    result = create_static_routes(tgen, input_dict)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    ospf_red_r0 = {
+        "r0": {
+            "ospf6": {
+                "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv6"}]
+            }
+        }
+    }
+    result = create_router_ospf(tgen, topo, ospf_red_r0)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Configure route map with set clause (set metric)")
+    # Create route map
+    routemaps = {
+        "r0": {
+            "route_maps": {
+                "rmap_ipv6": [
+                    {"action": "permit", "seq_id": 10, "set": {"metric": 123}}
+                ]
+            }
+        }
+    }
+    result = create_route_maps(tgen, routemaps)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that configured metric is applied to ospf routes.")
+    dut = "r1"
+    protocol = "ospf"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict, metric=123)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, metric=123)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("un configure the set clause")
+    # Create route map
+    routemaps = {
+        "r0": {
+            "route_maps": {
+                "rmap_ipv6": [
+                    {
+                        "action": "permit",
+                        "seq_id": 10,
+                        "set": {"metric": 123, "delete": True},
+                    }
+                ]
+            }
+        }
+    }
+    result = create_route_maps(tgen, routemaps)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    step("Verify that metric falls back to original metric for ospf routes.")
+    dut = "r1"
+    protocol = "ospf"
+
+    result = verify_ospf6_rib(tgen, dut, input_dict, metric=20)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol, metric=20)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    write_test_footer(tc_name)
+
+
 def test_ospfv3_routemaps_functionality_tc24_p0(request):
     """
     OSPF Route map - Multiple set clauses.